Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package buildstream for openSUSE:Factory 
checked in at 2023-02-23 16:30:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/buildstream (Old)
 and      /work/SRC/openSUSE:Factory/.buildstream.new.1706 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "buildstream"

Thu Feb 23 16:30:23 2023 rev:25 rq:1067348 version:1.6.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/buildstream/buildstream.changes  2022-10-16 
16:09:39.902817908 +0200
+++ /work/SRC/openSUSE:Factory/.buildstream.new.1706/buildstream.changes        
2023-02-23 16:54:02.969359596 +0100
@@ -1,0 +2,6 @@
+Wed Feb 22 11:58:55 UTC 2023 - Bjørn Lie <bjorn....@gmail.com>
+
+- Update to version 1.6.9:
+  + Further Python 3.11 fixes to regex flags.
+
+-------------------------------------------------------------------

Old:
----
  buildstream-1.6.8.tar.gz

New:
----
  buildstream-1.6.9.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ buildstream.spec ++++++
--- /var/tmp/diff_new_pack.QgwjSO/_old  2023-02-23 16:54:04.181366624 +0100
+++ /var/tmp/diff_new_pack.QgwjSO/_new  2023-02-23 16:54:04.185366647 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package buildstream
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           buildstream
-Version:        1.6.8
+Version:        1.6.9
 Release:        0
 Summary:        A framework for modelling build pipelines in YAML
 License:        LGPL-2.1-or-later

++++++ buildstream-1.6.8.tar.gz -> buildstream-1.6.9.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/.github/common.env 
new/buildstream-1.6.9/.github/common.env
--- old/buildstream-1.6.8/.github/common.env    2022-10-12 17:13:38.000000000 
+0200
+++ new/buildstream-1.6.9/.github/common.env    2023-02-21 15:31:28.000000000 
+0100
@@ -1,5 +1,5 @@
 # Shared common variables
 
-CI_IMAGE_VERSION=master-533491591
-CI_TOXENV_MAIN=py36-nocover,py37-nocover,py38-nocover,py39-nocover,py310-nocover
+CI_IMAGE_VERSION=master-784208155
+CI_TOXENV_MAIN=py36-nocover,py37-nocover,py38-nocover,py39-nocover,py310-nocover,py311-nocover
 CI_TOXENV_ALL="${CI_TOXENV_MAIN}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/buildstream-1.6.8/.github/compose/ci.docker-compose.yml 
new/buildstream-1.6.9/.github/compose/ci.docker-compose.yml
--- old/buildstream-1.6.8/.github/compose/ci.docker-compose.yml 2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/.github/compose/ci.docker-compose.yml 2023-02-21 
15:31:28.000000000 +0100
@@ -1,7 +1,7 @@
 version: '3.4'
 
 x-tests-template: &tests-template
-    image: 
registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:35-${CI_IMAGE_VERSION:-latest}
+    image: 
registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:36-${CI_IMAGE_VERSION:-latest}
     command: tox -vvvvv -- --color=yes --integration
     environment:
       TOXENV: ${CI_TOXENV_ALL}
@@ -22,14 +22,14 @@
 
 services:
 
-  fedora-35:
-    <<: *tests-template
-    image: 
registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:35-${CI_IMAGE_VERSION:-latest}
-
   fedora-36:
     <<: *tests-template
     image: 
registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:36-${CI_IMAGE_VERSION:-latest}
 
+  fedora-37:
+    <<: *tests-template
+    image: 
registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-fedora:37-${CI_IMAGE_VERSION:-latest}
+
   debian-10:
     <<: *tests-template
     image: 
registry.gitlab.com/buildstream/buildstream-docker-images/testsuite-debian:10-${CI_IMAGE_VERSION:-latest}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/.github/run-ci.sh 
new/buildstream-1.6.9/.github/run-ci.sh
--- old/buildstream-1.6.8/.github/run-ci.sh     2022-10-12 17:13:38.000000000 
+0200
+++ new/buildstream-1.6.9/.github/run-ci.sh     2023-02-21 15:31:28.000000000 
+0100
@@ -67,8 +67,8 @@
 if [ -z "${test_names}" ]; then
     runTest "lint"
     runTest "debian-10"
-    runTest "fedora-35"
     runTest "fedora-36"
+    runTest "fedora-37"
 else
     for test_name in "${test_names}"; do
        runTest "${test_name}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/.github/workflows/ci.yml 
new/buildstream-1.6.9/.github/workflows/ci.yml
--- old/buildstream-1.6.8/.github/workflows/ci.yml      2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/.github/workflows/ci.yml      2023-02-21 
15:31:28.000000000 +0100
@@ -26,8 +26,8 @@
         # "../compose/ci.docker-compose.yml"
         test-name:
           - debian-10
-          - fedora-35
           - fedora-36
+          - fedora-37
           - lint
 
     steps:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/NEWS new/buildstream-1.6.9/NEWS
--- old/buildstream-1.6.8/NEWS  2022-10-12 17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/NEWS  2023-02-21 15:31:28.000000000 +0100
@@ -1,4 +1,10 @@
 =================
+buildstream 1.6.9
+=================
+
+  o Further Python 3.11 fixes to regex flags.
+
+=================
 buildstream 1.6.8
 =================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/buildstream/_exceptions.py 
new/buildstream-1.6.9/buildstream/_exceptions.py
--- old/buildstream-1.6.8/buildstream/_exceptions.py    2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/buildstream/_exceptions.py    2023-02-21 
15:31:28.000000000 +0100
@@ -24,25 +24,10 @@
 # pylint: disable=global-statement
 
 # The last raised exception, this is used in test cases only
-_last_exception = None
 _last_task_error_domain = None
 _last_task_error_reason = None
 
 
-# get_last_exception()
-#
-# Fetches the last exception from the main process
-#
-# Used by regression tests
-#
-def get_last_exception():
-    global _last_exception
-
-    le = _last_exception
-    _last_exception = None
-    return le
-
-
 # get_last_task_error()
 #
 # Fetches the last exception from a task
@@ -102,7 +87,6 @@
 class BstError(Exception):
 
     def __init__(self, message, *, detail=None, domain=None, reason=None, 
temporary=False):
-        global _last_exception
 
         super().__init__(message)
 
@@ -126,9 +110,6 @@
         self.domain = domain
         self.reason = reason
 
-        # Hold on to the last raised exception for testing purposes
-        _last_exception = self
-
 
 # PluginError
 #
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/buildstream/_frontend/app.py 
new/buildstream-1.6.9/buildstream/_frontend/app.py
--- old/buildstream-1.6.8/buildstream/_frontend/app.py  2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/buildstream/_frontend/app.py  2023-02-21 
15:31:28.000000000 +0100
@@ -22,9 +22,11 @@
 import resource
 import traceback
 import datetime
+from enum import Enum
 from textwrap import TextWrapper
 from contextlib import contextmanager
 
+import ujson
 import click
 from click import UsageError
 
@@ -35,7 +37,7 @@
 from .._context import Context
 from .._platform import Platform
 from .._project import Project
-from .._exceptions import BstError, StreamError, LoadError, LoadErrorReason, 
AppError
+from .._exceptions import BstError, StreamError, LoadError, LoadErrorReason, 
AppError, get_last_task_error
 from .._message import Message, MessageType, unconditional_messages
 from .._stream import Stream
 from .._versions import BST_FORMAT_VERSION
@@ -682,6 +684,20 @@
             detail = '\n' + indent + indent.join(error.detail.splitlines(True))
             click.echo("{}".format(detail), err=True)
 
+        # Record machine readable errors in a tempfile for the test harness to 
read back
+        if 'BST_TEST_ERROR_CODES' in os.environ:
+            task_error_domain, task_error_reason = get_last_task_error ()
+            error_codes = ujson.dumps ({
+                'main_error_domain': error.domain.value if error.domain else 
None,
+                'main_error_reason': error.reason.value if isinstance 
(error.reason, Enum) else error.reason,
+                'task_error_domain': task_error_domain.value if 
task_error_domain else None,
+                'task_error_reason': (
+                    task_error_reason.value if isinstance (task_error_reason, 
Enum) else task_error_reason
+                )
+            })
+            with open (os.environ['BST_TEST_ERROR_CODES'], "w", 
encoding="utf-8") as f:
+                f.write (error_codes)
+
         sys.exit(-1)
 
     #
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/buildstream/_version.py 
new/buildstream-1.6.9/buildstream/_version.py
--- old/buildstream-1.6.8/buildstream/_version.py       2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/buildstream/_version.py       2023-02-21 
15:31:28.000000000 +0100
@@ -24,9 +24,9 @@
     # setup.py/versioneer.py will grep for the variable names, so they must
     # each be defined on a line of their own. _version.py will just call
     # get_keywords().
-    git_refnames = " (tag: 1.6.8, bst-1)"
-    git_full = "0f431178ffa5a6d3e385378660ba574f5f5fb17e"
-    git_date = "2022-10-13 00:13:38 +0900"
+    git_refnames = " (tag: 1.6.9, bst-1)"
+    git_full = "4abd1f3e1b5e5d128bc24e45ec9a37d61723be87"
+    git_date = "2023-02-21 23:31:28 +0900"
     keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
     return keywords
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/buildstream/element.py 
new/buildstream-1.6.9/buildstream/element.py
--- old/buildstream-1.6.8/buildstream/element.py        2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/buildstream/element.py        2023-02-21 
15:31:28.000000000 +0100
@@ -2311,7 +2311,9 @@
         bstdata = self.get_public_data('bst')
         splits = bstdata.get('split-rules')
         self.__splits = {
-            domain: re.compile('^(?:' + '|'.join([utils._glob2re(r) for r in 
rules]) + ')$')
+            domain: re.compile(
+                "^(?:" + "|".join([utils._glob2re(r) for r in rules]) + ")$", 
re.MULTILINE | re.DOTALL
+            )
             for domain, rules in self.node_items(splits)
         }
 
@@ -2386,7 +2388,7 @@
                 for index, exp in enumerate(whitelist)
             ]
             expression = ('^(?:' + '|'.join(whitelist_expressions) + ')$')
-            self.__whitelist_regex = re.compile(expression)
+            self.__whitelist_regex = re.compile(expression, re.MULTILINE | 
re.DOTALL)
         return self.__whitelist_regex.match(path) or 
self.__whitelist_regex.match(os.path.join(os.sep, path))
 
     # __extract():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/buildstream/plugins/sources/pip.py 
new/buildstream-1.6.9/buildstream/plugins/sources/pip.py
--- old/buildstream-1.6.8/buildstream/plugins/sources/pip.py    2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/buildstream/plugins/sources/pip.py    2023-02-21 
15:31:28.000000000 +0100
@@ -93,6 +93,7 @@
     'python3.8',
     'python3.9',
     'python3.10',
+    'python3.11',
 ]
 
 # List of allowed extensions taken from
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/buildstream/utils.py 
new/buildstream-1.6.9/buildstream/utils.py
--- old/buildstream-1.6.8/buildstream/utils.py  2022-10-12 17:13:38.000000000 
+0200
+++ new/buildstream-1.6.9/buildstream/utils.py  2023-02-21 15:31:28.000000000 
+0100
@@ -200,7 +200,7 @@
         pattern = os.sep + pattern
 
     expression = _glob2re(pattern)
-    regexer = re.compile(expression)
+    regexer = re.compile(expression, re.MULTILINE | re.DOTALL)
 
     for filename in paths:
         filename_try = filename
@@ -1138,7 +1138,7 @@
 #
 def _glob2re(pat):
     i, n = 0, len(pat)
-    res = '(?ms)'
+    res = ''
     while i < n:
         c = pat[i]
         i = i + 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/requirements/requirements.txt 
new/buildstream-1.6.9/requirements/requirements.txt
--- old/buildstream-1.6.8/requirements/requirements.txt 2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/requirements/requirements.txt 2023-02-21 
15:31:28.000000000 +0100
@@ -1,5 +1,5 @@
 click==8.1.3
-grpcio==1.48.0
+grpcio==1.51.1
 Jinja2==3.1.2
 pluginbase==1.0.1
 protobuf==4.21.4
@@ -9,5 +9,5 @@
 ujson==5.4.0
 ## The following requirements were added by pip freeze:
 MarkupSafe==2.1.1
-ruamel.yaml.clib==0.2.6
+ruamel.yaml.clib==0.2.7
 six==1.16.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/setup.py 
new/buildstream-1.6.9/setup.py
--- old/buildstream-1.6.8/setup.py      2022-10-12 17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/setup.py      2023-02-21 15:31:28.000000000 +0100
@@ -263,6 +263,8 @@
           'Programming Language :: Python :: 3.7',
           'Programming Language :: Python :: 3.8',
           'Programming Language :: Python :: 3.9',
+          'Programming Language :: Python :: 3.10',
+          'Programming Language :: Python :: 3.11',
           'Topic :: Software Development :: Build Tools'
       ],
       description='A framework for modelling build pipelines in YAML',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/tests/artifactcache/expiry.py 
new/buildstream-1.6.9/tests/artifactcache/expiry.py
--- old/buildstream-1.6.8/tests/artifactcache/expiry.py 2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/tests/artifactcache/expiry.py 2023-02-21 
15:31:28.000000000 +0100
@@ -289,6 +289,7 @@
 # has 10K total disk space, and 6K of it is already in use (not
 # including any space used by the artifact cache).
 #
+@pytest.mark.xfail(reason="unittest.mock() not supported when running tests in 
subprocesses")
 @pytest.mark.parametrize("quota,err_domain,err_reason", [
     # Valid configurations
     ("1", 'success', None),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/tests/format/assertion.py 
new/buildstream-1.6.9/tests/format/assertion.py
--- old/buildstream-1.6.8/tests/format/assertion.py     2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/tests/format/assertion.py     2023-02-21 
15:31:28.000000000 +0100
@@ -32,4 +32,4 @@
 
     # Assert that the assertion text provided by the user
     # is found in the exception text
-    assert assertion in str(result.exception)
+    assert assertion in str(result.stderr)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/tests/format/optionarch.py 
new/buildstream-1.6.9/tests/format/optionarch.py
--- old/buildstream-1.6.8/tests/format/optionarch.py    2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/tests/format/optionarch.py    2023-02-21 
15:31:28.000000000 +0100
@@ -12,6 +12,12 @@
 # Context manager to override the reported value of `os.uname()`
 @contextmanager
 def override_uname_arch(name):
+
+    #
+    # Disabling this test since we now run bst in a subprocess during tests.
+    #
+    pytest.xfail("Overriding os.uname() in bst subprocess is unsupported")
+
     orig_uname = os.uname
     orig_tuple = tuple(os.uname())
     override_result = (orig_tuple[0], orig_tuple[1],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/tests/frontend/fetch.py 
new/buildstream-1.6.9/tests/frontend/fetch.py
--- old/buildstream-1.6.8/tests/frontend/fetch.py       2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/tests/frontend/fetch.py       2023-02-21 
15:31:28.000000000 +0100
@@ -71,8 +71,7 @@
     #    more gracefully as a BUG message.
     #
     result = cli.run(project=project, args=['fetch', 'bug.bst'])
-    assert result.exc is not None
-    assert str(result.exc) == "Something went terribly wrong"
+    assert "Something went terribly wrong" in result.stderr
 
 
 @pytest.mark.datafiles(DATA_DIR)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/tests/frontend/show.py 
new/buildstream-1.6.9/tests/frontend/show.py
--- old/buildstream-1.6.8/tests/frontend/show.py        2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/tests/frontend/show.py        2023-02-21 
15:31:28.000000000 +0100
@@ -269,6 +269,7 @@
 ###############################################################
 #                   Testing recursion depth                   #
 ###############################################################
+@pytest.mark.xfail(reason="recursion errors not currently detectable")
 @pytest.mark.parametrize("dependency_depth", [100, 500, 1200])
 def test_exceed_max_recursion_depth(cli, tmpdir, dependency_depth):
     project_name = "recursion-test"
@@ -314,8 +315,14 @@
     if dependency_depth <= recursion_limit:
         result.assert_success()
     else:
-        #  Assert exception is thown and handled
-        assert not result.unhandled_exception
+        # XXX Assert exception is thown and handled
+        #
+        # We need to assert that the client has not thrown a stack trace for
+        # a recursion error, this should be done by creating a BstError instead
+        # of just handling it in app.py and doing sys.exit(), because we no 
longer
+        # have any way of detecting whether the client has thrown an exception
+        # otherwise
+        #
         assert result.exit_code == -1
 
     shutil.rmtree(project_path)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/tests/integration/symlinks.py 
new/buildstream-1.6.9/tests/integration/symlinks.py
--- old/buildstream-1.6.8/tests/integration/symlinks.py 2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/tests/integration/symlinks.py 2023-02-21 
15:31:28.000000000 +0100
@@ -70,5 +70,5 @@
     # point outside the sandbox which BuildStream needs to detect before it
     # tries to actually write there.
     result = cli.run(project=project, args=['checkout', element_name, 
checkout])
-    assert result.exit_code == -1
+    assert result.exit_code != 0
     assert "Destination path resolves to a path outside of the staging area" 
in result.stderr
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/tests/loader/junctions.py 
new/buildstream-1.6.9/tests/loader/junctions.py
--- old/buildstream-1.6.8/tests/loader/junctions.py     2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/tests/loader/junctions.py     2023-02-21 
15:31:28.000000000 +0100
@@ -135,10 +135,7 @@
     copy_subprojects(project, datafiles, ['foo', 'bar'])
 
     result = cli.run(project=project, args=['build', 'target.bst'])
-    assert result.exit_code != 0
-    assert result.exception
-    assert isinstance(result.exception, LoadError)
-    assert result.exception.reason == LoadErrorReason.CONFLICTING_JUNCTION
+    result.assert_main_error(ErrorDomain.LOAD, 
LoadErrorReason.CONFLICTING_JUNCTION)
 
 
 @pytest.mark.datafiles(DATA_DIR)
@@ -146,10 +143,7 @@
     project = os.path.join(str(datafiles), 'invalid')
 
     result = cli.run(project=project, args=['build', 'missing.bst'])
-    assert result.exit_code != 0
-    assert result.exception
-    assert isinstance(result.exception, LoadError)
-    assert result.exception.reason == LoadErrorReason.MISSING_FILE
+    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.MISSING_FILE)
 
 
 @pytest.mark.datafiles(DATA_DIR)
@@ -158,10 +152,7 @@
     copy_subprojects(project, datafiles, ['base'])
 
     result = cli.run(project=project, args=['build', 'junction-with-deps.bst'])
-    assert result.exit_code != 0
-    assert result.exception
-    assert isinstance(result.exception, ElementError)
-    assert result.exception.reason == 'element-forbidden-depends'
+    result.assert_main_error(ErrorDomain.ELEMENT, 'element-forbidden-depends')
 
 
 @pytest.mark.datafiles(DATA_DIR)
@@ -170,10 +161,7 @@
     copy_subprojects(project, datafiles, ['base'])
 
     result = cli.run(project=project, args=['build', 'junction-dep.bst'])
-    assert result.exit_code != 0
-    assert result.exception
-    assert isinstance(result.exception, LoadError)
-    assert result.exception.reason == LoadErrorReason.INVALID_DATA
+    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)
 
 
 @pytest.mark.datafiles(DATA_DIR)
@@ -248,10 +236,7 @@
 
     # Verify that bst show does not implicitly fetch subproject
     result = cli.run(project=project, args=['show', 'target.bst'])
-    assert result.exit_code != 0
-    assert result.exception
-    assert isinstance(result.exception, LoadError)
-    assert result.exception.reason == LoadErrorReason.SUBPROJECT_FETCH_NEEDED
+    result.assert_main_error(ErrorDomain.LOAD, 
LoadErrorReason.SUBPROJECT_FETCH_NEEDED)
 
     # Explicitly fetch subproject
     result = cli.run(project=project, args=['fetch', 'base.bst'])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/tests/sources/tar.py 
new/buildstream-1.6.9/tests/sources/tar.py
--- old/buildstream-1.6.8/tests/sources/tar.py  2022-10-12 17:13:38.000000000 
+0200
+++ new/buildstream-1.6.9/tests/sources/tar.py  2023-02-21 15:31:28.000000000 
+0100
@@ -348,6 +348,7 @@
 
 # Test that BuildStream doesnt crash if HOME is unset while
 # the netrc module is trying to find it's ~/.netrc file.
+@pytest.mark.xfail(reason="Cannot set environment variable to None when 
running tests in subprocesses")
 @pytest.mark.datafiles(os.path.join(DATA_DIR, 'fetch'))
 def test_homeless_environment(cli, tmpdir, datafiles):
     project = os.path.join(datafiles.dirname, datafiles.basename)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/tests/testutils/runcli.py 
new/buildstream-1.6.9/tests/testutils/runcli.py
--- old/buildstream-1.6.8/tests/testutils/runcli.py     2022-10-12 
17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/tests/testutils/runcli.py     2023-02-21 
15:31:28.000000000 +0100
@@ -7,6 +7,8 @@
 import traceback
 import subprocess
 from contextlib import contextmanager, ExitStack
+from enum import Enum
+import ujson
 import pytest
 
 # XXX Using pytest private internals here
@@ -22,50 +24,21 @@
 from buildstream._frontend import cli as bst_cli
 from buildstream import _yaml
 
-# Special private exception accessor, for test case purposes
-from buildstream._exceptions import BstError, get_last_exception, 
get_last_task_error
-
 
 # Wrapper for the click.testing result
 class Result():
 
     def __init__(self,
                  exit_code=None,
-                 exception=None,
-                 exc_info=None,
                  output=None,
                  stderr=None):
         self.exit_code = exit_code
-        self.exc = exception
-        self.exc_info = exc_info
         self.output = output
         self.stderr = stderr
-        self.unhandled_exception = False
-
-        # The last exception/error state is stored at exception
-        # creation time in BstError(), but this breaks down with
-        # recoverable errors where code blocks ignore some errors
-        # and fallback to alternative branches.
-        #
-        # For this reason, we just ignore the exception and errors
-        # in the case that the exit code reported is 0 (success).
-        #
-        if self.exit_code != 0:
-
-            # Check if buildstream failed to handle an
-            # exception, topevel CLI exit should always
-            # be a SystemExit exception.
-            #
-            if not isinstance(exception, SystemExit):
-                self.unhandled_exception = True
-
-            self.exception = get_last_exception()
-            self.task_error_domain, \
-                self.task_error_reason = get_last_task_error()
-        else:
-            self.exception = None
-            self.task_error_domain = None
-            self.task_error_reason = None
+        self.main_error_domain = None
+        self.main_error_reason = None
+        self.task_error_domain = None
+        self.task_error_reason = None
 
     # assert_success()
     #
@@ -79,9 +52,6 @@
     #
     def assert_success(self, fail_message=''):
         assert self.exit_code == 0, fail_message
-        assert self.exc is None, fail_message
-        assert self.exception is None, fail_message
-        assert self.unhandled_exception is False
 
     # assert_main_error()
     #
@@ -106,23 +76,20 @@
             print(
                 """
                 Exit code: {}
-                Exception: {}
                 Domain:    {}
                 Reason:    {}
                 """.format(
                     self.exit_code,
-                    self.exception,
-                    self.exception.domain,
-                    self.exception.reason
+                    self.main_error_domain,
+                    self.main_error_reason
                 ))
-        assert self.exit_code == -1, fail_message
-        assert self.exc is not None, fail_message
-        assert self.exception is not None, fail_message
-        assert isinstance(self.exception, BstError), fail_message
-        assert self.unhandled_exception is False
+        assert self.exit_code != 0, fail_message
+
+        test_domain = error_domain.value if isinstance (error_domain, Enum) 
else error_domain
+        test_reason = error_reason.value if isinstance (error_reason, Enum) 
else error_reason
 
-        assert self.exception.domain == error_domain, fail_message
-        assert self.exception.reason == error_reason, fail_message
+        assert self.main_error_domain == test_domain, fail_message
+        assert self.main_error_reason == test_reason, fail_message
 
     # assert_task_error()
     #
@@ -143,14 +110,12 @@
                           error_reason,
                           fail_message=''):
 
-        assert self.exit_code == -1, fail_message
-        assert self.exc is not None, fail_message
-        assert self.exception is not None, fail_message
-        assert isinstance(self.exception, BstError), fail_message
-        assert self.unhandled_exception is False
+        test_domain = error_domain.value if isinstance (error_domain, Enum) 
else error_domain
+        test_reason = error_reason.value if isinstance (error_reason, Enum) 
else error_reason
 
-        assert self.task_error_domain == error_domain, fail_message
-        assert self.task_error_reason == error_reason, fail_message
+        assert self.exit_code != 0, fail_message
+        assert self.task_error_domain == test_domain, fail_message
+        assert self.task_error_reason == test_reason, fail_message
 
     # get_tracked_elements()
     #
@@ -241,9 +206,21 @@
         if options is None:
             options = []
 
+        if env is None:
+            env = os.environ.copy()
+        else:
+            orig_env = os.environ.copy()
+            orig_env.update (env)
+            env = orig_env
+
         options = self.default_options + options
 
         with ExitStack() as stack:
+
+            # Prepare a tempfile for buildstream to record machine readable 
error codes
+            error_codes = stack.enter_context (tempfile.NamedTemporaryFile())
+            env['BST_TEST_ERROR_CODES'] = error_codes.name
+
             bst_args = ['--no-colors']
 
             if silent:
@@ -263,21 +240,34 @@
 
             bst_args += args
 
-            if cwd is not None:
-                stack.enter_context(chdir(cwd))
-
-            if env is not None:
-                stack.enter_context(environment(env))
-
-            # Ensure we have a working stdout - required to work
-            # around a bug that appears to cause AIX to close
-            # sys.__stdout__ after setup.py
-            try:
-                sys.__stdout__.fileno()
-            except ValueError:
-                sys.__stdout__ = open('/dev/stdout', 'w')
+            cmd = ["bst"] + bst_args
+            process = subprocess.Popen(
+                cmd,
+                env=env,
+                cwd=cwd,
+                stdin=subprocess.DEVNULL,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.PIPE,
+            )
+            out, err = process.communicate()
+            result = Result(
+                exit_code=process.poll(),
+                output=out.decode('utf-8'),
+                stderr=err.decode('utf-8')
+            )
 
-            result = self.invoke(bst_cli, bst_args)
+            #
+            # Collect machine readable error codes from the tmpfile
+            #
+            result_error_codes_string = error_codes.read()
+            result_error_codes = {}
+            if result_error_codes_string:
+                result_error_codes = ujson.loads (result_error_codes_string)
+            if result_error_codes:
+                result.main_error_domain = 
result_error_codes['main_error_domain']
+                result.main_error_reason = 
result_error_codes['main_error_reason']
+                result.task_error_domain = 
result_error_codes['task_error_domain']
+                result.task_error_reason = 
result_error_codes['task_error_reason']
 
         # Some informative stdout we can observe when anything fails
         if self.verbose:
@@ -289,54 +279,8 @@
             if result.stderr:
                 print("Program stderr was:\n{}".format(result.stderr))
 
-            if result.exc_info and result.exc_info[0] != SystemExit:
-                traceback.print_exception(*result.exc_info)
-
         return result
 
-    def invoke(self, cli, args=None, color=False, **extra):
-        exc_info = None
-        exception = None
-        exit_code = 0
-
-        # Temporarily redirect sys.stdin to /dev/null to ensure that
-        # Popen doesn't attempt to read pytest's dummy stdin.
-        old_stdin = sys.stdin
-        with open(os.devnull) as devnull:
-            sys.stdin = devnull
-            capture = MultiCapture(out=FDCapture(1), err=FDCapture(2), 
in_=None)
-            capture.start_capturing()
-
-            try:
-                cli.main(args=args or (), prog_name=cli.name, **extra)
-            except SystemExit as e:
-                if e.code != 0:
-                    exception = e
-
-                exc_info = sys.exc_info()
-
-                exit_code = e.code
-                if not isinstance(exit_code, int):
-                    sys.stdout.write('Program exit code was not an integer: ')
-                    sys.stdout.write(str(exit_code))
-                    sys.stdout.write('\n')
-                    exit_code = 1
-            except Exception as e:
-                exception = e
-                exit_code = -1
-                exc_info = sys.exc_info()
-            finally:
-                sys.stdout.flush()
-
-        sys.stdin = old_stdin
-        out, err = capture.readouterr()
-        capture.stop_capturing()
-
-        return Result(exit_code=exit_code,
-                      exception=exception,
-                      exc_info=exc_info,
-                      output=out,
-                      stderr=err)
 
     # Fetch an element state by name by
     # invoking bst show on the project with the CLI
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/buildstream-1.6.8/tox.ini 
new/buildstream-1.6.9/tox.ini
--- old/buildstream-1.6.8/tox.ini       2022-10-12 17:13:38.000000000 +0200
+++ new/buildstream-1.6.9/tox.ini       2023-02-21 15:31:28.000000000 +0100
@@ -2,7 +2,7 @@
 # Tox global configuration
 #
 [tox]
-envlist = py36-nocover,py37-nocover,py38-nocover,py39-nocover,py310-nocover
+envlist = 
py36-nocover,py37-nocover,py38-nocover,py39-nocover,py310-nocover,py311-nocover
 skip_missing_interpreters = true
 
 #
@@ -13,16 +13,16 @@
 [testenv]
 commands =
     # Running with coverage reporting enabled
-    py{36,37,38,39,310}-!nocover: pytest --basetemp {envtmpdir} 
--cov=buildstream --cov-config .coveragerc {posargs}
-    py{36,37,38,39,310}-!nocover: mkdir -p .coverage-reports
-    py{36,37,38,39,310}-!nocover: mv {envtmpdir}/.coverage 
{toxinidir}/.coverage-reports/.coverage.{env:COVERAGE_PREFIX:}{envname}
+    py{36,37,38,39,310,311}-!nocover: pytest --basetemp {envtmpdir} 
--cov=buildstream --cov-config .coveragerc {posargs}
+    py{36,37,38,39,310,311}-!nocover: mkdir -p .coverage-reports
+    py{36,37,38,39,310,311}-!nocover: mv {envtmpdir}/.coverage 
{toxinidir}/.coverage-reports/.coverage.{env:COVERAGE_PREFIX:}{envname}
 
     # Running with coverage reporting disabled
-    py{36,37,38,39,310}-nocover: pytest --basetemp {envtmpdir} {posargs}
+    py{36,37,38,39,310,311}-nocover: pytest --basetemp {envtmpdir} {posargs}
 deps =
-    py{36,37,38,39,310}: -rrequirements/requirements.txt
-    py{36,37,38,39,310}: -rrequirements/dev-requirements.txt
-    py{36,37,38,39,310}: -rrequirements/plugin-requirements.txt
+    py{36,37,38,39,310,311}: -rrequirements/requirements.txt
+    py{36,37,38,39,310,311}: -rrequirements/dev-requirements.txt
+    py{36,37,38,39,310,311}: -rrequirements/plugin-requirements.txt
 
     # Only require coverage and pytest-cov when using it
     !nocover: -rrequirements/cov-requirements.txt
@@ -35,9 +35,9 @@
 # These keys are not inherited by any other sections
 #
 setenv =
-    py{36,37,38,39,310}: COVERAGE_FILE = {envtmpdir}/.coverage
+    py{36,37,38,39,310,311}: COVERAGE_FILE = {envtmpdir}/.coverage
 whitelist_externals =
-    py{36,37,38,39,310}:
+    py{36,37,38,39,310,311}:
         mv
         mkdir
 

Reply via email to