Skip to content

Add private key password option to ssl adapters #752

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

jatalahd
Copy link

@jatalahd jatalahd commented Jul 16, 2025

  • It is now possible to use password protected private keys in both builtin and openssl ssl-adapters
  • Added also positive and negative unit test cases
  • With reference to #1583

What kind of change does this PR introduce?

  • 🐞 bug fix
  • 🐣 feature
  • 📋 docs update
  • 📋 tests/coverage improvement
  • 📋 refactoring
  • 💥 other

📋 What is the related issue number (starting with #)
#1583

Resolves #1583
(possibly in cherrypy repo)

What is the current behavior? (You can also link to an open issue here)
With the current functionality it is only possible to use ssl adapters with private keys without password protection

What is the new behavior (if this is a feature change)?
With this change, there is a new option to give the ssl adapter a "private_key_password" argument, which can be in either string or bytestring format.

📋 Other information:
Added also unit tests to test the new functionality

📋 Contribution checklist:

  • I wrote descriptive pull request text above
  • I think the code is well written
  • I wrote good commit messages
  • I have squashed related commits together after
    the changes have been approved
  • Unit tests for the changes exist
  • Integration tests for the changes exist (if applicable)
  • I used the same coding conventions as the rest of the project
  • The new code doesn't generate linter offenses
  • Documentation reflects the changes
  • The PR relates to only one subject with a clear title
    and description in grammatically correct, complete sentences

This change is Reviewable

- It is now possible to use password protected private keys
  in both builtin and openssl ssl-adapters

- Added also positive and negative unit test cases

- With reference to #1583
Copy link

codecov bot commented Jul 16, 2025

❌ 8 Tests Failed:

Tests completed Failed Passed Skipped
9555 8 9547 481
View the top 3 failed test(s) by shortest run time
cheroot.test.test_conn::test_streaming_11[True]
Stack Traces | 0s run time
self = <cheroot.makefile.StreamWriter name=-1>

    #x1B[0m#x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92m__del__#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m):#x1B[90m#x1B[39;49;00m
    #x1B[90m    #x1B[39;49;00m#x1B[33m"""Destructor.  Calls close()."""#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
            closed = #x1B[96mself#x1B[39;49;00m.closed#x1B[90m#x1B[39;49;00m
        #x1B[94mexcept#x1B[39;49;00m #x1B[96mAttributeError#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
            #x1B[90m# If getting closed fails, then the object is probably#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
            #x1B[90m# in an unusable state, so ignore.#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
            #x1B[94mreturn#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
        #x1B[94mif#x1B[39;49;00m closed:#x1B[90m#x1B[39;49;00m
            #x1B[94mreturn#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
        #x1B[94mif#x1B[39;49;00m dealloc_warn := #x1B[96mgetattr#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33m_dealloc_warn#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[94mNone#x1B[39;49;00m):#x1B[90m#x1B[39;49;00m
            dealloc_warn(#x1B[96mself#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
        #x1B[90m# If close() fails, the caller logs the exception with#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[90m# sys.unraisablehook. close() must be called at the end at __del__().#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
>       #x1B[96mself#x1B[39;49;00m.close()#x1B[90m#x1B[39;49;00m

closed     = False
dealloc_warn = <bound method _BufferedIOMixin._dealloc_warn of <cheroot.makefile.StreamWriter name=-1>>
self       = <cheroot.makefile.StreamWriter name=-1>

#x1B[1m#x1B[31mC:\hostedtoolcache\windows\Python\3.14.0-beta.4\x64\Lib\_pyio.py#x1B[0m:415: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
#x1B[1m#x1B[31mC:\hostedtoolcache\windows\Python\3.14.0-beta.4\x64\Lib\_pyio.py#x1B[0m:1310: in close
    #x1B[0m#x1B[96mself#x1B[39;49;00m.flush()#x1B[90m#x1B[39;49;00m
        self       = <cheroot.makefile.StreamWriter name=-1>
#x1B[1m#x1B[31mC:\hostedtoolcache\windows\Python\3.14.0-beta.4\x64\Lib\_pyio.py#x1B[0m:1271: in flush
    #x1B[0m#x1B[96mself#x1B[39;49;00m._flush_unlocked()#x1B[90m#x1B[39;49;00m
        self       = <cheroot.makefile.StreamWriter name=-1>
#x1B[1m#x1B[31mcheroot\makefile.py#x1B[0m:32: in _flush_unlocked
    #x1B[0mn = #x1B[96mself#x1B[39;49;00m.raw.write(#x1B[96mbytes#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m._write_buf))#x1B[90m#x1B[39;49;00m
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        self       = <cheroot.makefile.StreamWriter name=-1>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <socket.SocketIO object at 0x0000028397B91D80>, b = b'1'

    #x1B[0m#x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92mwrite#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m, b):#x1B[90m#x1B[39;49;00m
    #x1B[90m    #x1B[39;49;00m#x1B[33m"""Write the given bytes or bytearray object *b* to the socket#x1B[39;49;00m
    #x1B[33m    and return the number of bytes written.  This can be less than#x1B[39;49;00m
    #x1B[33m    len(b) if not all data could be written.  If the socket is#x1B[39;49;00m
    #x1B[33m    non-blocking and no bytes could be written None is returned.#x1B[39;49;00m
    #x1B[33m    """#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[96mself#x1B[39;49;00m._checkClosed()#x1B[90m#x1B[39;49;00m
        #x1B[96mself#x1B[39;49;00m._checkWritable()#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
>           #x1B[94mreturn#x1B[39;49;00m #x1B[96mself#x1B[39;49;00m._sock.send(b)#x1B[90m#x1B[39;49;00m
                   ^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31mE           OSError: [WinError 10038] An operation was attempted on something that is not a socket#x1B[0m

b          = b'1'
self       = <socket.SocketIO object at 0x0000028397B91D80>

#x1B[1m#x1B[31mC:\hostedtoolcache\windows\Python\3.14.0-beta.4\x64\Lib\socket.py#x1B[0m:743: OSError

#x1B[33mThe above exception was the direct cause of the following exception:#x1B[0m

cls = <class '_pytest.runner.CallInfo'>
func = <function call_and_report.<locals>.<lambda> at 0x0000028397E55B10>
when = 'setup'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    #x1B[0m#x1B[37m@classmethod#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92mfrom_call#x1B[39;49;00m(#x1B[90m#x1B[39;49;00m
        #x1B[96mcls#x1B[39;49;00m,#x1B[90m#x1B[39;49;00m
        func: Callable[[], TResult],#x1B[90m#x1B[39;49;00m
        when: Literal[#x1B[33m"#x1B[39;49;00m#x1B[33mcollect#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33msetup#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33mcall#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33mteardown#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m],#x1B[90m#x1B[39;49;00m
        reraise: #x1B[96mtype#x1B[39;49;00m[#x1B[96mBaseException#x1B[39;49;00m] | #x1B[96mtuple#x1B[39;49;00m[#x1B[96mtype#x1B[39;49;00m[#x1B[96mBaseException#x1B[39;49;00m], ...] | #x1B[94mNone#x1B[39;49;00m = #x1B[94mNone#x1B[39;49;00m,#x1B[90m#x1B[39;49;00m
    ) -> CallInfo[TResult]:#x1B[90m#x1B[39;49;00m
    #x1B[90m    #x1B[39;49;00m#x1B[33m"""Call func, wrapping the result in a CallInfo.#x1B[39;49;00m
    #x1B[33m#x1B[39;49;00m
    #x1B[33m    :param func:#x1B[39;49;00m
    #x1B[33m        The function to call. Called without arguments.#x1B[39;49;00m
    #x1B[33m    :type func: Callable[[], _pytest.runner.TResult]#x1B[39;49;00m
    #x1B[33m    :param when:#x1B[39;49;00m
    #x1B[33m        The phase in which the function is called.#x1B[39;49;00m
    #x1B[33m    :param reraise:#x1B[39;49;00m
    #x1B[33m        Exception or exceptions that shall propagate if raised by the#x1B[39;49;00m
    #x1B[33m        function, instead of being wrapped in the CallInfo.#x1B[39;49;00m
    #x1B[33m    """#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        excinfo = #x1B[94mNone#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        instant = timing.Instant()#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
>           result: TResult | #x1B[94mNone#x1B[39;49;00m = func()#x1B[90m#x1B[39;49;00m
                                     ^^^^^^#x1B[90m#x1B[39;49;00m

cls        = <class '_pytest.runner.CallInfo'>
duration   = Duration(start=Instant(time=1752730372.352525, perf_count=758.1132177), stop=Instant(time=1752730372.4540648, perf_count=758.2147574))
excinfo    = <ExceptionInfo PytestUnraisableExceptionWarning('Exception ignored while calling deallocator <function IOBase.__del__ at 0x00000283957B7ED0>: None\n') tblen=13>
func       = <function call_and_report.<locals>.<lambda> at 0x0000028397E55B10>
instant    = Instant(time=1752730372.352525, perf_count=758.1132177)
reraise    = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)
result     = None
when       = 'setup'

#x1B[1m#x1B[31m.tox\py\Lib\site-packages\_pytest\runner.py#x1B[0m:344: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
#x1B[1m#x1B[31m.tox\py\Lib\site-packages\_pytest\runner.py#x1B[0m:246: in <lambda>
    #x1B[0m#x1B[94mlambda#x1B[39;49;00m: runtest_hook(item=item, **kwds), when=when, reraise=reraise#x1B[90m#x1B[39;49;00m
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        item       = <Function test_streaming_11[True]>
        kwds       = {}
        runtest_hook = <HookCaller 'pytest_runtest_setup'>
#x1B[1m#x1B[31m.tox\py\Lib\site-packages\pluggy\_hooks.py#x1B[0m:512: in __call__
    #x1B[0m#x1B[94mreturn#x1B[39;49;00m #x1B[96mself#x1B[39;49;00m._hookexec(#x1B[96mself#x1B[39;49;00m.name, #x1B[96mself#x1B[39;49;00m._hookimpls.copy(), kwargs, firstresult)#x1B[90m#x1B[39;49;00m
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        firstresult = False
        kwargs     = {'item': <Function test_streaming_11[True]>}
        self       = <HookCaller 'pytest_runtest_setup'>
#x1B[1m#x1B[31m.tox\py\Lib\site-packages\pluggy\_manager.py#x1B[0m:120: in _hookexec
    #x1B[0m#x1B[94mreturn#x1B[39;49;00m #x1B[96mself#x1B[39;49;00m._inner_hookexec(hook_name, methods, kwargs, firstresult)#x1B[90m#x1B[39;49;00m
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        firstresult = False
        hook_name  = 'pytest_runtest_setup'
        kwargs     = {'item': <Function test_streaming_11[True]>}
        methods    = [<HookImpl plugin_name='threadexception', plugin=<module '_pytest.threadexception' from 'C:\\a\\cheroot\\cheroot\\.tox...tIOWrapper name='nul' mode='r' encoding='utf-8'>> _state='suspended' _in_suspended=False> _capture_fixture=None>>, ...]
        self       = <_pytest.config.PytestPluginManager object at 0x000002839442B8C0>
#x1B[1m#x1B[31m.tox\py\Lib\site-packages\_pytest\logging.py#x1B[0m:843: in pytest_runtest_setup
    #x1B[0m#x1B[94myield#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        empty      = {'setup': []}
        item       = <Function test_streaming_11[True]>
        self       = <_pytest.logging.LoggingPlugin object at 0x0000028395B5AA50>
#x1B[1m#x1B[31m.tox\py\Lib\site-packages\_pytest\capture.py#x1B[0m:895: in pytest_runtest_setup
    #x1B[0m#x1B[94mreturn#x1B[39;49;00m (#x1B[94myield#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
            ^^^^^#x1B[90m#x1B[39;49;00m
        item       = <Function test_streaming_11[True]>
        self       = <CaptureManager _method='fd' _global_capturing=<MultiCapture out=<FDCapture 1 oldfd=8 _state='suspended' tmpfile=<Enco..._io.TextIOWrapper name='nul' mode='r' encoding='utf-8'>> _state='suspended' _in_suspended=False> _capture_fixture=None>
#x1B[1m#x1B[31m.tox\py\Lib\site-packages\_pytest\unraisableexception.py#x1B[0m:153: in pytest_runtest_setup
    #x1B[0mcollect_unraisable(item.config)#x1B[90m#x1B[39;49;00m
        item       = <Function test_streaming_11[True]>
#x1B[1m#x1B[31m.tox\py\Lib\site-packages\_pytest\unraisableexception.py#x1B[0m:79: in collect_unraisable
    #x1B[0m#x1B[94mraise#x1B[39;49;00m errors[#x1B[94m0#x1B[39;49;00m]#x1B[90m#x1B[39;49;00m
        config     = <_pytest.config.Config object at 0x0000028394D88EC0>
        msg        = 'Exception ignored while calling deallocator <function IOBase.__del__ at 0x00000283957B7ED0>: None\n\nTraceback (most ...        ~~~~~~~~~~~~~~~^^^\nOSError: [WinError 10038] An operation was attempted on something that is not a socket\n\n'
        pop_unraisable = <built-in method pop of collections.deque object at 0x0000028395B0D8A0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

config = <_pytest.config.Config object at 0x0000028394D88EC0>

    #x1B[0m#x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92mcollect_unraisable#x1B[39;49;00m(config: Config) -> #x1B[94mNone#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
        pop_unraisable = config.stash[unraisable_exceptions].pop#x1B[90m#x1B[39;49;00m
        errors: #x1B[96mlist#x1B[39;49;00m[pytest.PytestUnraisableExceptionWarning | #x1B[96mRuntimeError#x1B[39;49;00m] = []#x1B[90m#x1B[39;49;00m
        meta = #x1B[94mNone#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        hook_error = #x1B[94mNone#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
            #x1B[94mwhile#x1B[39;49;00m #x1B[94mTrue#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
                #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
                    meta = pop_unraisable()#x1B[90m#x1B[39;49;00m
                #x1B[94mexcept#x1B[39;49;00m #x1B[96mIndexError#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
                    #x1B[94mbreak#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
                #x1B[94mif#x1B[39;49;00m #x1B[96misinstance#x1B[39;49;00m(meta, #x1B[96mBaseException#x1B[39;49;00m):#x1B[90m#x1B[39;49;00m
                    hook_error = #x1B[96mRuntimeError#x1B[39;49;00m(#x1B[33m"#x1B[39;49;00m#x1B[33mFailed to process unraisable exception#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
                    hook_error.__cause__ = meta#x1B[90m#x1B[39;49;00m
                    errors.append(hook_error)#x1B[90m#x1B[39;49;00m
                    #x1B[94mcontinue#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
                msg = meta.msg#x1B[90m#x1B[39;49;00m
                #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
>                   warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31mE                   pytest.PytestUnraisableExceptionWarning: Exception ignored while calling deallocator <function IOBase.__del__ at 0x00000283957B7ED0>: None#x1B[0m

config     = <_pytest.config.Config object at 0x0000028394D88EC0>
msg        = 'Exception ignored while calling deallocator <function IOBase.__del__ at 0x00000283957B7ED0>: None\n\nTraceback (most ...        ~~~~~~~~~~~~~~~^^^\nOSError: [WinError 10038] An operation was attempted on something that is not a socket\n\n'
pop_unraisable = <built-in method pop of collections.deque object at 0x0000028395B0D8A0>

#x1B[1m#x1B[31m.tox\py\Lib\site-packages\_pytest\unraisableexception.py#x1B[0m:67: PytestUnraisableExceptionWarning
cheroot.test.test_core::test_http_connect_request
Stack Traces | 0s run time
self = <cheroot.makefile.StreamWriter name=-1>

    #x1B[0m#x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92m__del__#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m):#x1B[90m#x1B[39;49;00m
    #x1B[90m    #x1B[39;49;00m#x1B[33m"""Destructor.  Calls close()."""#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
            closed = #x1B[96mself#x1B[39;49;00m.closed#x1B[90m#x1B[39;49;00m
        #x1B[94mexcept#x1B[39;49;00m #x1B[96mAttributeError#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
            #x1B[90m# If getting closed fails, then the object is probably#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
            #x1B[90m# in an unusable state, so ignore.#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
            #x1B[94mreturn#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
        #x1B[94mif#x1B[39;49;00m closed:#x1B[90m#x1B[39;49;00m
            #x1B[94mreturn#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
        #x1B[94mif#x1B[39;49;00m dealloc_warn := #x1B[96mgetattr#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33m_dealloc_warn#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[94mNone#x1B[39;49;00m):#x1B[90m#x1B[39;49;00m
            dealloc_warn(#x1B[96mself#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
        #x1B[90m# If close() fails, the caller logs the exception with#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[90m# sys.unraisablehook. close() must be called at the end at __del__().#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
>       #x1B[96mself#x1B[39;49;00m.close()#x1B[90m#x1B[39;49;00m

closed     = False
dealloc_warn = <bound method _BufferedIOMixin._dealloc_warn of <cheroot.makefile.StreamWriter name=-1>>
self       = <cheroot.makefile.StreamWriter name=-1>

#x1B[1m#x1B[.../hostedtoolcache/Python/3.14.0-beta..../arm64/lib/python3.14/_pyio.py#x1B[0m:415: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
#x1B[1m#x1B[.../hostedtoolcache/Python/3.14.0-beta..../arm64/lib/python3.14/_pyio.py#x1B[0m:1310: in close
    #x1B[0m#x1B[96mself#x1B[39;49;00m.flush()#x1B[90m#x1B[39;49;00m
        self       = <cheroot.makefile.StreamWriter name=-1>
#x1B[1m#x1B[.../hostedtoolcache/Python/3.14.0-beta..../arm64/lib/python3.14/_pyio.py#x1B[0m:1271: in flush
    #x1B[0m#x1B[96mself#x1B[39;49;00m._flush_unlocked()#x1B[90m#x1B[39;49;00m
        self       = <cheroot.makefile.StreamWriter name=-1>
#x1B[1m#x1B[31mcheroot/makefile.py#x1B[0m:32: in _flush_unlocked
    #x1B[0mn = #x1B[96mself#x1B[39;49;00m.raw.write(#x1B[96mbytes#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m._write_buf))#x1B[90m#x1B[39;49;00m
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        self       = <cheroot.makefile.StreamWriter name=-1>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <socket.SocketIO object at 0xff18ebeab3a0>, b = b'1'

    #x1B[0m#x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92mwrite#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m, b):#x1B[90m#x1B[39;49;00m
    #x1B[90m    #x1B[39;49;00m#x1B[33m"""Write the given bytes or bytearray object *b* to the socket#x1B[39;49;00m
    #x1B[33m    and return the number of bytes written.  This can be less than#x1B[39;49;00m
    #x1B[33m    len(b) if not all data could be written.  If the socket is#x1B[39;49;00m
    #x1B[33m    non-blocking and no bytes could be written None is returned.#x1B[39;49;00m
    #x1B[33m    """#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[96mself#x1B[39;49;00m._checkClosed()#x1B[90m#x1B[39;49;00m
        #x1B[96mself#x1B[39;49;00m._checkWritable()#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
>           #x1B[94mreturn#x1B[39;49;00m #x1B[96mself#x1B[39;49;00m._sock.send(b)#x1B[90m#x1B[39;49;00m
                   ^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31mE           OSError: [Errno 9] Bad file descriptor#x1B[0m

b          = b'1'
self       = <socket.SocketIO object at 0xff18ebeab3a0>

#x1B[1m#x1B[.../hostedtoolcache/Python/3.14.0-beta..../arm64/lib/python3.14/socket.py#x1B[0m:743: OSError

#x1B[33mThe above exception was the direct cause of the following exception:#x1B[0m

cls = <class '_pytest.runner.CallInfo'>
func = <function call_and_report.<locals>.<lambda> at 0xff18ebdc4bf0>
when = 'setup'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    #x1B[0m#x1B[37m@classmethod#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92mfrom_call#x1B[39;49;00m(#x1B[90m#x1B[39;49;00m
        #x1B[96mcls#x1B[39;49;00m,#x1B[90m#x1B[39;49;00m
        func: Callable[[], TResult],#x1B[90m#x1B[39;49;00m
        when: Literal[#x1B[33m"#x1B[39;49;00m#x1B[33mcollect#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33msetup#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33mcall#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33mteardown#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m],#x1B[90m#x1B[39;49;00m
        reraise: #x1B[96mtype#x1B[39;49;00m[#x1B[96mBaseException#x1B[39;49;00m] | #x1B[96mtuple#x1B[39;49;00m[#x1B[96mtype#x1B[39;49;00m[#x1B[96mBaseException#x1B[39;49;00m], ...] | #x1B[94mNone#x1B[39;49;00m = #x1B[94mNone#x1B[39;49;00m,#x1B[90m#x1B[39;49;00m
    ) -> CallInfo[TResult]:#x1B[90m#x1B[39;49;00m
    #x1B[90m    #x1B[39;49;00m#x1B[33m"""Call func, wrapping the result in a CallInfo.#x1B[39;49;00m
    #x1B[33m#x1B[39;49;00m
    #x1B[33m    :param func:#x1B[39;49;00m
    #x1B[33m        The function to call. Called without arguments.#x1B[39;49;00m
    #x1B[33m    :type func: Callable[[], _pytest.runner.TResult]#x1B[39;49;00m
    #x1B[33m    :param when:#x1B[39;49;00m
    #x1B[33m        The phase in which the function is called.#x1B[39;49;00m
    #x1B[33m    :param reraise:#x1B[39;49;00m
    #x1B[33m        Exception or exceptions that shall propagate if raised by the#x1B[39;49;00m
    #x1B[33m        function, instead of being wrapped in the CallInfo.#x1B[39;49;00m
    #x1B[33m    """#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        excinfo = #x1B[94mNone#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        instant = timing.Instant()#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
>           result: TResult | #x1B[94mNone#x1B[39;49;00m = func()#x1B[90m#x1B[39;49;00m
                                     ^^^^^^#x1B[90m#x1B[39;49;00m

cls        = <class '_pytest.runner.CallInfo'>
duration   = Duration(start=Instant(time=1752730117.558854, perf_count=340.242509199), stop=Instant(time=1752730117.6596255, perf_count=340.343281107))
excinfo    = <ExceptionInfo PytestUnraisableExceptionWarning('Exception ignored while calling deallocator <function IOBase.__del__ at 0xff18f15b8040>: None\n') tblen=13>
func       = <function call_and_report.<locals>.<lambda> at 0xff18ebdc4bf0>
instant    = Instant(time=1752730117.558854, perf_count=340.242509199)
reraise    = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)
result     = None
when       = 'setup'

#x1B[1m#x1B[31m..../py/lib/python3.14....../site-packages/_pytest/runner.py#x1B[0m:344: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
#x1B[1m#x1B[31m..../py/lib/python3.14....../site-packages/_pytest/runner.py#x1B[0m:246: in <lambda>
    #x1B[0m#x1B[94mlambda#x1B[39;49;00m: runtest_hook(item=item, **kwds), when=when, reraise=reraise#x1B[90m#x1B[39;49;00m
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        item       = <Function test_http_connect_request>
        kwds       = {}
        runtest_hook = <HookCaller 'pytest_runtest_setup'>
#x1B[1m#x1B[31m..../py/lib/python3.14.../site-packages/pluggy/_hooks.py#x1B[0m:512: in __call__
    #x1B[0m#x1B[94mreturn#x1B[39;49;00m #x1B[96mself#x1B[39;49;00m._hookexec(#x1B[96mself#x1B[39;49;00m.name, #x1B[96mself#x1B[39;49;00m._hookimpls.copy(), kwargs, firstresult)#x1B[90m#x1B[39;49;00m
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        firstresult = False
        kwargs     = {'item': <Function test_http_connect_request>}
        self       = <HookCaller 'pytest_runtest_setup'>
#x1B[1m#x1B[31m..../py/lib/python3.14.../site-packages/pluggy/_manager.py#x1B[0m:120: in _hookexec
    #x1B[0m#x1B[94mreturn#x1B[39;49;00m #x1B[96mself#x1B[39;49;00m._inner_hookexec(hook_name, methods, kwargs, firstresult)#x1B[90m#x1B[39;49;00m
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        firstresult = False
        hook_name  = 'pytest_runtest_setup'
        kwargs     = {'item': <Function test_http_connect_request>}
        methods    = [<HookImpl plugin_name='threadexception', plugin=<module '_pytest.threadexception' from '.../work/cheroot/che...pper name='/dev/null' mode='r' encoding='utf-8'>> _state='suspended' _in_suspended=False> _capture_fixture=None>>, ...]
        self       = <_pytest.config.PytestPluginManager object at 0xff18f268c1a0>
#x1B[1m#x1B[31m..../py/lib/python3.14.../site-packages/_pytest/logging.py#x1B[0m:843: in pytest_runtest_setup
    #x1B[0m#x1B[94myield#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        empty      = {'setup': []}
        item       = <Function test_http_connect_request>
        self       = <_pytest.logging.LoggingPlugin object at 0xff18f14c5fd0>
#x1B[1m#x1B[31m..../py/lib/python3.14.../site-packages/_pytest/capture.py#x1B[0m:895: in pytest_runtest_setup
    #x1B[0m#x1B[94mreturn#x1B[39;49;00m (#x1B[94myield#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
            ^^^^^#x1B[90m#x1B[39;49;00m
        item       = <Function test_http_connect_request>
        self       = <CaptureManager _method='fd' _global_capturing=<MultiCapture out=<FDCapture 1 oldfd=7 _state='suspended' tmpfile=<Enco...xtIOWrapper name='/dev/null' mode='r' encoding='utf-8'>> _state='suspended' _in_suspended=False> _capture_fixture=None>
#x1B[1m#x1B[31m..../py/lib/python3.14........./site-packages/_pytest/unraisableexception.py#x1B[0m:153: in pytest_runtest_setup
    #x1B[0mcollect_unraisable(item.config)#x1B[90m#x1B[39;49;00m
        item       = <Function test_http_connect_request>
#x1B[1m#x1B[31m..../py/lib/python3.14........./site-packages/_pytest/unraisableexception.py#x1B[0m:79: in collect_unraisable
    #x1B[0m#x1B[94mraise#x1B[39;49;00m errors[#x1B[94m0#x1B[39;49;00m]#x1B[90m#x1B[39;49;00m
        config     = <_pytest.config.Config object at 0xff18f268d6a0>
        msg        = 'Exception ignored while calling deallocator <function IOBase.__del__ at 0xff18f15b8040>: None\n\nTraceback (most rece...43, in write\n    return self._sock.send(b)\n           ~~~~~~~~~~~~~~~^^^\nOSError: [Errno 9] Bad file descriptor\n\n'
        pop_unraisable = <built-in method pop of collections.deque object at 0xff18f15e7e20>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

config = <_pytest.config.Config object at 0xff18f268d6a0>

    #x1B[0m#x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92mcollect_unraisable#x1B[39;49;00m(config: Config) -> #x1B[94mNone#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
        pop_unraisable = config.stash[unraisable_exceptions].pop#x1B[90m#x1B[39;49;00m
        errors: #x1B[96mlist#x1B[39;49;00m[pytest.PytestUnraisableExceptionWarning | #x1B[96mRuntimeError#x1B[39;49;00m] = []#x1B[90m#x1B[39;49;00m
        meta = #x1B[94mNone#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        hook_error = #x1B[94mNone#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
            #x1B[94mwhile#x1B[39;49;00m #x1B[94mTrue#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
                #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
                    meta = pop_unraisable()#x1B[90m#x1B[39;49;00m
                #x1B[94mexcept#x1B[39;49;00m #x1B[96mIndexError#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
                    #x1B[94mbreak#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
                #x1B[94mif#x1B[39;49;00m #x1B[96misinstance#x1B[39;49;00m(meta, #x1B[96mBaseException#x1B[39;49;00m):#x1B[90m#x1B[39;49;00m
                    hook_error = #x1B[96mRuntimeError#x1B[39;49;00m(#x1B[33m"#x1B[39;49;00m#x1B[33mFailed to process unraisable exception#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
                    hook_error.__cause__ = meta#x1B[90m#x1B[39;49;00m
                    errors.append(hook_error)#x1B[90m#x1B[39;49;00m
                    #x1B[94mcontinue#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
                msg = meta.msg#x1B[90m#x1B[39;49;00m
                #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
>                   warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31mE                   pytest.PytestUnraisableExceptionWarning: Exception ignored while calling deallocator <function IOBase.__del__ at 0xff18f15b8040>: None#x1B[0m

config     = <_pytest.config.Config object at 0xff18f268d6a0>
msg        = 'Exception ignored while calling deallocator <function IOBase.__del__ at 0xff18f15b8040>: None\n\nTraceback (most rece...43, in write\n    return self._sock.send(b)\n           ~~~~~~~~~~~~~~~^^^\nOSError: [Errno 9] Bad file descriptor\n\n'
pop_unraisable = <built-in method pop of collections.deque object at 0xff18f15e7e20>

#x1B[1m#x1B[31m..../py/lib/python3.14........./site-packages/_pytest/unraisableexception.py#x1B[0m:67: PytestUnraisableExceptionWarning
cheroot.test.test_core::test_http_connect_request
Stack Traces | 0s run time
self = <cheroot.makefile.StreamWriter name=-1>

    #x1B[0m#x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92m__del__#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m):#x1B[90m#x1B[39;49;00m
    #x1B[90m    #x1B[39;49;00m#x1B[33m"""Destructor.  Calls close()."""#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
            closed = #x1B[96mself#x1B[39;49;00m.closed#x1B[90m#x1B[39;49;00m
        #x1B[94mexcept#x1B[39;49;00m #x1B[96mAttributeError#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
            #x1B[90m# If getting closed fails, then the object is probably#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
            #x1B[90m# in an unusable state, so ignore.#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
            #x1B[94mreturn#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
        #x1B[94mif#x1B[39;49;00m closed:#x1B[90m#x1B[39;49;00m
            #x1B[94mreturn#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
        #x1B[94mif#x1B[39;49;00m dealloc_warn := #x1B[96mgetattr#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33m_dealloc_warn#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[94mNone#x1B[39;49;00m):#x1B[90m#x1B[39;49;00m
            dealloc_warn(#x1B[96mself#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
        #x1B[90m# If close() fails, the caller logs the exception with#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[90m# sys.unraisablehook. close() must be called at the end at __del__().#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
>       #x1B[96mself#x1B[39;49;00m.close()#x1B[90m#x1B[39;49;00m

closed     = False
dealloc_warn = <bound method _BufferedIOMixin._dealloc_warn of <cheroot.makefile.StreamWriter name=-1>>
self       = <cheroot.makefile.StreamWriter name=-1>

#x1B[1m#x1B[.../hostedtoolcache/Python/3.14.0-beta..../x64/lib/python3.14/_pyio.py#x1B[0m:415: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
#x1B[1m#x1B[.../hostedtoolcache/Python/3.14.0-beta..../x64/lib/python3.14/_pyio.py#x1B[0m:1310: in close
    #x1B[0m#x1B[96mself#x1B[39;49;00m.flush()#x1B[90m#x1B[39;49;00m
        self       = <cheroot.makefile.StreamWriter name=-1>
#x1B[1m#x1B[.../hostedtoolcache/Python/3.14.0-beta..../x64/lib/python3.14/_pyio.py#x1B[0m:1271: in flush
    #x1B[0m#x1B[96mself#x1B[39;49;00m._flush_unlocked()#x1B[90m#x1B[39;49;00m
        self       = <cheroot.makefile.StreamWriter name=-1>
#x1B[1m#x1B[31mcheroot/makefile.py#x1B[0m:32: in _flush_unlocked
    #x1B[0mn = #x1B[96mself#x1B[39;49;00m.raw.write(#x1B[96mbytes#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m._write_buf))#x1B[90m#x1B[39;49;00m
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        self       = <cheroot.makefile.StreamWriter name=-1>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <socket.SocketIO object at 0x7f7658912a70>, b = b'1'

    #x1B[0m#x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92mwrite#x1B[39;49;00m(#x1B[96mself#x1B[39;49;00m, b):#x1B[90m#x1B[39;49;00m
    #x1B[90m    #x1B[39;49;00m#x1B[33m"""Write the given bytes or bytearray object *b* to the socket#x1B[39;49;00m
    #x1B[33m    and return the number of bytes written.  This can be less than#x1B[39;49;00m
    #x1B[33m    len(b) if not all data could be written.  If the socket is#x1B[39;49;00m
    #x1B[33m    non-blocking and no bytes could be written None is returned.#x1B[39;49;00m
    #x1B[33m    """#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[96mself#x1B[39;49;00m._checkClosed()#x1B[90m#x1B[39;49;00m
        #x1B[96mself#x1B[39;49;00m._checkWritable()#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
>           #x1B[94mreturn#x1B[39;49;00m #x1B[96mself#x1B[39;49;00m._sock.send(b)#x1B[90m#x1B[39;49;00m
                   ^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31mE           OSError: [Errno 9] Bad file descriptor#x1B[0m

b          = b'1'
self       = <socket.SocketIO object at 0x7f7658912a70>

#x1B[1m#x1B[.../hostedtoolcache/Python/3.14.0-beta..../x64/lib/python3.14/socket.py#x1B[0m:743: OSError

#x1B[33mThe above exception was the direct cause of the following exception:#x1B[0m

cls = <class '_pytest.runner.CallInfo'>
func = <function call_and_report.<locals>.<lambda> at 0x7f7658828930>
when = 'setup'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    #x1B[0m#x1B[37m@classmethod#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92mfrom_call#x1B[39;49;00m(#x1B[90m#x1B[39;49;00m
        #x1B[96mcls#x1B[39;49;00m,#x1B[90m#x1B[39;49;00m
        func: Callable[[], TResult],#x1B[90m#x1B[39;49;00m
        when: Literal[#x1B[33m"#x1B[39;49;00m#x1B[33mcollect#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33msetup#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33mcall#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[33m"#x1B[39;49;00m#x1B[33mteardown#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m],#x1B[90m#x1B[39;49;00m
        reraise: #x1B[96mtype#x1B[39;49;00m[#x1B[96mBaseException#x1B[39;49;00m] | #x1B[96mtuple#x1B[39;49;00m[#x1B[96mtype#x1B[39;49;00m[#x1B[96mBaseException#x1B[39;49;00m], ...] | #x1B[94mNone#x1B[39;49;00m = #x1B[94mNone#x1B[39;49;00m,#x1B[90m#x1B[39;49;00m
    ) -> CallInfo[TResult]:#x1B[90m#x1B[39;49;00m
    #x1B[90m    #x1B[39;49;00m#x1B[33m"""Call func, wrapping the result in a CallInfo.#x1B[39;49;00m
    #x1B[33m#x1B[39;49;00m
    #x1B[33m    :param func:#x1B[39;49;00m
    #x1B[33m        The function to call. Called without arguments.#x1B[39;49;00m
    #x1B[33m    :type func: Callable[[], _pytest.runner.TResult]#x1B[39;49;00m
    #x1B[33m    :param when:#x1B[39;49;00m
    #x1B[33m        The phase in which the function is called.#x1B[39;49;00m
    #x1B[33m    :param reraise:#x1B[39;49;00m
    #x1B[33m        Exception or exceptions that shall propagate if raised by the#x1B[39;49;00m
    #x1B[33m        function, instead of being wrapped in the CallInfo.#x1B[39;49;00m
    #x1B[33m    """#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        excinfo = #x1B[94mNone#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        instant = timing.Instant()#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
>           result: TResult | #x1B[94mNone#x1B[39;49;00m = func()#x1B[90m#x1B[39;49;00m
                                     ^^^^^^#x1B[90m#x1B[39;49;00m

cls        = <class '_pytest.runner.CallInfo'>
duration   = Duration(start=Instant(time=1752730202.714425, perf_count=77.05883863), stop=Instant(time=1752730202.815481, perf_count=77.159895008))
excinfo    = <ExceptionInfo PytestUnraisableExceptionWarning('Exception ignored while calling deallocator <function IOBase.__del__ at 0x7f765a4cfe20>: None\n') tblen=13>
func       = <function call_and_report.<locals>.<lambda> at 0x7f7658828930>
instant    = Instant(time=1752730202.714425, perf_count=77.05883863)
reraise    = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)
result     = None
when       = 'setup'

#x1B[1m#x1B[31m..../py/lib/python3.14....../site-packages/_pytest/runner.py#x1B[0m:344: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
#x1B[1m#x1B[31m..../py/lib/python3.14....../site-packages/_pytest/runner.py#x1B[0m:246: in <lambda>
    #x1B[0m#x1B[94mlambda#x1B[39;49;00m: runtest_hook(item=item, **kwds), when=when, reraise=reraise#x1B[90m#x1B[39;49;00m
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        item       = <Function test_http_connect_request>
        kwds       = {}
        runtest_hook = <HookCaller 'pytest_runtest_setup'>
#x1B[1m#x1B[31m..../py/lib/python3.14.../site-packages/pluggy/_hooks.py#x1B[0m:512: in __call__
    #x1B[0m#x1B[94mreturn#x1B[39;49;00m #x1B[96mself#x1B[39;49;00m._hookexec(#x1B[96mself#x1B[39;49;00m.name, #x1B[96mself#x1B[39;49;00m._hookimpls.copy(), kwargs, firstresult)#x1B[90m#x1B[39;49;00m
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        firstresult = False
        kwargs     = {'item': <Function test_http_connect_request>}
        self       = <HookCaller 'pytest_runtest_setup'>
#x1B[1m#x1B[31m..../py/lib/python3.14.../site-packages/pluggy/_manager.py#x1B[0m:120: in _hookexec
    #x1B[0m#x1B[94mreturn#x1B[39;49;00m #x1B[96mself#x1B[39;49;00m._inner_hookexec(hook_name, methods, kwargs, firstresult)#x1B[90m#x1B[39;49;00m
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
        firstresult = False
        hook_name  = 'pytest_runtest_setup'
        kwargs     = {'item': <Function test_http_connect_request>}
        methods    = [<HookImpl plugin_name='threadexception', plugin=<module '_pytest.threadexception' from '.../work/cheroot/che...pper name='/dev/null' mode='r' encoding='utf-8'>> _state='suspended' _in_suspended=False> _capture_fixture=None>>, ...]
        self       = <_pytest.config.PytestPluginManager object at 0x7f765b1f01a0>
#x1B[1m#x1B[31m..../py/lib/python3.14.../site-packages/_pytest/logging.py#x1B[0m:843: in pytest_runtest_setup
    #x1B[0m#x1B[94myield#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        empty      = {'setup': []}
        item       = <Function test_http_connect_request>
        self       = <_pytest.logging.LoggingPlugin object at 0x7f765a299fd0>
#x1B[1m#x1B[31m..../py/lib/python3.14.../site-packages/_pytest/capture.py#x1B[0m:895: in pytest_runtest_setup
    #x1B[0m#x1B[94mreturn#x1B[39;49;00m (#x1B[94myield#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
            ^^^^^#x1B[90m#x1B[39;49;00m
        item       = <Function test_http_connect_request>
        self       = <CaptureManager _method='fd' _global_capturing=<MultiCapture out=<FDCapture 1 oldfd=7 _state='suspended' tmpfile=<Enco...xtIOWrapper name='/dev/null' mode='r' encoding='utf-8'>> _state='suspended' _in_suspended=False> _capture_fixture=None>
#x1B[1m#x1B[31m..../py/lib/python3.14........./site-packages/_pytest/unraisableexception.py#x1B[0m:153: in pytest_runtest_setup
    #x1B[0mcollect_unraisable(item.config)#x1B[90m#x1B[39;49;00m
        item       = <Function test_http_connect_request>
#x1B[1m#x1B[31m..../py/lib/python3.14........./site-packages/_pytest/unraisableexception.py#x1B[0m:79: in collect_unraisable
    #x1B[0m#x1B[94mraise#x1B[39;49;00m errors[#x1B[94m0#x1B[39;49;00m]#x1B[90m#x1B[39;49;00m
        config     = <_pytest.config.Config object at 0x7f765b1f16a0>
        msg        = 'Exception ignored while calling deallocator <function IOBase.__del__ at 0x7f765a4cfe20>: None\n\nTraceback (most rece...43, in write\n    return self._sock.send(b)\n           ~~~~~~~~~~~~~~~^^^\nOSError: [Errno 9] Bad file descriptor\n\n'
        pop_unraisable = <built-in method pop of collections.deque object at 0x7f765a1bbe20>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

config = <_pytest.config.Config object at 0x7f765b1f16a0>

    #x1B[0m#x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92mcollect_unraisable#x1B[39;49;00m(config: Config) -> #x1B[94mNone#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
        pop_unraisable = config.stash[unraisable_exceptions].pop#x1B[90m#x1B[39;49;00m
        errors: #x1B[96mlist#x1B[39;49;00m[pytest.PytestUnraisableExceptionWarning | #x1B[96mRuntimeError#x1B[39;49;00m] = []#x1B[90m#x1B[39;49;00m
        meta = #x1B[94mNone#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        hook_error = #x1B[94mNone#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
            #x1B[94mwhile#x1B[39;49;00m #x1B[94mTrue#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
                #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
                    meta = pop_unraisable()#x1B[90m#x1B[39;49;00m
                #x1B[94mexcept#x1B[39;49;00m #x1B[96mIndexError#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
                    #x1B[94mbreak#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
                #x1B[94mif#x1B[39;49;00m #x1B[96misinstance#x1B[39;49;00m(meta, #x1B[96mBaseException#x1B[39;49;00m):#x1B[90m#x1B[39;49;00m
                    hook_error = #x1B[96mRuntimeError#x1B[39;49;00m(#x1B[33m"#x1B[39;49;00m#x1B[33mFailed to process unraisable exception#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
                    hook_error.__cause__ = meta#x1B[90m#x1B[39;49;00m
                    errors.append(hook_error)#x1B[90m#x1B[39;49;00m
                    #x1B[94mcontinue#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
                msg = meta.msg#x1B[90m#x1B[39;49;00m
                #x1B[94mtry#x1B[39;49;00m:#x1B[90m#x1B[39;49;00m
>                   warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31mE                   pytest.PytestUnraisableExceptionWarning: Exception ignored while calling deallocator <function IOBase.__del__ at 0x7f765a4cfe20>: None#x1B[0m

config     = <_pytest.config.Config object at 0x7f765b1f16a0>
msg        = 'Exception ignored while calling deallocator <function IOBase.__del__ at 0x7f765a4cfe20>: None\n\nTraceback (most rece...43, in write\n    return self._sock.send(b)\n           ~~~~~~~~~~~~~~~^^^\nOSError: [Errno 9] Bad file descriptor\n\n'
pop_unraisable = <built-in method pop of collections.deque object at 0x7f765a1bbe20>

#x1B[1m#x1B[31m..../py/lib/python3.14........./site-packages/_pytest/unraisableexception.py#x1B[0m:67: PytestUnraisableExceptionWarning

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

- It is now possible to use password protected private keys
  in both builtin and openssl ssl-adapters

- Added also positive and negative unit test cases

- With reference to #1583
@jatalahd
Copy link
Author

Fixed linter issues with second commit, but now it seems that I need to do the git squash... Anyway, it would be important for us to get this improvement into some upcoming cheroot release, which we can then reference in our pipfile so that we can take these changes into use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant