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
-Version: 24.3.0
+Version: 24.7.0
 Summary: An asynchronous networking framework written in Python
 Project-URL: Changelog, https://github.com/twisted/twisted/blob/HEAD/NEWS.rst
 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: constantly>=15.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: zope-interface>=5
 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
-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
 Requires-Dist: appdirs>=1.4.0; extra == 'conch'
 Requires-Dist: bcrypt>=3.1.3; extra == 'conch'
 Requires-Dist: cryptography>=3.3; extra == 'conch'
 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: pyhamcrest>=2; 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'
 Provides-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: towncrier~=23.6; extra == 'dev_release'
 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: 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
+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: 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
 Requires-Dist: h2<5.0,>=3.0; extra == 'http2'
 Requires-Dist: priority<2.0,>=1.1.0; extra == 'http2'
 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-framework-cfnetwork; 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
+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-framework-cfnetwork; 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
+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~=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-setuptools; extra == 'mypy'
 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
-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
 Requires-Dist: pyserial>=3.0; 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: service-identity>=18.1.0; extra == 'tls'
 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: 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
+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: 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
 
 Twisted
@@ -135,7 +288,7 @@ To install the latest version of Twisted using pip::
 
   $ 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

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

@@ -34,7 +34,7 @@ To install the latest version of Twisted using pip::
 
   $ 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

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

@@ -7,5 +7,5 @@ Provides Twisted version information.
 
 from incremental import Version
 
-__version__ = Version("Twisted", 24, 3, 0)
+__version__ = Version("Twisted", 24, 7, 0)
 __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
 """
 
+from __future__ import annotations
 
 import hmac
 import sys
 from binascii import Error as DecodeError, a2b_base64, b2a_base64
 from contextlib import closing
 from hashlib import sha1
+from typing import IO, Callable, Literal
 
 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.ssh.keys import BadKeyError, FingerprintFormats, Key
 from twisted.internet import defer
+from twisted.internet.defer import Deferred
 from twisted.logger import Logger
 from twisted.python.compat import nativeString
+from twisted.python.filepath import FilePath
 from twisted.python.randbytes import secureRandom
 from twisted.python.util import FancyEqMixin
 
@@ -111,34 +115,33 @@ class PlainEntry(_BaseEntry):
     file.
 
     @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)
 
     @classmethod
-    def fromString(cls, string):
+    def fromString(cls, string: bytes) -> PlainEntry:
         """
         Parse a plain-text entry in a known_hosts file, and return a
         corresponding L{PlainEntry}.
 
         @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 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
-        actually an SSH key.
+            actually an SSH key.
 
         @return: an IKnownHostEntry representing the hostname and key in the
-        input line.
+            input line.
 
         @rtype: L{PlainEntry}
         """
@@ -146,30 +149,27 @@ class PlainEntry(_BaseEntry):
         self = cls(hostnames.split(b","), keyType, key, comment)
         return self
 
-    def matchesHost(self, hostname):
+    def matchesHost(self, hostname: bytes | str) -> bool:
         """
         Check to see if this entry matches a given hostname.
 
         @param hostname: A hostname or IP address literal to check against this
             entry.
-        @type hostname: L{bytes}
 
         @return: C{True} if this entry is for the given hostname or IP address,
             C{False} otherwise.
-        @rtype: L{bool}
         """
         if isinstance(hostname, str):
             hostname = hostname.encode("utf-8")
         return hostname in self._hostnames
 
-    def toString(self):
+    def toString(self) -> bytes:
         """
         Implement L{IKnownHostEntry.toString} by recording the comma-separated
         hostnames, key type, and base-64 encoded key.
 
         @return: The string representation of this entry, with unhashed hostname
             information.
-        @rtype: L{bytes}
         """
         fields = [
             b",".join(self._hostnames),
@@ -256,33 +256,39 @@ class HashedEntry(_BaseEntry, FancyEqMixin):
 
     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._hostHash = hostHash
         super().__init__(keyType, publicKey, comment)
 
     @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
         file.
 
         @param string: A complete single line from a I{known_hosts} file,
             formatted as defined by OpenSSH.
-        @type string: L{bytes}
 
         @raise DecodeError: if the key, the hostname, or the is not valid
             encoded as valid base64
 
         @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
             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)
         saltAndHash = stuff[len(cls.MAGIC) :].split(b"|")
@@ -346,7 +352,7 @@ class KnownHostsFile:
     @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.
 
@@ -356,12 +362,12 @@ class KnownHostsFile:
         @param savePath: The L{FilePath} to which to save new entries.
         @type savePath: L{FilePath}
         """
-        self._added = []
+        self._added: list[IKnownHostEntry] = []
         self._savePath = savePath
         self._clobber = True
 
     @property
-    def savePath(self):
+    def savePath(self) -> FilePath[str]:
         """
         @see: C{savePath} parameter of L{__init__}
         """
@@ -431,7 +437,9 @@ class KnownHostsFile:
                     raise HostKeyChanged(entry, path, line)
         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
         confirmation from, and notifying, the given UI about changes to this
@@ -453,20 +461,21 @@ class KnownHostsFile:
         """
         hhk = defer.execute(self.hasHostKey, hostname, key)
 
-        def gotHasKey(result):
+        def gotHasKey(result: bool) -> bool | Deferred[bool]:
             if result:
                 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.save()
                 return result
             else:
 
-                def promptResponse(response):
+                def promptResponse(response: bool) -> bool:
                     if response:
                         self.addHostKey(hostname, key)
                         self.addHostKey(ip, key)
@@ -475,7 +484,7 @@ class KnownHostsFile:
                     else:
                         raise UserRejectedKey()
 
-                keytype = key.type()
+                keytype: str = key.type()
 
                 if keytype == "EC":
                     keytype = "ECDSA"
@@ -497,7 +506,7 @@ class KnownHostsFile:
 
         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.
 
@@ -520,7 +529,7 @@ class KnownHostsFile:
         self._added.append(entry)
         return entry
 
-    def save(self):
+    def save(self) -> None:
         """
         Save this L{KnownHostsFile} to the path it was loaded from.
         """
@@ -528,11 +537,7 @@ class KnownHostsFile:
         if not p.isdir():
             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:
             if self._added:
                 hostsFileObj.write(
@@ -542,7 +547,7 @@ class KnownHostsFile:
         self._clobber = False
 
     @classmethod
-    def fromPath(cls, path):
+    def fromPath(cls, path: FilePath[str]) -> KnownHostsFile:
         """
         Create a new L{KnownHostsFile}, potentially reading existing known
         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
             later saving to.  If no file exists at this path, it is not an
             error; a L{KnownHostsFile} with no entries is returned.
-        @type path: L{FilePath}
 
         @return: A L{KnownHostsFile} initialized with entries from C{path}.
-        @rtype: L{KnownHostsFile}
         """
         knownHosts = cls(path)
         knownHosts._clobber = False
@@ -566,7 +569,7 @@ class ConsoleUI:
     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
             binary-mode file-like object to be used for reading and writing.
@@ -576,7 +579,7 @@ class ConsoleUI:
         """
         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
         result from the console input.
@@ -598,20 +601,19 @@ class ConsoleUI:
                     answer = f.readline().strip().lower()
                     if answer == b"yes":
                         return True
-                    elif answer == b"no":
+                    elif answer in {b"no", b""}:
                         return False
                     else:
                         f.write(b"Please type 'yes' or 'no': ")
 
         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
         to the console.
 
         @param text: Some information the user is to be made aware of.
-        @type text: L{bytes}
         """
         try:
             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.
 """
 
-__all__ = ["AuthenticationFailed", "SSHCommandAddress", "SSHCommandClientEndpoint"]
+from __future__ import annotations
+
+__all__ = [
+    "AuthenticationFailed",
+    "SSHCommandAddress",
+    "SSHCommandClientEndpoint",
+]
 
 import signal
+from io import BytesIO
 from os.path import expanduser
 from struct import unpack
+from typing import IO, Any
 
 from zope.interface import Interface, implementer
 
@@ -689,44 +697,6 @@ class SSHCommandClientEndpoint:
         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)
 class _NewConnectionHelper:
     """
@@ -739,17 +709,17 @@ class _NewConnectionHelper:
 
     def __init__(
         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}.
@@ -773,9 +743,9 @@ class _NewConnectionHelper:
         if ui is None:
             ui = ConsoleUI(self._opener)
         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
         which C{b"no"} can be read.
@@ -783,11 +753,11 @@ class _NewConnectionHelper:
         For use as the opener argument to L{ConsoleUI}.
         """
         try:
-            return self.tty.open("rb+")
+            return self.tty.open("r+")
         except BaseException:
             # Give back a file-like object from which can be read a byte string
             # that KnownHostsFile recognizes as rejecting some option (b"no").
-            return _ReadFile(b"no")
+            return BytesIO(b"no")
 
     @classmethod
     def _knownHosts(cls):

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

@@ -431,23 +431,7 @@ _KEY_NAMES = (
     "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)

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

@@ -6,6 +6,8 @@ Simple insults-based widget library
 @author: Jp Calderone
 """
 
+from __future__ import annotations
+
 import array
 
 from twisted.conch.insults import helper, insults
@@ -47,7 +49,8 @@ class Widget:
     focused = False
     parent = None
     dirty = False
-    width = height = None
+    width: int | None = None
+    height: int | None = None
 
     def repaint(self):
         if not self.dirty:
@@ -109,7 +112,12 @@ class Widget:
         name = keyID
         if not isinstance(keyID, str):
             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:
             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.
 """
 
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
 from zope.interface import Attribute, Interface
 
+if TYPE_CHECKING:
+    from twisted.conch.ssh.keys import Key
+
 
 class IConchUser(Interface):
     """
@@ -363,16 +370,15 @@ class IKnownHostEntry(Interface):
     @since: 8.2
     """
 
-    def matchesKey(key):
+    def matchesKey(key: Key) -> bool:
         """
         Return True if this entry matches the given Key object, False
         otherwise.
 
         @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.
 
@@ -381,16 +387,12 @@ class IKnownHostEntry(Interface):
         quad string.
 
         @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
-        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.internet import defer
-from twisted.python.compat import _get_async_param
 from twisted.python.htmlizer import TokenPrinter
 from twisted.python.monkey import MonkeyPatcher
 
@@ -161,8 +160,7 @@ class ManholeInterpreter(code.InteractiveInterpreter):
         del self._pendingDeferreds[id(obj)]
         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)
 
 
@@ -239,8 +237,7 @@ class Manhole(recvline.HistoricRecvLine):
         w = self.terminal.lastWrite
         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:
             self.terminal.eraseLine()
             self.terminal.cursorBackward(len(self.lineBuffer) + len(self.ps[self.pn]))
@@ -309,10 +306,6 @@ class VT102Writer:
         s = b"".join(self.written)
         return s.strip(b"\n").splitlines()[-1]
 
-    if bytes == str:
-        # Compat with Python 2.7
-        __str__ = __bytes__
-
 
 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 twisted.logger import Logger
 from twisted.python.deprecate import getWarningMethod
 from twisted.python.failure import Failure
-from twisted.python.log import err
 from twisted.python.reflect import qual
 
+_log = Logger()
+
 _missingProcessExited = (
     "Since Twisted 8.2, IProcessProtocol.processExited "
     "is required.  %s must implement it."
@@ -39,10 +41,8 @@ class BaseProcess:
                 stacklevel=0,
             )
         else:
-            try:
+            with _log.failuresHandled("while calling processExited:"):
                 processExited(Failure(reason))
-            except BaseException:
-                err(None, "unexpected error in processExited")
 
     def processEnded(self, status):
         """
@@ -62,7 +62,5 @@ class BaseProcess:
             reason = self._getReason(self.status)
             proto = self.proto
             self.proto = None
-            try:
+            with _log.failuresHandled("while calling processEnded:"):
                 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