Browse Source

Intermediate changes

robot-piglet 6 months ago
parent
commit
4a64a813e1

+ 171 - 18
contrib/python/Twisted/py3/.dist-info/METADATA

@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.3
 Name: Twisted
 Name: Twisted
-Version: 24.3.0
+Version: 24.7.0
 Summary: An asynchronous networking framework written in Python
 Summary: An asynchronous networking framework written in Python
 Project-URL: Changelog, https://github.com/twisted/twisted/blob/HEAD/NEWS.rst
 Project-URL: Changelog, https://github.com/twisted/twisted/blob/HEAD/NEWS.rst
 Project-URL: Documentation, https://docs.twistedmatrix.com/
 Project-URL: Documentation, https://docs.twistedmatrix.com/
@@ -23,23 +23,52 @@ Requires-Dist: attrs>=21.3.0
 Requires-Dist: automat>=0.8.0
 Requires-Dist: automat>=0.8.0
 Requires-Dist: constantly>=15.1
 Requires-Dist: constantly>=15.1
 Requires-Dist: hyperlink>=17.1.1
 Requires-Dist: hyperlink>=17.1.1
-Requires-Dist: incremental>=22.10.0
-Requires-Dist: twisted-iocpsupport<2,>=1.0.2; platform_system == 'Windows'
+Requires-Dist: incremental>=24.7.0
 Requires-Dist: typing-extensions>=4.2.0
 Requires-Dist: typing-extensions>=4.2.0
 Requires-Dist: zope-interface>=5
 Requires-Dist: zope-interface>=5
 Provides-Extra: all-non-platform
 Provides-Extra: all-non-platform
-Requires-Dist: twisted[conch,http2,serial,test,tls]; extra == 'all-non-platform'
+Requires-Dist: appdirs>=1.4.0; extra == 'all-non-platform'
+Requires-Dist: bcrypt>=3.1.3; extra == 'all-non-platform'
+Requires-Dist: cryptography>=3.3; extra == 'all-non-platform'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'all-non-platform'
+Requires-Dist: h2<5.0,>=3.0; extra == 'all-non-platform'
+Requires-Dist: hypothesis>=6.56; extra == 'all-non-platform'
+Requires-Dist: idna>=2.4; extra == 'all-non-platform'
+Requires-Dist: priority<2.0,>=1.1.0; extra == 'all-non-platform'
+Requires-Dist: pyhamcrest>=2; extra == 'all-non-platform'
+Requires-Dist: pyopenssl>=21.0.0; extra == 'all-non-platform'
+Requires-Dist: pyserial>=3.0; extra == 'all-non-platform'
+Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'all-non-platform'
+Requires-Dist: service-identity>=18.1.0; extra == 'all-non-platform'
 Provides-Extra: all_non_platform
 Provides-Extra: all_non_platform
-Requires-Dist: twisted[conch,http2,serial,test,tls]; extra == 'all_non_platform'
+Requires-Dist: appdirs>=1.4.0; extra == 'all_non_platform'
+Requires-Dist: bcrypt>=3.1.3; extra == 'all_non_platform'
+Requires-Dist: cryptography>=3.3; extra == 'all_non_platform'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'all_non_platform'
+Requires-Dist: h2<5.0,>=3.0; extra == 'all_non_platform'
+Requires-Dist: hypothesis>=6.56; extra == 'all_non_platform'
+Requires-Dist: idna>=2.4; extra == 'all_non_platform'
+Requires-Dist: priority<2.0,>=1.1.0; extra == 'all_non_platform'
+Requires-Dist: pyhamcrest>=2; extra == 'all_non_platform'
+Requires-Dist: pyopenssl>=21.0.0; extra == 'all_non_platform'
+Requires-Dist: pyserial>=3.0; extra == 'all_non_platform'
+Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'all_non_platform'
+Requires-Dist: service-identity>=18.1.0; extra == 'all_non_platform'
 Provides-Extra: conch
 Provides-Extra: conch
 Requires-Dist: appdirs>=1.4.0; extra == 'conch'
 Requires-Dist: appdirs>=1.4.0; extra == 'conch'
 Requires-Dist: bcrypt>=3.1.3; extra == 'conch'
 Requires-Dist: bcrypt>=3.1.3; extra == 'conch'
 Requires-Dist: cryptography>=3.3; extra == 'conch'
 Requires-Dist: cryptography>=3.3; extra == 'conch'
 Provides-Extra: dev
 Provides-Extra: dev
-Requires-Dist: coverage<7,>=6b1; extra == 'dev'
+Requires-Dist: coverage~=7.5; extra == 'dev'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'dev'
+Requires-Dist: hypothesis>=6.56; extra == 'dev'
+Requires-Dist: pydoctor~=23.9.0; extra == 'dev'
 Requires-Dist: pyflakes~=2.2; extra == 'dev'
 Requires-Dist: pyflakes~=2.2; extra == 'dev'
+Requires-Dist: pyhamcrest>=2; extra == 'dev'
 Requires-Dist: python-subunit~=1.4; extra == 'dev'
 Requires-Dist: python-subunit~=1.4; extra == 'dev'
-Requires-Dist: twisted[dev-release]; extra == 'dev'
+Requires-Dist: sphinx-rtd-theme~=1.3; extra == 'dev'
+Requires-Dist: sphinx<7,>=6; extra == 'dev'
+Requires-Dist: towncrier~=23.6; extra == 'dev'
 Requires-Dist: twistedchecker~=0.7; extra == 'dev'
 Requires-Dist: twistedchecker~=0.7; extra == 'dev'
 Provides-Extra: dev-release
 Provides-Extra: dev-release
 Requires-Dist: pydoctor~=23.9.0; extra == 'dev-release'
 Requires-Dist: pydoctor~=23.9.0; extra == 'dev-release'
@@ -52,34 +81,132 @@ Requires-Dist: sphinx-rtd-theme~=1.3; extra == 'dev_release'
 Requires-Dist: sphinx<7,>=6; extra == 'dev_release'
 Requires-Dist: sphinx<7,>=6; extra == 'dev_release'
 Requires-Dist: towncrier~=23.6; extra == 'dev_release'
 Requires-Dist: towncrier~=23.6; extra == 'dev_release'
 Provides-Extra: gtk-platform
 Provides-Extra: gtk-platform
+Requires-Dist: appdirs>=1.4.0; extra == 'gtk-platform'
+Requires-Dist: bcrypt>=3.1.3; extra == 'gtk-platform'
+Requires-Dist: cryptography>=3.3; extra == 'gtk-platform'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'gtk-platform'
+Requires-Dist: h2<5.0,>=3.0; extra == 'gtk-platform'
+Requires-Dist: hypothesis>=6.56; extra == 'gtk-platform'
+Requires-Dist: idna>=2.4; extra == 'gtk-platform'
+Requires-Dist: priority<2.0,>=1.1.0; extra == 'gtk-platform'
 Requires-Dist: pygobject; extra == 'gtk-platform'
 Requires-Dist: pygobject; extra == 'gtk-platform'
-Requires-Dist: twisted[all-non-platform]; extra == 'gtk-platform'
+Requires-Dist: pyhamcrest>=2; extra == 'gtk-platform'
+Requires-Dist: pyopenssl>=21.0.0; extra == 'gtk-platform'
+Requires-Dist: pyserial>=3.0; extra == 'gtk-platform'
+Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'gtk-platform'
+Requires-Dist: service-identity>=18.1.0; extra == 'gtk-platform'
 Provides-Extra: gtk_platform
 Provides-Extra: gtk_platform
+Requires-Dist: appdirs>=1.4.0; extra == 'gtk_platform'
+Requires-Dist: bcrypt>=3.1.3; extra == 'gtk_platform'
+Requires-Dist: cryptography>=3.3; extra == 'gtk_platform'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'gtk_platform'
+Requires-Dist: h2<5.0,>=3.0; extra == 'gtk_platform'
+Requires-Dist: hypothesis>=6.56; extra == 'gtk_platform'
+Requires-Dist: idna>=2.4; extra == 'gtk_platform'
+Requires-Dist: priority<2.0,>=1.1.0; extra == 'gtk_platform'
 Requires-Dist: pygobject; extra == 'gtk_platform'
 Requires-Dist: pygobject; extra == 'gtk_platform'
-Requires-Dist: twisted[all-non-platform]; extra == 'gtk_platform'
+Requires-Dist: pyhamcrest>=2; extra == 'gtk_platform'
+Requires-Dist: pyopenssl>=21.0.0; extra == 'gtk_platform'
+Requires-Dist: pyserial>=3.0; extra == 'gtk_platform'
+Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'gtk_platform'
+Requires-Dist: service-identity>=18.1.0; extra == 'gtk_platform'
 Provides-Extra: http2
 Provides-Extra: http2
 Requires-Dist: h2<5.0,>=3.0; extra == 'http2'
 Requires-Dist: h2<5.0,>=3.0; extra == 'http2'
 Requires-Dist: priority<2.0,>=1.1.0; extra == 'http2'
 Requires-Dist: priority<2.0,>=1.1.0; extra == 'http2'
 Provides-Extra: macos-platform
 Provides-Extra: macos-platform
+Requires-Dist: appdirs>=1.4.0; extra == 'macos-platform'
+Requires-Dist: bcrypt>=3.1.3; extra == 'macos-platform'
+Requires-Dist: cryptography>=3.3; extra == 'macos-platform'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'macos-platform'
+Requires-Dist: h2<5.0,>=3.0; extra == 'macos-platform'
+Requires-Dist: hypothesis>=6.56; extra == 'macos-platform'
+Requires-Dist: idna>=2.4; extra == 'macos-platform'
+Requires-Dist: priority<2.0,>=1.1.0; extra == 'macos-platform'
+Requires-Dist: pyhamcrest>=2; extra == 'macos-platform'
 Requires-Dist: pyobjc-core; extra == 'macos-platform'
 Requires-Dist: pyobjc-core; extra == 'macos-platform'
 Requires-Dist: pyobjc-framework-cfnetwork; extra == 'macos-platform'
 Requires-Dist: pyobjc-framework-cfnetwork; extra == 'macos-platform'
 Requires-Dist: pyobjc-framework-cocoa; extra == 'macos-platform'
 Requires-Dist: pyobjc-framework-cocoa; extra == 'macos-platform'
-Requires-Dist: twisted[all-non-platform]; extra == 'macos-platform'
+Requires-Dist: pyopenssl>=21.0.0; extra == 'macos-platform'
+Requires-Dist: pyserial>=3.0; extra == 'macos-platform'
+Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'macos-platform'
+Requires-Dist: service-identity>=18.1.0; extra == 'macos-platform'
 Provides-Extra: macos_platform
 Provides-Extra: macos_platform
+Requires-Dist: appdirs>=1.4.0; extra == 'macos_platform'
+Requires-Dist: bcrypt>=3.1.3; extra == 'macos_platform'
+Requires-Dist: cryptography>=3.3; extra == 'macos_platform'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'macos_platform'
+Requires-Dist: h2<5.0,>=3.0; extra == 'macos_platform'
+Requires-Dist: hypothesis>=6.56; extra == 'macos_platform'
+Requires-Dist: idna>=2.4; extra == 'macos_platform'
+Requires-Dist: priority<2.0,>=1.1.0; extra == 'macos_platform'
+Requires-Dist: pyhamcrest>=2; extra == 'macos_platform'
 Requires-Dist: pyobjc-core; extra == 'macos_platform'
 Requires-Dist: pyobjc-core; extra == 'macos_platform'
 Requires-Dist: pyobjc-framework-cfnetwork; extra == 'macos_platform'
 Requires-Dist: pyobjc-framework-cfnetwork; extra == 'macos_platform'
 Requires-Dist: pyobjc-framework-cocoa; extra == 'macos_platform'
 Requires-Dist: pyobjc-framework-cocoa; extra == 'macos_platform'
-Requires-Dist: twisted[all-non-platform]; extra == 'macos_platform'
+Requires-Dist: pyopenssl>=21.0.0; extra == 'macos_platform'
+Requires-Dist: pyserial>=3.0; extra == 'macos_platform'
+Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'macos_platform'
+Requires-Dist: service-identity>=18.1.0; extra == 'macos_platform'
 Provides-Extra: mypy
 Provides-Extra: mypy
+Requires-Dist: appdirs>=1.4.0; extra == 'mypy'
+Requires-Dist: bcrypt>=3.1.3; extra == 'mypy'
+Requires-Dist: coverage~=7.5; extra == 'mypy'
+Requires-Dist: cryptography>=3.3; extra == 'mypy'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'mypy'
+Requires-Dist: h2<5.0,>=3.0; extra == 'mypy'
+Requires-Dist: hypothesis>=6.56; extra == 'mypy'
+Requires-Dist: idna>=2.4; extra == 'mypy'
 Requires-Dist: mypy-zope~=1.0.3; extra == 'mypy'
 Requires-Dist: mypy-zope~=1.0.3; extra == 'mypy'
 Requires-Dist: mypy~=1.8; extra == 'mypy'
 Requires-Dist: mypy~=1.8; extra == 'mypy'
-Requires-Dist: twisted[all-non-platform,dev]; extra == 'mypy'
+Requires-Dist: priority<2.0,>=1.1.0; extra == 'mypy'
+Requires-Dist: pydoctor~=23.9.0; extra == 'mypy'
+Requires-Dist: pyflakes~=2.2; extra == 'mypy'
+Requires-Dist: pyhamcrest>=2; extra == 'mypy'
+Requires-Dist: pyopenssl>=21.0.0; extra == 'mypy'
+Requires-Dist: pyserial>=3.0; extra == 'mypy'
+Requires-Dist: python-subunit~=1.4; extra == 'mypy'
+Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'mypy'
+Requires-Dist: service-identity>=18.1.0; extra == 'mypy'
+Requires-Dist: sphinx-rtd-theme~=1.3; extra == 'mypy'
+Requires-Dist: sphinx<7,>=6; extra == 'mypy'
+Requires-Dist: towncrier~=23.6; extra == 'mypy'
+Requires-Dist: twistedchecker~=0.7; extra == 'mypy'
 Requires-Dist: types-pyopenssl; extra == 'mypy'
 Requires-Dist: types-pyopenssl; extra == 'mypy'
 Requires-Dist: types-setuptools; extra == 'mypy'
 Requires-Dist: types-setuptools; extra == 'mypy'
 Provides-Extra: osx-platform
 Provides-Extra: osx-platform
-Requires-Dist: twisted[macos-platform]; extra == 'osx-platform'
+Requires-Dist: appdirs>=1.4.0; extra == 'osx-platform'
+Requires-Dist: bcrypt>=3.1.3; extra == 'osx-platform'
+Requires-Dist: cryptography>=3.3; extra == 'osx-platform'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'osx-platform'
+Requires-Dist: h2<5.0,>=3.0; extra == 'osx-platform'
+Requires-Dist: hypothesis>=6.56; extra == 'osx-platform'
+Requires-Dist: idna>=2.4; extra == 'osx-platform'
+Requires-Dist: priority<2.0,>=1.1.0; extra == 'osx-platform'
+Requires-Dist: pyhamcrest>=2; extra == 'osx-platform'
+Requires-Dist: pyobjc-core; extra == 'osx-platform'
+Requires-Dist: pyobjc-framework-cfnetwork; extra == 'osx-platform'
+Requires-Dist: pyobjc-framework-cocoa; extra == 'osx-platform'
+Requires-Dist: pyopenssl>=21.0.0; extra == 'osx-platform'
+Requires-Dist: pyserial>=3.0; extra == 'osx-platform'
+Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'osx-platform'
+Requires-Dist: service-identity>=18.1.0; extra == 'osx-platform'
 Provides-Extra: osx_platform
 Provides-Extra: osx_platform
-Requires-Dist: twisted[macos-platform]; extra == 'osx_platform'
+Requires-Dist: appdirs>=1.4.0; extra == 'osx_platform'
+Requires-Dist: bcrypt>=3.1.3; extra == 'osx_platform'
+Requires-Dist: cryptography>=3.3; extra == 'osx_platform'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'osx_platform'
+Requires-Dist: h2<5.0,>=3.0; extra == 'osx_platform'
+Requires-Dist: hypothesis>=6.56; extra == 'osx_platform'
+Requires-Dist: idna>=2.4; extra == 'osx_platform'
+Requires-Dist: priority<2.0,>=1.1.0; extra == 'osx_platform'
+Requires-Dist: pyhamcrest>=2; extra == 'osx_platform'
+Requires-Dist: pyobjc-core; extra == 'osx_platform'
+Requires-Dist: pyobjc-framework-cfnetwork; extra == 'osx_platform'
+Requires-Dist: pyobjc-framework-cocoa; extra == 'osx_platform'
+Requires-Dist: pyopenssl>=21.0.0; extra == 'osx_platform'
+Requires-Dist: pyserial>=3.0; extra == 'osx_platform'
+Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'osx_platform'
+Requires-Dist: service-identity>=18.1.0; extra == 'osx_platform'
 Provides-Extra: serial
 Provides-Extra: serial
 Requires-Dist: pyserial>=3.0; extra == 'serial'
 Requires-Dist: pyserial>=3.0; extra == 'serial'
 Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'serial'
 Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'serial'
@@ -92,11 +219,37 @@ Requires-Dist: idna>=2.4; extra == 'tls'
 Requires-Dist: pyopenssl>=21.0.0; extra == 'tls'
 Requires-Dist: pyopenssl>=21.0.0; extra == 'tls'
 Requires-Dist: service-identity>=18.1.0; extra == 'tls'
 Requires-Dist: service-identity>=18.1.0; extra == 'tls'
 Provides-Extra: windows-platform
 Provides-Extra: windows-platform
+Requires-Dist: appdirs>=1.4.0; extra == 'windows-platform'
+Requires-Dist: bcrypt>=3.1.3; extra == 'windows-platform'
+Requires-Dist: cryptography>=3.3; extra == 'windows-platform'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'windows-platform'
+Requires-Dist: h2<5.0,>=3.0; extra == 'windows-platform'
+Requires-Dist: hypothesis>=6.56; extra == 'windows-platform'
+Requires-Dist: idna>=2.4; extra == 'windows-platform'
+Requires-Dist: priority<2.0,>=1.1.0; extra == 'windows-platform'
+Requires-Dist: pyhamcrest>=2; extra == 'windows-platform'
+Requires-Dist: pyopenssl>=21.0.0; extra == 'windows-platform'
+Requires-Dist: pyserial>=3.0; extra == 'windows-platform'
 Requires-Dist: pywin32!=226; extra == 'windows-platform'
 Requires-Dist: pywin32!=226; extra == 'windows-platform'
-Requires-Dist: twisted[all-non-platform]; extra == 'windows-platform'
+Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'windows-platform'
+Requires-Dist: service-identity>=18.1.0; extra == 'windows-platform'
+Requires-Dist: twisted-iocpsupport>=1.0.2; extra == 'windows-platform'
 Provides-Extra: windows_platform
 Provides-Extra: windows_platform
+Requires-Dist: appdirs>=1.4.0; extra == 'windows_platform'
+Requires-Dist: bcrypt>=3.1.3; extra == 'windows_platform'
+Requires-Dist: cryptography>=3.3; extra == 'windows_platform'
+Requires-Dist: cython-test-exception-raiser<2,>=1.0.2; extra == 'windows_platform'
+Requires-Dist: h2<5.0,>=3.0; extra == 'windows_platform'
+Requires-Dist: hypothesis>=6.56; extra == 'windows_platform'
+Requires-Dist: idna>=2.4; extra == 'windows_platform'
+Requires-Dist: priority<2.0,>=1.1.0; extra == 'windows_platform'
+Requires-Dist: pyhamcrest>=2; extra == 'windows_platform'
+Requires-Dist: pyopenssl>=21.0.0; extra == 'windows_platform'
+Requires-Dist: pyserial>=3.0; extra == 'windows_platform'
 Requires-Dist: pywin32!=226; extra == 'windows_platform'
 Requires-Dist: pywin32!=226; extra == 'windows_platform'
-Requires-Dist: twisted[all-non-platform]; extra == 'windows_platform'
+Requires-Dist: pywin32!=226; (platform_system == 'Windows') and extra == 'windows_platform'
+Requires-Dist: service-identity>=18.1.0; extra == 'windows_platform'
+Requires-Dist: twisted-iocpsupport>=1.0.2; extra == 'windows_platform'
 Description-Content-Type: text/x-rst
 Description-Content-Type: text/x-rst
 
 
 Twisted
 Twisted
@@ -135,7 +288,7 @@ To install the latest version of Twisted using pip::
 
 
   $ pip install twisted
   $ pip install twisted
 
 
-Additional instructions for installing this software are in `the installation instructions <https://github.com/twisted/twisted/blob/trunk/INSTALL.rst>`_.
+Additional instructions for installing this software are in `the installation instructions <https://docs.twisted.org/en/latest/installations.rst>`_.
 
 
 
 
 Documentation and Support
 Documentation and Support

+ 1 - 1
contrib/python/Twisted/py3/README.rst

@@ -34,7 +34,7 @@ To install the latest version of Twisted using pip::
 
 
   $ pip install twisted
   $ pip install twisted
 
 
-Additional instructions for installing this software are in `the installation instructions <INSTALL.rst>`_.
+Additional instructions for installing this software are in `the installation instructions <https://docs.twisted.org/en/latest/installations.rst>`_.
 
 
 
 
 Documentation and Support
 Documentation and Support

+ 1 - 1
contrib/python/Twisted/py3/twisted/_version.py

@@ -7,5 +7,5 @@ Provides Twisted version information.
 
 
 from incremental import Version
 from incremental import Version
 
 
-__version__ = Version("Twisted", 24, 3, 0)
+__version__ = Version("Twisted", 24, 7, 0)
 __all__ = ["__version__"]
 __all__ = ["__version__"]

+ 50 - 48
contrib/python/Twisted/py3/twisted/conch/client/knownhosts.py

@@ -8,12 +8,14 @@ An implementation of the OpenSSH known_hosts database.
 @since: 8.2
 @since: 8.2
 """
 """
 
 
+from __future__ import annotations
 
 
 import hmac
 import hmac
 import sys
 import sys
 from binascii import Error as DecodeError, a2b_base64, b2a_base64
 from binascii import Error as DecodeError, a2b_base64, b2a_base64
 from contextlib import closing
 from contextlib import closing
 from hashlib import sha1
 from hashlib import sha1
+from typing import IO, Callable, Literal
 
 
 from zope.interface import implementer
 from zope.interface import implementer
 
 
@@ -21,8 +23,10 @@ from twisted.conch.error import HostKeyChanged, InvalidEntry, UserRejectedKey
 from twisted.conch.interfaces import IKnownHostEntry
 from twisted.conch.interfaces import IKnownHostEntry
 from twisted.conch.ssh.keys import BadKeyError, FingerprintFormats, Key
 from twisted.conch.ssh.keys import BadKeyError, FingerprintFormats, Key
 from twisted.internet import defer
 from twisted.internet import defer
+from twisted.internet.defer import Deferred
 from twisted.logger import Logger
 from twisted.logger import Logger
 from twisted.python.compat import nativeString
 from twisted.python.compat import nativeString
+from twisted.python.filepath import FilePath
 from twisted.python.randbytes import secureRandom
 from twisted.python.randbytes import secureRandom
 from twisted.python.util import FancyEqMixin
 from twisted.python.util import FancyEqMixin
 
 
@@ -111,34 +115,33 @@ class PlainEntry(_BaseEntry):
     file.
     file.
 
 
     @ivar _hostnames: the list of all host-names associated with this entry.
     @ivar _hostnames: the list of all host-names associated with this entry.
-    @type _hostnames: L{list} of L{bytes}
     """
     """
 
 
-    def __init__(self, hostnames, keyType, publicKey, comment):
-        self._hostnames = hostnames
+    def __init__(
+        self, hostnames: list[bytes], keyType: bytes, publicKey: Key, comment: bytes
+    ):
+        self._hostnames: list[bytes] = hostnames
         super().__init__(keyType, publicKey, comment)
         super().__init__(keyType, publicKey, comment)
 
 
     @classmethod
     @classmethod
-    def fromString(cls, string):
+    def fromString(cls, string: bytes) -> PlainEntry:
         """
         """
         Parse a plain-text entry in a known_hosts file, and return a
         Parse a plain-text entry in a known_hosts file, and return a
         corresponding L{PlainEntry}.
         corresponding L{PlainEntry}.
 
 
         @param string: a space-separated string formatted like "hostname
         @param string: a space-separated string formatted like "hostname
-        key-type base64-key-data comment".
-
-        @type string: L{bytes}
+            key-type base64-key-data comment".
 
 
         @raise DecodeError: if the key is not valid encoded as valid base64.
         @raise DecodeError: if the key is not valid encoded as valid base64.
 
 
         @raise InvalidEntry: if the entry does not have the right number of
         @raise InvalidEntry: if the entry does not have the right number of
-        elements and is therefore invalid.
+            elements and is therefore invalid.
 
 
         @raise BadKeyError: if the key, once decoded from base64, is not
         @raise BadKeyError: if the key, once decoded from base64, is not
-        actually an SSH key.
+            actually an SSH key.
 
 
         @return: an IKnownHostEntry representing the hostname and key in the
         @return: an IKnownHostEntry representing the hostname and key in the
-        input line.
+            input line.
 
 
         @rtype: L{PlainEntry}
         @rtype: L{PlainEntry}
         """
         """
@@ -146,30 +149,27 @@ class PlainEntry(_BaseEntry):
         self = cls(hostnames.split(b","), keyType, key, comment)
         self = cls(hostnames.split(b","), keyType, key, comment)
         return self
         return self
 
 
-    def matchesHost(self, hostname):
+    def matchesHost(self, hostname: bytes | str) -> bool:
         """
         """
         Check to see if this entry matches a given hostname.
         Check to see if this entry matches a given hostname.
 
 
         @param hostname: A hostname or IP address literal to check against this
         @param hostname: A hostname or IP address literal to check against this
             entry.
             entry.
-        @type hostname: L{bytes}
 
 
         @return: C{True} if this entry is for the given hostname or IP address,
         @return: C{True} if this entry is for the given hostname or IP address,
             C{False} otherwise.
             C{False} otherwise.
-        @rtype: L{bool}
         """
         """
         if isinstance(hostname, str):
         if isinstance(hostname, str):
             hostname = hostname.encode("utf-8")
             hostname = hostname.encode("utf-8")
         return hostname in self._hostnames
         return hostname in self._hostnames
 
 
-    def toString(self):
+    def toString(self) -> bytes:
         """
         """
         Implement L{IKnownHostEntry.toString} by recording the comma-separated
         Implement L{IKnownHostEntry.toString} by recording the comma-separated
         hostnames, key type, and base-64 encoded key.
         hostnames, key type, and base-64 encoded key.
 
 
         @return: The string representation of this entry, with unhashed hostname
         @return: The string representation of this entry, with unhashed hostname
             information.
             information.
-        @rtype: L{bytes}
         """
         """
         fields = [
         fields = [
             b",".join(self._hostnames),
             b",".join(self._hostnames),
@@ -256,33 +256,39 @@ class HashedEntry(_BaseEntry, FancyEqMixin):
 
 
     compareAttributes = ("_hostSalt", "_hostHash", "keyType", "publicKey", "comment")
     compareAttributes = ("_hostSalt", "_hostHash", "keyType", "publicKey", "comment")
 
 
-    def __init__(self, hostSalt, hostHash, keyType, publicKey, comment):
+    def __init__(
+        self,
+        hostSalt: bytes,
+        hostHash: bytes,
+        keyType: bytes,
+        publicKey: Key,
+        comment: bytes | None,
+    ) -> None:
         self._hostSalt = hostSalt
         self._hostSalt = hostSalt
         self._hostHash = hostHash
         self._hostHash = hostHash
         super().__init__(keyType, publicKey, comment)
         super().__init__(keyType, publicKey, comment)
 
 
     @classmethod
     @classmethod
-    def fromString(cls, string):
+    def fromString(cls, string: bytes) -> HashedEntry:
         """
         """
         Load a hashed entry from a string representing a line in a known_hosts
         Load a hashed entry from a string representing a line in a known_hosts
         file.
         file.
 
 
         @param string: A complete single line from a I{known_hosts} file,
         @param string: A complete single line from a I{known_hosts} file,
             formatted as defined by OpenSSH.
             formatted as defined by OpenSSH.
-        @type string: L{bytes}
 
 
         @raise DecodeError: if the key, the hostname, or the is not valid
         @raise DecodeError: if the key, the hostname, or the is not valid
             encoded as valid base64
             encoded as valid base64
 
 
         @raise InvalidEntry: if the entry does not have the right number of
         @raise InvalidEntry: if the entry does not have the right number of
-            elements and is therefore invalid, or the host/hash portion contains
-            more items than just the host and hash.
+            elements and is therefore invalid, or the host/hash portion
+            contains more items than just the host and hash.
 
 
         @raise BadKeyError: if the key, once decoded from base64, is not
         @raise BadKeyError: if the key, once decoded from base64, is not
             actually an SSH key.
             actually an SSH key.
 
 
-        @return: The newly created L{HashedEntry} instance, initialized with the
-            information from C{string}.
+        @return: The newly created L{HashedEntry} instance, initialized with
+            the information from C{string}.
         """
         """
         stuff, keyType, key, comment = _extractCommon(string)
         stuff, keyType, key, comment = _extractCommon(string)
         saltAndHash = stuff[len(cls.MAGIC) :].split(b"|")
         saltAndHash = stuff[len(cls.MAGIC) :].split(b"|")
@@ -346,7 +352,7 @@ class KnownHostsFile:
     @ivar _savePath: See C{savePath} parameter of L{__init__}.
     @ivar _savePath: See C{savePath} parameter of L{__init__}.
     """
     """
 
 
-    def __init__(self, savePath):
+    def __init__(self, savePath: FilePath[str]) -> None:
         """
         """
         Create a new, empty KnownHostsFile.
         Create a new, empty KnownHostsFile.
 
 
@@ -356,12 +362,12 @@ class KnownHostsFile:
         @param savePath: The L{FilePath} to which to save new entries.
         @param savePath: The L{FilePath} to which to save new entries.
         @type savePath: L{FilePath}
         @type savePath: L{FilePath}
         """
         """
-        self._added = []
+        self._added: list[IKnownHostEntry] = []
         self._savePath = savePath
         self._savePath = savePath
         self._clobber = True
         self._clobber = True
 
 
     @property
     @property
-    def savePath(self):
+    def savePath(self) -> FilePath[str]:
         """
         """
         @see: C{savePath} parameter of L{__init__}
         @see: C{savePath} parameter of L{__init__}
         """
         """
@@ -431,7 +437,9 @@ class KnownHostsFile:
                     raise HostKeyChanged(entry, path, line)
                     raise HostKeyChanged(entry, path, line)
         return False
         return False
 
 
-    def verifyHostKey(self, ui, hostname, ip, key):
+    def verifyHostKey(
+        self, ui: ConsoleUI, hostname: bytes, ip: bytes, key: Key
+    ) -> Deferred[bool]:
         """
         """
         Verify the given host key for the given IP and host, asking for
         Verify the given host key for the given IP and host, asking for
         confirmation from, and notifying, the given UI about changes to this
         confirmation from, and notifying, the given UI about changes to this
@@ -453,20 +461,21 @@ class KnownHostsFile:
         """
         """
         hhk = defer.execute(self.hasHostKey, hostname, key)
         hhk = defer.execute(self.hasHostKey, hostname, key)
 
 
-        def gotHasKey(result):
+        def gotHasKey(result: bool) -> bool | Deferred[bool]:
             if result:
             if result:
                 if not self.hasHostKey(ip, key):
                 if not self.hasHostKey(ip, key):
-                    ui.warn(
-                        "Warning: Permanently added the %s host key for "
-                        "IP address '%s' to the list of known hosts."
-                        % (key.type(), nativeString(ip))
+                    addMessage = (
+                        f"Warning: Permanently added the {key.type()} host key"
+                        f" for IP address '{ip.decode()}' to the list of known"
+                        " hosts.\n"
                     )
                     )
+                    ui.warn(addMessage.encode("utf-8"))
                     self.addHostKey(ip, key)
                     self.addHostKey(ip, key)
                     self.save()
                     self.save()
                 return result
                 return result
             else:
             else:
 
 
-                def promptResponse(response):
+                def promptResponse(response: bool) -> bool:
                     if response:
                     if response:
                         self.addHostKey(hostname, key)
                         self.addHostKey(hostname, key)
                         self.addHostKey(ip, key)
                         self.addHostKey(ip, key)
@@ -475,7 +484,7 @@ class KnownHostsFile:
                     else:
                     else:
                         raise UserRejectedKey()
                         raise UserRejectedKey()
 
 
-                keytype = key.type()
+                keytype: str = key.type()
 
 
                 if keytype == "EC":
                 if keytype == "EC":
                     keytype = "ECDSA"
                     keytype = "ECDSA"
@@ -497,7 +506,7 @@ class KnownHostsFile:
 
 
         return hhk.addCallback(gotHasKey)
         return hhk.addCallback(gotHasKey)
 
 
-    def addHostKey(self, hostname, key):
+    def addHostKey(self, hostname: bytes, key: Key) -> HashedEntry:
         """
         """
         Add a new L{HashedEntry} to the key database.
         Add a new L{HashedEntry} to the key database.
 
 
@@ -520,7 +529,7 @@ class KnownHostsFile:
         self._added.append(entry)
         self._added.append(entry)
         return entry
         return entry
 
 
-    def save(self):
+    def save(self) -> None:
         """
         """
         Save this L{KnownHostsFile} to the path it was loaded from.
         Save this L{KnownHostsFile} to the path it was loaded from.
         """
         """
@@ -528,11 +537,7 @@ class KnownHostsFile:
         if not p.isdir():
         if not p.isdir():
             p.makedirs()
             p.makedirs()
 
 
-        if self._clobber:
-            mode = "wb"
-        else:
-            mode = "ab"
-
+        mode: Literal["a", "w"] = "w" if self._clobber else "a"
         with self._savePath.open(mode) as hostsFileObj:
         with self._savePath.open(mode) as hostsFileObj:
             if self._added:
             if self._added:
                 hostsFileObj.write(
                 hostsFileObj.write(
@@ -542,7 +547,7 @@ class KnownHostsFile:
         self._clobber = False
         self._clobber = False
 
 
     @classmethod
     @classmethod
-    def fromPath(cls, path):
+    def fromPath(cls, path: FilePath[str]) -> KnownHostsFile:
         """
         """
         Create a new L{KnownHostsFile}, potentially reading existing known
         Create a new L{KnownHostsFile}, potentially reading existing known
         hosts information from the given file.
         hosts information from the given file.
@@ -550,10 +555,8 @@ class KnownHostsFile:
         @param path: A path object to use for both reading contents from and
         @param path: A path object to use for both reading contents from and
             later saving to.  If no file exists at this path, it is not an
             later saving to.  If no file exists at this path, it is not an
             error; a L{KnownHostsFile} with no entries is returned.
             error; a L{KnownHostsFile} with no entries is returned.
-        @type path: L{FilePath}
 
 
         @return: A L{KnownHostsFile} initialized with entries from C{path}.
         @return: A L{KnownHostsFile} initialized with entries from C{path}.
-        @rtype: L{KnownHostsFile}
         """
         """
         knownHosts = cls(path)
         knownHosts = cls(path)
         knownHosts._clobber = False
         knownHosts._clobber = False
@@ -566,7 +569,7 @@ class ConsoleUI:
     console, to be used during key verification.
     console, to be used during key verification.
     """
     """
 
 
-    def __init__(self, opener):
+    def __init__(self, opener: Callable[[], IO[bytes]]):
         """
         """
         @param opener: A no-argument callable which should open a console
         @param opener: A no-argument callable which should open a console
             binary-mode file-like object to be used for reading and writing.
             binary-mode file-like object to be used for reading and writing.
@@ -576,7 +579,7 @@ class ConsoleUI:
         """
         """
         self.opener = opener
         self.opener = opener
 
 
-    def prompt(self, text):
+    def prompt(self, text: bytes) -> Deferred[bool]:
         """
         """
         Write the given text as a prompt to the console output, then read a
         Write the given text as a prompt to the console output, then read a
         result from the console input.
         result from the console input.
@@ -598,20 +601,19 @@ class ConsoleUI:
                     answer = f.readline().strip().lower()
                     answer = f.readline().strip().lower()
                     if answer == b"yes":
                     if answer == b"yes":
                         return True
                         return True
-                    elif answer == b"no":
+                    elif answer in {b"no", b""}:
                         return False
                         return False
                     else:
                     else:
                         f.write(b"Please type 'yes' or 'no': ")
                         f.write(b"Please type 'yes' or 'no': ")
 
 
         return d.addCallback(body)
         return d.addCallback(body)
 
 
-    def warn(self, text):
+    def warn(self, text: bytes) -> None:
         """
         """
         Notify the user (non-interactively) of the provided text, by writing it
         Notify the user (non-interactively) of the provided text, by writing it
         to the console.
         to the console.
 
 
         @param text: Some information the user is to be made aware of.
         @param text: Some information the user is to be made aware of.
-        @type text: L{bytes}
         """
         """
         try:
         try:
             with closing(self.opener()) as f:
             with closing(self.opener()) as f:

+ 24 - 54
contrib/python/Twisted/py3/twisted/conch/endpoints.py

@@ -6,11 +6,19 @@
 Endpoint implementations of various SSH interactions.
 Endpoint implementations of various SSH interactions.
 """
 """
 
 
-__all__ = ["AuthenticationFailed", "SSHCommandAddress", "SSHCommandClientEndpoint"]
+from __future__ import annotations
+
+__all__ = [
+    "AuthenticationFailed",
+    "SSHCommandAddress",
+    "SSHCommandClientEndpoint",
+]
 
 
 import signal
 import signal
+from io import BytesIO
 from os.path import expanduser
 from os.path import expanduser
 from struct import unpack
 from struct import unpack
+from typing import IO, Any
 
 
 from zope.interface import Interface, implementer
 from zope.interface import Interface, implementer
 
 
@@ -689,44 +697,6 @@ class SSHCommandClientEndpoint:
         return commandConnected
         return commandConnected
 
 
 
 
-class _ReadFile:
-    """
-    A weakly file-like object which can be used with L{KnownHostsFile} to
-    respond in the negative to all prompts for decisions.
-    """
-
-    def __init__(self, contents):
-        """
-        @param contents: L{bytes} which will be returned from every C{readline}
-            call.
-        """
-        self._contents = contents
-
-    def write(self, data):
-        """
-        No-op.
-
-        @param data: ignored
-        """
-
-    def readline(self, count=-1):
-        """
-        Always give back the byte string that this L{_ReadFile} was initialized
-        with.
-
-        @param count: ignored
-
-        @return: A fixed byte-string.
-        @rtype: L{bytes}
-        """
-        return self._contents
-
-    def close(self):
-        """
-        No-op.
-        """
-
-
 @implementer(_ISSHConnectionCreator)
 @implementer(_ISSHConnectionCreator)
 class _NewConnectionHelper:
 class _NewConnectionHelper:
     """
     """
@@ -739,17 +709,17 @@ class _NewConnectionHelper:
 
 
     def __init__(
     def __init__(
         self,
         self,
-        reactor,
-        hostname,
-        port,
-        command,
-        username,
-        keys,
-        password,
-        agentEndpoint,
-        knownHosts,
-        ui,
-        tty=FilePath(b"/dev/tty"),
+        reactor: Any,
+        hostname: str,
+        port: int,
+        command: str,
+        username: str,
+        keys: str,
+        password: str,
+        agentEndpoint: str,
+        knownHosts: str | None,
+        ui: ConsoleUI | None,
+        tty: FilePath[bytes] | FilePath[str] = FilePath(b"/dev/tty"),
     ):
     ):
         """
         """
         @param tty: The path of the tty device to use in case C{ui} is L{None}.
         @param tty: The path of the tty device to use in case C{ui} is L{None}.
@@ -773,9 +743,9 @@ class _NewConnectionHelper:
         if ui is None:
         if ui is None:
             ui = ConsoleUI(self._opener)
             ui = ConsoleUI(self._opener)
         self.ui = ui
         self.ui = ui
-        self.tty = tty
+        self.tty: FilePath[bytes] | FilePath[str] = tty
 
 
-    def _opener(self):
+    def _opener(self) -> IO[bytes]:
         """
         """
         Open the tty if possible, otherwise give back a file-like object from
         Open the tty if possible, otherwise give back a file-like object from
         which C{b"no"} can be read.
         which C{b"no"} can be read.
@@ -783,11 +753,11 @@ class _NewConnectionHelper:
         For use as the opener argument to L{ConsoleUI}.
         For use as the opener argument to L{ConsoleUI}.
         """
         """
         try:
         try:
-            return self.tty.open("rb+")
+            return self.tty.open("r+")
         except BaseException:
         except BaseException:
             # Give back a file-like object from which can be read a byte string
             # Give back a file-like object from which can be read a byte string
             # that KnownHostsFile recognizes as rejecting some option (b"no").
             # that KnownHostsFile recognizes as rejecting some option (b"no").
-            return _ReadFile(b"no")
+            return BytesIO(b"no")
 
 
     @classmethod
     @classmethod
     def _knownHosts(cls):
     def _knownHosts(cls):

+ 1 - 17
contrib/python/Twisted/py3/twisted/conch/insults/insults.py

@@ -431,23 +431,7 @@ _KEY_NAMES = (
     "CONTROL",
     "CONTROL",
 )
 )
 
 
-
-class _const:
-    """
-    @ivar name: A string naming this constant
-    """
-
-    def __init__(self, name: str) -> None:
-        self.name = name
-
-    def __repr__(self) -> str:
-        return "[" + self.name + "]"
-
-    def __bytes__(self) -> bytes:
-        return ("[" + self.name + "]").encode("ascii")
-
-
-FUNCTION_KEYS = [_const(_name).__bytes__() for _name in _KEY_NAMES]
+FUNCTION_KEYS = [f"[{_name}]".encode("ascii") for _name in _KEY_NAMES]
 
 
 
 
 @implementer(ITerminalTransport)
 @implementer(ITerminalTransport)

+ 10 - 2
contrib/python/Twisted/py3/twisted/conch/insults/window.py

@@ -6,6 +6,8 @@ Simple insults-based widget library
 @author: Jp Calderone
 @author: Jp Calderone
 """
 """
 
 
+from __future__ import annotations
+
 import array
 import array
 
 
 from twisted.conch.insults import helper, insults
 from twisted.conch.insults import helper, insults
@@ -47,7 +49,8 @@ class Widget:
     focused = False
     focused = False
     parent = None
     parent = None
     dirty = False
     dirty = False
-    width = height = None
+    width: int | None = None
+    height: int | None = None
 
 
     def repaint(self):
     def repaint(self):
         if not self.dirty:
         if not self.dirty:
@@ -109,7 +112,12 @@ class Widget:
         name = keyID
         name = keyID
         if not isinstance(keyID, str):
         if not isinstance(keyID, str):
             name = name.decode("utf-8")
             name = name.decode("utf-8")
-        func = getattr(self, "func_" + name, None)
+
+        # Peel off the square brackets added by the computed definition of
+        # twisted.conch.insults.insults.FUNCTION_KEYS.
+        methodName = "func_" + name[1:-1]
+
+        func = getattr(self, methodName, None)
         if func is not None:
         if func is not None:
             func(modifier)
             func(modifier)
 
 

+ 11 - 9
contrib/python/Twisted/py3/twisted/conch/interfaces.py

@@ -5,8 +5,15 @@
 This module contains interfaces defined for the L{twisted.conch} package.
 This module contains interfaces defined for the L{twisted.conch} package.
 """
 """
 
 
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
 from zope.interface import Attribute, Interface
 from zope.interface import Attribute, Interface
 
 
+if TYPE_CHECKING:
+    from twisted.conch.ssh.keys import Key
+
 
 
 class IConchUser(Interface):
 class IConchUser(Interface):
     """
     """
@@ -363,16 +370,15 @@ class IKnownHostEntry(Interface):
     @since: 8.2
     @since: 8.2
     """
     """
 
 
-    def matchesKey(key):
+    def matchesKey(key: Key) -> bool:
         """
         """
         Return True if this entry matches the given Key object, False
         Return True if this entry matches the given Key object, False
         otherwise.
         otherwise.
 
 
         @param key: The key object to match against.
         @param key: The key object to match against.
-        @type key: L{twisted.conch.ssh.keys.Key}
         """
         """
 
 
-    def matchesHost(hostname):
+    def matchesHost(hostname: bytes) -> bool:
         """
         """
         Return True if this entry matches the given hostname, False otherwise.
         Return True if this entry matches the given hostname, False otherwise.
 
 
@@ -381,16 +387,12 @@ class IKnownHostEntry(Interface):
         quad string.
         quad string.
 
 
         @param hostname: The hostname to match against.
         @param hostname: The hostname to match against.
-        @type hostname: L{str}
         """
         """
 
 
-    def toString():
+    def toString() -> bytes:
         """
         """
-
         @return: a serialized string representation of this entry, suitable for
         @return: a serialized string representation of this entry, suitable for
-        inclusion in a known_hosts file.  (Newline not included.)
-
-        @rtype: L{str}
+            inclusion in a known_hosts file.  (Newline not included.)
         """
         """
 
 
 
 

+ 2 - 9
contrib/python/Twisted/py3/twisted/conch/manhole.py

@@ -23,7 +23,6 @@ from typing import Type
 
 
 from twisted.conch import recvline
 from twisted.conch import recvline
 from twisted.internet import defer
 from twisted.internet import defer
-from twisted.python.compat import _get_async_param
 from twisted.python.htmlizer import TokenPrinter
 from twisted.python.htmlizer import TokenPrinter
 from twisted.python.monkey import MonkeyPatcher
 from twisted.python.monkey import MonkeyPatcher
 
 
@@ -161,8 +160,7 @@ class ManholeInterpreter(code.InteractiveInterpreter):
         del self._pendingDeferreds[id(obj)]
         del self._pendingDeferreds[id(obj)]
         return failure
         return failure
 
 
-    def write(self, data, isAsync=None, **kwargs):
-        isAsync = _get_async_param(isAsync, **kwargs)
+    def write(self, data, isAsync=None):
         self.handler.addOutput(data, isAsync)
         self.handler.addOutput(data, isAsync)
 
 
 
 
@@ -239,8 +237,7 @@ class Manhole(recvline.HistoricRecvLine):
         w = self.terminal.lastWrite
         w = self.terminal.lastWrite
         return not w.endswith(b"\n") and not w.endswith(b"\x1bE")
         return not w.endswith(b"\n") and not w.endswith(b"\x1bE")
 
 
-    def addOutput(self, data, isAsync=None, **kwargs):
-        isAsync = _get_async_param(isAsync, **kwargs)
+    def addOutput(self, data, isAsync=None):
         if isAsync:
         if isAsync:
             self.terminal.eraseLine()
             self.terminal.eraseLine()
             self.terminal.cursorBackward(len(self.lineBuffer) + len(self.ps[self.pn]))
             self.terminal.cursorBackward(len(self.lineBuffer) + len(self.ps[self.pn]))
@@ -309,10 +306,6 @@ class VT102Writer:
         s = b"".join(self.written)
         s = b"".join(self.written)
         return s.strip(b"\n").splitlines()[-1]
         return s.strip(b"\n").splitlines()[-1]
 
 
-    if bytes == str:
-        # Compat with Python 2.7
-        __str__ = __bytes__
-
 
 
 def lastColorizedLine(source):
 def lastColorizedLine(source):
     """
     """

+ 5 - 7
contrib/python/Twisted/py3/twisted/internet/_baseprocess.py

@@ -9,11 +9,13 @@ L{IReactorProcess} implementations.
 
 
 from typing import Optional
 from typing import Optional
 
 
+from twisted.logger import Logger
 from twisted.python.deprecate import getWarningMethod
 from twisted.python.deprecate import getWarningMethod
 from twisted.python.failure import Failure
 from twisted.python.failure import Failure
-from twisted.python.log import err
 from twisted.python.reflect import qual
 from twisted.python.reflect import qual
 
 
+_log = Logger()
+
 _missingProcessExited = (
 _missingProcessExited = (
     "Since Twisted 8.2, IProcessProtocol.processExited "
     "Since Twisted 8.2, IProcessProtocol.processExited "
     "is required.  %s must implement it."
     "is required.  %s must implement it."
@@ -39,10 +41,8 @@ class BaseProcess:
                 stacklevel=0,
                 stacklevel=0,
             )
             )
         else:
         else:
-            try:
+            with _log.failuresHandled("while calling processExited:"):
                 processExited(Failure(reason))
                 processExited(Failure(reason))
-            except BaseException:
-                err(None, "unexpected error in processExited")
 
 
     def processEnded(self, status):
     def processEnded(self, status):
         """
         """
@@ -62,7 +62,5 @@ class BaseProcess:
             reason = self._getReason(self.status)
             reason = self._getReason(self.status)
             proto = self.proto
             proto = self.proto
             self.proto = None
             self.proto = None
-            try:
+            with _log.failuresHandled("while calling processEnded:"):
                 proto.processEnded(Failure(reason))
                 proto.processEnded(Failure(reason))
-            except BaseException:
-                err(None, "unexpected error in processEnded")

Some files were not shown because too many files changed in this diff