amoffat / sh

Python process launching

Home Page:https://sh.readthedocs.io/en/latest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2.0.4: pytest is failing in two units

kloczek opened this issue · comments

I'm packaging your module as an rpm package so I'm using the typical PEP517 based build, install and test cycle used on building packages from non-root account.

  • python3 -sBm build -w --no-isolation
  • because I'm calling build with --no-isolation I'm using during all processes only locally installed modules
  • install .whl file in </install/prefix> using 'installer` module
  • run pytest with $PYTHONPATH pointing to sitearch and sitelib inside </install/prefix>
  • build is performed in env which is cut off from access to the public network (pytest is executed with -m "not network")

First of all pytest by default is not able to find units because by default pytest scans only pests_*py files

+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-sh-2.0.4-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-sh-2.0.4-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra -m 'not network'
==================================================================================== test session starts ====================================================================================
platform linux -- Python 3.8.17, pytest-7.4.0, pluggy-1.2.0
rootdir: /home/tkloczko/rpmbuild/BUILD/sh-2.0.4
collected 0 items

=================================================================================== no tests ran in 0.01s ===================================================================================

After specify tests/test.py as param

+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-sh-2.0.4-5.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-sh-2.0.4-5.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra -m 'not network' tests/test.py
============================= test session starts ==============================
platform linux -- Python 3.8.17, pytest-7.4.0, pluggy-1.2.0
rootdir: /home/tkloczko/rpmbuild/BUILD/sh-2.0.4
collected 178 items

tests/test.py .......................................................... [ 32%]
.................................................F.......s.............. [ 73%]
............................................F...                         [100%]

=================================== FAILURES ===================================
_______________________ FunctionalTests.test_environment _______________________

self = <tests.test.FunctionalTests testMethod=test_environment>

        def test_environment(self):
            """tests that environments variables that we pass into sh commands
            exist in the environment, and on the sh module"""
            import os

            # this is the environment we'll pass into our commands
            env = {"HERP": "DERP"}

            # first we test that the environment exists in our child process as
            # we've set it
            py = create_tmp_test(
                """
    import os

    for key in list(os.environ.keys()):
        if key != "HERP":
            del os.environ[key]
    print(dict(os.environ))
    """
            )
            out = python(py.name, _env=env).strip()
            self.assertEqual(out, "{'HERP': 'DERP'}")

            py = create_tmp_test(
                """
    import os, sys
    sys.path.insert(0, os.getcwd())
    import sh
    for key in list(os.environ.keys()):
        if key != "HERP":
            del os.environ[key]
    print(dict(HERP=sh.HERP))
    """
            )
>           out = python(py.name, _env=env, _cwd=THIS_DIR).strip()

tests/test.py:561:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sh.py:1524: in __call__
    rc = self.__class__.RunningCommandCls(cmd, call_args, stdin, stdout, stderr)
sh.py:750: in __init__
    self.wait()
sh.py:812: in wait
    self.handle_command_exit_code(exit_code)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = , code = 1

    def handle_command_exit_code(self, code):
        """here we determine if we had an exception, or an error code that we
        weren't expecting to see.  if we did, we create and raise an exception
        """
        ca = self.call_args
        exc_class = get_exc_exit_code_would_raise(code, ca["ok_code"], ca["piped"])
        if exc_class:
            exc = exc_class(
                self.ran, self.process.stdout, self.process.stderr, ca["truncate_exc"]
            )
>           raise exc
E           sh.ErrorReturnCode_1:
E
E             RAN: /usr/bin/python3 /tmp/tmpj69wvicz
E
E             STDOUT:
E
E
E             STDERR:
E           Traceback (most recent call last):
E             File "/tmp/tmpj69wvicz", line 4, in <module>
E               import sh
E           ModuleNotFoundError: No module named 'sh'

sh.py:839: ErrorReturnCode_1
________________ ExecutionContextTests.test_multiline_defaults _________________

self = <tests.test.ExecutionContextTests testMethod=test_multiline_defaults>

        def test_multiline_defaults(self):
            py = create_tmp_test(
                """
    import os
    print(os.environ["ABC"])
    """
            )

            sh2 = sh.bake(
                _env={
                    "ABC": "123",
                }
            )
>           output = sh2.python(py.name).strip()

tests/test.py:3437:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sh.py:3676: in __getattr__
    return self.__env[name]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = {}, k = 'python'

    def __getitem__(self, k):
        if k == "args":
            # Let the deprecated '_args' context manager be imported as 'args'
            k = "_args"

        # if we're trying to import something real, see if it's in our global scope.
        # what defines "real" is that it's in our allowlist
        if k in self.allowlist:
            return self.globs[k]

        # somebody tried to be funny and do "from sh import *"
        if k == "__all__":
            warnings.warn(
                "Cannot import * from sh. Please import sh or import programs "
                "individually."
            )
            return []

        # check if we're naming a dynamically generated ReturnCode exception
        exc = get_exc_from_name(k)
        if exc:
            return exc

        # https://github.com/ipython/ipython/issues/2577
        # https://github.com/amoffat/sh/issues/97#issuecomment-10610629
        if k.startswith("__") and k.endswith("__"):
            raise AttributeError

        # is it a command?
        cmd = resolve_command(k, self.globs[Command.__name__], self.baked_args)
        if cmd:
            return cmd

        # is it a custom builtin?
        builtin = getattr(self, "b_" + k, None)
        if builtin:
            return builtin

        # how about an environment variable?
        # this check must come after testing if its a command, because on some
        # systems, there are an environment variables that can conflict with
        # command names.
        # https://github.com/amoffat/sh/issues/238
        try:
            return os.environ[k]
        except KeyError:
            pass

        # nothing found, raise an exception
>       raise CommandNotFound(k)
E       sh.CommandNotFound: python

sh.py:3456: CommandNotFound
=============================== warnings summary ===============================
tests/test.py::FunctionalTests::test_fg_alternative
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread STDIN thread for pid 2891644

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2607, in input_thread
      done = stdin.write()
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2920, in write
      chunk = self.get_chunk()
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2861, in fn
      chunk = stdin.read(bufsize)
    File "/usr/lib/python3.8/site-packages/_pytest/capture.py", line 202, in read
      raise OSError(
  OSError: pytest: reading from stdin while output is captured!  Consider using `-s`.

    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/test.py::FunctionalTests::test_signal_group
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 2891689

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2657, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2348, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 839, in handle_command_exit_code
      raise exc
  sh.SignalException_SIGKILL:

    RAN: /usr/bin/python3 /tmp/tmphvw6e9i8

    STDOUT:
  2891694
  2891689


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/test.py::FunctionalTests::test_general_signal
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 2891699

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2657, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2348, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 839, in handle_command_exit_code
      raise exc
  sh.SignalException_SIGKILL:

    RAN: /usr/bin/python3 /tmp/tmphvw6e9i8

    STDOUT:
  2891704
  2891699


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/test.py::FunctionalTests::test_done_cb_exc
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 2891774

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2657, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2348, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 839, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_1:

    RAN: /usr/bin/python3 /tmp/tmpsqp3jbqi

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/test.py::FunctionalTests::test_stdout_callback_terminate
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 2891942

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2657, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2348, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 839, in handle_command_exit_code
      raise exc
  sh.SignalException_SIGTERM:

    RAN: /usr/bin/python3 -u /tmp/tmpgumk0zii

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/test.py::FunctionalTests::test_unchecked_producer_failure
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 2892081

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2657, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2348, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 839, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_2:

    RAN: /usr/bin/python3 /tmp/tmpevgaxuj1

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/test.py::FunctionalTests::test_piped_exception1
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 2892164

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2657, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2348, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 839, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_2:

    RAN: /usr/bin/python3 /tmp/tmpq44bwo30

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/test.py::FunctionalTests::test_piped_exception2
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 2892204

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2657, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2348, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 839, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_2:

    RAN: /usr/bin/python3 /tmp/tmp2h4nd4d_

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/test.py::FunctionalTests::test_unchecked_pipeline_failure
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 2892280

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2657, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2348, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 839, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_2:

    RAN: /usr/bin/python3 /tmp/tmp0e4wbgzt

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/test.py::FunctionalTests::test_stdout_callback_kill
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 2892347

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2657, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2348, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 839, in handle_command_exit_code
      raise exc
  sh.SignalException_SIGKILL:

    RAN: /usr/bin/python3 -u /tmp/tmpy_51g1en

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/test.py::FunctionalTests::test_exit_code_with_hasattr
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 2892451

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2657, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2348, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 839, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_3:

    RAN: /usr/bin/python3 /tmp/tmp9o6e7lpx

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/test.py::FunctionalTests::test_signal_exception
  /usr/lib/python3.8/site-packages/_pytest/threadexception.py:73: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 2892466

  Traceback (most recent call last):
    File "/usr/lib64/python3.8/threading.py", line 932, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.8/threading.py", line 870, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 1655, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2657, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 2348, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.4/sh.py", line 839, in handle_command_exit_code
      raise exc
  sh.SignalException_SIGTERM:

    RAN: /usr/bin/python3 /tmp/tmp61l9pcls

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
SKIPPED [1] tests/test.py:2310: what's the best way to test a different '_encoding' special keywordargument?
FAILED tests/test.py::FunctionalTests::test_environment - sh.ErrorReturnCode_1:
FAILED tests/test.py::ExecutionContextTests::test_multiline_defaults - sh.Com...
============ 2 failed, 175 passed, 1 skipped, 12 warnings in 51.79s ============

Here is list of installed modules in build env

Package         Version
--------------- -------
build           0.10.0
distro          1.8.0
exceptiongroup  1.1.1
gpg             1.20.0
iniconfig       2.0.0
installer       0.7.0
libcomps        0.1.19
packaging       23.1
pluggy          1.2.0
poetry-core     1.6.1
pyproject_hooks 1.0.0
pytest          7.4.0
python-dateutil 2.8.2
six             1.16.0
tomli           2.0.1
wheel           0.40.0
commented

I am making a change so that pytest finds the tests easier.

The test failures appear to be unique to your environment. It looks to be related to your setting of PYTHONPATH, but I cannot be sure.

The test failures appear to be unique to your environment. It looks to be related to your setting of PYTHONPATH, but I cannot be sure.

Currently that methodology is widely used during packaging across Fedora and Debian.
As you see test suite is not able to locate sh module only in two units so probably those units are messing with $PATHONPATH and/or with os.path.

commented

Yes the tests do alter the PYTHONPATH as well, here. Do you have any idea why the test environment may not be respecting the alterations?

No idea .. 😞

FYI: as long as looks like this issue is strictly related to test suite and not to the tested code I've added in my build procedure those two units to --deselect list so it is not kind of critical issue.

Just retested 2.0.6 and I see that still one unit is failing

Here is pytest output:
+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-sh-2.0.6-5.fc36.x86_64/usr/lib64/python3.9/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-sh-2.0.6-5.fc36.x86_64/usr/lib/python3.9/site-packages
+ /usr/bin/pytest -ra -m 'not network'
==================================================================================== test session starts ====================================================================================
platform linux -- Python 3.9.18, pytest-8.1.1, pluggy-1.4.0
rootdir: /home/tkloczko/rpmbuild/BUILD/sh-2.0.6
configfile: pyproject.toml
collected 179 items

tests/sh_test.py .....Fs............................................................................................................................................................. [ 91%]
...............                                                                                                                                                                       [100%]

========================================================================================= FAILURES ==========================================================================================
_____________________________________________________________________________ FunctionalTests.test_environment ______________________________________________________________________________

self = <tests.sh_test.FunctionalTests testMethod=test_environment>

        def test_environment(self):
            """tests that environments variables that we pass into sh commands
            exist in the environment, and on the sh module"""
            import os

            # this is the environment we'll pass into our commands
            env = {"HERP": "DERP"}

            # first we test that the environment exists in our child process as
            # we've set it
            py = create_tmp_test(
                """
    import os

    for key in list(os.environ.keys()):
        if key != "HERP":
            del os.environ[key]
    print(dict(os.environ))
    """
            )
            out = python(py.name, _env=env).strip()
            self.assertEqual(out, "{'HERP': 'DERP'}")

            py = create_tmp_test(
                """
    import os, sys
    sys.path.insert(0, os.getcwd())
    import sh
    for key in list(os.environ.keys()):
        if key != "HERP":
            del os.environ[key]
    print(dict(HERP=sh.HERP))
    """
            )
>           out = python(py.name, _env=env, _cwd=THIS_DIR).strip()

tests/sh_test.py:561:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sh.py:1508: in __call__
    rc = self.__class__.RunningCommandCls(cmd, call_args, stdin, stdout, stderr)
sh.py:737: in __init__
    self.wait()
sh.py:799: in wait
    self.handle_command_exit_code(exit_code)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = , code = 1

    def handle_command_exit_code(self, code):
        """here we determine if we had an exception, or an error code that we
        weren't expecting to see.  if we did, we create and raise an exception
        """
        ca = self.call_args
        exc_class = get_exc_exit_code_would_raise(code, ca["ok_code"], ca["piped"])
        if exc_class:
            exc = exc_class(
                self.ran, self.process.stdout, self.process.stderr, ca["truncate_exc"]
            )
>           raise exc
E           sh.ErrorReturnCode_1:
E
E             RAN: /usr/bin/python3 /tmp/tmploev9u33
E
E             STDOUT:
E
E
E             STDERR:
E           Traceback (most recent call last):
E             File "/tmp/tmploev9u33", line 4, in <module>
E               import sh
E           ModuleNotFoundError: No module named 'sh'

sh.py:826: ErrorReturnCode_1
===================================================================================== warnings summary ======================================================================================
tests/sh_test.py::FunctionalTests::test_piped_exception1
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 822369

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2641, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2332, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 826, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_2:

    RAN: /usr/bin/python3 /tmp/tmpdr759avs

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/sh_test.py::FunctionalTests::test_unchecked_pipeline_failure
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 822409

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2641, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2332, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 826, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_2:

    RAN: /usr/bin/python3 /tmp/tmp5jpqf11u

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/sh_test.py::FunctionalTests::test_signal_exception
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 822487

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2641, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2332, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 826, in handle_command_exit_code
      raise exc
  sh.SignalException_SIGTERM:

    RAN: /usr/bin/python3 /tmp/tmpywy3tq5j

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/sh_test.py::FunctionalTests::test_piped_exception2
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 822547

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2641, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2332, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 826, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_2:

    RAN: /usr/bin/python3 /tmp/tmp5d2lbaku

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/sh_test.py::FunctionalTests::test_fg_alternative
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread STDIN thread for pid 822582

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2591, in input_thread
      done = stdin.write()
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2904, in write
      chunk = self.get_chunk()
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2845, in fn
      chunk = stdin.read(bufsize)
    File "/usr/lib/python3.9/site-packages/_pytest/capture.py", line 207, in read
      raise OSError(
  OSError: pytest: reading from stdin while output is captured!  Consider using `-s`.

    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/sh_test.py::FunctionalTests::test_stdout_callback_terminate
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 822778

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2641, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2332, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 826, in handle_command_exit_code
      raise exc
  sh.SignalException_SIGTERM:

    RAN: /usr/bin/python3 -u /tmp/tmp0edtxg5s

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/sh_test.py::FunctionalTests::test_signal_group
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 822843

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2641, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2332, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 826, in handle_command_exit_code
      raise exc
  sh.SignalException_SIGKILL:

    RAN: /usr/bin/python3 /tmp/tmpk7tedzaj

    STDOUT:
  822847
  822843


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/sh_test.py::FunctionalTests::test_exit_code_with_hasattr
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 822866

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2641, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2332, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 826, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_3:

    RAN: /usr/bin/python3 /tmp/tmpgsgg71kw

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/sh_test.py::FunctionalTests::test_multiple_bakes
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 822852

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2641, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2332, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 826, in handle_command_exit_code
      raise exc
  sh.SignalException_SIGKILL:

    RAN: /usr/bin/python3 /tmp/tmpk7tedzaj

    STDOUT:
  822856
  822852


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/sh_test.py::FunctionalTests::test_done_cb_exc
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 823156

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2641, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2332, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 826, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_1:

    RAN: /usr/bin/python3 /tmp/tmphy6rcpcq

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/sh_test.py::FunctionalTests::test_stdout_callback_kill
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 823210

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2641, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2332, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 826, in handle_command_exit_code
      raise exc
  sh.SignalException_SIGKILL:

    RAN: /usr/bin/python3 -u /tmp/tmpzt1iowt3

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

tests/sh_test.py::FunctionalTests::test_unchecked_producer_failure
  /usr/lib/python3.9/site-packages/_pytest/threadexception.py:77: PytestUnhandledThreadExceptionWarning: Exception in thread background thread for pid 823295

  Traceback (most recent call last):
    File "/usr/lib64/python3.9/threading.py", line 980, in _bootstrap_inner
      self.run()
    File "/usr/lib64/python3.9/threading.py", line 917, in run
      self._target(*self._args, **self._kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 1639, in wrap
      fn(*rgs, **kwargs)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2641, in background_thread
      handle_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 2332, in fn
      return self.command.handle_command_exit_code(exit_code)
    File "/home/tkloczko/rpmbuild/BUILD/sh-2.0.6/sh.py", line 826, in handle_command_exit_code
      raise exc
  sh.ErrorReturnCode_2:

    RAN: /usr/bin/python3 /tmp/tmpeg6orsaf

    STDOUT:


    STDERR:


    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================================================================== short test summary info ==================================================================================
SKIPPED [1] tests/sh_test.py:2322: what's the best way to test a different '_encoding' special keywordargument?
FAILED tests/sh_test.py::FunctionalTests::test_environment - sh.ErrorReturnCode_1:
============================================================= 1 failed, 177 passed, 1 skipped, 12 warnings in 60.92s (0:01:00) ==============================================================