diff --git a/botocore/__init__.py b/botocore/__init__.py index 8a5d154c45..ba34282f27 100644 --- a/botocore/__init__.py +++ b/botocore/__init__.py @@ -61,7 +61,7 @@ def emit(self, record): # Used to specify anonymous (unsigned) request signature -class UNSIGNED: +class _UNSIGNED: def __copy__(self): return self @@ -69,7 +69,7 @@ def __deepcopy__(self, memodict): return self -UNSIGNED = UNSIGNED() +UNSIGNED = _UNSIGNED() def xform_name(name, sep='_', _xform_cache=_xform_cache): diff --git a/botocore/client.py b/botocore/client.py index ab1be75365..d37b370737 100644 --- a/botocore/client.py +++ b/botocore/client.py @@ -11,6 +11,7 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. import logging +from typing import Dict from botocore import waiter, xform_name from botocore.args import ClientArgsCreator @@ -864,7 +865,7 @@ class BaseClient: # snake_case name, but we need to know the ListObjects form. # xform_name() does the ListObjects->list_objects conversion, but # we need the reverse mapping here. - _PY_TO_OP_NAME = {} + _PY_TO_OP_NAME: Dict[str, str] = {} def __init__( self, diff --git a/botocore/compat.py b/botocore/compat.py index 6f79d43e3f..ef397ebd3e 100644 --- a/botocore/compat.py +++ b/botocore/compat.py @@ -13,47 +13,62 @@ import copy import datetime -import sys -import inspect -import warnings import hashlib -from http.client import HTTPMessage +import inspect import logging -import shlex -import re import os +import re +import shlex +import sys +import warnings from collections import OrderedDict from collections.abc import MutableMapping +from http.client import HTTPMessage from math import floor -from botocore.vendored import six -from botocore.exceptions import MD5UnavailableError from dateutil.tz import tzlocal from urllib3 import exceptions +from botocore.exceptions import MD5UnavailableError +from botocore.vendored import six + logger = logging.getLogger(__name__) class HTTPHeaders(HTTPMessage): - pass + @classmethod + def from_dict(cls, d): + new_instance = cls() + for key, value in d.items(): + new_instance[key] = value + return new_instance + @classmethod + def from_pairs(cls, pairs): + new_instance = cls() + for key, value in pairs: + new_instance[key] = value + return new_instance + + +from base64 import encodebytes +from email.utils import formatdate +from http.client import HTTPResponse +from io import IOBase as _IOBase +from itertools import zip_longest from urllib.parse import ( + parse_qs, + parse_qsl, quote, - urlencode, unquote, unquote_plus, + urlencode, + urljoin, urlparse, urlsplit, urlunsplit, - urljoin, - parse_qsl, - parse_qs, ) -from http.client import HTTPResponse -from io import IOBase as _IOBase -from base64 import encodebytes -from email.utils import formatdate -from itertools import zip_longest + file_type = _IOBase zip = zip @@ -61,6 +76,7 @@ class HTTPHeaders(HTTPMessage): # then takes the bytestring and decodes it to utf-8. unquote_str = unquote_plus + def set_socket_timeout(http_response, timeout): """Set the timeout of the socket from an HTTPResponse. @@ -69,15 +85,18 @@ def set_socket_timeout(http_response, timeout): """ http_response._fp.fp.raw._sock.settimeout(timeout) + def accepts_kwargs(func): # In python3.4.1, there's backwards incompatible # changes when using getargspec with functools.partials. return inspect.getfullargspec(func)[2] + def ensure_unicode(s, encoding=None, errors=None): # NOOP in Python 3, because every string is already unicode return s + def ensure_bytes(s, encoding='utf-8', errors='strict'): if isinstance(s, str): return s.encode(encoding, errors) @@ -86,9 +105,9 @@ def ensure_bytes(s, encoding='utf-8', errors='strict'): raise ValueError(f"Expected str or bytes, received {type(s)}.") -try: +if sys.version_info < (3, 9): import xml.etree.cElementTree as ETree -except ImportError: +else: # cElementTree does not exist from Python3.9+ import xml.etree.ElementTree as ETree XMLParseError = ETree.ParseError @@ -105,26 +124,6 @@ def filter_ssl_warnings(): ) -@classmethod -def from_dict(cls, d): - new_instance = cls() - for key, value in d.items(): - new_instance[key] = value - return new_instance - - -@classmethod -def from_pairs(cls, pairs): - new_instance = cls() - for key, value in pairs: - new_instance[key] = value - return new_instance - - -HTTPHeaders.from_dict = from_dict -HTTPHeaders.from_pairs = from_pairs - - def copy_kwargs(kwargs): """ This used to be a compat shim for 2.6 but is now just an alias. @@ -342,6 +341,7 @@ def get_tzinfo_options(): # Detect if gzip is available for use try: import gzip + HAS_GZIP = True except ImportError: HAS_GZIP = False diff --git a/botocore/configprovider.py b/botocore/configprovider.py index 3341802e53..f369e84b33 100644 --- a/botocore/configprovider.py +++ b/botocore/configprovider.py @@ -17,6 +17,7 @@ import copy import logging import os +from typing import Callable, Dict, List, Optional, Tuple, Union from botocore import utils from botocore.exceptions import InvalidConfigError @@ -50,7 +51,17 @@ #: found. #: NOTE: Fixing the spelling of this variable would be a breaking change. #: Please leave as is. -BOTOCORE_DEFAUT_SESSION_VARIABLES = { +BOTOCORE_DEFAUT_SESSION_VARIABLES: Dict[ + str, + Tuple[ + Optional[str], # Config key (or None) + Union[str, List[str], None], # Env var or list of env vars + Union[str, int, dict, None], # Default value (None, str, int, or dict) + Optional[ + Callable[[str], Union[str, int, None]] + ], # Conversion function (e.g., int) or None + ], +] = { # logical: config_file, env_var, default_value, conversion_func 'profile': (None, ['AWS_DEFAULT_PROFILE', 'AWS_PROFILE'], None, None), 'region': ('region', 'AWS_DEFAULT_REGION', None, None), diff --git a/botocore/credentials.py b/botocore/credentials.py index dd7e718255..3b31367c41 100644 --- a/botocore/credentials.py +++ b/botocore/credentials.py @@ -22,6 +22,7 @@ from collections import namedtuple from copy import deepcopy from hashlib import sha1 +from typing import Optional from dateutil.parser import parse from dateutil.tz import tzlocal, tzutc @@ -939,7 +940,7 @@ def _assume_role_kwargs(self): class CredentialProvider: # A short name to identify the provider within botocore. - METHOD = None + METHOD: Optional[str] = None # A name to identify the provider for use in cross-sdk features like # assume role's `credential_source` configuration option. These names @@ -947,7 +948,7 @@ class CredentialProvider: # implemented in botocore MUST prefix their canonical names with # 'custom' or we DO NOT guarantee that it will work with any features # that this provides. - CANONICAL_NAME = None + CANONICAL_NAME: Optional[str] = None def __init__(self, session=None): self.session = session diff --git a/botocore/crt/auth.py b/botocore/crt/auth.py index 0d1a81def4..d9e34bdf1c 100644 --- a/botocore/crt/auth.py +++ b/botocore/crt/auth.py @@ -13,6 +13,7 @@ import datetime from io import BytesIO +from typing import Dict, Type from botocore.auth import ( SIGNED_HEADERS_BLACKLIST, @@ -618,7 +619,7 @@ def _should_add_content_sha256_header(self, explicit_payload): # Defined at the bottom of module to ensure all Auth # classes are defined. -CRT_AUTH_TYPE_MAPS = { +CRT_AUTH_TYPE_MAPS: Dict[str, Type[BaseSigner]] = { 'v4': CrtSigV4Auth, 'v4-query': CrtSigV4QueryAuth, 'v4a': CrtSigV4AsymAuth, diff --git a/botocore/docs/utils.py b/botocore/docs/utils.py index 161e260229..4e9959b937 100644 --- a/botocore/docs/utils.py +++ b/botocore/docs/utils.py @@ -78,7 +78,7 @@ def get_official_service_name(service_model): _DocumentedShape = namedtuple( - 'DocumentedShape', + '_DocumentedShape', [ 'name', 'type_name', diff --git a/botocore/hooks.py b/botocore/hooks.py index 583cb39c3b..a4ab5135df 100644 --- a/botocore/hooks.py +++ b/botocore/hooks.py @@ -20,7 +20,7 @@ logger = logging.getLogger(__name__) -_NodeList = namedtuple('NodeList', ['first', 'middle', 'last']) +_NodeList = namedtuple('_NodeList', ['first', 'middle', 'last']) _FIRST = 0 _MIDDLE = 1 _LAST = 2 diff --git a/botocore/httpsession.py b/botocore/httpsession.py index bd8b82fafa..b8cae78cb8 100644 --- a/botocore/httpsession.py +++ b/botocore/httpsession.py @@ -85,7 +85,7 @@ from certifi import where except ImportError: - def where(): + def where() -> str: return DEFAULT_CA_BUNDLE diff --git a/botocore/loaders.py b/botocore/loaders.py index f5072a3e5f..bb352120cd 100644 --- a/botocore/loaders.py +++ b/botocore/loaders.py @@ -104,13 +104,14 @@ import logging import os +from typing import IO, Callable, Dict from botocore import BOTOCORE_ROOT from botocore.compat import HAS_GZIP, OrderedDict, json from botocore.exceptions import DataNotFoundError, UnknownServiceError from botocore.utils import deep_merge -_JSON_OPEN_METHODS = { +_JSON_OPEN_METHODS: Dict[str, Callable[..., IO[str]]] = { '.json': open, } diff --git a/botocore/parsers.py b/botocore/parsers.py index 0c7a34f218..1f70dd94c9 100644 --- a/botocore/parsers.py +++ b/botocore/parsers.py @@ -120,6 +120,7 @@ import json import logging import re +from typing import Optional, Type from botocore.compat import ETree, XMLParseError from botocore.eventstream import EventStream, NoInitialResponseError @@ -200,7 +201,7 @@ class ResponseParser: """ DEFAULT_ENCODING = 'utf-8' - EVENT_STREAM_PARSER_CLS = None + EVENT_STREAM_PARSER_CLS: Optional[Type['BaseEventStreamParser']] = None def __init__(self, timestamp_parser=None, blob_parser=None): if timestamp_parser is None: diff --git a/botocore/regions.py b/botocore/regions.py index 4c23737270..b108b3ca2e 100644 --- a/botocore/regions.py +++ b/botocore/regions.py @@ -21,6 +21,7 @@ import logging import re from enum import Enum +from typing import Dict from botocore import UNSIGNED, xform_name from botocore.auth import AUTH_TYPE_MAPS, HAS_CRT @@ -46,7 +47,7 @@ LOG = logging.getLogger(__name__) DEFAULT_URI_TEMPLATE = '{service}.{region}.{dnsSuffix}' # noqa -DEFAULT_SERVICE_DATA = {'endpoints': {}} +DEFAULT_SERVICE_DATA: Dict[str, Dict[str, str]] = {'endpoints': {}} class BaseEndpointResolver: diff --git a/botocore/vendored/requests/__init__.py b/botocore/vendored/requests/__init__.py index 0ada6e0f4c..1f7875fc6c 100644 --- a/botocore/vendored/requests/__init__.py +++ b/botocore/vendored/requests/__init__.py @@ -5,6 +5,10 @@ # / ( (- (/ (/ (- _) / _) # / from .exceptions import ( - RequestException, Timeout, URLRequired, - TooManyRedirects, HTTPError, ConnectionError + RequestException, + Timeout, + URLRequired, + TooManyRedirects, + HTTPError, + ConnectionError, ) diff --git a/botocore/vendored/requests/exceptions.py b/botocore/vendored/requests/exceptions.py index 89135a802e..d978e1ba8c 100644 --- a/botocore/vendored/requests/exceptions.py +++ b/botocore/vendored/requests/exceptions.py @@ -7,6 +7,7 @@ This module contains the set of Requests' exceptions. """ + from .packages.urllib3.exceptions import HTTPError as BaseHTTPError @@ -21,8 +22,11 @@ def __init__(self, *args, **kwargs): response = kwargs.pop('response', None) self.response = response self.request = kwargs.pop('request', None) - if (response is not None and not self.request and - hasattr(response, 'request')): + if ( + response is not None + and not self.request + and hasattr(response, 'request') + ): self.request = self.response.request super(RequestException, self).__init__(*args, **kwargs) @@ -80,7 +84,7 @@ class InvalidSchema(RequestException, ValueError): class InvalidURL(RequestException, ValueError): - """ The URL provided was somehow invalid. """ + """The URL provided was somehow invalid.""" class ChunkedEncodingError(RequestException): diff --git a/botocore/vendored/requests/packages/urllib3/exceptions.py b/botocore/vendored/requests/packages/urllib3/exceptions.py index 31bda1c07e..446429649e 100644 --- a/botocore/vendored/requests/packages/urllib3/exceptions.py +++ b/botocore/vendored/requests/packages/urllib3/exceptions.py @@ -1,18 +1,21 @@ - ## Base Exceptions + class HTTPError(Exception): "Base exception used by this module." + pass + class HTTPWarning(Warning): "Base warning used by this module." - pass + pass class PoolError(HTTPError): "Base exception for errors caused within a pool." + def __init__(self, pool, message): self.pool = pool HTTPError.__init__(self, "%s: %s" % (pool, message)) @@ -24,6 +27,7 @@ def __reduce__(self): class RequestError(PoolError): "Base exception for PoolErrors that have associated URLs." + def __init__(self, pool, url, message): self.url = url PoolError.__init__(self, pool, message) @@ -35,21 +39,25 @@ def __reduce__(self): class SSLError(HTTPError): "Raised when SSL certificate fails in an HTTPS connection." + pass class ProxyError(HTTPError): "Raised when the connection to a proxy fails." + pass class DecodeError(HTTPError): "Raised when automatic decoding based on Content-Type fails." + pass class ProtocolError(HTTPError): "Raised when something unexpected happens mid-request/response." + pass @@ -59,6 +67,7 @@ class ProtocolError(HTTPError): ## Leaf Exceptions + class MaxRetryError(RequestError): """Raised when the maximum number of retries is exceeded. @@ -73,7 +82,9 @@ def __init__(self, pool, url, reason=None): self.reason = reason message = "Max retries exceeded with url: %s (Caused by %r)" % ( - url, reason) + url, + reason, + ) RequestError.__init__(self, pool, url, message) @@ -88,21 +99,24 @@ def __init__(self, pool, url, retries=3): class TimeoutStateError(HTTPError): - """ Raised when passing an invalid state to a timeout """ + """Raised when passing an invalid state to a timeout""" + pass class TimeoutError(HTTPError): - """ Raised when a socket timeout error occurs. + """Raised when a socket timeout error occurs. Catching this error will catch both :exc:`ReadTimeoutErrors ` and :exc:`ConnectTimeoutErrors `. """ + pass class ReadTimeoutError(TimeoutError, RequestError): "Raised when a socket timeout occurs while receiving data from a server" + pass @@ -110,21 +124,25 @@ class ReadTimeoutError(TimeoutError, RequestError): # base HTTPError class ConnectTimeoutError(TimeoutError): "Raised when a socket timeout occurs while connecting to a server" + pass class EmptyPoolError(PoolError): "Raised when a pool runs out of connections and no more are allowed." + pass class ClosedPoolError(PoolError): "Raised when a request enters a pool after the pool has been closed." + pass class LocationValueError(ValueError, HTTPError): "Raised when there is something wrong with a given URL input." + pass @@ -140,30 +158,36 @@ def __init__(self, location): class ResponseError(HTTPError): "Used as a container for an error reason supplied in a MaxRetryError." + GENERIC_ERROR = 'too many error responses' SPECIFIC_ERROR = 'too many {status_code} error responses' class SecurityWarning(HTTPWarning): "Warned when perfoming security reducing actions" + pass class InsecureRequestWarning(SecurityWarning): "Warned when making an unverified HTTPS request." + pass class SystemTimeWarning(SecurityWarning): "Warned when system time is suspected to be wrong" + pass class InsecurePlatformWarning(SecurityWarning): "Warned when certain SSL configuration is not available on a platform." + pass class ResponseNotChunked(ProtocolError, ValueError): "Response needs to be chunked in order to read it as chunks." + pass diff --git a/botocore/vendored/six.py b/botocore/vendored/six.py index 4e15675d8b..bc986ac50f 100644 --- a/botocore/vendored/six.py +++ b/botocore/vendored/six.py @@ -38,15 +38,15 @@ PY34 = sys.version_info[0:2] >= (3, 4) if PY3: - string_types = str, - integer_types = int, - class_types = type, + string_types = (str,) + integer_types = (int,) + class_types = (type,) text_type = str binary_type = bytes MAXSIZE = sys.maxsize else: - string_types = basestring, + string_types = (basestring,) integer_types = (int, long) class_types = (type, types.ClassType) text_type = unicode @@ -58,9 +58,9 @@ else: # It's possible to have sizeof(long) != sizeof(Py_ssize_t). class X(object): - def __len__(self): return 1 << 31 + try: len(X()) except OverflowError: @@ -89,7 +89,6 @@ def _import_module(name): class _LazyDescr(object): - def __init__(self, name): self.name = name @@ -106,7 +105,6 @@ def __get__(self, obj, tp): class MovedModule(_LazyDescr): - def __init__(self, name, old, new=None): super(MovedModule, self).__init__(name) if PY3: @@ -127,7 +125,6 @@ def __getattr__(self, attr): class _LazyModule(types.ModuleType): - def __init__(self, name): super(_LazyModule, self).__init__(name) self.__doc__ = self.__class__.__doc__ @@ -142,7 +139,6 @@ def __dir__(self): class MovedAttribute(_LazyDescr): - def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): super(MovedAttribute, self).__init__(name) if PY3: @@ -167,7 +163,6 @@ def _resolve(self): class _SixMetaPathImporter(object): - """ A meta path importer to import six.moves and its submodules. @@ -231,6 +226,7 @@ def get_code(self, fullname): Required, if is_package is implemented""" self.__get_module(fullname) # eventually raises ImportError return None + get_source = get_code # same as get_code def create_module(self, spec): @@ -239,19 +235,22 @@ def create_module(self, spec): def exec_module(self, module): pass + _importer = _SixMetaPathImporter(__name__) class _MovedItems(_LazyModule): - """Lazy loading of moved objects""" + __path__ = [] # mark as package _moved_attributes = [ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), - MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute( + "filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse" + ), MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), MovedAttribute("intern", "__builtin__", "sys"), MovedAttribute("map", "itertools", "builtins", "imap", "map"), @@ -259,7 +258,12 @@ class _MovedItems(_LazyModule): MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), MovedAttribute("getoutput", "commands", "subprocess"), MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute( + "reload_module", + "__builtin__", + "importlib" if PY34 else "imp", + "reload", + ), MovedAttribute("reduce", "__builtin__", "functools"), MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), MovedAttribute("StringIO", "StringIO", "io"), @@ -268,14 +272,24 @@ class _MovedItems(_LazyModule): MovedAttribute("UserString", "UserString", "collections"), MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), - MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedAttribute( + "zip_longest", "itertools", "itertools", "izip_longest", "zip_longest" + ), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), - MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"), + MovedModule( + "collections_abc", + "collections", + "collections.abc" if sys.version_info >= (3, 3) else "collections", + ), MovedModule("copyreg", "copy_reg"), MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"), - MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"), + MovedModule( + "_dummy_thread", + "dummy_thread", + "_dummy_thread" if sys.version_info < (3, 9) else "_thread", + ), MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), MovedModule("http_cookies", "Cookie", "http.cookies"), MovedModule("html_entities", "htmlentitydefs", "html.entities"), @@ -283,8 +297,14 @@ class _MovedItems(_LazyModule): MovedModule("http_client", "httplib", "http.client"), MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), - MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), - MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule( + "email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart" + ), + MovedModule( + "email_mime_nonmultipart", + "email.MIMENonMultipart", + "email.mime.nonmultipart", + ), MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), @@ -297,24 +317,37 @@ class _MovedItems(_LazyModule): MovedModule("tkinter", "Tkinter"), MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), - MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), - MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule( + "tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext" + ), + MovedModule( + "tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog" + ), MovedModule("tkinter_tix", "Tix", "tkinter.tix"), MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), - MovedModule("tkinter_colorchooser", "tkColorChooser", - "tkinter.colorchooser"), - MovedModule("tkinter_commondialog", "tkCommonDialog", - "tkinter.commondialog"), + MovedModule( + "tkinter_colorchooser", "tkColorChooser", "tkinter.colorchooser" + ), + MovedModule( + "tkinter_commondialog", "tkCommonDialog", "tkinter.commondialog" + ), MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), MovedModule("tkinter_font", "tkFont", "tkinter.font"), MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), - MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", - "tkinter.simpledialog"), - MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), - MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), - MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule( + "tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog" + ), + MovedModule( + "urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse" + ), + MovedModule( + "urllib_error", __name__ + ".moves.urllib_error", "urllib.error" + ), + MovedModule( + "urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib" + ), MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), @@ -338,7 +371,6 @@ class _MovedItems(_LazyModule): class Module_six_moves_urllib_parse(_LazyModule): - """Lazy loading of moved objects in six.moves.urllib_parse""" @@ -357,7 +389,13 @@ class Module_six_moves_urllib_parse(_LazyModule): MovedAttribute("quote_plus", "urllib", "urllib.parse"), MovedAttribute("unquote", "urllib", "urllib.parse"), MovedAttribute("unquote_plus", "urllib", "urllib.parse"), - MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"), + MovedAttribute( + "unquote_to_bytes", + "urllib", + "urllib.parse", + "unquote", + "unquote_to_bytes", + ), MovedAttribute("urlencode", "urllib", "urllib.parse"), MovedAttribute("splitquery", "urllib", "urllib.parse"), MovedAttribute("splittag", "urllib", "urllib.parse"), @@ -373,14 +411,18 @@ class Module_six_moves_urllib_parse(_LazyModule): setattr(Module_six_moves_urllib_parse, attr.name, attr) del attr -Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes +Module_six_moves_urllib_parse._moved_attributes = ( + _urllib_parse_moved_attributes +) -_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), - "moves.urllib_parse", "moves.urllib.parse") +_importer._add_module( + Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", + "moves.urllib.parse", +) class Module_six_moves_urllib_error(_LazyModule): - """Lazy loading of moved objects in six.moves.urllib_error""" @@ -393,14 +435,18 @@ class Module_six_moves_urllib_error(_LazyModule): setattr(Module_six_moves_urllib_error, attr.name, attr) del attr -Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes +Module_six_moves_urllib_error._moved_attributes = ( + _urllib_error_moved_attributes +) -_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), - "moves.urllib_error", "moves.urllib.error") +_importer._add_module( + Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", + "moves.urllib.error", +) class Module_six_moves_urllib_request(_LazyModule): - """Lazy loading of moved objects in six.moves.urllib_request""" @@ -419,7 +465,9 @@ class Module_six_moves_urllib_request(_LazyModule): MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), MovedAttribute("BaseHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute( + "HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request" + ), MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), @@ -445,14 +493,18 @@ class Module_six_moves_urllib_request(_LazyModule): setattr(Module_six_moves_urllib_request, attr.name, attr) del attr -Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes +Module_six_moves_urllib_request._moved_attributes = ( + _urllib_request_moved_attributes +) -_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), - "moves.urllib_request", "moves.urllib.request") +_importer._add_module( + Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", + "moves.urllib.request", +) class Module_six_moves_urllib_response(_LazyModule): - """Lazy loading of moved objects in six.moves.urllib_response""" @@ -466,14 +518,18 @@ class Module_six_moves_urllib_response(_LazyModule): setattr(Module_six_moves_urllib_response, attr.name, attr) del attr -Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes +Module_six_moves_urllib_response._moved_attributes = ( + _urllib_response_moved_attributes +) -_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), - "moves.urllib_response", "moves.urllib.response") +_importer._add_module( + Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", + "moves.urllib.response", +) class Module_six_moves_urllib_robotparser(_LazyModule): - """Lazy loading of moved objects in six.moves.urllib_robotparser""" @@ -484,15 +540,22 @@ class Module_six_moves_urllib_robotparser(_LazyModule): setattr(Module_six_moves_urllib_robotparser, attr.name, attr) del attr -Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes +Module_six_moves_urllib_robotparser._moved_attributes = ( + _urllib_robotparser_moved_attributes +) -_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), - "moves.urllib_robotparser", "moves.urllib.robotparser") +_importer._add_module( + Module_six_moves_urllib_robotparser( + __name__ + ".moves.urllib.robotparser" + ), + "moves.urllib_robotparser", + "moves.urllib.robotparser", +) class Module_six_moves_urllib(types.ModuleType): - """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package parse = _importer._get_module("moves.urllib_parse") error = _importer._get_module("moves.urllib_error") @@ -503,8 +566,10 @@ class Module_six_moves_urllib(types.ModuleType): def __dir__(self): return ['parse', 'error', 'request', 'response', 'robotparser'] -_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), - "moves.urllib") + +_importer._add_module( + Module_six_moves_urllib(__name__ + ".moves.urllib"), "moves.urllib" +) def add_move(move): @@ -544,19 +609,24 @@ def remove_move(name): try: advance_iterator = next except NameError: + def advance_iterator(it): return it.next() + + next = advance_iterator try: callable = callable except NameError: + def callable(obj): return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) if PY3: + def get_unbound_function(unbound): return unbound @@ -567,6 +637,7 @@ def create_unbound_method(func, cls): Iterator = object else: + def get_unbound_function(unbound): return unbound.im_func @@ -577,13 +648,14 @@ def create_unbound_method(func, cls): return types.MethodType(func, None, cls) class Iterator(object): - def next(self): return type(self).__next__(self) callable = callable -_add_doc(get_unbound_function, - """Get the function out of a possibly unbound function""") +_add_doc( + get_unbound_function, + """Get the function out of a possibly unbound function""", +) get_method_function = operator.attrgetter(_meth_func) @@ -595,6 +667,7 @@ def next(self): if PY3: + def iterkeys(d, **kw): return iter(d.keys(**kw)) @@ -613,6 +686,7 @@ def iterlists(d, **kw): viewitems = operator.methodcaller("items") else: + def iterkeys(d, **kw): return d.iterkeys(**kw) @@ -633,26 +707,34 @@ def iterlists(d, **kw): _add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") _add_doc(itervalues, "Return an iterator over the values of a dictionary.") -_add_doc(iteritems, - "Return an iterator over the (key, value) pairs of a dictionary.") -_add_doc(iterlists, - "Return an iterator over the (key, [values]) pairs of a dictionary.") +_add_doc( + iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.", +) +_add_doc( + iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.", +) if PY3: + def b(s): return s.encode("latin-1") def u(s): return s + unichr = chr import struct + int2byte = struct.Struct(">B").pack del struct byte2int = operator.itemgetter(0) indexbytes = operator.getitem iterbytes = iter import io + StringIO = io.StringIO BytesIO = io.BytesIO del io @@ -666,12 +748,15 @@ def u(s): _assertRegex = "assertRegex" _assertNotRegex = "assertNotRegex" else: + def b(s): return s + # Workaround for standalone backslash def u(s): return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr int2byte = chr @@ -680,8 +765,10 @@ def byte2int(bs): def indexbytes(buf, i): return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) import StringIO + StringIO = BytesIO = StringIO.StringIO _assertCountEqual = "assertItemsEqual" _assertRaisesRegex = "assertRaisesRegexp" @@ -722,6 +809,7 @@ def reraise(tp, value, tb=None): tb = None else: + def exec_(_code_, _globs_=None, _locs_=None): """Execute code in a namespace.""" if _globs_ is None: @@ -750,12 +838,14 @@ def exec_(_code_, _globs_=None, _locs_=None): value = None """) else: + def raise_from(value, from_value): raise value print_ = getattr(moves.builtins, "print", None) if print_ is None: + def print_(*args, **kwargs): """The new-style print function for Python 2.4 and 2.5.""" fp = kwargs.pop("file", sys.stdout) @@ -766,14 +856,17 @@ def write(data): if not isinstance(data, basestring): data = str(data) # If the file has an encoding, encode unicode with it. - if (isinstance(fp, file) and - isinstance(data, unicode) and - fp.encoding is not None): + if ( + isinstance(fp, file) + and isinstance(data, unicode) + and fp.encoding is not None + ): errors = getattr(fp, "errors", None) if errors is None: errors = "strict" data = data.encode(fp.encoding, errors) fp.write(data) + want_unicode = False sep = kwargs.pop("sep", None) if sep is not None: @@ -809,6 +902,8 @@ def write(data): write(sep) write(arg) write(end) + + if sys.version_info[:2] < (3, 3): _print = print_ @@ -819,6 +914,7 @@ def print_(*args, **kwargs): if flush and fp is not None: fp.flush() + _add_doc(reraise, """Reraise an exception.""") if sys.version_info[0:2] < (3, 4): @@ -827,9 +923,12 @@ def print_(*args, **kwargs): # attribute on ``wrapper`` object and it doesn't raise an error if any of # the attributes mentioned in ``assigned`` and ``updated`` are missing on # ``wrapped`` object. - def _update_wrapper(wrapper, wrapped, - assigned=functools.WRAPPER_ASSIGNMENTS, - updated=functools.WRAPPER_UPDATES): + def _update_wrapper( + wrapper, + wrapped, + assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES, + ): for attr in assigned: try: value = getattr(wrapped, attr) @@ -841,12 +940,21 @@ def _update_wrapper(wrapper, wrapped, getattr(wrapper, attr).update(getattr(wrapped, attr, {})) wrapper.__wrapped__ = wrapped return wrapper + _update_wrapper.__doc__ = functools.update_wrapper.__doc__ - def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, - updated=functools.WRAPPER_UPDATES): - return functools.partial(_update_wrapper, wrapped=wrapped, - assigned=assigned, updated=updated) + def wraps( + wrapped, + assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES, + ): + return functools.partial( + _update_wrapper, + wrapped=wrapped, + assigned=assigned, + updated=updated, + ) + wraps.__doc__ = functools.wraps.__doc__ else: @@ -855,11 +963,11 @@ def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, def with_metaclass(meta, *bases): """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy # metaclass for one level of class instantiation that replaces itself with # the actual metaclass. class metaclass(type): - def __new__(cls, name, this_bases, d): if sys.version_info[:2] >= (3, 7): # This version introduced PEP 560 that requires a bit @@ -874,11 +982,13 @@ def __new__(cls, name, this_bases, d): @classmethod def __prepare__(cls, name, this_bases): return meta.__prepare__(name, bases) + return type.__new__(metaclass, 'temporary_class', (), {}) def add_metaclass(metaclass): """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): orig_vars = cls.__dict__.copy() slots = orig_vars.get('__slots__') @@ -892,6 +1002,7 @@ def wrapper(cls): if hasattr(cls, '__qualname__'): orig_vars['__qualname__'] = cls.__qualname__ return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper @@ -965,9 +1076,10 @@ def python_2_unicode_compatible(klass): """ if PY2: if '__str__' not in klass.__dict__: - raise ValueError("@python_2_unicode_compatible cannot be applied " - "to %s because it doesn't define __str__()." % - klass.__name__) + raise ValueError( + "@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % klass.__name__ + ) klass.__unicode__ = klass.__str__ klass.__str__ = lambda self: self.__unicode__().encode('utf-8') return klass @@ -989,8 +1101,10 @@ def python_2_unicode_compatible(klass): # be floating around. Therefore, we can't use isinstance() to check for # the six meta path importer, since the other six instance will have # inserted an importer with different class. - if (type(importer).__name__ == "_SixMetaPathImporter" and - importer.name == __name__): + if ( + type(importer).__name__ == "_SixMetaPathImporter" + and importer.name == __name__ + ): del sys.meta_path[i] break del i, importer