ÿØÿà JFIF    ÿÛ „ ( %!1!%*+...983,7(-.- PK&]9jalternatives/ldnu[auto /opt/rh/gcc-toolset-13/root/usr/bin/ld /opt/rh/gcc-toolset-13/root/usr/bin/ld.gold 30 /opt/rh/gcc-toolset-13/root/usr/bin/ld.bfd 50 PK H]sii .packlistnu[/usr/local/share/man/man3/POD2::DE::local::lib.3pm /usr/local/share/man/man3/POD2::PT_BR::local::lib.3pm /usr/local/share/man/man3/lib::core::only.3pm /usr/local/share/man/man3/local::lib.3pm /usr/local/share/perl5/POD2/DE/local/lib.pod /usr/local/share/perl5/POD2/PT_BR/local/lib.pod /usr/local/share/perl5/lib/core/only.pm /usr/local/share/perl5/local/lib.pm PKH]b/q1python3.10/site-packages/distutils-precedence.pthnu[import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'stdlib') == 'local'; enabled and __import__('_distutils_hack').add_shim(); PKH](??Mpython3.10/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pycnu[o Xaih@sddlZddlZddlZddlZddlZdejvZeddeddZ ddZ d d Z d d Z d dZ GdddZeZddZddZdS)NZ__pypy__ignorez.+ distutils\b.+ deprecatedcCs.dtjvrdStrtjdkrdStddS)N distutils)aDistutils was imported before Setuptools, but importing Setuptools also replaces the `distutils` module in `sys.modules`. This may lead to undesirable behaviors or errors. To avoid these issues, avoid using distutils directly, ensure that setuptools is installed in the traditional way (e.g. not an editable install), and/or make sure that setuptools is always imported before distutils.)sysmodulesis_pypy version_infowarningswarnr r /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/_distutils_hack/__init__.pywarn_distutils_presents rcCs>dtjvrdStdddtjD}|D]}tj|=qdS)Nrz"Setuptools is replacing distutils.cSsg|] }td|r|qS)z distutils\b)rematch).0namer r r $sz#clear_distutils..)rrr r )Zmodsrr r r clear_distutils s   rcCstjdd}|dkS)z? Allow selection of distutils by environment variable. ZSETUPTOOLS_USE_DISTUTILSstdliblocal)osenvironget)whichr r r enabled)srcCsBttd}d|_|tjd<td}d|jvsJ|jdS)Nsetuptools._distutilsrzdistutils.core _distutils)r importlib import_module__name__rr__file__)rcorer r r ensure_local_distutils1s    r#cCstr ttdSdS)z Ensure that the local copy of distutils is preferred over stdlib. See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401 for more motivation. N)rrr#r r r r do_override<s r$c@s2eZdZd ddZddZddZedd ZdS) DistutilsMetaFinderNcCs4|durdSdjdit}t||dd}|S)Nzspec_for_{fullname}cSdSNr r r r r Nz/DistutilsMetaFinder.find_spec..r )formatlocalsgetattr)selffullnamepathtarget method_namemethodr r r find_specIs zDistutilsMetaFinder.find_speccs8ddlddlGfdddjj}jd|S)Nrcs eZdZfddZddZdS)z?DistutilsMetaFinder.spec_for_distutils..DistutilsLoadercs dS)Nr)r)r-specrr r create_moduleWs zMDistutilsMetaFinder.spec_for_distutils..DistutilsLoader.create_modulecSr&r'r )r-moduler r r exec_moduleZszKDistutilsMetaFinder.spec_for_distutils..DistutilsLoader.exec_moduleN)r __module__ __qualname__r6r8r r5r r DistutilsLoaderUs  r;r)Z importlib.abcimportlib.utilabcLoaderutilspec_from_loader)r-r;r r5r spec_for_distutilsQsz&DistutilsMetaFinder.spec_for_distutilscCs |rdStdd|_dS)zj Ensure stdlib distutils when running under pip. See pypa/pip#8761 for rationale. NcSr&r'r r r r r r(gr)z2DistutilsMetaFinder.spec_for_pip..)pip_imported_during_buildrrA)r-r r r spec_for_pip_sz DistutilsMetaFinder.spec_for_pipcCs ddl}tdd|dDS)zO Detect if pip is being imported in a build script. Ref #2355. rNcss$|] \}}|jddVqdS)r!zsetup.pyN) f_globalsendswith)rframeliner r r os  z@DistutilsMetaFinder.pip_imported_during_build..) tracebackany walk_stack)rIr r r rBisz-DistutilsMetaFinder.pip_imported_during_buildr')r r9r:r3rArC staticmethodrBr r r r r%Hs   r%cCstjdtdS)Nr)r meta_pathinsertDISTUTILS_FINDERr r r r add_shimxsrPcCs(z tjtWdStyYdSwr')rrMremoverO ValueErrorr r r r remove_shim|s  rS)rrrrr builtin_module_namesrfilterwarningsDeprecationWarningrrrr#r$r%rOrPrSr r r r s&    - PKH]4>!!Mpython3.10/site-packages/_distutils_hack/__pycache__/override.cpython-310.pycnu[o Xai,@seddS)Z_distutils_hackN) __import__Z do_overriderr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/_distutils_hack/override.pysPKH] ,,4python3.10/site-packages/_distutils_hack/override.pynu[__import__('_distutils_hack').do_override() PKH]@= hh4python3.10/site-packages/_distutils_hack/__init__.pynu[import sys import os import re import importlib import warnings is_pypy = '__pypy__' in sys.builtin_module_names warnings.filterwarnings('ignore', r'.+ distutils\b.+ deprecated', DeprecationWarning) def warn_distutils_present(): if 'distutils' not in sys.modules: return if is_pypy and sys.version_info < (3, 7): # PyPy for 3.6 unconditionally imports distutils, so bypass the warning # https://foss.heptapod.net/pypy/pypy/-/blob/be829135bc0d758997b3566062999ee8b23872b4/lib-python/3/site.py#L250 return warnings.warn( "Distutils was imported before Setuptools, but importing Setuptools " "also replaces the `distutils` module in `sys.modules`. This may lead " "to undesirable behaviors or errors. To avoid these issues, avoid " "using distutils directly, ensure that setuptools is installed in the " "traditional way (e.g. not an editable install), and/or make sure " "that setuptools is always imported before distutils.") def clear_distutils(): if 'distutils' not in sys.modules: return warnings.warn("Setuptools is replacing distutils.") mods = [name for name in sys.modules if re.match(r'distutils\b', name)] for name in mods: del sys.modules[name] def enabled(): """ Allow selection of distutils by environment variable. """ which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'stdlib') return which == 'local' def ensure_local_distutils(): clear_distutils() distutils = importlib.import_module('setuptools._distutils') distutils.__name__ = 'distutils' sys.modules['distutils'] = distutils # sanity check that submodules load as expected core = importlib.import_module('distutils.core') assert '_distutils' in core.__file__, core.__file__ def do_override(): """ Ensure that the local copy of distutils is preferred over stdlib. See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401 for more motivation. """ if enabled(): warn_distutils_present() ensure_local_distutils() class DistutilsMetaFinder: def find_spec(self, fullname, path, target=None): if path is not None: return method_name = 'spec_for_{fullname}'.format(**locals()) method = getattr(self, method_name, lambda: None) return method() def spec_for_distutils(self): import importlib.abc import importlib.util class DistutilsLoader(importlib.abc.Loader): def create_module(self, spec): return importlib.import_module('setuptools._distutils') def exec_module(self, module): pass return importlib.util.spec_from_loader('distutils', DistutilsLoader()) def spec_for_pip(self): """ Ensure stdlib distutils when running under pip. See pypa/pip#8761 for rationale. """ if self.pip_imported_during_build(): return clear_distutils() self.spec_for_distutils = lambda: None @staticmethod def pip_imported_during_build(): """ Detect if pip is being imported in a build script. Ref #2355. """ import traceback return any( frame.f_globals['__file__'].endswith('setup.py') for frame, line in traceback.walk_stack(None) ) DISTUTILS_FINDER = DistutilsMetaFinder() def add_shim(): sys.meta_path.insert(0, DISTUTILS_FINDER) def remove_shim(): try: sys.meta_path.remove(DISTUTILS_FINDER) except ValueError: pass PKH]Q  -python3.10/site-packages/setuptools/errors.pynu["""setuptools.errors Provides exceptions used by setuptools modules. """ from distutils.errors import DistutilsError class RemovedCommandError(DistutilsError, RuntimeError): """Error used for commands that have been removed in setuptools. Since ``setuptools`` is built on ``distutils``, simply removing a command from ``setuptools`` will make the behavior fall back to ``distutils``; this error is raised if a command exists in ``distutils`` but has been actively removed in ``setuptools``. """ PKH]2 OO+python3.10/site-packages/setuptools/dist.pynu[# -*- coding: utf-8 -*- __all__ = ['Distribution'] import io import sys import re import os import warnings import numbers import distutils.log import distutils.core import distutils.cmd import distutils.dist import distutils.command from distutils.util import strtobool from distutils.debug import DEBUG from distutils.fancy_getopt import translate_longopt from glob import iglob import itertools import textwrap from typing import List, Optional, TYPE_CHECKING from collections import defaultdict from email import message_from_file from distutils.errors import DistutilsOptionError, DistutilsSetupError from distutils.util import rfc822_escape from distutils.version import StrictVersion from setuptools.extern import packaging from setuptools.extern import ordered_set from setuptools.extern.more_itertools import unique_everseen from . import SetuptoolsDeprecationWarning import setuptools import setuptools.command from setuptools import windows_support from setuptools.monkey import get_unpatched from setuptools.config import parse_configuration import pkg_resources if TYPE_CHECKING: from email.message import Message __import__('setuptools.extern.packaging.specifiers') __import__('setuptools.extern.packaging.version') def _get_unpatched(cls): warnings.warn("Do not call this function", DistDeprecationWarning) return get_unpatched(cls) def get_metadata_version(self): mv = getattr(self, 'metadata_version', None) if mv is None: mv = StrictVersion('2.1') self.metadata_version = mv return mv def rfc822_unescape(content: str) -> str: """Reverse RFC-822 escaping by removing leading whitespaces from content.""" lines = content.splitlines() if len(lines) == 1: return lines[0].lstrip() return '\n'.join((lines[0].lstrip(), textwrap.dedent('\n'.join(lines[1:])))) def _read_field_from_msg(msg: "Message", field: str) -> Optional[str]: """Read Message header field.""" value = msg[field] if value == 'UNKNOWN': return None return value def _read_field_unescaped_from_msg(msg: "Message", field: str) -> Optional[str]: """Read Message header field and apply rfc822_unescape.""" value = _read_field_from_msg(msg, field) if value is None: return value return rfc822_unescape(value) def _read_list_from_msg(msg: "Message", field: str) -> Optional[List[str]]: """Read Message header field and return all results as list.""" values = msg.get_all(field, None) if values == []: return None return values def _read_payload_from_msg(msg: "Message") -> Optional[str]: value = msg.get_payload().strip() if value == 'UNKNOWN': return None return value def read_pkg_file(self, file): """Reads the metadata values from a file object.""" msg = message_from_file(file) self.metadata_version = StrictVersion(msg['metadata-version']) self.name = _read_field_from_msg(msg, 'name') self.version = _read_field_from_msg(msg, 'version') self.description = _read_field_from_msg(msg, 'summary') # we are filling author only. self.author = _read_field_from_msg(msg, 'author') self.maintainer = None self.author_email = _read_field_from_msg(msg, 'author-email') self.maintainer_email = None self.url = _read_field_from_msg(msg, 'home-page') self.license = _read_field_unescaped_from_msg(msg, 'license') if 'download-url' in msg: self.download_url = _read_field_from_msg(msg, 'download-url') else: self.download_url = None self.long_description = _read_field_unescaped_from_msg(msg, 'description') if self.long_description is None and self.metadata_version >= StrictVersion('2.1'): self.long_description = _read_payload_from_msg(msg) self.description = _read_field_from_msg(msg, 'summary') if 'keywords' in msg: self.keywords = _read_field_from_msg(msg, 'keywords').split(',') self.platforms = _read_list_from_msg(msg, 'platform') self.classifiers = _read_list_from_msg(msg, 'classifier') # PEP 314 - these fields only exist in 1.1 if self.metadata_version == StrictVersion('1.1'): self.requires = _read_list_from_msg(msg, 'requires') self.provides = _read_list_from_msg(msg, 'provides') self.obsoletes = _read_list_from_msg(msg, 'obsoletes') else: self.requires = None self.provides = None self.obsoletes = None self.license_files = _read_list_from_msg(msg, 'license-file') def single_line(val): # quick and dirty validation for description pypa/setuptools#1390 if '\n' in val: # TODO after 2021-07-31: Replace with `raise ValueError("newlines not allowed")` warnings.warn("newlines not allowed and will break in the future") val = val.replace('\n', ' ') return val # Based on Python 3.5 version def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME """Write the PKG-INFO format data to a file object.""" version = self.get_metadata_version() def write_field(key, value): file.write("%s: %s\n" % (key, value)) write_field('Metadata-Version', str(version)) write_field('Name', self.get_name()) write_field('Version', self.get_version()) write_field('Summary', single_line(self.get_description())) write_field('Home-page', self.get_url()) optional_fields = ( ('Author', 'author'), ('Author-email', 'author_email'), ('Maintainer', 'maintainer'), ('Maintainer-email', 'maintainer_email'), ) for field, attr in optional_fields: attr_val = getattr(self, attr, None) if attr_val is not None: write_field(field, attr_val) license = rfc822_escape(self.get_license()) write_field('License', license) if self.download_url: write_field('Download-URL', self.download_url) for project_url in self.project_urls.items(): write_field('Project-URL', '%s, %s' % project_url) keywords = ','.join(self.get_keywords()) if keywords: write_field('Keywords', keywords) for platform in self.get_platforms(): write_field('Platform', platform) self._write_list(file, 'Classifier', self.get_classifiers()) # PEP 314 self._write_list(file, 'Requires', self.get_requires()) self._write_list(file, 'Provides', self.get_provides()) self._write_list(file, 'Obsoletes', self.get_obsoletes()) # Setuptools specific for PEP 345 if hasattr(self, 'python_requires'): write_field('Requires-Python', self.python_requires) # PEP 566 if self.long_description_content_type: write_field('Description-Content-Type', self.long_description_content_type) if self.provides_extras: for extra in self.provides_extras: write_field('Provides-Extra', extra) self._write_list(file, 'License-File', self.license_files or []) file.write("\n%s\n\n" % self.get_long_description()) sequence = tuple, list def check_importable(dist, attr, value): try: ep = pkg_resources.EntryPoint.parse('x=' + value) assert not ep.extras except (TypeError, ValueError, AttributeError, AssertionError) as e: raise DistutilsSetupError( "%r must be importable 'module:attrs' string (got %r)" % (attr, value) ) from e def assert_string_list(dist, attr, value): """Verify that value is a string list""" try: # verify that value is a list or tuple to exclude unordered # or single-use iterables assert isinstance(value, (list, tuple)) # verify that elements of value are strings assert ''.join(value) != value except (TypeError, ValueError, AttributeError, AssertionError) as e: raise DistutilsSetupError( "%r must be a list of strings (got %r)" % (attr, value) ) from e def check_nsp(dist, attr, value): """Verify that namespace packages are valid""" ns_packages = value assert_string_list(dist, attr, ns_packages) for nsp in ns_packages: if not dist.has_contents_for(nsp): raise DistutilsSetupError( "Distribution contains no modules or packages for " + "namespace package %r" % nsp ) parent, sep, child = nsp.rpartition('.') if parent and parent not in ns_packages: distutils.log.warn( "WARNING: %r is declared as a package namespace, but %r" " is not: please correct this in setup.py", nsp, parent, ) def check_extras(dist, attr, value): """Verify that extras_require mapping is valid""" try: list(itertools.starmap(_check_extra, value.items())) except (TypeError, ValueError, AttributeError) as e: raise DistutilsSetupError( "'extras_require' must be a dictionary whose values are " "strings or lists of strings containing valid project/version " "requirement specifiers." ) from e def _check_extra(extra, reqs): name, sep, marker = extra.partition(':') if marker and pkg_resources.invalid_marker(marker): raise DistutilsSetupError("Invalid environment marker: " + marker) list(pkg_resources.parse_requirements(reqs)) def assert_bool(dist, attr, value): """Verify that value is True, False, 0, or 1""" if bool(value) != value: tmpl = "{attr!r} must be a boolean value (got {value!r})" raise DistutilsSetupError(tmpl.format(attr=attr, value=value)) def invalid_unless_false(dist, attr, value): if not value: warnings.warn(f"{attr} is ignored.", DistDeprecationWarning) return raise DistutilsSetupError(f"{attr} is invalid.") def check_requirements(dist, attr, value): """Verify that install_requires is a valid requirements list""" try: list(pkg_resources.parse_requirements(value)) if isinstance(value, (dict, set)): raise TypeError("Unordered types are not allowed") except (TypeError, ValueError) as error: tmpl = ( "{attr!r} must be a string or list of strings " "containing valid project/version requirement specifiers; {error}" ) raise DistutilsSetupError(tmpl.format(attr=attr, error=error)) from error def check_specifier(dist, attr, value): """Verify that value is a valid version specifier""" try: packaging.specifiers.SpecifierSet(value) except (packaging.specifiers.InvalidSpecifier, AttributeError) as error: tmpl = ( "{attr!r} must be a string " "containing valid version specifiers; {error}" ) raise DistutilsSetupError(tmpl.format(attr=attr, error=error)) from error def check_entry_points(dist, attr, value): """Verify that entry_points map is parseable""" try: pkg_resources.EntryPoint.parse_map(value) except ValueError as e: raise DistutilsSetupError(e) from e def check_test_suite(dist, attr, value): if not isinstance(value, str): raise DistutilsSetupError("test_suite must be a string") def check_package_data(dist, attr, value): """Verify that value is a dictionary of package names to glob lists""" if not isinstance(value, dict): raise DistutilsSetupError( "{!r} must be a dictionary mapping package names to lists of " "string wildcard patterns".format(attr) ) for k, v in value.items(): if not isinstance(k, str): raise DistutilsSetupError( "keys of {!r} dict must be strings (got {!r})".format(attr, k) ) assert_string_list(dist, 'values of {!r} dict'.format(attr), v) def check_packages(dist, attr, value): for pkgname in value: if not re.match(r'\w+(\.\w+)*', pkgname): distutils.log.warn( "WARNING: %r not a valid package name; please use only " ".-separated package names in setup.py", pkgname, ) _Distribution = get_unpatched(distutils.core.Distribution) class Distribution(_Distribution): """Distribution with support for tests and package data This is an enhanced version of 'distutils.dist.Distribution' that effectively adds the following new optional keyword arguments to 'setup()': 'install_requires' -- a string or sequence of strings specifying project versions that the distribution requires when installed, in the format used by 'pkg_resources.require()'. They will be installed automatically when the package is installed. If you wish to use packages that are not available in PyPI, or want to give your users an alternate download location, you can add a 'find_links' option to the '[easy_install]' section of your project's 'setup.cfg' file, and then setuptools will scan the listed web pages for links that satisfy the requirements. 'extras_require' -- a dictionary mapping names of optional "extras" to the additional requirement(s) that using those extras incurs. For example, this:: extras_require = dict(reST = ["docutils>=0.3", "reSTedit"]) indicates that the distribution can optionally provide an extra capability called "reST", but it can only be used if docutils and reSTedit are installed. If the user installs your package using EasyInstall and requests one of your extras, the corresponding additional requirements will be installed if needed. 'test_suite' -- the name of a test suite to run for the 'test' command. If the user runs 'python setup.py test', the package will be installed, and the named test suite will be run. The format is the same as would be used on a 'unittest.py' command line. That is, it is the dotted name of an object to import and call to generate a test suite. 'package_data' -- a dictionary mapping package names to lists of filenames or globs to use to find data files contained in the named packages. If the dictionary has filenames or globs listed under '""' (the empty string), those names will be searched for in every package, in addition to any names for the specific package. Data files found using these names/globs will be installed along with the package, in the same location as the package. Note that globs are allowed to reference the contents of non-package subdirectories, as long as you use '/' as a path separator. (Globs are automatically converted to platform-specific paths at runtime.) In addition to these new keywords, this class also has several new methods for manipulating the distribution's contents. For example, the 'include()' and 'exclude()' methods can be thought of as in-place add and subtract commands that add or remove packages, modules, extensions, and so on from the distribution. """ _DISTUTILS_UNSUPPORTED_METADATA = { 'long_description_content_type': lambda: None, 'project_urls': dict, 'provides_extras': ordered_set.OrderedSet, 'license_file': lambda: None, 'license_files': lambda: None, } _patched_dist = None def patch_missing_pkg_info(self, attrs): # Fake up a replacement for the data that would normally come from # PKG-INFO, but which might not yet be built if this is a fresh # checkout. # if not attrs or 'name' not in attrs or 'version' not in attrs: return key = pkg_resources.safe_name(str(attrs['name'])).lower() dist = pkg_resources.working_set.by_key.get(key) if dist is not None and not dist.has_metadata('PKG-INFO'): dist._version = pkg_resources.safe_version(str(attrs['version'])) self._patched_dist = dist def __init__(self, attrs=None): have_package_data = hasattr(self, "package_data") if not have_package_data: self.package_data = {} attrs = attrs or {} self.dist_files = [] # Filter-out setuptools' specific options. self.src_root = attrs.pop("src_root", None) self.patch_missing_pkg_info(attrs) self.dependency_links = attrs.pop('dependency_links', []) self.setup_requires = attrs.pop('setup_requires', []) for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'): vars(self).setdefault(ep.name, None) _Distribution.__init__( self, { k: v for k, v in attrs.items() if k not in self._DISTUTILS_UNSUPPORTED_METADATA }, ) self._set_metadata_defaults(attrs) self.metadata.version = self._normalize_version( self._validate_version(self.metadata.version) ) self._finalize_requires() def _set_metadata_defaults(self, attrs): """ Fill-in missing metadata fields not supported by distutils. Some fields may have been set by other tools (e.g. pbr). Those fields (vars(self.metadata)) take precedence to supplied attrs. """ for option, default in self._DISTUTILS_UNSUPPORTED_METADATA.items(): vars(self.metadata).setdefault(option, attrs.get(option, default())) @staticmethod def _normalize_version(version): if isinstance(version, setuptools.sic) or version is None: return version normalized = str(packaging.version.Version(version)) if version != normalized: tmpl = "Normalizing '{version}' to '{normalized}'" warnings.warn(tmpl.format(**locals())) return normalized return version @staticmethod def _validate_version(version): if isinstance(version, numbers.Number): # Some people apparently take "version number" too literally :) version = str(version) if version is not None: try: packaging.version.Version(version) except (packaging.version.InvalidVersion, TypeError): warnings.warn( "The version specified (%r) is an invalid version, this " "may not work as expected with newer versions of " "setuptools, pip, and PyPI. Please see PEP 440 for more " "details." % version ) return setuptools.sic(version) return version def _finalize_requires(self): """ Set `metadata.python_requires` and fix environment markers in `install_requires` and `extras_require`. """ if getattr(self, 'python_requires', None): self.metadata.python_requires = self.python_requires if getattr(self, 'extras_require', None): for extra in self.extras_require.keys(): # Since this gets called multiple times at points where the # keys have become 'converted' extras, ensure that we are only # truly adding extras we haven't seen before here. extra = extra.split(':')[0] if extra: self.metadata.provides_extras.add(extra) self._convert_extras_requirements() self._move_install_requirements_markers() def _convert_extras_requirements(self): """ Convert requirements in `extras_require` of the form `"extra": ["barbazquux; {marker}"]` to `"extra:{marker}": ["barbazquux"]`. """ spec_ext_reqs = getattr(self, 'extras_require', None) or {} self._tmp_extras_require = defaultdict(list) for section, v in spec_ext_reqs.items(): # Do not strip empty sections. self._tmp_extras_require[section] for r in pkg_resources.parse_requirements(v): suffix = self._suffix_for(r) self._tmp_extras_require[section + suffix].append(r) @staticmethod def _suffix_for(req): """ For a requirement, return the 'extras_require' suffix for that requirement. """ return ':' + str(req.marker) if req.marker else '' def _move_install_requirements_markers(self): """ Move requirements in `install_requires` that are using environment markers `extras_require`. """ # divide the install_requires into two sets, simple ones still # handled by install_requires and more complex ones handled # by extras_require. def is_simple_req(req): return not req.marker spec_inst_reqs = getattr(self, 'install_requires', None) or () inst_reqs = list(pkg_resources.parse_requirements(spec_inst_reqs)) simple_reqs = filter(is_simple_req, inst_reqs) complex_reqs = itertools.filterfalse(is_simple_req, inst_reqs) self.install_requires = list(map(str, simple_reqs)) for r in complex_reqs: self._tmp_extras_require[':' + str(r.marker)].append(r) self.extras_require = dict( (k, [str(r) for r in map(self._clean_req, v)]) for k, v in self._tmp_extras_require.items() ) def _clean_req(self, req): """ Given a Requirement, remove environment markers and return it. """ req.marker = None return req def _finalize_license_files(self): """Compute names of all license files which should be included.""" license_files: Optional[List[str]] = self.metadata.license_files patterns: List[str] = license_files if license_files else [] license_file: Optional[str] = self.metadata.license_file if license_file and license_file not in patterns: patterns.append(license_file) if license_files is None and license_file is None: # Default patterns match the ones wheel uses # See https://wheel.readthedocs.io/en/stable/user_guide.html # -> 'Including license files in the generated wheel file' patterns = ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*') self.metadata.license_files = list( unique_everseen(self._expand_patterns(patterns)) ) @staticmethod def _expand_patterns(patterns): """ >>> list(Distribution._expand_patterns(['LICENSE'])) ['LICENSE'] >>> list(Distribution._expand_patterns(['setup.cfg', 'LIC*'])) ['setup.cfg', 'LICENSE'] """ return ( path for pattern in patterns for path in sorted(iglob(pattern)) if not path.endswith('~') and os.path.isfile(path) ) # FIXME: 'Distribution._parse_config_files' is too complex (14) def _parse_config_files(self, filenames=None): # noqa: C901 """ Adapted from distutils.dist.Distribution.parse_config_files, this method provides the same functionality in subtly-improved ways. """ from configparser import ConfigParser # Ignore install directory options if we have a venv ignore_options = ( [] if sys.prefix == sys.base_prefix else [ 'install-base', 'install-platbase', 'install-lib', 'install-platlib', 'install-purelib', 'install-headers', 'install-scripts', 'install-data', 'prefix', 'exec-prefix', 'home', 'user', 'root', ] ) ignore_options = frozenset(ignore_options) if filenames is None: filenames = self.find_config_files() if DEBUG: self.announce("Distribution.parse_config_files():") parser = ConfigParser() parser.optionxform = str for filename in filenames: with io.open(filename, encoding='utf-8') as reader: if DEBUG: self.announce(" reading {filename}".format(**locals())) parser.read_file(reader) for section in parser.sections(): options = parser.options(section) opt_dict = self.get_option_dict(section) for opt in options: if opt == '__name__' or opt in ignore_options: continue val = parser.get(section, opt) opt = self.warn_dash_deprecation(opt, section) opt = self.make_option_lowercase(opt, section) opt_dict[opt] = (filename, val) # Make the ConfigParser forget everything (so we retain # the original filenames that options come from) parser.__init__() if 'global' not in self.command_options: return # If there was a "global" section in the config file, use it # to set Distribution options. for (opt, (src, val)) in self.command_options['global'].items(): alias = self.negative_opt.get(opt) if alias: val = not strtobool(val) elif opt in ('verbose', 'dry_run'): # ugh! val = strtobool(val) try: setattr(self, alias or opt, val) except ValueError as e: raise DistutilsOptionError(e) from e def warn_dash_deprecation(self, opt, section): if section in ( 'options.extras_require', 'options.data_files', ): return opt underscore_opt = opt.replace('-', '_') commands = distutils.command.__all__ + self._setuptools_commands() if ( not section.startswith('options') and section != 'metadata' and section not in commands ): return underscore_opt if '-' in opt: warnings.warn( "Usage of dash-separated '%s' will not be supported in future " "versions. Please use the underscore name '%s' instead" % (opt, underscore_opt) ) return underscore_opt def _setuptools_commands(self): try: dist = pkg_resources.get_distribution('setuptools') return list(dist.get_entry_map('distutils.commands')) except pkg_resources.DistributionNotFound: # during bootstrapping, distribution doesn't exist return [] def make_option_lowercase(self, opt, section): if section != 'metadata' or opt.islower(): return opt lowercase_opt = opt.lower() warnings.warn( "Usage of uppercase key '%s' in '%s' will be deprecated in future " "versions. Please use lowercase '%s' instead" % (opt, section, lowercase_opt) ) return lowercase_opt # FIXME: 'Distribution._set_command_options' is too complex (14) def _set_command_options(self, command_obj, option_dict=None): # noqa: C901 """ Set the options for 'command_obj' from 'option_dict'. Basically this means copying elements of a dictionary ('option_dict') to attributes of an instance ('command'). 'command_obj' must be a Command instance. If 'option_dict' is not supplied, uses the standard option dictionary for this command (from 'self.command_options'). (Adopted from distutils.dist.Distribution._set_command_options) """ command_name = command_obj.get_command_name() if option_dict is None: option_dict = self.get_option_dict(command_name) if DEBUG: self.announce(" setting options for '%s' command:" % command_name) for (option, (source, value)) in option_dict.items(): if DEBUG: self.announce(" %s = %s (from %s)" % (option, value, source)) try: bool_opts = [translate_longopt(o) for o in command_obj.boolean_options] except AttributeError: bool_opts = [] try: neg_opt = command_obj.negative_opt except AttributeError: neg_opt = {} try: is_string = isinstance(value, str) if option in neg_opt and is_string: setattr(command_obj, neg_opt[option], not strtobool(value)) elif option in bool_opts and is_string: setattr(command_obj, option, strtobool(value)) elif hasattr(command_obj, option): setattr(command_obj, option, value) else: raise DistutilsOptionError( "error in %s: command '%s' has no such option '%s'" % (source, command_name, option) ) except ValueError as e: raise DistutilsOptionError(e) from e def parse_config_files(self, filenames=None, ignore_option_errors=False): """Parses configuration files from various levels and loads configuration. """ self._parse_config_files(filenames=filenames) parse_configuration( self, self.command_options, ignore_option_errors=ignore_option_errors ) self._finalize_requires() self._finalize_license_files() def fetch_build_eggs(self, requires): """Resolve pre-setup requirements""" resolved_dists = pkg_resources.working_set.resolve( pkg_resources.parse_requirements(requires), installer=self.fetch_build_egg, replace_conflicting=True, ) for dist in resolved_dists: pkg_resources.working_set.add(dist, replace=True) return resolved_dists def finalize_options(self): """ Allow plugins to apply arbitrary operations to the distribution. Each hook may optionally define a 'order' to influence the order of execution. Smaller numbers go first and the default is 0. """ group = 'setuptools.finalize_distribution_options' def by_order(hook): return getattr(hook, 'order', 0) defined = pkg_resources.iter_entry_points(group) filtered = itertools.filterfalse(self._removed, defined) loaded = map(lambda e: e.load(), filtered) for ep in sorted(loaded, key=by_order): ep(self) @staticmethod def _removed(ep): """ When removing an entry point, if metadata is loaded from an older version of Setuptools, that removed entry point will attempt to be loaded and will fail. See #2765 for more details. """ removed = { # removed 2021-09-05 '2to3_doctests', } return ep.name in removed def _finalize_setup_keywords(self): for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'): value = getattr(self, ep.name, None) if value is not None: ep.require(installer=self.fetch_build_egg) ep.load()(self, ep.name, value) def get_egg_cache_dir(self): egg_cache_dir = os.path.join(os.curdir, '.eggs') if not os.path.exists(egg_cache_dir): os.mkdir(egg_cache_dir) windows_support.hide_file(egg_cache_dir) readme_txt_filename = os.path.join(egg_cache_dir, 'README.txt') with open(readme_txt_filename, 'w') as f: f.write( 'This directory contains eggs that were downloaded ' 'by setuptools to build, test, and run plug-ins.\n\n' ) f.write( 'This directory caches those eggs to prevent ' 'repeated downloads.\n\n' ) f.write('However, it is safe to delete this directory.\n\n') return egg_cache_dir def fetch_build_egg(self, req): """Fetch an egg needed for building""" from setuptools.installer import fetch_build_egg return fetch_build_egg(self, req) def get_command_class(self, command): """Pluggable version of get_command_class()""" if command in self.cmdclass: return self.cmdclass[command] eps = pkg_resources.iter_entry_points('distutils.commands', command) for ep in eps: ep.require(installer=self.fetch_build_egg) self.cmdclass[command] = cmdclass = ep.load() return cmdclass else: return _Distribution.get_command_class(self, command) def print_commands(self): for ep in pkg_resources.iter_entry_points('distutils.commands'): if ep.name not in self.cmdclass: # don't require extras as the commands won't be invoked cmdclass = ep.resolve() self.cmdclass[ep.name] = cmdclass return _Distribution.print_commands(self) def get_command_list(self): for ep in pkg_resources.iter_entry_points('distutils.commands'): if ep.name not in self.cmdclass: # don't require extras as the commands won't be invoked cmdclass = ep.resolve() self.cmdclass[ep.name] = cmdclass return _Distribution.get_command_list(self) def include(self, **attrs): """Add items to distribution that are named in keyword arguments For example, 'dist.include(py_modules=["x"])' would add 'x' to the distribution's 'py_modules' attribute, if it was not already there. Currently, this method only supports inclusion for attributes that are lists or tuples. If you need to add support for adding to other attributes in this or a subclass, you can add an '_include_X' method, where 'X' is the name of the attribute. The method will be called with the value passed to 'include()'. So, 'dist.include(foo={"bar":"baz"})' will try to call 'dist._include_foo({"bar":"baz"})', which can then handle whatever special inclusion logic is needed. """ for k, v in attrs.items(): include = getattr(self, '_include_' + k, None) if include: include(v) else: self._include_misc(k, v) def exclude_package(self, package): """Remove packages, modules, and extensions in named package""" pfx = package + '.' if self.packages: self.packages = [ p for p in self.packages if p != package and not p.startswith(pfx) ] if self.py_modules: self.py_modules = [ p for p in self.py_modules if p != package and not p.startswith(pfx) ] if self.ext_modules: self.ext_modules = [ p for p in self.ext_modules if p.name != package and not p.name.startswith(pfx) ] def has_contents_for(self, package): """Return true if 'exclude_package(package)' would do something""" pfx = package + '.' for p in self.iter_distribution_names(): if p == package or p.startswith(pfx): return True def _exclude_misc(self, name, value): """Handle 'exclude()' for list/tuple attrs without a special handler""" if not isinstance(value, sequence): raise DistutilsSetupError( "%s: setting must be a list or tuple (%r)" % (name, value) ) try: old = getattr(self, name) except AttributeError as e: raise DistutilsSetupError("%s: No such distribution setting" % name) from e if old is not None and not isinstance(old, sequence): raise DistutilsSetupError( name + ": this setting cannot be changed via include/exclude" ) elif old: setattr(self, name, [item for item in old if item not in value]) def _include_misc(self, name, value): """Handle 'include()' for list/tuple attrs without a special handler""" if not isinstance(value, sequence): raise DistutilsSetupError("%s: setting must be a list (%r)" % (name, value)) try: old = getattr(self, name) except AttributeError as e: raise DistutilsSetupError("%s: No such distribution setting" % name) from e if old is None: setattr(self, name, value) elif not isinstance(old, sequence): raise DistutilsSetupError( name + ": this setting cannot be changed via include/exclude" ) else: new = [item for item in value if item not in old] setattr(self, name, old + new) def exclude(self, **attrs): """Remove items from distribution that are named in keyword arguments For example, 'dist.exclude(py_modules=["x"])' would remove 'x' from the distribution's 'py_modules' attribute. Excluding packages uses the 'exclude_package()' method, so all of the package's contained packages, modules, and extensions are also excluded. Currently, this method only supports exclusion from attributes that are lists or tuples. If you need to add support for excluding from other attributes in this or a subclass, you can add an '_exclude_X' method, where 'X' is the name of the attribute. The method will be called with the value passed to 'exclude()'. So, 'dist.exclude(foo={"bar":"baz"})' will try to call 'dist._exclude_foo({"bar":"baz"})', which can then handle whatever special exclusion logic is needed. """ for k, v in attrs.items(): exclude = getattr(self, '_exclude_' + k, None) if exclude: exclude(v) else: self._exclude_misc(k, v) def _exclude_packages(self, packages): if not isinstance(packages, sequence): raise DistutilsSetupError( "packages: setting must be a list or tuple (%r)" % (packages,) ) list(map(self.exclude_package, packages)) def _parse_command_opts(self, parser, args): # Remove --with-X/--without-X options when processing command args self.global_options = self.__class__.global_options self.negative_opt = self.__class__.negative_opt # First, expand any aliases command = args[0] aliases = self.get_option_dict('aliases') while command in aliases: src, alias = aliases[command] del aliases[command] # ensure each alias can expand only once! import shlex args[:1] = shlex.split(alias, True) command = args[0] nargs = _Distribution._parse_command_opts(self, parser, args) # Handle commands that want to consume all remaining arguments cmd_class = self.get_command_class(command) if getattr(cmd_class, 'command_consumes_arguments', None): self.get_option_dict(command)['args'] = ("command line", nargs) if nargs is not None: return [] return nargs def get_cmdline_options(self): """Return a '{cmd: {opt:val}}' map of all command-line options Option names are all long, but do not include the leading '--', and contain dashes rather than underscores. If the option doesn't take an argument (e.g. '--quiet'), the 'val' is 'None'. Note that options provided by config files are intentionally excluded. """ d = {} for cmd, opts in self.command_options.items(): for opt, (src, val) in opts.items(): if src != "command line": continue opt = opt.replace('_', '-') if val == 0: cmdobj = self.get_command_obj(cmd) neg_opt = self.negative_opt.copy() neg_opt.update(getattr(cmdobj, 'negative_opt', {})) for neg, pos in neg_opt.items(): if pos == opt: opt = neg val = None break else: raise AssertionError("Shouldn't be able to get here") elif val == 1: val = None d.setdefault(cmd, {})[opt] = val return d def iter_distribution_names(self): """Yield all packages, modules, and extension names in distribution""" for pkg in self.packages or (): yield pkg for module in self.py_modules or (): yield module for ext in self.ext_modules or (): if isinstance(ext, tuple): name, buildinfo = ext else: name = ext.name if name.endswith('module'): name = name[:-6] yield name def handle_display_options(self, option_order): """If there were any non-global "display-only" options (--help-commands or the metadata display options) on the command line, display the requested info and return true; else return false. """ import sys if self.help_commands: return _Distribution.handle_display_options(self, option_order) # Stdout may be StringIO (e.g. in tests) if not isinstance(sys.stdout, io.TextIOWrapper): return _Distribution.handle_display_options(self, option_order) # Don't wrap stdout if utf-8 is already the encoding. Provides # workaround for #334. if sys.stdout.encoding.lower() in ('utf-8', 'utf8'): return _Distribution.handle_display_options(self, option_order) # Print metadata in UTF-8 no matter the platform encoding = sys.stdout.encoding errors = sys.stdout.errors newline = sys.platform != 'win32' and '\n' or None line_buffering = sys.stdout.line_buffering sys.stdout = io.TextIOWrapper( sys.stdout.detach(), 'utf-8', errors, newline, line_buffering ) try: return _Distribution.handle_display_options(self, option_order) finally: sys.stdout = io.TextIOWrapper( sys.stdout.detach(), encoding, errors, newline, line_buffering ) class DistDeprecationWarning(SetuptoolsDeprecationWarning): """Class for warning about deprecations in dist in setuptools. Not ignored by default, unlike DeprecationWarning.""" PKH];.##Jpython3.10/site-packages/setuptools/__pycache__/build_meta.cpython-310.pycnu[o Xai((@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z gdZ Gddde ZGdddejjZejd d Zd d Zd dZddZGdddeZGdddeZeZejZejZejZejZejZeZdS)a-A PEP 517 interface to setuptools Previously, when a user or a command line tool (let's call it a "frontend") needed to make a request of setuptools to take a certain action, for example, generating a list of installation requirements, the frontend would would call "setup.py egg_info" or "setup.py bdist_wheel" on the command line. PEP 517 defines a different method of interfacing with setuptools. Rather than calling "setup.py" directly, the frontend should: 1. Set the current directory to the directory with a setup.py file 2. Import this module into a safe python interpreter (one in which setuptools can potentially set global variables or crash hard). 3. Call one of the functions defined in PEP 517. What each function does is defined in PEP 517. However, here is a "casual" definition of the functions (this definition should not be relied on for bug reports or API stability): - `build_wheel`: build a wheel in the folder and return the basename - `get_requires_for_build_wheel`: get the `setup_requires` to build - `prepare_metadata_for_build_wheel`: get the `install_requires` - `build_sdist`: build an sdist in the folder and return the basename - `get_requires_for_build_sdist`: get the `setup_requires` to build Again, this is not a formal definition! Just a "taste" of the module. N)parse_requirements)get_requires_for_build_sdistget_requires_for_build_wheel prepare_metadata_for_build_wheel build_wheel build_sdist __legacy__SetupRequirementsErrorc@seZdZddZdS)r cCs ||_dSN) specifiers)selfr r /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/build_meta.py__init__4s zSetupRequirementsError.__init__N)__name__ __module__ __qualname__rr r r rr 3s r c@s&eZdZddZeejddZdS) DistributioncCstttt|}t|r )listmapstrrr )r r Zspecifier_listr r rfetch_build_eggs9szDistribution.fetch_build_eggsccs2tjj}|tj_z dVW|tj_dS|tj_w)zw Replace distutils.dist.Distribution with this class for the duration of this context. N) distutilscorer)clsorigr r rpatch>s zDistribution.patchN)rrrr classmethod contextlibcontextmanagerrr r r rr8s rccs.tj}ddt_z dVW|t_dS|t_w)a Temporarily disable installing setup_requires Under PEP 517, the backend reports build dependencies to the frontend, and the frontend is responsible for ensuring they're installed. So setuptools (acting as a backend) should not try to install them. cSsdSr r )attrsr r rWsz+no_install_setup_requires..N) setuptoolsZ_install_setup_requires)rr r rno_install_setup_requiresNs  r#csfddtDS)Ncs&g|]}tjtj|r|qSr )ospathisdirjoin).0nameZa_dirr r _s z1_get_immediate_subdirectories..)r$listdirr*r r*r_get_immediate_subdirectories^sr-cs<fddt|D}z|\}W|Stytdw)Nc3s|] }|r|VqdSr endswithr(f extensionr r ds z'_file_with_extension..z[No distribution was found. Ensure that `setup.py` is not empty and that it calls `setup()`.)r$r, ValueError) directoryr3Zmatchingfiler r2r_file_with_extensioncs  r8cCs&tj|s tdSttdt|S)Nz%from setuptools import setup; setup()open)r$r%existsioStringIOgetattrtokenizer9 setup_scriptr r r_open_setup_scriptqs  rAc@sfeZdZddZddZdddZdd d Zdd d Z dd dZddZ  dddZ dddZ dS)_BuildMetaBackendcCs|pi}|dg|S)N--global-option) setdefaultr config_settingsr r r _fix_config{s z_BuildMetaBackend._fix_configc Cs||}tjdddg|dt_zt|WdW|S1s*wYW|StyI}z ||j7}WYd}~|Sd}~ww)Negg_inforC)rGsysargvrr run_setupr r )r rF requirementser r r_get_build_requiress    z%_BuildMetaBackend._get_build_requiressetup.pycCsX|}d}t|}|dd}Wdn1swYtt||dtdS)N__main__z\r\nz\nexec)rAreadreplacerRcompilelocals)r r@__file__rr1coder r rrLs  z_BuildMetaBackend.run_setupNcCs||}|j|dgdS)NwheelrMrGrOrEr r rrs z._BuildMetaBackend.get_requires_for_build_wheelcCs||}|j|gdS)NrZr[rEr r rrs z._BuildMetaBackend.get_requires_for_build_sdistcCstjdddd|gt_t |Wdn1swY|} ddt|D}t|dkrLtt|dkrLtj |t|d}q&t|dksTJ ||krmt tj ||d|t j |dd|dS) NrHZ dist_infoz --egg-baseTcSsg|] }|dr|qS)z .dist-infor.r0r r rr+s zF_BuildMetaBackend.prepare_metadata_for_build_wheel..r) ignore_errors) rJrKr#rLr$r,lenr-r%r'shutilmovermtree)r metadata_directoryrFZdist_info_directoryZ dist_infosr r rrs0   z2_BuildMetaBackend.prepare_metadata_for_build_wheelc Cs||}tj|}tj|ddtj|dT}tjdd|d|g|dt_t | Wdn1s=wYt ||}tj ||}tj |rYt|ttj |||Wd|S1sowY|S)NT)exist_ok)dirrHz --dist-dirrC)rGr$r%abspathmakedirstempfileTemporaryDirectoryrJrKr#rLr8r'r:removerename)r Z setup_commandZresult_extensionZresult_directoryrFZ tmp_dist_dirZresult_basename result_pathr r r_build_with_temp_dirs.      z&_BuildMetaBackend._build_with_temp_dircCs|dgd||S)N bdist_wheelz.whlrk)r wheel_directoryrFrar r rrs z_BuildMetaBackend.build_wheelcCs|gdd||S)N)sdistz --formatsgztarz.tar.gzrm)r sdist_directoryrFr r rrs z_BuildMetaBackend.build_sdistrPr )NN) rrrrGrOrLrrrrkrrr r r rrBys  " rBcs"eZdZdZdfdd ZZS)_BuildMetaLegacyBackendaOCompatibility backend for setuptools This is a version of setuptools.build_meta that endeavors to maintain backwards compatibility with pre-PEP 517 modes of invocation. It exists as a temporary bridge between the old packaging mechanism and the new packaging mechanism, and will eventually be removed. rPc sttj}tjtj|}|tjvrtjd|tjd}|tjd<ztt |j |dW|tjdd<|tjd<dS|tjdd<|tjd<w)Nrr?) rrJr%r$dirnamerdinsertrKsuperrsrL)r r@sys_pathZ script_dirZ sys_argv_0 __class__r rrLs     z!_BuildMetaLegacyBackend.run_setuprr)rrr__doc__rL __classcell__r r rxrrss rs) rzr;r$rJr>r^rrfr"r pkg_resourcesr__all__ BaseExceptionr distrrr#r-r8rAobjectrBrsZ_BACKENDrrrrrrr r r rs8   m) PKH]{2{{Gpython3.10/site-packages/setuptools/__pycache__/version.cpython-310.pycnu[o Xai@s4ddlZz edjZWdSeydZYdSw)N setuptoolsunknown) pkg_resourcesget_distributionversion __version__ Exceptionr r /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/version.pys   PKH]4Fpython3.10/site-packages/setuptools/__pycache__/errors.cpython-310.pycnu[o Xai @s&dZddlmZGdddeeZdS)zCsetuptools.errors Provides exceptions used by setuptools modules. )DistutilsErrorc@seZdZdZdS)RemovedCommandErroraOError used for commands that have been removed in setuptools. Since ``setuptools`` is built on ``distutils``, simply removing a command from ``setuptools`` will make the behavior fall back to ``distutils``; this error is raised if a command exists in ``distutils`` but has been actively removed in ``setuptools``. N)__name__ __module__ __qualname____doc__rr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/errors.pyr srN)rdistutils.errorsr RuntimeErrorrrrrr s PKH]ocDpython3.10/site-packages/setuptools/__pycache__/dist.cpython-310.pycnu[o XaiO@sdgZddlZddlZddlZddlZddlZddlZddlZddl Zddl Zddl Zddl Zddl mZddlmZddlmZddlmZddlZddlZddlmZmZmZddlmZdd lmZdd lm Z m!Z!dd l m"Z"dd l#m$Z$dd l%m&Z&ddl%m'Z'ddl(m)Z)ddl*m+Z+ddl,Z,ddl-Z,ddl,m.Z.ddl/m0Z0ddl1m2Z2ddl3Z3erddl4m5Z5e6de6dddZ7ddZ8de9de9fddZ:d d!d"e9dee9fd#d$Z;d d!d"e9dee9fd%d&Zd+d,Z?d-d.Z@d/d0ZAeBeCfZDd1d2ZEd3d4ZFd5d6ZGd7d8ZHd9d:ZId;d<ZJd=d>ZKd?d@ZLdAdBZMdCdDZNdEdFZOdGdHZPdIdJZQe0ejRjSZTGdKddeTZSGdLdMdMe+ZUdS)N DistributionN) strtobool)DEBUGtranslate_longopt)iglob)ListOptional TYPE_CHECKING) defaultdict)message_from_file)DistutilsOptionErrorDistutilsSetupError) rfc822_escape) StrictVersion) packaging) ordered_set)unique_everseen)SetuptoolsDeprecationWarning)windows_support) get_unpatched)parse_configuration)Messagez&setuptools.extern.packaging.specifiersz#setuptools.extern.packaging.versioncCstdtt|S)NzDo not call this function)warningswarnDistDeprecationWarningr)clsr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/dist.py_get_unpatched2s r cCs&t|dd}|durtd}||_|S)Nmetadata_version2.1)getattrrr!)selfmvrrrget_metadata_version7s r&contentreturnc CsJ|}t|dkr|dSd|dtd|ddfS)zFReverse RFC-822 escaping by removing leading whitespaces from content.rr N) splitlineslenlstripjointextwrapdedent)r'linesrrrrfc822_unescape?s  *r1msgrfieldcCs||}|dkr dS|S)zRead Message header field.UNKNOWNNrr2r3valuerrr_read_field_from_msgGsr7cCst||}|dur |St|S)z4Read Message header field and apply rfc822_unescape.N)r7r1r5rrr_read_field_unescaped_from_msgOs r8cCs||d}|gkr dS|S)z9Read Message header field and return all results as list.N)get_all)r2r3valuesrrr_read_list_from_msgWs r;cCs|}|dkr dS|S)Nr4) get_payloadstrip)r2r6rrr_read_payload_from_msg_s r>cCsTt|}t|d|_t|d|_t|d|_t|d|_t|d|_d|_t|d|_ d|_ t|d|_ t |d |_ d |vrFt|d |_nd|_t |d |_|jdur`|jtd kr`t||_t|d|_d |vrst|d d|_t|d|_t|d|_|jtdkrt|d|_t|d|_t|d|_n d|_d|_d|_t|d|_dS)z-Reads the metadata values from a file object.zmetadata-versionnameversionsummaryauthorNz author-emailz home-pagelicensez download-url descriptionr"keywords,platform classifierz1.1requiresprovides obsoletesz license-file)r rr!r7r?r@rDrB maintainer author_emailmaintainer_emailurlr8rC download_urllong_descriptionr>splitrEr; platforms classifiersrIrJrK license_files)r$filer2rrr read_pkg_filefs<              rWcCs"d|vrtd|dd}|S)Nr)z1newlines not allowed and will break in the future )rrreplace)valrrr single_lines  r[c s|}fdd}|dt||d||d||dt||d|d}|D]\}}t||d }|d urF|||q3t| }|d ||j r[|d |j |j D] } |d d | q`d |} | rx|d| |D]} |d| q||d||d||d||d|t|dr|d|j|jr|d|j|jr|jD]} |d| q|d|jpgd|d S)z0Write the PKG-INFO format data to a file object.csd||fdS)Nz%s: %s )write)keyr6rVrr write_fieldsz#write_pkg_file..write_fieldzMetadata-VersionNameVersionZSummaryz Home-page))ZAuthorrB)z Author-emailrM)Z MaintainerrL)zMaintainer-emailrNNZLicensez Download-URLz Project-URLz%s, %srFZKeywordsPlatform ClassifierRequiresProvides Obsoletespython_requireszRequires-PythonzDescription-Content-TypezProvides-Extraz License-Filez %s )r&strget_name get_versionr[get_descriptionget_urlr#r get_licenserP project_urlsitemsr- get_keywords get_platforms _write_listget_classifiers get_requires get_provides get_obsoleteshasattrrglong_description_content_typeprovides_extrasrUr\get_long_description) r$rVr@r_Zoptional_fieldsr3attrZattr_valrC project_urlrErGextrarr^rwrite_pkg_filesJ               r~c CsTztjd|}|jrJWdSttttfy)}z td||f|d}~ww)Nzx=z4%r must be importable 'module:attrs' string (got %r)) pkg_resources EntryPointparseextras TypeError ValueErrorAttributeErrorAssertionErrorr)distr{r6eperrrcheck_importables rc Cs^zt|ttfs Jd||ksJWdSttttfy.}z td||f|d}~ww)z"Verify that value is a string listz%%r must be a list of strings (got %r)N) isinstancelisttupler-rrrrrrr{r6rrrrassert_string_lists rcCsd|}t||||D]%}||stdd||d\}}}|r/||vr/tjd||q dS)z(Verify that namespace packages are validz1Distribution contains no modules or packages for znamespace package %r.z^WARNING: %r is declared as a package namespace, but %r is not: please correct this in setup.pyN)rhas_contents_forr rpartition distutilslogr)rr{r6Z ns_packagesnspparentsepchildrrr check_nsps$   rc CsDz ttt|WdStttfy!}ztd|d}~ww)z+Verify that extras_require mapping is validz'extras_require' must be a dictionary whose values are strings or lists of strings containing valid project/version requirement specifiers.N) r itertoolsstarmap _check_extrarorrrrrrrr check_extras srcCs<|d\}}}|rt|rtd|tt|dS)N:zInvalid environment marker: ) partitionrinvalid_markerrrparse_requirements)r}reqsr?rmarkerrrrrs rcCs&t||krd}t|j||ddS)z)Verify that value is True, False, 0, or 1z0{attr!r} must be a boolean value (got {value!r}))r{r6N)boolrformat)rr{r6tmplrrr assert_bools rcCs(|s t|dtdSt|d)Nz is ignored.z is invalid.)rrrrrr{r6rrrinvalid_unless_false$src Cs`ztt|t|ttfrtdWdSttfy/}z d}t|j ||d|d}~ww)z9Verify that install_requires is a valid requirements listzUnordered types are not allowedzm{attr!r} must be a string or list of strings containing valid project/version requirement specifiers; {error}r{errorN) rrrrdictsetrrrrrr{r6rrrrrcheck_requirements+src CsLz tj|WdStjjtfy%}z d}t|j||d|d}~ww)z.Verify that value is a valid version specifierzF{attr!r} must be a string containing valid version specifiers; {error}rN)r specifiers SpecifierSetInvalidSpecifierrrrrrrrcheck_specifier9src Cs6z tj|WdSty}zt||d}~ww)z)Verify that entry_points map is parseableN)rr parse_maprrrrrrcheck_entry_pointsDs  rcCst|ts tddS)Nztest_suite must be a string)rrhrrrrrcheck_test_suiteLs rcCsZt|ts td||D]\}}t|ts!td||t|d||qdS)z@Verify that value is a dictionary of package names to glob listszT{!r} must be a dictionary mapping package names to lists of string wildcard patternsz,keys of {!r} dict must be strings (got {!r})zvalues of {!r} dictN)rrrrrorhr)rr{r6kvrrrcheck_package_dataQs   rcCs(|D]}td|stjd|qdS)Nz \w+(\.\w+)*z[WARNING: %r not a valid package name; please use only .-separated package names in setup.py)rematchrrr)rr{r6pkgnamerrrcheck_packages`s rc@s~eZdZdZddeejdddddZdZdd Z dUd d Z d d Z e ddZ e ddZddZddZe ddZddZddZddZe ddZdUd d!Zd"d#Zd$d%Zd&d'ZdUd(d)ZdVd+d,Zd-d.Zd/d0Ze d1d2Zd3d4Zd5d6Z d7d8Z!d9d:Z"d;d<Z#d=d>Z$d?d@Z%dAdBZ&dCdDZ'dEdFZ(dGdHZ)dIdJZ*dKdLZ+dMdNZ,dOdPZ-dQdRZ.dSdTZ/dS)WraG Distribution with support for tests and package data This is an enhanced version of 'distutils.dist.Distribution' that effectively adds the following new optional keyword arguments to 'setup()': 'install_requires' -- a string or sequence of strings specifying project versions that the distribution requires when installed, in the format used by 'pkg_resources.require()'. They will be installed automatically when the package is installed. If you wish to use packages that are not available in PyPI, or want to give your users an alternate download location, you can add a 'find_links' option to the '[easy_install]' section of your project's 'setup.cfg' file, and then setuptools will scan the listed web pages for links that satisfy the requirements. 'extras_require' -- a dictionary mapping names of optional "extras" to the additional requirement(s) that using those extras incurs. For example, this:: extras_require = dict(reST = ["docutils>=0.3", "reSTedit"]) indicates that the distribution can optionally provide an extra capability called "reST", but it can only be used if docutils and reSTedit are installed. If the user installs your package using EasyInstall and requests one of your extras, the corresponding additional requirements will be installed if needed. 'test_suite' -- the name of a test suite to run for the 'test' command. If the user runs 'python setup.py test', the package will be installed, and the named test suite will be run. The format is the same as would be used on a 'unittest.py' command line. That is, it is the dotted name of an object to import and call to generate a test suite. 'package_data' -- a dictionary mapping package names to lists of filenames or globs to use to find data files contained in the named packages. If the dictionary has filenames or globs listed under '""' (the empty string), those names will be searched for in every package, in addition to any names for the specific package. Data files found using these names/globs will be installed along with the package, in the same location as the package. Note that globs are allowed to reference the contents of non-package subdirectories, as long as you use '/' as a path separator. (Globs are automatically converted to platform-specific paths at runtime.) In addition to these new keywords, this class also has several new methods for manipulating the distribution's contents. For example, the 'include()' and 'exclude()' methods can be thought of as in-place add and subtract commands that add or remove packages, modules, extensions, and so on from the distribution. cCdSNrrrrrzDistribution.cCrrrrrrrrrcCrrrrrrrrr)rxrnry license_filerUNcCst|r d|vs d|vr dStt|d}tjj|}|dur6|ds8tt|d|_ ||_ dSdSdS)Nr?r@zPKG-INFO) r safe_namerhlower working_setby_keyget has_metadata safe_version_version _patched_dist)r$attrsr]rrrrpatch_missing_pkg_infos z#Distribution.patch_missing_pkg_infocstd}|s i_|p i}g_|dd_||dg_|dg_t dD] }t  |j dq0t fdd|D|jjj_dS)N package_datasrc_rootdependency_linkssetup_requiresdistutils.setup_keywordscs i|] \}}|jvr||qSr)_DISTUTILS_UNSUPPORTED_METADATA.0rrr$rr s  z)Distribution.__init__..)rwr dist_filespoprrrrriter_entry_pointsvars setdefaultr? _Distribution__init__ro_set_metadata_defaults_normalize_version_validate_versionmetadatar@_finalize_requires)r$rZhave_package_datarrrrrs,      zDistribution.__init__cCs4|jD]\}}t|j||||qdS)z Fill-in missing metadata fields not supported by distutils. Some fields may have been set by other tools (e.g. pbr). Those fields (vars(self.metadata)) take precedence to supplied attrs. N)rrorrrr)r$roptiondefaultrrrrsz#Distribution._set_metadata_defaultscCsTt|tjs |dur |Sttj|}||kr(d}t|j dit |S|S)Nz)Normalizing '{version}' to '{normalized}'r) r setuptoolssicrhrr@rarrrlocals)r@ normalizedrrrrrszDistribution._normalize_versionc Csft|tjr t|}|dur1z tj|W|Stjjtfy0t d|t |YSw|S)NzThe version specified (%r) is an invalid version, this may not work as expected with newer versions of setuptools, pip, and PyPI. Please see PEP 440 for more details.) rnumbersNumberrhrr@raInvalidVersionrrrrr)r@rrrrs  zDistribution._validate_versioncCsft|ddr |j|j_t|ddr)|jD]}|dd}|r(|jj|q|| dS)z Set `metadata.python_requires` and fix environment markers in `install_requires` and `extras_require`. rgNextras_requirerr) r#rgrrkeysrRryadd_convert_extras_requirements"_move_install_requirements_markers)r$r}rrrrs    zDistribution._finalize_requirescCsht|ddpi}tt|_|D] \}}|j|t|D]}||}|j|||qqdS)z Convert requirements in `extras_require` of the form `"extra": ["barbazquux; {marker}"]` to `"extra:{marker}": ["barbazquux"]`. rN) r#r r_tmp_extras_requirerorr _suffix_forappend)r$Z spec_ext_reqssectionrrsuffixrrrrs   z)Distribution._convert_extras_requirementscCs|jr dt|jSdS)ze For a requirement, return the 'extras_require' suffix for that requirement. rr)rrhreqrrrr!szDistribution._suffix_forcsdd}tddp d}tt|}t||}t||}ttt|_ |D]}j dt|j  |q(t fddj D_dS) zv Move requirements in `install_requires` that are using environment markers `extras_require`. cSs|j Srrrrrr is_simple_req3szFDistribution._move_install_requirements_markers..is_simple_reqinstall_requiresNrrc3s.|]\}}|ddtj|DfVqdS)cSg|]}t|qSr)rh)rrrrr ?zMDistribution._move_install_requirements_markers...N)map _clean_reqrrrr >s  zBDistribution._move_install_requirements_markers..)r#rrrfilterr filterfalserrhrrrrrror)r$rZspec_inst_reqsZ inst_reqsZ simple_reqsZ complex_reqsrrrrr)s    z/Distribution._move_install_requirements_markerscCs d|_|S)zP Given a Requirement, remove environment markers and return it. Nr)r$rrrrrCszDistribution._clean_reqcCs`|jj}|r|ng}|jj}|r||vr|||dur#|dur#d}tt|||j_dS)z>> list(Distribution._expand_patterns(['LICENSE'])) ['LICENSE'] >>> list(Distribution._expand_patterns(['setup.cfg', 'LIC*'])) ['setup.cfg', 'LICENSE'] css<|]}tt|D]}|ds tj|r |Vq qdS)~N)sortedrendswithospathisfile)rpatternr rrrres   z0Distribution._expand_patterns..r)rrrrr]szDistribution._expand_patternsc Csddlm}tjtjkrgngd}t|}|dur|}tr%|d|}t |_ |D]g}t j |dd}trE|dj d it||Wdn1sTwY|D]2}||}||} |D]#} | d ksu| |vrvqk||| } || |} || |} || f| | <qkq]|q-d |jvrdS|jd D]7\} \} } |j| } | rt|  } n| d vrt| } z t|| p| | Wqty}zt||d}~wwdS) z Adapted from distutils.dist.Distribution.parse_config_files, this method provides the same functionality in subtly-improved ways. r) ConfigParser) z install-basezinstall-platbasez install-libzinstall-platlibzinstall-purelibzinstall-headerszinstall-scriptsz install-dataprefixz exec-prefixhomeuserrootNz"Distribution.parse_config_files():utf-8)encodingz reading {filename}__name__global)verbosedry_runr) configparserrsysr base_prefix frozensetfind_config_filesrannouncerh optionxformioopenrr read_filesectionsoptionsget_option_dictrwarn_dash_deprecationmake_option_lowercasercommand_optionsro negative_optrsetattrrr )r$ filenamesrignore_optionsparserfilenamereaderrr&opt_dictoptrZsrcaliasrrrr_parse_config_filesmsZ              z Distribution._parse_config_filescCsd|dvr|S|dd}tjj|}|ds#|dkr#||vr#|Sd|vr0td||f|S)N)zoptions.extras_requirezoptions.data_files-_r&rzrUsage of dash-separated '%s' will not be supported in future versions. Please use the underscore name '%s' instead)rYrcommand__all___setuptools_commands startswithrr)r$r3rZunderscore_optcommandsrrrr(s  z"Distribution.warn_dash_deprecationcCs4z td}t|dWStjygYSw)Nrdistutils.commands)rget_distributionr get_entry_mapDistributionNotFound)r$rrrrr;s  z!Distribution._setuptools_commandscCs4|dks|r |S|}td|||f|S)NrzlUsage of uppercase key '%s' in '%s' will be deprecated in future versions. Please use lowercase '%s' instead)islowerrrr)r$r3rZ lowercase_optrrrr)sz"Distribution.make_option_lowercasec CsH|}|dur ||}tr|d||D]\}\}}tr,|d|||fz dd|jD}Wn tyAg}Ynwz|j}Wn tyRi}Ynwz=t|t } ||vrk| rkt |||t | n$||vrz| rzt ||t |nt ||rt |||n t d|||fWqty} zt | | d} ~ wwdS)a Set the options for 'command_obj' from 'option_dict'. Basically this means copying elements of a dictionary ('option_dict') to attributes of an instance ('command'). 'command_obj' must be a Command instance. If 'option_dict' is not supplied, uses the standard option dictionary for this command (from 'self.command_options'). (Adopted from distutils.dist.Distribution._set_command_options) Nz# setting options for '%s' command:z %s = %s (from %s)cSrrr)rorrrrrz5Distribution._set_command_options..z1error in %s: command '%s' has no such option '%s')get_command_namer'rr roboolean_optionsrr+rrhr,rrwr r) r$ command_obj option_dict command_namersourcer6 bool_optsneg_opt is_stringrrrr_set_command_optionssJ          z!Distribution._set_command_optionsFcCs0|j|dt||j|d||dS)zYParses configuration files from various levels and loads configuration. )r-)ignore_option_errorsN)r6rr*rr)r$r-rNrrrparse_config_filess  zDistribution.parse_config_filescCs8tjjt||jdd}|D] }tjj|ddq|S)zResolve pre-setup requirementsT) installerreplace_conflicting)rY)rrresolverfetch_build_eggr)r$rIZresolved_distsrrrrfetch_build_eggs$szDistribution.fetch_build_eggscCsPd}dd}t|}t|j|}tdd|}t||dD]}||qdS)z Allow plugins to apply arbitrary operations to the distribution. Each hook may optionally define a 'order' to influence the order of execution. Smaller numbers go first and the default is 0. z(setuptools.finalize_distribution_optionscSs t|ddS)Norderr)r#)hookrrrby_order8s z/Distribution.finalize_options..by_ordercSs|Sr)load)rrrrr=sz/Distribution.finalize_options..)r]N)rrrr_removedrr )r$grouprWZdefinedfilteredZloadedrrrrfinalize_options/s  zDistribution.finalize_optionscCsdh}|j|vS)z When removing an entry point, if metadata is loaded from an older version of Setuptools, that removed entry point will attempt to be loaded and will fail. See #2765 for more details. Z 2to3_doctests)r?)rremovedrrrrYAs  zDistribution._removedcCsJtdD]}t||jd}|dur"|j|jd|||j|qdS)NrrP)rrr#r?requirerSrX)r$rr6rrr_finalize_setup_keywordsOsz%Distribution._finalize_setup_keywordscCstjtjd}tj|sDt|t|tj|d}t|d}| d| d| dWd|S1s?wY|S)Nz.eggsz README.txtwzcThis directory contains eggs that were downloaded by setuptools to build, test, and run plug-ins. zAThis directory caches those eggs to prevent repeated downloads. z/However, it is safe to delete this directory. ) r r r-curdirexistsmkdirrZ hide_filer#r\)r$Z egg_cache_dirZreadme_txt_filenamefrrrget_egg_cache_dirVs"        zDistribution.get_egg_cache_dircCsddlm}|||S)z Fetch an egg needed for buildingr)rS)Zsetuptools.installerrS)r$rrSrrrrSis  zDistribution.fetch_build_eggcCs\||jvr |j|Std|}|D]}|j|jd||j|<}|St||S)z(Pluggable version of get_command_class()r>r^)cmdclassrrr_rSrXrget_command_class)r$r9Zepsrrgrrrrhos    zDistribution.get_command_classcC:tdD]}|j|jvr|}||j|j<qt|SNr>)rrr?rgrRrprint_commandsr$rrgrrrrk|    zDistribution.print_commandscCrirj)rrr?rgrRrget_command_listrlrrrrnrmzDistribution.get_command_listcK@|D]\}}t|d|d}|r||q|||qdS)aAdd items to distribution that are named in keyword arguments For example, 'dist.include(py_modules=["x"])' would add 'x' to the distribution's 'py_modules' attribute, if it was not already there. Currently, this method only supports inclusion for attributes that are lists or tuples. If you need to add support for adding to other attributes in this or a subclass, you can add an '_include_X' method, where 'X' is the name of the attribute. The method will be called with the value passed to 'include()'. So, 'dist.include(foo={"bar":"baz"})' will try to call 'dist._include_foo({"bar":"baz"})', which can then handle whatever special inclusion logic is needed. Z _include_N)ror# _include_misc)r$rrrincluderrrrqs  zDistribution.includecsjd|jrfdd|jD|_|jr"fdd|jD|_|jr3fdd|jD|_dSdS)z9Remove packages, modules, and extensions in named packagerc"g|] }|kr|s|qSrr<rppackagepfxrrrz0Distribution.exclude_package..crrrrsrtrvrrrrycs&g|]}|jkr|js|qSr)r?r<rtrvrrrs N)packages py_modules ext_modules)r$rwrrvrexclude_packages    zDistribution.exclude_packagecCs2|d}|D]}||ks||rdSqdS)z.rsequencerr#rr,)r$r?r6oldrrrr _exclude_miscs"  zDistribution._exclude_miscc st|ts td||fzt||Wnty'}ztd||d}~wwdur4t|||dStts?t|dfdd|D}t|||dS)zAHandle 'include()' for list/tuple attrs without a special handlerz%s: setting must be a list (%r)rNrcrrrrrrrrrz.Distribution._include_misc..r)r$r?r6rnewrrrrps  zDistribution._include_misccKro)aRemove items from distribution that are named in keyword arguments For example, 'dist.exclude(py_modules=["x"])' would remove 'x' from the distribution's 'py_modules' attribute. Excluding packages uses the 'exclude_package()' method, so all of the package's contained packages, modules, and extensions are also excluded. Currently, this method only supports exclusion from attributes that are lists or tuples. If you need to add support for excluding from other attributes in this or a subclass, you can add an '_exclude_X' method, where 'X' is the name of the attribute. The method will be called with the value passed to 'exclude()'. So, 'dist.exclude(foo={"bar":"baz"})' will try to call 'dist._exclude_foo({"bar":"baz"})', which can then handle whatever special exclusion logic is needed. Z _exclude_N)ror#r)r$rrrexcluderrrrs  zDistribution.excludecCs,t|ts td|ftt|j|dS)Nz.packages: setting must be a list or tuple (%r))rrrrrr})r$rzrrr_exclude_packagess zDistribution._exclude_packagesc Cs|jj|_|jj|_|d}|d}||vr6||\}}||=ddl}||d|dd<|d}||vst|||}||} t | ddrWd|f||d<|durWgS|S)NraliasesTrZcommand_consumes_arguments command lineargs) __class__global_optionsr+r'shlexrRr_parse_command_optsrhr#) r$r/rr9rr4r5rnargs cmd_classrrrrs$      z Distribution._parse_command_optsc Csi}|jD]W\}}|D]N\}\}}|dkrq|dd}|dkrO||}|j}|t|di|D]\} } | |krI| }d}nq;tdn|dkrUd}|| |i|<qq|S) ahReturn a '{cmd: {opt:val}}' map of all command-line options Option names are all long, but do not include the leading '--', and contain dashes rather than underscores. If the option doesn't take an argument (e.g. '--quiet'), the 'val' is 'None'. Note that options provided by config files are intentionally excluded. rr8r7rr+NzShouldn't be able to get herer) r*rorYget_command_objr+copyupdater#rr) r$dcmdoptsr3r4rZZcmdobjrKnegposrrrget_cmdline_optionss.    z Distribution.get_cmdline_optionsccsx|jpdD]}|Vq|jpdD]}|Vq|jpdD]}t|tr(|\}}n|j}|dr6|dd}|VqdS)z@Yield all packages, modules, and extension names in distributionrmoduleNi)rzr{r|rrr?r )r$pkgrextr?Z buildinforrrr~Es    z$Distribution.iter_distribution_namesc Csddl}|jr t||St|jtjst||S|jj dvr(t||S|jj}|jj }|j dkr7dp8d}|jj }t|j d||||_zt||Wt|j |||||_St|j |||||_w)zIf there were any non-global "display-only" options (--help-commands or the metadata display options) on the command line, display the requested info and return true; else return false. rN)rutf8win32r)r)r help_commandsrhandle_display_optionsrstdoutr" TextIOWrapperrrerrorsrGline_bufferingdetach)r$ option_orderrrrnewlinerrrrrWs*     z#Distribution.handle_display_optionsr)NF)0r __module__ __qualname____doc__rrZ OrderedSetrrrrr staticmethodrrrrrrrrrr6r(r;r)rMrOrTr\rYr`rfrSrhrkrnrqr}rrrprrrrr~rrrrrrmsh4      O .      ( c@seZdZdZdS)rzrClass for warning about deprecations in dist in setuptools. Not ignored by default, unlike DeprecationWarning.N)rrrrrrrrr|sr)Vr:r"rrr rrZ distutils.logrdistutils.core distutils.cmddistutils.distdistutils.commanddistutils.utilrdistutils.debugrdistutils.fancy_getoptrglobrrr.typingrr r collectionsr emailr distutils.errorsr rrZdistutils.versionrZsetuptools.externrrZ setuptools.extern.more_itertoolsrrrrZsetuptools.commandrZsetuptools.monkeyrZsetuptools.configrr email.messager __import__r r&rhr1r7r8r;r>rWr[r~rrrrrrrrrrrrrrrrcorerrrrrrrs                - >    PKH]C o Ipython3.10/site-packages/setuptools/__pycache__/installer.cpython-310.pycnu[o Xai @spddlZddlZddlZddlZddlZddlmZddlmZddl Z ddl m Z ddZ ddZ d d ZdS) N)log)DistutilsError)WheelcCs(t|tr |St|ttfsJ|S)z8Ensure find-links option end-up being a list of strings.) isinstancestrsplittuplelist) find_linksr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/installer.py_fixup_find_links s r c Cs<ztdWntjy|dtjYnwt|}|d}d|vr*tddt j vo3dt j v}dt j vrs    CPKH] VQQFpython3.10/site-packages/setuptools/__pycache__/config.cpython-310.pycnu[o XaiSZ@sddlZddlZddlZddlZddlZddlZddlZddlmZddlm Z ddlm Z ddl m Z ddl Z ddlmZmZddlmZmZddlmZGd d d Ze jd d ZdddZddZddZdddZGdddZGdddeZGdddeZdS)N) defaultdict)partialwraps)iglob)DistutilsOptionErrorDistutilsFileError) LegacyVersionparse) SpecifierSetc@s eZdZdZddZddZdS) StaticModulez0 Attempt to load the module by the name cCs`tj|}t|j }|}Wdn1swYt|}t| t |` dSN) importlibutil find_specopenoriginreadastr varsupdatelocalsself)rnamespecstrmsrcmoduler/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/config.py__init__s    zStaticModule.__init__c sNztfdd|jjDWSty&}z tdjdit|d}~ww)Nc3sJ|] }t|tjr"|jD]}t|tjr!|jkr t|jVq qdSr ) isinstancerAssigntargetsNameid literal_evalvalue).0Z statementtargetattrrr #s    z+StaticModule.__getattr__..z#{self.name} has no attribute {attr}r)nextrbody ExceptionAttributeErrorformatr)rr+err*r __getattr__!s  zStaticModule.__getattr__N)__name__ __module__ __qualname____doc__r r3rrrrr s r c cs8ztjd|dVWtj|dStj|w)zH Add path to front of sys.path for the duration of the context. rN)syspathinsertremove)r9rrr patch_path0s r<Fc Csddlm}m}tj|}tj|std|t}t tj |z-|}|r1| ng}||vr<| ||j ||dt||j|d}Wt |t|St |w)a,Read given configuration file and returns options from it as a dict. :param str|unicode filepath: Path to configuration file to get options from. :param bool find_others: Whether to search for other configuration files which could be on in various places. :param bool ignore_option_errors: Whether to silently ignore options, values of which could not be resolved (e.g. due to exceptions in directives such as file:, attr:, etc.). If False exceptions are propagated as expected. :rtype: dict r) Distribution _Distributionz%Configuration file %s does not exist.) filenames)ignore_option_errors)Zsetuptools.distr=r>osr9abspathisfilergetcwdchdirdirnamefind_config_filesappendparse_config_filesparse_configurationcommand_optionsconfiguration_to_dict) filepathZ find_othersr@r=r>Zcurrent_directorydistr?handlersrrrread_configuration<s$      rPcCs2djdit}tt||}t|||}|S)z Given a target object and option key, get that option from the target object, either through a get_{key} method or from an attribute directly. z get_{key}Nr)r1r functoolsrgetattr) target_objkeyZ getter_nameZ by_attributegetterrrr _get_optionis rVcCs<tt}|D]}|jD]}t|j|}|||j|<q q|S)zReturns configuration data gathered by given handlers as a dict. :param list[ConfigHandler] handlers: Handlers list, usually from parse_configuration() :rtype: dict )rdict set_optionsrVrSsection_prefix)rOZ config_dicthandleroptionr'rrrrLus  rLcCs6t|||}|t|j|||j}|||fS)aPerforms additional parsing of configuration options for a distribution. Returns a list of used option handlers. :param Distribution distribution: :param dict command_options: :param bool ignore_option_errors: Whether to silently ignore options, values of which could not be resolved (e.g. due to exceptions in directives such as file:, attr:, etc.). If False exceptions are propagated as expected. :rtype: list )ConfigOptionsHandlerr ConfigMetadataHandlermetadata package_dir) distributionrKr@optionsmetarrrrJs rJc@seZdZdZdZ iZ d'ddZeddZdd Z e d(d d Z e d(d dZ e ddZ e ddZe ddZe ddZeddZeddZe d)ddZe ddZe d)dd Zd!d"Zd#d$Zd%d&ZdS)* ConfigHandlerz1Handles metadata supplied in configuration files.NFcCs^i}|j}|D]\}}||sq ||dd}|||<q ||_||_||_g|_dS)N.) rYitems startswithreplacestripr@rSsectionsrX)rrSrar@rjrY section_namesection_optionsrrrr s   zConfigHandler.__init__cCstd|jj).Metadata item name to parser function mapping.z!%s must provide .parsers property)NotImplementedError __class__r4)rrrrparserss zConfigHandler.parsersc Cst}|j}|j||}t|||}||urt||rdSd}|j|}|r?z||}Wnty>d}|js<Ynw|rCdSt|d|d}|durVt |||n|||j |dS)NFTzset_%s) tuplerSaliasesgetrRKeyErrorrpr/r@setattrrXrH) rZ option_namer'unknownrSZ current_valueZ skip_optionparsersetterrrr __setitem__s4    zConfigHandler.__setitem__,cCs8t|tr|Sd|vr|}n||}dd|DS)zRepresents value as a list. Value is split either by separator (defaults to comma) or by lines. :param value: :param separator: List items separator character. :rtype: list  cSsg|] }|r|qSr)ri)r(chunkrrr sz-ConfigHandler._parse_list..)r!list splitlinessplit)clsr' separatorrrr _parse_lists   zConfigHandler._parse_listc sjd}|j|d}g}|D]%tfdd|Dr-|tddttjDq |q |S)aEquivalent to _parse_list() but expands any glob patterns using glob(). However, unlike with glob() calls, the results remain relative paths. :param value: :param separator: List items separator character. :rtype: list )*?[]{}rc3s|]}|vVqdSr r)r(charr'rrr,sz1ConfigHandler._parse_list_glob..css"|] }tj|tVqdSr )rAr9relpathrDr(r9rrrr,s  ) ranyextendsortedrrAr9rBrH)rr'rZglob_charactersvaluesZexpanded_valuesrrr_parse_list_globs   zConfigHandler._parse_list_globcCsPd}i}||D]}||\}}}||krtd||||<q |S)zPRepresents value as a dict. :param value: :rtype: dict =z(Unable to parse option value to dict: %s)r partitionrri)rr'rresultlinerTsepvalrrr _parse_dict szConfigHandler._parse_dictcCs|}|dvS)zQRepresents value as boolean. :param value: :rtype: bool )1trueyes)lower)rr'rrr _parse_bool3szConfigHandler._parse_boolcfdd}|S)zReturns a parser function to make sure field inputs are not files. Parses a value after getting the key so error messages are more informative. :param key: :rtype: callable cs d}||rtd|S)Nfile:zCOnly strings are accepted for the {0} field, files are not accepted)rg ValueErrorr1)r'Zexclude_directiverTrrrwIs z3ConfigHandler._exclude_files_parser..parserr)rrTrwrrr_exclude_files_parser=s  z#ConfigHandler._exclude_files_parsercs\d}t|ts |S||s|S|t|d}dd|dD}dfdd|DS)aORepresents value as a string, allowing including text from nearest files using `file:` directive. Directive is sandboxed and won't reach anything outside directory with setup.py. Examples: file: README.rst, CHANGELOG.md, src/file.txt :param str value: :rtype: str rNcss |] }tj|VqdSr )rAr9rBrirrrrr,ksz,ConfigHandler._parse_file..rzr{c3s4|]}|s tj|r|VqdS)TN) _assert_localrAr9rC _read_filerrrrr,ls  )r!strrglenrjoin)rr'Zinclude_directiverZ filepathsrrr _parse_fileTs  zConfigHandler._parse_filecCs|ts td|dS)Nz#`file:` directive can not access %s)rgrArDr)rMrrrrrs zConfigHandler._assert_localcCs:tj|dd }|WdS1swYdS)Nzutf-8)encoding)iorr)rMfrrrrws$zConfigHandler._read_filec Cs0d}||s |S||dd}|}d|}|p d}t}|ra|d|vrR||d}|dd} t | dkrOtj t| d}| d}n|}nd|vratj t|d}t |&zt t ||WWdStyt|} YnwWdn1swYt | |S) zRepresents value as a module attribute. Examples: attr: package.attr attr: package.module.attr :param str value: :rtype: str zattr:rdrer r/N)rgrhrirpoprrArDrsplitrr9r<rRr r/r import_module) rr'r_Zattr_directiveZ attrs_path attr_name module_name parent_pathZ custom_pathpartsrrrr _parse_attr|s8          zConfigHandler._parse_attrcr)zReturns parser function to represents value as a list. Parses a value applying given methods one after another. :param parse_methods: :rtype: callable cs|}D]}||}q|Sr r)r'parsedmethod parse_methodsrrr s z1ConfigHandler._get_parser_compound..parser)rrr rrr_get_parser_compounds z"ConfigHandler._get_parser_compoundcCs6i}|pdd}|D] \}\}}||||<q |S)zParses section options into a dictionary. Optionally applies a given parser to values. :param dict section_options: :param callable values_parser: :rtype: dict cSs|Sr r)rrrrsz6ConfigHandler._parse_section_to_dict..)rf)rrlZ values_parserr'rT_rrrr_parse_section_to_dicts  z$ConfigHandler._parse_section_to_dictc Cs8|D]\}\}}z|||<WqtyYqwdS)zQParses configuration file section. :param dict section_options: N)rfrt)rrlrrr'rrr parse_sections  zConfigHandler.parse_sectioncCsb|jD])\}}d}|rd|}t|d|ddd}|dur*td|j|f||qdS)zTParses configuration file items from one or more related sections. rdz_%szparse_section%sre__Nz0Unsupported distribution option section: [%s.%s])rjrfrRrhrrY)rrkrlZmethod_postfixZsection_parser_methodrrrr s" zConfigHandler.parsecstfdd}|S)zthis function will wrap around parameters that are deprecated :param msg: deprecation message :param warning_class: class of warning exception to be raised :param func: function to be wrapped around cst|i|Sr )warningswarn)argskwargsfuncmsg warning_classrrconfig_handlers z@ConfigHandler._deprecated_config_handler..config_handlerr)rrrrrrrr_deprecated_config_handlersz(ConfigHandler._deprecated_config_handlerF)rzr )r4r5r6r7rYrrr propertyrpry classmethodrrrrrr staticmethodrrrrrrr rrrrrrcsF  &         -   rccsLeZdZdZdddddZdZ dfd d Zed d Zd dZ Z S)r]r^url description classifiers platforms)Z home_pagesummary classifierplatformFNcstt||||||_dSr )superr]r r_)rrSrar@r_rorrr s  zConfigMetadataHandler.__init__cCs^|j}|j}|j}|j}|||||dt|||||d||ddt||||j|d S)rmz[The requires parameter is deprecated, please use install_requires for runtime dependencies.license license_filezDThe license_file parameter is deprecated, use license_files instead.) rkeywordsprovidesrequires obsoletesrrrZ license_filesrlong_descriptionversionZ project_urls)rrrrrDeprecationWarningr_parse_version)r parse_listZ parse_file parse_dictZexclude_files_parserrrrrps4 zConfigMetadataHandler.parserscCs||}||kr#|}tt|tr!d}t|jdit|S|||j }t |r1|}t|t sIt |drEd tt |}|Sd|}|S)zSParses `version` option value. :param value: :rtype: str zCVersion loaded from {value} does not comply with PEP 440: {version}__iter__rez%sNr)rrir!r r rr1rrr_callablerhasattrrmap)rr'rtmplrrrr?s"   z$ConfigMetadataHandler._parse_version)FN) r4r5r6rYrrZ strict_moder rrpr __classcell__rrrrr]s !r]c@sdeZdZdZeddZddZddZdd Zd d Z d d Z ddZ ddZ ddZ ddZdS)r\racCsN|j}t|jdd}|j}|j}|j}|||||||||||j|j|t|dS)rm;r)Zzip_safeZinclude_package_datar_scriptsZeager_resourcesZdependency_linksZnamespace_packagesZinstall_requiresZsetup_requiresZ tests_requirepackages entry_points py_modulesZpython_requirescmdclass)rrrr_parse_cmdclass_parse_packagesrr )rrZparse_list_semicolonZ parse_boolrZparse_cmdclassrrrrpgs*zConfigOptionsHandler.parserscs$ddfdd||DS)NcSs8|d}||dd}|d|}t|}t||S)Nrer)rfind __import__rR)Zqualified_class_nameidx class_namepkg_namerrrr resolve_classs   z;ConfigOptionsHandler._parse_cmdclass..resolve_classcsi|] \}}||qSrrr(kvrrr sz8ConfigOptionsHandler._parse_cmdclass..)rrf)rr'rrrrs z$ConfigOptionsHandler._parse_cmdclasscCsnddg}|}||vr||S||dk}||jdi}|r*ddlm}nddlm}|d i|S) zTParses `packages` option value. :param value: :rtype: list zfind:zfind_namespace:rz packages.findr)find_namespace_packages) find_packagesNr)rirparse_section_packages__findrjrs setuptoolsrr)rr'Zfind_directivesZ trimmed_valueZfindns find_kwargsrrrrrs    z$ConfigOptionsHandler._parse_packagescsR|||j}gdtfdd|D}|d}|dur'|d|d<|S)zParses `packages.find` configuration file section. To be used in conjunction with _parse_packages(). :param dict section_options: )whereincludeexcludecs$g|]\}}|vr|r||fqSrrrZ valid_keysrrr}s$zEConfigOptionsHandler.parse_section_packages__find..rNr)rrrWrfrs)rrlZ section_datarrrrrrs  z1ConfigOptionsHandler.parse_section_packages__findcCs|||j}||d<dS)z`Parses `entry_points` configuration file section. :param dict section_options: rN)rrrrlrrrrparse_section_entry_pointss z/ConfigOptionsHandler.parse_section_entry_pointscCs.|||j}|d}|r||d<|d=|S)Nrrd)rrrs)rrlrrootrrr_parse_package_datas  z(ConfigOptionsHandler._parse_package_datacC|||d<dS)z`Parses `package_data` configuration file section. :param dict section_options: package_dataNr rrlrrrparse_section_package_dataz/ConfigOptionsHandler.parse_section_package_datacCr )zhParses `exclude_package_data` configuration file section. :param dict section_options: Zexclude_package_dataNrrrrr"parse_section_exclude_package_datarz7ConfigOptionsHandler.parse_section_exclude_package_datacCs"t|jdd}||||d<dS)zbParses `extras_require` configuration file section. :param dict section_options: rrZextras_requireN)rrr)rrlrrrrparse_section_extras_requires z1ConfigOptionsHandler.parse_section_extras_requirecCs(|||j}dd|D|d<dS)z^Parses `data_files` configuration file section. :param dict section_options: cSsg|]\}}||fqSrrrrrrr}szAConfigOptionsHandler.parse_section_data_files.. data_filesN)rrrfrrrrparse_section_data_filessz-ConfigOptionsHandler.parse_section_data_filesN)r4r5r6rYrrprrrr r rrrrrrrrr\cs    r\)FFr) rrrAr8rrQr collectionsrrrglobr contextlibdistutils.errorsrrZ#setuptools.extern.packaging.versionr r Z&setuptools.extern.packaging.specifiersr r contextmanagerr<rPrVrLrJrcr]r\rrrrs6       - c_PKH]iYYJpython3.10/site-packages/setuptools/__pycache__/namespaces.cpython-310.pycnu[o Xai @sFddlZddlmZddlZejjZGdddZGdddeZdS)N)logc@sXeZdZdZddZddZddZdZ d Z d d Z d d Z ddZ e ddZ dS) Installerz -nspkg.pthcCs|}|sdStj|\}}||j7}|j|t d|t |j |}|j r2t |dSt|d}||WddS1sHwYdS)Nz Installing %swt)_get_all_ns_packagesospathsplitext _get_target nspkg_extoutputsappendrinfomap_gen_nspkg_linedry_runlistopen writelines)selfnspfilenameextlinesfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/namespaces.pyinstall_namespaces s      "zInstaller.install_namespacescCsHtj|\}}||j7}tj|sdStd|t|dS)Nz Removing %s) rrrr r existsrr remove)rrrrrruninstall_namespacess    zInstaller.uninstall_namespacescC|jSN)targetrrrrr 'zInstaller._get_target) zimport sys, types, osz#has_mfs = sys.version_info > (3, 5)z$p = os.path.join(%(root)s, *%(pth)r)z4importlib = has_mfs and __import__('importlib.util')z-has_mfs and __import__('importlib.machinery')zm = has_mfs and sys.modules.setdefault(%(pkg)r, importlib.util.module_from_spec(importlib.machinery.PathFinder.find_spec(%(pkg)r, [os.path.dirname(p)])))zCm = m or sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))z7mp = (m or []) and m.__dict__.setdefault('__path__',[])z(p not in mp) and mp.append(p))z4m and setattr(sys.modules[%(parent)r], %(child)r, m)cCsdS)Nz$sys._getframe(1).f_locals['sitedir']rr#rrr _get_rootEszInstaller._get_rootcCsNt|d}|}|j}|d\}}}|r||j7}d|tdS)N.; )tuplesplitr% _nspkg_tmpl rpartition_nspkg_tmpl_multijoinlocals)rpkgpthrootZ tmpl_linesparentsepchildrrrrHs zInstaller._gen_nspkg_linecCs |jjpg}ttt|j|S)z,Return sorted list of all package namespaces) distributionZnamespace_packagessortedflattenr _pkg_names)rpkgsrrrrQs zInstaller._get_all_ns_packagesccs0|d}|rd|V||sdSdS)z Given a namespace package, yield the components of that package. >>> names = Installer._pkg_names('a.b.c') >>> set(names) == set(['a', 'a.b', 'a.b.c']) True r&N)r*r.pop)r0partsrrrr9Vs    zInstaller._pkg_namesN)__name__ __module__ __qualname__r rrr r+r-r%rr staticmethodr9rrrrr s rc@seZdZddZddZdS)DevelopInstallercCstt|jSr!)reprstrZegg_pathr#rrrr%gszDevelopInstaller._get_rootcCr r!)egg_linkr#rrrr jr$zDevelopInstaller._get_targetN)r=r>r?r%r rrrrrAfs rA) r distutilsr itertoolschain from_iterabler8rrArrrrs  ]PKH]^Of"f"Hpython3.10/site-packages/setuptools/__pycache__/__init__.cpython-310.pycnu[o Xai@sFdZddlmZddlZddlZddlZddlZddlZddl Z ddl m Z ddl mZddlmZddlZddlmZdd lmZdd lmZdd lmZgd ZejjZdZGd ddZGdddeZ ej!Z"e j!Z#ddZ$ddZ%e j&j%je%_e'e j&j(Z)Gddde)Z(ddZ*ej+fddZ,Gddde-Z.e/dS)z@Extensions to the 'distutils' for large or complex distributions fnmatchcaseN)DistutilsOptionError) convert_path)SetuptoolsDeprecationWarning) Extension) Distribution)Require)monkey)setupr Commandrr r find_packagesfind_namespace_packagesc@sBeZdZdZedddZeddZed d Zed d Z d S) PackageFinderzI Generate a list of all Python packages found within a directory .*cCs,t|t||jddg|R|j|S)a Return a list all Python packages found within directory 'where' 'where' is the root directory which will be searched for packages. It should be supplied as a "cross-platform" (i.e. URL-style) path; it will be converted to the appropriate local path syntax. 'exclude' is a sequence of package names to exclude; '*' can be used as a wildcard in the names, such that 'foo.*' will exclude all subpackages of 'foo' (but not 'foo' itself). 'include' is a sequence of package names to include. If it's specified, only the named packages will be included. If it's not specified, all found packages will be included. 'include' can contain shell style wildcard patterns just like 'exclude'. Zez_setupz *__pycache__)list_find_packages_iterr _build_filter)clswhereexcludeincluderr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/__init__.pyfind-szPackageFinder.findc cstj|ddD]F\}}}|dd}g|dd<|D]2}tj||} tj| |} | tjjd} d|vs<|| s=q|| rH|| sH| V||qqdS)zy All the packages found in 'where' that pass the 'include' filter, but not the 'exclude' filter. T followlinksNr) oswalkpathjoinrelpathreplacesep_looks_like_packageappend) rrrrrootdirsfilesZall_dirsdir full_pathrel_pathpackagerrrrGs   z!PackageFinder._find_packages_itercCstjtj|dS)z%Does a directory look like a package?z __init__.py)r r"isfiler#r"rrrr'csz!PackageFinder._looks_like_packagecs fddS)z Given a list of patterns, return a callable that will be true only if the input matches at least one of the patterns. cstfddDS)Nc3s|] }t|dVqdS))patNr).0r2namerr nsz@PackageFinder._build_filter....)anyr4patternsr4rnz-PackageFinder._build_filter..rr8rr8rrhs zPackageFinder._build_filterN)rrr) __name__ __module__ __qualname____doc__ classmethodrr staticmethodr'rrrrrr(s   rc@seZdZeddZdS)PEP420PackageFindercCdS)NTrr1rrrr'rsz'PEP420PackageFinder._looks_like_packageN)r<r=r>rAr'rrrrrBqsrBcCsNGdddtjj}||}|jdd|jr%tdt||jdSdS)Nc@s eZdZdZddZddZdS)z4_install_setup_requires..MinimalDistributionzl A minimal version of a distribution for supporting the fetch_build_eggs interface. cs6d}fddt|t@D}tjj||dS)N)Zdependency_linkssetup_requirescsi|]}||qSrr)r3kattrsrr r;zQ_install_setup_requires..MinimalDistribution.__init__..)set distutilscorer __init__)selfrGZ_inclfilteredrrFrrLsz=_install_setup_requires..MinimalDistribution.__init__cSrC)zl Disable finalize_options to avoid building the working set. Ref #2158. Nr)rMrrrfinalize_optionsszE_install_setup_requires..MinimalDistribution.finalize_optionsN)r<r=r>r?rLrOrrrrMinimalDistribution~s rPT)Zignore_option_errorszdsetup_requires is deprecated. Supply build dependencies using PEP 517 pyproject.toml build-requires.) rJrKr parse_config_filesrDwarningswarnrZfetch_build_eggs)rGrPdistrrr_install_setup_requires{s rUcKst|tjjdi|S)Nr)rUrJrKr rFrrrr sr c@s:eZdZejZdZddZd ddZddZd d d Z dS)r FcKst||t||dS)zj Construct the command for dist, updating vars(self) with any keyword parameters. N)_CommandrLvarsupdate)rMrTkwrrrrLs zCommand.__init__NcCsBt||}|durt||||St|tstd|||f|S)Nz'%s' must be a %s (got `%s`))getattrsetattr isinstancestrr)rMoptionwhatdefaultvalrrr_ensure_stringlikes    zCommand._ensure_stringlikecCsrt||}|dur dSt|trt||td|dSt|tr+tdd|D}nd}|s7td||fdS)zEnsure that 'option' is a list of strings. If 'option' is currently a string, we split it either on /,\s*/ or /\s+/, so "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become ["foo", "bar", "baz"]. Nz,\s*|\s+css|]}t|tVqdSN)r\r])r3vrrrr6sz-Command.ensure_string_list..Fz''%s' must be a list of strings (got %r)) rZr\r]r[resplitrallr)rMr^raokrrrensure_string_lists    zCommand.ensure_string_listrcKs t|||}t|||Src)rVreinitialize_commandrWrX)rMcommandreinit_subcommandsrYcmdrrrrjszCommand.reinitialize_commandrc)r) r<r=r>rVr?Zcommand_consumes_argumentsrLrbrirjrrrrr s  r cCs&ddtj|ddD}ttjj|S)z% Find all files under 'path' css.|]\}}}|D] }tj||Vq qdSrc)r r"r#)r3baser*r+filerrrr6s z#_find_all_simple..Tr)r r!filterr"r0)r"resultsrrr_find_all_simples rrcCs6t|}|tjkrtjtjj|d}t||}t|S)z Find all files under 'dir' and return the list of full filenames. Unless dir is '.', return full filenames with dir prepended. )start) rrr curdir functoolspartialr"r$mapr)r,r+Zmake_relrrrfindalls   rxc@seZdZdZdS)sicz;Treat this string as-is (https://en.wikipedia.org/wiki/Sic)N)r<r=r>r?rrrrrysry)0r?fnmatchrrur rerRZ_distutils_hack.overrideZ_distutils_hackdistutils.corerJdistutils.errorsrdistutils.utilrZ_deprecation_warningrZsetuptools.version setuptoolsZsetuptools.extensionrZsetuptools.distr Zsetuptools.dependsr r __all__version __version__Zbootstrap_install_fromrrBrrrrUr rKZ get_unpatchedr rVrrrtrxr]ryZ patch_allrrrrs@         I! 3  PKH]Ur+RRFpython3.10/site-packages/setuptools/__pycache__/monkey.cpython-310.pycnu[o Xaia@sdZddlZddlZddlZddlZddlZddlmZddl Z ddl Z gZ ddZ ddZ dd Zd d Zd d ZddZddZddZdS)z Monkey patching of distutils. N) import_modulecCs"tdkr |f|jSt|S)am Returns the bases classes for cls sorted by the MRO. Works around an issue on Jython where inspect.getmro will not return all base classes if multiple classes share the same name. Instead, this function will return a tuple containing the class itself, and the contents of cls.__bases__. See https://github.com/pypa/setuptools/issues/1024. Jython)platformpython_implementation __bases__inspectgetmro)clsr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/monkey.py_get_mros  r cCs.t|trtn t|tjrtndd}||S)NcSsdS)Nr )itemr r r (szget_unpatched..) isinstancetypeget_unpatched_classtypes FunctionTypeget_unpatched_function)r lookupr r r get_unpatched$s rcCs:ddt|D}t|}|jdsd|}t||S)zProtect against re-patching the distutils if reloaded Also ensures that no other distutils extension monkeypatched the distutils first. css |] }|jds|VqdS) setuptoolsN) __module__ startswith).0r r r r 3s  z&get_unpatched_class.. distutilsz(distutils has already been patched by %r)r nextrrAssertionError)r Zexternal_basesbasemsgr r r r-s rcCstjtj_tjdk}|rtjtj_tjdkp/dtjko dknp/dtjko-dkn}|r9d}|tjj _ t tj tjtj fD]}tj j|_qDtjjtj_tjjtj_dtjvretjjtjd_tdS)N)r!) )r!)r!r&)r!r"zhttps://upload.pypi.org/legacy/zdistutils.command.build_ext)rCommandrcoresys version_infofindallfilelistconfig PyPIRCCommandDEFAULT_REPOSITORY_patch_distribution_metadatadistcmd Distribution extension Extensionmodules#patch_for_msvc_specialized_compiler)Zhas_issue_12885Zneeds_warehouseZ warehousemoduler r r patch_all?s*          r:cCs*dD]}ttj|}ttjj||qdS)zDPatch write_pkg_file and read_pkg_file for higher metadata standards)write_pkg_file read_pkg_fileZget_metadata_versionN)getattrrr2setattrrDistributionMetadata)attrnew_valr r r r1fs r1cCs*t||}t|d|t|||dS)z Patch func_name in target_mod with replacement Important - original must be resolved by name to avoid patching an already patched function. unpatchedN)r=vars setdefaultr>) replacementZ target_mod func_nameoriginalr r r patch_funcms rHcCs t|dS)NrB)r=) candidater r r r~s rcstdtdkr dSfdd}t|d}t|d}zt|dt|d Wn ty5Ynwzt|d Wn tyGYnwz t|d WdSty[YdSw) z\ Patch functions in distutils to use standalone Microsoft Visual C++ compilers. zsetuptools.msvcWindowsNcsLd|vrdnd}||d}t|}t|}t||s!t||||fS)zT Prepare the parameters for patch_func to patch indicated function. msvc9Zmsvc9_Zmsvc14__)lstripr=rhasattr ImportError)mod_namerFZ repl_prefixZ repl_namereplmodZmsvcr r patch_paramss   z9patch_for_msvc_specialized_compiler..patch_paramszdistutils.msvc9compilerzdistutils._msvccompilerZfind_vcvarsallZquery_vcvarsallZ _get_vc_envZgen_lib_options)rrsystem functoolspartialrHrO)rTrKZmsvc14r rSr r8s,       r8)__doc__r*distutils.filelistrrrrV importlibrrr__all__r rrr:r1rHrr8r r r r s&  ' PKH]3%k488Opython3.10/site-packages/setuptools/__pycache__/windows_support.cpython-310.pycnu[o Xai@s(ddlZddlZddZeddZdS)NcCstdkr ddS|S)NWindowsc_sdS)N)argskwargsrr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/windows_support.pyszwindows_only..)platformsystem)funcrrr windows_onlys r cCsLtdtjjj}tjjtjjf|_tjj |_ d}|||}|s$t dS)z Set the hidden attribute on a file or directory. From http://stackoverflow.com/questions/19622133/ `path` must be text. zctypes.wintypesN) __import__ctypeswindllZkernel32ZSetFileAttributesWZwintypesZLPWSTRZDWORDargtypesZBOOLrestypeZWinError)pathZSetFileAttributesFILE_ATTRIBUTE_HIDDENretrrr hide_file s   r)rrr rrrrrs PKH]A|=fFpython3.10/site-packages/setuptools/__pycache__/launch.cpython-310.pycnu[o Xai,@s2dZddlZddlZddZedkredSdS)z[ Launch the Python script on the command line after setuptools is bootstrapped via import. NcCsttjd}t|ddd}tjddtjdd<ttdt}|| }|}Wdn1s3wY|dd}t ||d}t ||dS) zP Run the script in sys.argv[1] as if it had been invoked naturally. __main__N)__file____name____doc__openz\r\nz\nexec) __builtins__sysargvdictgetattrtokenizerreadreplacecompiler) script_name namespaceopen_ZfidscriptZ norm_scriptcoder/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/launch.pyrun s      rr)rrr rrrrrrs PKH]XL Mpython3.10/site-packages/setuptools/__pycache__/unicode_utils.cpython-310.pycnu[o Xai@s,ddlZddlZddZddZddZdS)NcCsRt|tr td|Sz|d}td|}|d}W|Sty(Y|Sw)NZNFDutf-8) isinstancestr unicodedata normalizedecodeencode UnicodeError)pathr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/unicode_utils.py decomposes      r c CsRt|tr|Stp d}|df}|D]}z||WSty&YqwdS)zY Ensure that the given path is decoded, NONE when no expected encoding works rN)rrsysgetfilesystemencodingrUnicodeDecodeError)r Zfs_enc candidatesencr r r filesys_decodes   rcCs"z||WStyYdSw)z/turn unicode encoding into a functional routineN)rUnicodeEncodeError)stringrr r r try_encode%s   r)rrr rrr r r r s  PKH]Gpython3.10/site-packages/setuptools/__pycache__/depends.cpython-310.pycnu[o Xaib@sddlZddlZddlZddlZddlmZddlmZmZm Z m Z ddl mZgdZ GdddZ d d Zdd d ZdddZddZedS)N) StrictVersion) find_module PY_COMPILED PY_FROZEN PY_SOURCE)_imp)Requirerget_module_constantextract_constantc@sLeZdZdZ  dddZddZdd Zdd d Zdd dZdddZ dS)r z7A prerequisite to building or installing a distributionNcCsF|dur |dur t}|dur||}|durd}|jt|`dS)N __version__)r__dict__updatelocalsself)rnamerequested_versionmoduleZhomepage attributeformatr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/depends.py__init__szRequire.__init__cCs |jdur d|j|jfS|jS)z0Return full package/distribution name, w/versionNz%s-%s)rr)rrrr full_name"s zRequire.full_namecCs*|jdup|jdupt|dko||jkS)z%Is 'version' sufficiently up-to-date?Nunknown)rrstrr)rversionrrr version_ok(szRequire.version_okrcCs~|jdur"zt|j|\}}}|r||WSty!YdSwt|j|j||}|dur=||ur=|jdur=||S|S)aGet version number of installed module, 'None', or 'default' Search 'paths' for module. If not found, return 'None'. If found, return the extracted version attribute, or 'default' if no version attribute was specified, or the value cannot be determined without importing the module. The version is formatted according to the requirement's version format (if any), unless it is 'None' or the supplied 'default'. N)rrrclose ImportErrorr r)rpathsdefaultfpivrrr get_version-s   zRequire.get_versioncCs||duS)z/Return true if dependency is present on 'paths'N)r')rr!rrr is_presentHszRequire.is_presentcCs ||}|dur dS||S)z>Return true if dependency is present and up-to-date on 'paths'NF)r'r)rr!rrrr is_currentLs  zRequire.is_current)r NN)NrN) __name__ __module__ __qualname____doc__rrrr'r(r)rrrrr s   r cCs"tjdd}|s |St|S)Ncss dVdSr*rrrrremptyUszmaybe_close..empty) contextlibcontextmanagerclosing)r#r/rrr maybe_closeTs   r3c Cszt||\}}\}}}} Wn tyYdSwt|C|tkr.|dt|} n,|tkr9t ||} n!|t krFt ||d} nt ||| } t | |dWdSWdn1sdwYt| ||S)zFind 'module' by searching 'paths', and extract 'symbol' Return 'None' if 'module' does not exist on 'paths', or it does not define 'symbol'. If the module defines 'symbol' as a constant, return the constant. Otherwise, return 'default'.Nexec)rr r3rreadmarshalloadrrget_frozen_objectrcompileZ get_modulegetattrr ) rsymbolr"r!r#pathsuffixmodekindinfocodeZimportedrrrr _s&      r c Cs||jvrdSt|j|}d}d}d}|}t|D]$}|j} |j} | |kr.|j| }q| |kr>| |ks:| |kr>|S|}qdS)aExtract the constant value of 'symbol' from 'code' If the name 'symbol' is bound to a constant value by the Python code object 'code', return that value. If 'symbol' is bound to an expression, return 'default'. Otherwise, return 'None'. Return value is based on the first assignment to 'symbol'. 'symbol' must be a global, or at least a non-"fast" local in the code block. That is, only 'STORE_NAME' and 'STORE_GLOBAL' opcodes are checked, and 'symbol' must be present in 'code.co_names'. NZad)co_nameslistindexdisBytecodeopcodearg co_consts) rCr=r"Zname_idx STORE_NAME STORE_GLOBAL LOAD_CONSTconstZ byte_codeoprMrrrr |s  r cCs>tjds tjdkr dSd}|D] }t|=t|qdS)z Patch the globals to remove the objects not available on some platforms. XXX it'd be better to test assertions about bytecode instead. javacliN)r r )sysplatform startswithglobals__all__remove)Z incompatiblerrrr_update_globalss r\)r4N)r4)rVr8r0rJZdistutils.versionrrrrrrr rZr r3r r r\rrrrs  D $ PKH],  Lpython3.10/site-packages/setuptools/__pycache__/archive_util.cpython-310.pycnu[o Xai@sdZddlZddlZddlZddlZddlZddlZddlmZddl m Z gdZ GdddeZ dd Z e dfd d Ze fd d Ze fddZddZddZe fddZeeefZdS)z/Utilities for extracting common archive formatsN)DistutilsError)ensure_directory)unpack_archiveunpack_zipfileunpack_tarfiledefault_filterUnrecognizedFormatextraction_driversunpack_directoryc@seZdZdZdS)rz#Couldn't recognize the archive typeN)__name__ __module__ __qualname____doc__rr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/archive_util.pyrsrcCs|S)z@The default progress/filter callback; returns True for all filesr)srcdstrrrrsrc Cs@|ptD]}z ||||WdStyYqwtd|)aUnpack `filename` to `extract_dir`, or raise ``UnrecognizedFormat`` `progress_filter` is a function taking two arguments: a source path internal to the archive ('/'-separated), and a filesystem path where it will be extracted. The callback must return the desired extract path (which may be the same as the one passed in), or else ``None`` to skip that file or directory. The callback can thus be used to report on the progress of the extraction, as well as to filter the items extracted or alter their extraction paths. `drivers`, if supplied, must be a non-empty sequence of functions with the same signature as this function (minus the `drivers` argument), that raise ``UnrecognizedFormat`` if they do not support extracting the designated archive type. The `drivers` are tried in sequence until one is found that does not raise an error, or until all are exhausted (in which case ``UnrecognizedFormat`` is raised). If you do not supply a sequence of drivers, the module's ``extraction_drivers`` constant will be used, which means that ``unpack_zipfile`` and ``unpack_tarfile`` will be tried, in that order. Nz!Not a recognized archive type: %s)r r)filename extract_dirprogress_filterZdriversZdriverrrrrs  rc Cstj|s td||d|fi}t|D]Q\}}}||\}}|D]} || dtj|| f|tj|| <q$|D]*} tj|| } ||| | } | sPq=t| tj|| } t| | t | | q=qdS)z"Unpack" a directory, using the same interface as for archives Raises ``UnrecognizedFormat`` if `filename` is not a directory z%s is not a directory/N) ospathisdirrwalkjoinrshutilcopyfilecopystat) rrrpathsbasedirsfilesrrdftargetrrrr @s&   * r c Cst|s td|ft|p}|D]b}|j}|ds'd|dvr(qtj j |g|dR}|||}|s=q| drGt |n$t || |j}t|d }||Wdn1sfwY|jd?} | rxt|| qWddS1swYdS)zUnpack zip `filename` to `extract_dir` Raises ``UnrecognizedFormat`` if `filename` is not a zipfile (as determined by ``zipfile.is_zipfile()``). See ``unpack_archive()`` for an explanation of the `progress_filter` argument. z%s is not a zip filer..wbN)zipfile is_zipfilerZipFileinfolistr startswithsplitrrrendswithrreadopenwrite external_attrchmod) rrrzinfonamer&datar%Zunix_attributesrrrr[s0           "rcCs|dur5|s |r5|j}|r$t|j}t||}t|}||}|dur5|s |s |duo@| p@| }|rE|St d)z;Resolve any links and extract link targets as normal files.NzGot unknown file type) islnkissymlinkname posixpathdirnamer8rnormpath _getmemberisfiler LookupError)tar_objZtar_member_objlinkpathr!Zis_file_or_dirrrr_resolve_tar_file_or_dirs,     rEc csdd|_t|U|D]I}|j}|dsd|dvr qtjj|g|dR}zt ||}Wn t y=Yqw|||}|sFq| tj rR|dd}||fVqWddS1scwYdS)z1Emit member-destination pairs from a tar archive.cWsdS)Nr)argsrrrsz _iter_open_tar..rr'N) chown contextlibclosingr8r.r/rrrrErBr0sep)rCrrmemberr8Z prelim_dst final_dstrrr_iter_open_tars*       "rOc Csxzt|}Wntjy}ztd|f|d}~wwt|||D]\}}z|||Wq#tjy9Yq#wdS)zUnpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` Raises ``UnrecognizedFormat`` if `filename` is not a tarfile (as determined by ``tarfile.open()``). See ``unpack_archive()`` for an explanation of the `progress_filter` argument. z/%s is not a compressed or uncompressed tar fileNT)tarfiler2TarErrorrrO_extract_member ExtractError)rrrtarobjerMrNrrrrs& r)rr*rPrrr=rJdistutils.errorsr pkg_resourcesr__all__rrrr rrErOrr rrrrs*   $ % PKH]Cc]]Tpython3.10/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-310.pycnu[o Xai@sGdddeZdS)c@seZdZdZdS)SetuptoolsDeprecationWarningz Base class for warning deprecations in ``setuptools`` This class is not derived from ``DeprecationWarning``, and as such is visible by default. N)__name__ __module__ __qualname____doc__rr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_deprecation_warning.pyrsrN)WarningrrrrrsPKH][Dpython3.10/site-packages/setuptools/__pycache__/glob.cpython-310.pycnu[o Xai @sdZddlZddlZddlZgdZdddZdddZd d Zd d Zd dZ ddZ ddZ e dZ e dZddZddZddZdS)z Filename globbing utility. Mostly a copy of `glob` from Python 3.5. Changes include: * `yield from` and PEP3102 `*` removed. * Hidden files are not ignored. N)globiglobescapeFcCstt||dS)ayReturn a list of paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la fnmatch. However, unlike fnmatch, filenames starting with a dot are special cases that are not matched by '*' and '?' patterns. If recursive is true, the pattern '**' will match any files and zero or more directories and subdirectories. ) recursive)listr)pathnamerr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/glob.pyrs rcCs*t||}|rt|rt|}|rJ|S)aReturn an iterator which yields the paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la fnmatch. However, unlike fnmatch, filenames starting with a dot are special cases that are not matched by '*' and '?' patterns. If recursive is true, the pattern '**' will match any files and zero or more directories and subdirectories. )_iglob _isrecursivenext)rritsrrr rs rccstj|\}}|rt|rtnt}t|s/|r$tj|r"|VdStj|r-|VdS|s;|||EdHdS||krIt|rIt ||}n|g}t|sRt }|D]}|||D] }tj ||Vq[qTdSN) ospathsplitr glob2glob1 has_magiclexistsisdirr glob0join)rrdirnamebasename glob_in_dirdirsnamerrr r 0s0   r cCsT|st|trtjd}ntj}zt|}Wn ty#gYSwt||SNASCII) isinstancebytesrcurdirencodelistdirOSErrorfnmatchfilter)rpatternnamesrrr rTs   rcCs:|s tj|r |gSgStjtj||r|gSgSr)rrrrr)rrrrr ras rccs4t|sJ|ddVt|D]}|VqdS)Nr)r _rlistdir)rr)xrrr rqs   rccs|st|trtjd}ntj}zt|}Wn tjy$YdSw|D]}|V|r5tj||n|}t |D] }tj||Vq;q'dSr) r!r"rr#r$r%errorrrr+)rr*r,ryrrr r+ys"  r+z([*?[])s([*?[])cCs.t|trt|}|duSt|}|duSr)r!r"magic_check_bytessearch magic_check)rmatchrrr rs   rcCst|tr |dkS|dkS)Ns**z**)r!r")r)rrr r s r cCsBtj|\}}t|trtd|}||Std|}||S)z#Escape all special characters. s[\1]z[\1])rr splitdriver!r"r/subr1)rdriverrr rs    r)F)__doc__rrer'__all__rrr rrrr+compiler1r/rr rrrrr s"  $    PKH]rmƦƦDpython3.10/site-packages/setuptools/__pycache__/msvc.cpython-310.pycnu[o Xai@sdZddlZddlmZddlmZmZddlmZm Z m Z m Z ddl Z ddl Z ddlZddlZddlZddlZddlmZddlmZdd lmZed kr[ddlZdd lmZn Gd d d ZeZeejjfZ zddl!m"Z"Wn e y|YnwddZ#d/ddZ$ddZ%ddZ&dddddZ'ddZ(ddZ)d d!Z*d"d#Z+d0d%d&Z,Gd'd(d(Z-Gd)d*d*Z.Gd+d,d,Z/Gd-d.d.Z0dS)1a Improved support for Microsoft Visual C++ compilers. Known supported compilers: -------------------------- Microsoft Visual C++ 9.0: Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64) Microsoft Windows SDK 6.1 (x86, x64, ia64) Microsoft Windows SDK 7.0 (x86, x64, ia64) Microsoft Visual C++ 10.0: Microsoft Windows SDK 7.1 (x86, x64, ia64) Microsoft Visual C++ 14.X: Microsoft Visual C++ Build Tools 2015 (x86, x64, arm) Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64) Microsoft Visual Studio Build Tools 2019 (x86, x64, arm, arm64) This may also support compilers shipped with compatible Visual Studio versions. N)open)listdirpathsep)joinisfileisdirdirname) LegacyVersion)unique_everseen) get_unpatchedWindows)environc@seZdZdZdZdZdZdS)winregN)__name__ __module__ __qualname__ HKEY_USERSHKEY_CURRENT_USERHKEY_LOCAL_MACHINEHKEY_CLASSES_ROOTrr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/msvc.pyr+s r)Regc Csd}|d|f}zt|d}Wn#ty3z|d|f}t|d}Wn ty0d}YnwYnw|rAt|d}t|rA|Stt|S)a Patched "distutils.msvc9compiler.find_vcvarsall" to use the standalone compiler build for Python (VCForPython / Microsoft Visual C++ Compiler for Python 2.7). Fall back to original behavior when the standalone compiler is not available. Redirect the path of "vcvarsall.bat". Parameters ---------- version: float Required Microsoft Visual C++ version. Return ------ str vcvarsall.bat path z-Software\%sMicrosoft\DevDiv\VCForPython\%0.1f installdirz Wow6432Node\N vcvarsall.bat)r get_valueKeyErrorrrr msvc9_find_vcvarsall)versionZvc_basekey productdir vcvarsallrrrrBs$      rx86c Osztt}|||g|Ri|WStjjyYn ty$Ynwzt||WStjjyB}zt|||d}~ww)ao Patched "distutils.msvc9compiler.query_vcvarsall" for support extra Microsoft Visual C++ 9.0 and 10.0 compilers. Set environment without use of "vcvarsall.bat". Parameters ---------- ver: float Required Microsoft Visual C++ version. arch: str Target architecture. Return ------ dict environment N) r msvc9_query_vcvarsall distutilserrorsDistutilsPlatformError ValueErrorEnvironmentInfo return_env_augment_exception)verarchargskwargsorigexcrrrr%ls  r%c CszttjddtjtjB}Wn tyYdSwd}d}|^tD]D}z t||\}}}Wn ty<Yn8w|ri|tj krit |rizt t |}Wn t tfy[Yq%w|dkri||kri||}}q%Wd||fSWd||fS1swY||fS)0Python 3.8 "distutils/_msvccompiler.py" backportz'Software\Microsoft\VisualStudio\SxS\VC7rNNN)rOpenKeyrKEY_READZKEY_WOW64_32KEYOSError itertoolscount EnumValueREG_SZrintfloatr) TypeError)r! best_versionbest_dirivZvc_dirZvtr rrr_msvc14_find_vc2015sH          rDcCstdp td}|sdSztt|dddddd d d d d d dddg jddd}Wntjtt fy;YdSwt|ddd}t |rKd|fSdS)aPython 3.8 "distutils/_msvccompiler.py" backport Returns "15, path" based on the result of invoking vswhere.exe If no install is found, returns "None, None" The version is returned to avoid unnecessarily changing the function result. It may be ignored when the path is not None. If vswhere.exe is not available, by definition, VS 2017 is not installed. ProgramFiles(x86) ProgramFilesr4zMicrosoft Visual StudioZ Installerz vswhere.exez-latestz -prereleasez -requiresAnyz -requiresz1Microsoft.VisualStudio.Component.VC.Tools.x86.x64z)Microsoft.VisualStudio.Workload.WDExpressz -propertyinstallationPathz -products*mbcsstrict)encodingr'VCZ AuxiliaryZBuild) rget subprocess check_outputrdecodestripCalledProcessErrorr8UnicodeDecodeErrorr)rootpathrrr_msvc14_find_vc2017s2     rWx64armarm64)r$Z x86_amd64Zx86_armZ x86_arm64c Cst\}}d}|tvrt|}nd|vrdnd}|rDt|ddddd|d d }zd dl}|j|d d d}WntttfyCd}Ynw|sUt\}}|rUt|d|dd }|sYdSt|d}t|sddS|rjt|sld}||fS)r3Namd64rXr$z..redistZMSVCz**zMicrosoft.VC14*.CRTzvcruntime140.dllrT) recursivezMicrosoft.VC140.CRTr4r) rWPLAT_SPEC_TO_RUNTIMErglob ImportErrorr8 LookupErrorrDr) plat_spec_rA vcruntimeZvcruntime_platZvcredistr`r@r#rrr_msvc14_find_vcvarsalls<     rfc Csdtvr ddtDSt|\}}|stjdztjd||tj dj ddd }Wntj yF}z tjd |j |d }~wwd dd d| DD}|r[||d<|S)r3ZDISTUTILS_USE_SDKcSsi|] \}}||qSrlower).0r!valuerrr sz&_msvc14_get_vc_env..zUnable to find vcvarsall.batzcmd /u /c "{}" {} && set)stderrzutf-16lereplace)r'zError executing {}NcSs$i|]\}}}|r|r||qSrrg)rir!rdrjrrrrkscss|]}|dVqdS)=N) partition)rilinerrr sz%_msvc14_get_vc_env..py_vcruntime_redist)ritemsrfr&r'r(rOrPformatSTDOUTrQrScmd splitlines)rcr#reoutr2envrrr_msvc14_get_vc_envs<    rzc Cs4zt|WStjjy}zt|dd}~ww)a* Patched "distutils._msvccompiler._get_vc_env" for support extra Microsoft Visual C++ 14.X compilers. Set environment without use of "vcvarsall.bat". Parameters ---------- plat_spec: str Target architecture. Return ------ dict environment ,@N)rzr&r'r(r,)rcr2rrrmsvc14_get_vc_env(s  r|cOsJdtjvrddl}t|jtdkr|jjj|i|Stt |i|S)z Patched "distutils._msvccompiler.gen_lib_options" for fix compatibility between "numpy.distutils" and "distutils._msvccompiler" (for Numpy < 1.11.2) znumpy.distutilsrNz1.11.2) sysmodulesZnumpyr __version__r&Z ccompilerZgen_lib_optionsr msvc14_gen_lib_options)r/r0nprrrrBs rrcCs|jd}d|vsd|vrLd}|jdit}d}|dkr5|ddkr0|d 7}n|d 7}n|d krD|d 7}||d 7}n|dkrL|d7}|f|_dS)zl Add details to the exception message to help guide the user as to what action will resolve it. rr#zvisual cz;Microsoft Visual C++ {version:0.1f} or greater is required.z-www.microsoft.com/download/details.aspx?id=%d"@Zia64r^z( Get it with "Microsoft Windows SDK 7.0"z% Get it from http://aka.ms/vcpython27$@z* Get it with "Microsoft Windows SDK 7.1": iW r{zd Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/Nr)r/rhrtlocalsfind)r2r r.messagetmplZ msdownloadrrrr,Os    r,c@sbeZdZdZeddZddZe ddZ dd Z d d Z dd dZ dddZdddZdS) PlatformInfoz Current and Target Architectures information. Parameters ---------- arch: str Target architecture. Zprocessor_architecturercCs|dd|_dS)NrXr[)rhrmr.)selfr.rrr__init__szPlatformInfo.__init__cCs|j|jdddS)zs Return Target CPU architecture. Return ------ str Target CPU rdr N)r.rrrrr target_cpus zPlatformInfo.target_cpucC |jdkS)z Return True if target CPU is x86 32 bits.. Return ------ bool CPU is x86 32 bits r$rrrrr target_is_x86 zPlatformInfo.target_is_x86cCr)z Return True if current CPU is x86 32 bits.. Return ------ bool CPU is x86 32 bits r$ current_cpurrrrcurrent_is_x86rzPlatformInfo.current_is_x86FcC.|jdkr |r dS|jdkr|rdSd|jS)uk Current platform specific subfolder. Parameters ---------- hidex86: bool return '' and not '†' if architecture is x86. x64: bool return 'd' and not 'md64' if architecture is amd64. Return ------ str subfolder: ' arget', or '' (see hidex86 parameter) r$rr[\x64\%srrhidex86rXrrr current_dir zPlatformInfo.current_dircCr)ar Target platform specific subfolder. Parameters ---------- hidex86: bool return '' and not '\x86' if architecture is x86. x64: bool return '\x64' and not '\amd64' if architecture is amd64. Return ------ str subfolder: '\current', or '' (see hidex86 parameter) r$rr[rrrrrrr target_dirrzPlatformInfo.target_dircCs0|rdn|j}|j|krdS|dd|S)ap Cross platform specific subfolder. Parameters ---------- forcex86: bool Use 'x86' as current architecture even if current architecture is not x86. Return ------ str subfolder: '' if target architecture is current architecture, '\current_target' if not. r$r\z\%s_)rrrrm)rforcex86currentrrr cross_dirs  zPlatformInfo.cross_dirN)FFF)rrr__doc__rrNrhrrpropertyrrrrrrrrrrrts   rc@seZdZdZejejejejfZ ddZ e ddZ e ddZ e dd Ze d d Ze d d Ze ddZe ddZe ddZe ddZdddZddZdS) RegistryInfoz Microsoft Visual Studio related registry information. Parameters ---------- platform_info: PlatformInfo "PlatformInfo" instance. cCs ||_dSN)pi)rZ platform_inforrrrs zRegistryInfo.__init__cCdS)z Microsoft Visual Studio root registry key. Return ------ str Registry key Z VisualStudiorrrrr visualstudio zRegistryInfo.visualstudiocC t|jdS)z Microsoft Visual Studio SxS registry key. Return ------ str Registry key ZSxS)rrrrrrsxs zRegistryInfo.sxscCr)z| Microsoft Visual C++ VC7 registry key. Return ------ str Registry key ZVC7rrrrrrvcrzRegistryInfo.vccCr)z Microsoft Visual Studio VS7 registry key. Return ------ str Registry key ZVS7rrrrrvsrzRegistryInfo.vscCr)z Microsoft Visual C++ for Python registry key. Return ------ str Registry key zDevDiv\VCForPythonrrrrr vc_for_python(rzRegistryInfo.vc_for_pythoncCr)zq Microsoft SDK registry key. Return ------ str Registry key zMicrosoft SDKsrrrrr microsoft_sdk4rzRegistryInfo.microsoft_sdkcCr)z Microsoft Windows/Platform SDK registry key. Return ------ str Registry key r rrrrrr windows_sdk@rzRegistryInfo.windows_sdkcCr)z Microsoft .NET Framework SDK registry key. Return ------ str Registry key ZNETFXSDKrrrrr netfx_sdkLrzRegistryInfo.netfx_sdkcCr)z Microsoft Windows Kits Roots registry key. Return ------ str Registry key zWindows Kits\Installed Rootsrrrrrwindows_kits_rootsXrzRegistryInfo.windows_kits_rootsFcCs$|js|r dnd}td|d|S)a Return key in Microsoft software registry. Parameters ---------- key: str Registry key path where look. x86: str Force x86 software registry. Return ------ str Registry key rZ Wow6432NodeZSoftware Microsoft)rrr)rr!r$Znode64rrr microsoftdszRegistryInfo.microsoftc Cstj}tj}tj}|j}|jD]l}d}z ||||d|}Wn+ttfyI|j sEz ||||dd|}WnttfyDYYqwYqYnwz)zt ||dWW|r^||SSttfykYnwW|rs||q|r{||wwdS)a Look for values in registry in Microsoft software registry. Parameters ---------- key: str Registry key path where look. name: str Value name to find. Return ------ str value NrT) rr7r6ZCloseKeyrHKEYSr8IOErrorrr QueryValueEx) rr!nameZkey_readZopenkeyZclosekeymshkeybkeyrrrlookupwsD   zRegistryInfo.lookupNr)rrrrrrrrrrrrrrrrrrrrrrrrrrrrs8          rc@s<eZdZdZeddZeddZedeZd7ddZ d d Z d d Z d dZ e ddZeddZeddZddZddZeddZeddZeddZedd Zed!d"Zed#d$Zed%d&Zed'd(Zed)d*Zed+d,Zed-d.Zed/d0Zed1d2Z d3d4Z!e d8d5d6Z"dS)9 SystemInfoz Microsoft Windows and Visual Studio related system information. Parameters ---------- registry_info: RegistryInfo "RegistryInfo" instance. vc_ver: float Required Microsoft Visual C++ version. WinDirrrFrENcCs2||_|jj|_||_|p||_|_dSr)rirfind_programdata_vs_versknown_vs_paths_find_latest_available_vs_vervs_vervc_ver)rZ registry_inforrrrrs    zSystemInfo.__init__cCs>|}|s|jstjdt|}||jt|dS)zm Find the latest VC version Return ------ float version z%No Microsoft Visual C++ version foundr^)find_reg_vs_versrr&r'r(setupdatesorted)rZ reg_vc_versZvc_versrrrrs   z(SystemInfo._find_latest_available_vs_verc Csb|jj}|jj|jj|jjf}g}t|jj|D]\}}z t |||dtj }Wn t t fy5Yqw|lt |\}}} t|D]*} tttt|| d} | |vr`|| Wdn1sjwYqEt|D](} tttt|| } | |vr|| Wdn1swYqtWdn1swYqt|S)z Find Microsoft Visual Studio versions available in registry. Return ------ list of float Versions rN)rrrrrr9productrrr6r7r8rZ QueryInfoKeyrange contextlibsuppressr)r>r;appendEnumKeyr) rrZvckeysZvs_versrr!rZsubkeysvaluesrdrBr-rrrrs>        zSystemInfo.find_reg_vs_versc Csi}d}zt|}Wn ttfy|YSw|D]F}z8t||d}t|ddd }t|}Wdn1s:wY|d}tt|d||||d <Wqtttfy`Yqw|S) z Find Visual studio 2017+ versions from information in "C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances". Return ------ dict float version as key, path as value. z9C:\ProgramData\Microsoft\VisualStudio\Packages\_Instancesz state.jsonrtzutf-8)rKNrG VC\Tools\MSVCZinstallationVersion) rr8rrrjsonload_as_float_versionr) rZ vs_versionsZ instances_dirZ hashed_namesrZ state_pathZ state_filestateZvs_pathrrrrs0    z#SystemInfo.find_programdata_vs_verscCstd|dddS)z Return a string version as a simplified float version (major.minor) Parameters ---------- version: str Version. Return ------ float version .N)r>rsplit)r rrrrszSystemInfo._as_float_versioncCs.t|jd|j}|j|jjd|jp|S)zp Microsoft Visual Studio directory. Return ------ str path zMicrosoft Visual Studio %0.1f%0.1f)rProgramFilesx86rrrr)rdefaultrrr VSInstallDir)s zSystemInfo.VSInstallDircCs,|p|}t|sd}tj||S)zm Microsoft Visual C++ directory. Return ------ str path z(Microsoft Visual C++ directory not found) _guess_vc_guess_vc_legacyrr&r'r()rrVmsgrrr VCInstallDir:s   zSystemInfo.VCInstallDirc Cs|jdkrdSz|j|j}Wn ty|j}Ynwt|d}zt|d}|||_t||WStt t fy@YdSw)zl Locate Visual C++ for VS2017+. Return ------ str path r{rrr^) rrrrrrrrr8r IndexError)rZvs_dirZguess_vcrrrrrLs       zSystemInfo._guess_vccCsbt|jd|j}t|jjd|j}|j|d}|r!t|dn|}|j|jjd|jp0|S)z{ Locate Visual C++ for versions prior to 2017. Return ------ str path z Microsoft Visual Studio %0.1f\VCrrrL)rrrrrrr)rrZreg_pathZ python_vcZ default_vcrrrrjs zSystemInfo._guess_vc_legacycCsJ|jdkrdS|jdkrdS|jdkrdS|jdkrdS|jd kr#d Sd S) z Microsoft Windows SDK versions for specified MSVC++ version. Return ------ tuple of str versions r)z7.0z6.1z6.0ar)z7.1z7.0a&@)z8.0z8.0a(@)8.1z8.1ar{)z10.0rNrrrrrWindowsSdkVersion~s     zSystemInfo.WindowsSdkVersioncC|t|jdS)zt Microsoft Windows SDK last version. Return ------ str version lib)_use_last_dir_namer WindowsSdkDirrrrrWindowsSdkLastVersion z SystemInfo.WindowsSdkLastVersioncCs d}|jD]}t|jjd|}|j|d}|rnq|r"t|s:t|jjd|j}|j|d}|r:t|d}|r@t|s_|jD]}|d|d}d |}t|j |}t|r^|}qC|ret|s{|jD]}d |}t|j |}t|rz|}qh|st|j d }|S) zn Microsoft Windows SDK directory. Return ------ str path rzv%sinstallationfolderrrZWinSDKNrzMicrosoft SDKs\Windows Kits\%szMicrosoft SDKs\Windows\v%sZ PlatformSDK) rrrrrrrrrfindrFr)rsdkdirr-locrV install_baseZintverdrrrrs<          zSystemInfo.WindowsSdkDirc Cs|jdkr d}d}nd}|jdkrdnd}|jjd|d}d ||d d f}g}|jd kr?|jD] }|t|jj||g7}q1|jD]}|t|jj d ||g7}qB|D]}|j |d}|rc|SqTdS)zy Microsoft Windows SDK executable directory. Return ------ str path r#r(rTF)rXrzWinSDK-NetFx%dTools%sr-r{zv%sArN) rrrrmNetFxSdkVersionrrrrrr) rZnetfxverr.rZfxZregpathsr-rVZexecpathrrrWindowsSDKExecutablePaths&    z#SystemInfo.WindowsSDKExecutablePathcCs&t|jjd|j}|j|dpdS)zl Microsoft Visual F# directory. Return ------ str path z%0.1f\Setup\F#r"r)rrrrr)rrVrrrFSharpInstallDirs zSystemInfo.FSharpInstallDircCsF|jdkrdnd}|D]}|j|jjd|}|r |pdSq dS)zt Microsoft Universal CRT SDK directory. Return ------ str path r{)10Z81rz kitsroot%srN)rrrr)rversr-rrrrUniversalCRTSdkDirs   zSystemInfo.UniversalCRTSdkDircCr)z Microsoft Universal C Runtime SDK last version. Return ------ str version r)rrrrrrrUniversalCRTSdkLastVersionrz%SystemInfo.UniversalCRTSdkLastVersioncCs|jdkrdSdS)z Microsoft .NET Framework SDK versions. Return ------ tuple of str versions r{) z4.7.2z4.7.1z4.7z4.6.2z4.6.1z4.6z4.5.2z4.5.1z4.5rrrrrrrs zSystemInfo.NetFxSdkVersioncCs:d}|jD]}t|jj|}|j|d}|r|Sq|S)zu Microsoft .NET Framework SDK directory. Return ------ str path rZkitsinstallationfolder)rrrrr)rrr-rrrr NetFxSdkDir*s zSystemInfo.NetFxSdkDircC"t|jd}|j|jjdp|S)zw Microsoft .NET Framework 32bit directory. Return ------ str path zMicrosoft.NET\FrameworkZframeworkdir32rrrrrrZguess_fwrrrFrameworkDir32< zSystemInfo.FrameworkDir32cCr)zw Microsoft .NET Framework 64bit directory. Return ------ str path zMicrosoft.NET\Framework64Zframeworkdir64rrrrrFrameworkDir64LrzSystemInfo.FrameworkDir64cC |dS)z Microsoft .NET Framework 32bit versions. Return ------ tuple of str versions _find_dot_net_versionsrrrrFrameworkVersion32\ zSystemInfo.FrameworkVersion32cCr)z Microsoft .NET Framework 64bit versions. Return ------ tuple of str versions @rrrrrFrameworkVersion64hr zSystemInfo.FrameworkVersion64cCs|j|jjd|}t|d|}|p||dpd}|jdkr%|dfS|jdkr<|dd d kr8d d fS|d fS|jd krCdS|jdkrJdSdS)z Find Microsoft .NET Framework versions. Parameters ---------- bits: int Platform number of bits: 32 or 64. Return ------ tuple of str versions zframeworkver%dzFrameworkDir%drCrrzv4.0rNrZv4z v4.0.30319v3.5r)r v2.0.50727g @)zv3.0r)rrrgetattrrrrh)rbitsZreg_verZ dot_net_dirr-rrrr ts  $  z!SystemInfo._find_dot_net_versionscs*fddttD}t|dpdS)a) Return name of the last dir in path or '' if no dir found. Parameters ---------- path: str Use dirs in this path prefix: str Use only dirs starting by this prefix Return ------ str name c3s,|]}tt|r|r|VqdSr)rr startswith)ridir_namerVprefixrrrqs  z0SystemInfo._use_last_dir_name..Nr)reversedrnext)rVrZ matching_dirsrrrrs  zSystemInfo._use_last_dir_namerr)#rrrrrrNrrFrrrrr staticmethodrrrrrrrrrrrrrrrrrr r r rrrrrrs\    *      * "          rc@sTeZdZdZd=ddZeddZedd Zed d Zed d Z eddZ eddZ eddZ eddZ eddZeddZeddZddZeddZed d!Zed"d#Zed$d%Zed&d'Zed(d)Zed*d+Zed,d-Zed.d/Zed0d1Zed2d3Zed4d5Zed6d7Zd>d9d:Zd;d<Z dS)?r*aY Return environment variables for specified Microsoft Visual C++ version and platform : Lib, Include, Path and libpath. This function is compatible with Microsoft Visual C++ 9.0 to 14.X. Script created by analysing Microsoft environment configuration files like "vcvars[...].bat", "SetEnv.Cmd", "vcbuildtools.bat", ... Parameters ---------- arch: str Target architecture. vc_ver: float Required Microsoft Visual C++ version. If not set, autodetect the last version. vc_min_ver: float Minimum Microsoft Visual C++ version. NrcCsBt||_t|j|_t|j||_|j|krd}tj |dS)Nz.No suitable Microsoft Visual C++ version found) rrrrrsirr&r'r()rr.rZ vc_min_vererrrrrrs    zEnvironmentInfo.__init__cC|jjS)zk Microsoft Visual Studio. Return ------ float version )rrrrrrr zEnvironmentInfo.vs_vercCr)zp Microsoft Visual C++ version. Return ------ float version )rrrrrrrrzEnvironmentInfo.vc_vercsVddg}jdkr"jjddd}|dg7}|dg7}|d|g7}fd d |DS) zu Microsoft Visual Studio Tools. Return ------ list of str paths z Common7\IDEz Common7\Toolsr{TrrXz1Common7\IDE\CommonExtensions\Microsoft\TestWindowzTeam Tools\Performance ToolszTeam Tools\Performance Tools%scg|] }tjj|qSrrrrrirVrrr z+EnvironmentInfo.VSTools..)rrr)rpaths arch_subdirrrrVSToolss   zEnvironmentInfo.VSToolscCst|jjdt|jjdgS)z Microsoft Visual C++ & Microsoft Foundation Class Includes. Return ------ list of str paths IncludezATLMFC\Includerrrrrrr VCIncludess zEnvironmentInfo.VCIncludescsbjdkr jjdd}njjdd}d|d|g}jdkr(|d|g7}fd d |DS) z Microsoft Visual C++ & Microsoft Foundation Class Libraries. Return ------ list of str paths .@TrXrLib%sz ATLMFC\Lib%sr{z Lib\store%scrrr(r!rrrr"r#z/EnvironmentInfo.VCLibraries..)rrr)rr%r$rrr VCLibrariess  zEnvironmentInfo.VCLibrariescC|jdkrgSt|jjdgS)z Microsoft Visual C++ store references Libraries. Return ------ list of str paths r{zLib\store\references)rrrrrrrr VCStoreRefss zEnvironmentInfo.VCStoreRefscCs|j}t|jdg}|jdkrdnd}|j|}|r&|t|jd|g7}|jdkr?d|jjdd}|t|j|g7}|S|jdkrw|jrKd nd }|t|j||jjdd g7}|jj |jj kru|t|j||jjdd g7}|S|t|jd g7}|S) zr Microsoft Visual C++ Tools. Return ------ list of str paths Z VCPackagesrTFBin%sr{r,r*z bin\HostX86%sz bin\HostX64%sr+Bin) rrrrrrrrrrr)rrtoolsrr%rVZhost_dirrrrVCTools(s0    zEnvironmentInfo.VCToolscCsd|jdkr|jjddd}t|jjd|gS|jjdd}t|jjd}|j}t|d||fgS)zw Microsoft Windows SDK Libraries. Return ------ list of str paths rTrr-r+rz%sum%s)rrrrrr _sdk_subdir)rr%rZlibverrrr OSLibrariesMs zEnvironmentInfo.OSLibrariescCsdt|jjd}|jdkr|t|dgS|jdkr|j}nd}t|d|t|d|t|d|gS) zu Microsoft Windows SDK Include. Return ------ list of str paths includerglr{rz%ssharedz%sumz%swinrt)rrrrr5)rr7sdkverrrr OSIncludesas     zEnvironmentInfo.OSIncludescCst|jjd}g}|jdkr||j7}|jdkr |t|dg7}|jdkrM||t|jjdt|ddt|d dt|d dt|jjd d d |jdddg7}|S)z} Microsoft Windows SDK Libraries Paths. Return ------ list of str paths Z ReferencesrrzCommonConfiguration\Neutralr{Z UnionMetadataz'Windows.Foundation.UniversalApiContractz1.0.0.0z%Windows.Foundation.FoundationContractz,Windows.Networking.Connectivity.WwanContractZ ExtensionSDKszMicrosoft.VCLibsrZCommonConfigurationZneutral)rrrrr6)rreflibpathrrr OSLibpathys2         zEnvironmentInfo.OSLibpathcCs t|S)zs Microsoft Windows SDK Tools. Return ------ list of str paths )list _sdk_toolsrrrrSdkToolsrzEnvironmentInfo.SdkToolsccs|jdkr|jdkr dnd}t|jj|V|js/|jjdd}d|}t|jj|V|jdvrQ|jr.crJr)rrrKrLrrr"rM) rrrrrrrr r )rrZ include32Z include64r3rrLrFxToolss"    zEnvironmentInfo.FxToolscCs8|jdks |jjs gS|jjdd}t|jjd|gS)z~ Microsoft .Net Framework SDK Libraries. Return ------ list of str paths r{Tr+zlib\um%s)rrrrrr)rr%rrrNetFxSDKLibrariess z!EnvironmentInfo.NetFxSDKLibrariescCs&|jdks |jjs gSt|jjdgS)z} Microsoft .Net Framework SDK Includes. Return ------ list of str paths r{z include\um)rrrrrrrrNetFxSDKIncludess z EnvironmentInfo.NetFxSDKIncludescCst|jjdgS)z Microsoft Visual Studio Team System Database. Return ------ list of str paths z VSTSDB\Deployr rrrrVsTDb$s zEnvironmentInfo.VsTDbcCsv|jdkrgS|jdkr|jj}|jjdd}n|jj}d}d|j|f}t||g}|jdkr9|t||dg7}|S)zn Microsoft Build Engine. Return ------ list of str paths rr*Tr,rzMSBuild\%0.1f\bin%sZRoslyn)rrrrrrr)r base_pathr%rVbuildrrrMSBuild0s    zEnvironmentInfo.MSBuildcCr/)zt Microsoft HTML Help Workshop. Return ------ list of str paths rzHTML Help Workshop)rrrrrrrrHTMLHelpWorkshopLrIz EnvironmentInfo.HTMLHelpWorkshopcCsD|jdkrgS|jjdd}t|jjd}|j}t|d||fgS)z Microsoft Universal C Runtime SDK Libraries. Return ------ list of str paths r{Tr+rz%sucrt%s)rrrrrr _ucrt_subdir)rr%rrErrr UCRTLibraries[s zEnvironmentInfo.UCRTLibrariescCs.|jdkrgSt|jjd}t|d|jgS)z Microsoft Universal C Runtime SDK Include. Return ------ list of str paths r{r7z%sucrt)rrrrrV)rr7rrr UCRTIncludesms zEnvironmentInfo.UCRTIncludescCrB)z Microsoft Universal C Runtime SDK version subdir. Return ------ str subdir rCr)rrrDrrrrV}rFzEnvironmentInfo._ucrt_subdircCs$d|jkr dkr gS|jjgS)zk Microsoft Visual F#. Return ------ list of str paths rr)rrrrrrrFSharps  zEnvironmentInfo.FSharpc Csd|j}|jjddd}g}|jj}t|dd}t|r3t |t |d}||t |dg7}|t |d g7}d |jd d t |j d f}t ||D]\}}t ||||} t| rd| SqQd S) z Microsoft Visual C++ runtime redistributable dll. Return ------ str path zvcruntime%d0.dllTr+rz\Toolsz\Redistr^Zonecorer\zMicrosoft.VC%d.CRT N)rrrrRrrrrmrrrr=rr9rr) rrer%prefixesZ tools_pathZ redist_pathZcrt_dirsrZcrt_dirrVrrrVCRuntimeRedists$  zEnvironmentInfo.VCRuntimeRedistTcCst|d|j|j|j|jg||d|j|j|j|j |j g||d|j|j|j |j g||d|j |j|j|j|j|j|j|j|jg |d}|jdkrWt|jrW|j|d<|S)z Return environment dict. Parameters ---------- exists: bool It True, only return existing paths. Return ------ dict environment r7rr<rV)r7rr<rVr5rr)dict _build_pathsr)r:rXrPr.r6rNrWrOr0r=r4r&rQr@rHrTrUrYrrr\)rexistsryrrrr+sV  zEnvironmentInfo.return_envc Csntj|}t|dt}t||}|rttt |n|}|s.d| }t j |t|} t| S)aC Given an environment variable name and specified paths, return a pathsep-separated string of paths containing unique, extant, directories from those paths and from the environment variable. Raise an error if no paths are resolved. Parameters ---------- name: str Environment variable name spec_path_lists: list of str Paths exists: bool It True, only return existing paths. Return ------ str Pathsep-separated paths rz %s environment variable is empty)r9chain from_iterablerrNrrr>filterrupperr&r'r(r r) rrZspec_path_listsr_Z spec_pathsZ env_pathsr$Z extant_pathsrZ unique_pathsrrrr^s     zEnvironmentInfo._build_paths)Nr)T)!rrrrrrrrr&r)r.r0r4r6r:r=r@r?r5rHrNrOrPrQrTrUrWrXrVrYr\r+r^rrrrr*sl        $   #  #              " 2r*)r$r)1rriorosrros.pathrrrrr}rplatformr9rOdistutils.errorsr&Z#setuptools.extern.packaging.versionr Z setuptools.extern.more_itertoolsr Zmonkeyr systemrrr]rar'r(Z_msvc9_suppress_errorsZdistutils.msvc9compilerrrr%rDrWr_rfrzr|rr,rrrr*rrrrsd        *&&'$ %s:PKH]4!!Mpython3.10/site-packages/setuptools/__pycache__/package_index.cpython-310.pycnu[o XaiΛ@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl ZddlZddlZddlZddlmZddlZddlmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#ddl$m%Z%ddl&m'Z'ddl(m)Z)ddl*m+Z+dd l,m-Z-e.d Z/e.d ej0Z1e.d Z2e.d ej0j3Z4d5Z6gdZ7dZ8dZ9e9j:dj:ej;edZddZ?dBddZ@dBddZAdBddZBdedfd d!ZCd"d#ZDe.d$ej0ZEeDd%d&ZFGd'd(d(ZGGd)d*d*eGZHGd+d,d,eZIe.d-jJZKd.d/ZLd0d1ZMdCd2d3ZNd4d5ZOGd6d7d7ZPGd8d9d9e jQZRejSjTfd:d;ZUdd?ZWd@dAZXdS)Dz#PyPI and direct package downloadingNwraps) CHECKOUT_DIST Distribution BINARY_DISTnormalize_path SOURCE_DIST Environmentfind_distributions safe_name safe_version to_filename Requirement DEVELOP_DISTEGG_DIST)log)DistutilsError) translate)Wheelunique_everseenz^egg=([-A-Za-z0-9_.+!]+)$zhref\s*=\s*['"]?([^'"> ]+)z([^<]+)\n\s+\(md5\)z([-+.a-z0-9]{2,}):z.tar.gz .tar.bz2 .tar .zip .tgz) PackageIndexdistros_for_urlparse_bdist_wininstinterpret_distro_namezsz(interpret_distro_name..Nr3) py_versionrArS)r7anyrangerPrjoin)rJrQrFr]rArSr9rZr!r!r"rs $ rcstfdd}|S)zs Wrap a function returning an iterable such that the resulting iterable only ever yields unique items. cst|i|SNr)argskwargsfuncr!r"wrapperszunique_values..wrapperr)rerfr!rdr" unique_valuessrgz(<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>c cst|D]2}|\}}tttj|d}d|vs#d|vr8t |D]}t j |t |dVq(qdD] }||}|dkr[t ||}|r[t j |t |dVq;dS)zEFind rel="homepage" and rel="download" links in `page`, yielding URLs,Zhomepager0r3)z Home PagezDownload URLr/N)RELfinditergroupssetmapstrstripr'r7HREFr4rurljoin htmldecoderEfindsearch)r8pagerDtagrelZrelsposr!r!r"find_external_linkss    ryc@(eZdZdZddZddZddZdS) ContentCheckerzP A null content checker that defines the interface for checking content cCdS)z3 Feed a block of data to the hash. Nr!selfblockr!r!r"feedzContentChecker.feedcCr|)zC Check the hash. Return False if validation fails. Tr!r~r!r!r"is_validrzContentChecker.is_validcCr|)zu Call reporter with information about the checker (hash name) substituted into the template. Nr!)r~reportertemplater!r!r"reportszContentChecker.reportN)__name__ __module__ __qualname____doc__rrrr!r!r!r"r{s  r{c@sBeZdZedZddZeddZddZ dd Z d d Z d S) HashCheckerzK(?Psha1|sha224|sha384|sha256|sha512|md5)=(?P[a-f0-9]+)cCs||_t||_||_dSra) hash_namehashlibnewhashexpected)r~rrr!r!r"__init__s  zHashChecker.__init__cCsBtj|d}|s tS|j|}|stS|di|S)z5Construct a (possibly null) ContentChecker from a URLr/Nr!)r4rr5r{patternrt groupdict)clsr8r?rDr!r!r"from_urls zHashChecker.from_urlcCs|j|dSra)rupdater}r!r!r"rzHashChecker.feedcCs|j|jkSra)r hexdigestrrr!r!r"rrzHashChecker.is_validcCs||j}||Sra)r)r~rrmsgr!r!r"rs zHashChecker.reportN) rrrrXcompilerr classmethodrrrrr!r!r!r"rs   rcsLeZdZdZ  dLddZdMd d ZdMd d ZdMd dZddZddZ ddZ ddZ ddZ dNddZ ddZdNfdd Zdd Zd!d"Zd#d$Zd%d&Zd'd(Z  dOd)d*ZdPd+d,Zd-d.Zd/Zd0d1Zd2d3ZdNd4d5Zd6d7Zd8d9Zd:d;Zdd?Z e!dMd@dAZ"dBdCZ#dDdEZ$dFdGZ%dHdIZ&dJdKZ'Z(S)Qrz;A distribution index that scans web pages for download URLshttps://pypi.org/simple/*NTcOsrtj|g|Ri||dd|d |_i|_i|_i|_td t t |j |_ g|_tjj|_dS)Nr.|)r rr( index_url scanned_urls fetched_urls package_pagesrXrr`rmrrDallowsto_scanr4requesturlopenopener)r~rhostsZ ca_bundleZ verify_sslrbkwr!r!r"rszPackageIndex.__init__Fc Cs||jvr |s dSd|j|<t|s||dStt|}|r.||s(dS|d||s7|r7||jvrAtt|j |dS||sMd|j|<dS| d|d|j|<d}| |||}|durhdSt |t jjr||jdkr|| d|jd|j|j<d|jd d vr|dS|j}|}t |tst |t jjrd }n|jd pd }||d }|t|D]} t j|t| d} |!| q|"|j#rt$|dddkr|%||}dSdSdS)z.)filterrUr<rr itertoolsstarmap scan_egg_link)r~ search_pathdirsZ egg_linksr!r!r"scan_egg_links|s zPackageIndex.scan_egg_linkscCsttj||}ttdttj|}Wdn1swYt |dkr,dS|\}}t tj||D]}tjj|g|R|_ t |_ ||q9dS)Nr\)openrUr<r`rrrmrnrorPr rJrrAr)r~r<rZ raw_lineslinesZegg_pathZ setup_pathrGr!r!r"rs  zPackageIndex.scan_egg_linkcCsd}||js |Stttjj|t|jdd}t|dks)d|dvr+|St |d}t |d}d|j | i|<t|t|fS)N)NNr.r\r2r3rT)r)rrrmr4rr6rPr7r r r setdefaultr'r )r~rZNO_MATCH_SENTINELr9pkgverr!r!r"_scans   zPackageIndex._scanc Cst|D]}z|tj|t|dWqty!Yqw||\}}|s-dSt ||D]$}t |\}}| drQ|sQ|rL|d||f7}n| || |q2tdd|S)z#Process the contents of a PyPI pager3r.pyz #egg=%s-%scSsd|dddS)Nz%sr3r\)rE)mr!r!r"sz,PackageIndex.process_index..)rprjrr4rrqrrrErryr@r(need_version_infoscan_urlPYPI_MD5sub) r~r8rurDrrnew_urlr+fragr!r!r"rs&"    zPackageIndex.process_indexcCs|d|dS)NzPPage at %s links to .py file(s) without version info; an index scan is required.)scan_allr~r8r!r!r"rszPackageIndex.need_version_infocGs<|j|jvr|r|j|g|R|d||jdS)Nz6Scanning index of all packages (this may take a while))rrrrrr~rrbr!r!r"rs zPackageIndex.scan_allcCsz||j|jd|j|js||j|jd|j|js)||t|j|jdD]}||q3dS)Nr.r!) rr unsafe_namerrkeyrKnot_found_in_indexr)r~ requirementr8r!r!r" find_packagess  zPackageIndex.find_packagescsR|||||jD]}||vr|S|d||qtt|||S)Nz%s does not match %s)prescanrrrsuperrobtain)r~r installerrG __class__r!r"rs zPackageIndex.obtaincCsL||jd||s$|t|td|jjtj |fdS)z- checker is a ContentChecker zValidating %%s checksum for %sz7%s validation failed for %s; possible download problem?N) rrrrrUunlinkrrr*r<rQ)r~checkerrVtfpr!r!r" check_hashs zPackageIndex.check_hashcCsN|D]"}|jdust|r|dstt|r||q|j|qdS)z;Add `urls` to the list that will be prescanned for searchesNfile:)rrr)rrrappend)r~urlsr8r!r!r"add_find_linkss   zPackageIndex.add_find_linkscCs"|jr tt|j|jd|_dS)z7Scan urls scheduled for prescanning (e.g. --find-links)N)rrrmrrr!r!r"r s zPackageIndex.prescancCs<||jr |jd}}n|jd}}|||j|dS)Nz#Couldn't retrieve index page for %rz3Couldn't find index page for %r (maybe misspelled?))rrrrr)r~rmethrr!r!r"rs   zPackageIndex.not_found_in_indexcCs~t|ts5t|}|r)||d||}t|\}}|dr'||||}|Stj |r1|St |}t | ||ddS)aLocate and/or download `spec` to `tmpdir`, returning a local path `spec` may be a ``Requirement`` object, or a string containing a URL, an existing local filename, or a project/version requirement spec (i.e. the string form of a ``Requirement`` object). If it is the URL of a .py file with an unambiguous ``#egg=name-version`` tag (i.e., one that escapes ``-`` as ``_`` throughout), a trivial ``setup.py`` is automatically created alongside the downloaded file. If `spec` is a ``Requirement`` object or a string containing a project/version requirement spec, this method returns the location of a matching distribution (possibly after downloading it to `tmpdir`). If `spec` is a locally existing file or directory name, it is simply returned unchanged. If `spec` is a URL, it is downloaded to a subpath of `tmpdir`, and the local filename is returned. Various errors may be raised if a problem occurs during downloading. r3rrJN)rrr _download_urlrEr@r( gen_setuprUr<rr#rfetch_distribution)r~rtmpdirr:foundr+r?r!r!r"r0s    zPackageIndex.downloadc sd|id}d fdd }|r$|||}|s/|dur/|||}|dur@jdur<||}|durO|sO|||}|dur`drZdp[d|dSd||j|jd S) a|Obtain a distribution suitable for fulfilling `requirement` `requirement` must be a ``pkg_resources.Requirement`` instance. If necessary, or if the `force_scan` flag is set, the requirement is searched for in the (online) package index as well as the locally installed packages. If a distribution matching `requirement` is found, the returned distribution's ``location`` is the value you would have gotten from calling the ``download()`` method with the matching distribution's URL or filename. If no matching distribution is found, ``None`` is returned. If the `source` flag is set, only source distributions and source checkout links will be considered. Unless the `develop_ok` flag is set, development and system eggs (i.e., those using the ``.egg-info`` format) will be ignored. zSearching for %sNcs|dur}||jD];}|jtkr#s#|vr"d|d|<q ||vo.|jtkp. }|rF|j}||_tj |jrF|Sq dS)Nz&Skipping development or system egg: %sr3) rrArrrr0rJdownload_locationrUr<r)reqenvrGtestloc develop_okr~skippedsourcer r!r"rsUs(z-PackageIndex.fetch_distribution..findz:No local packages or working download links found for %s%sza source distribution of rzBest match: %s)rJra)rrrrrcloner ) r~rr  force_scanrrZ local_indexrGrsr!rr"r=s2         zPackageIndex.fetch_distributioncCs"|||||}|dur|jSdS)a3Obtain a file suitable for fulfilling `requirement` DEPRECATED; use the ``fetch_distribution()`` method now instead. For backward compatibility, this routine is identical but returns the ``location`` of the downloaded distribution instead of a distribution object. N)rrJ)r~rr rrrGr!r!r"fetchszPackageIndex.fetchc Cs t|}|rddt||ddDpg}t|dkrxtj|}tj||krEtj ||}ddl m }|||sEt |||}ttj |dd} | d|dj|djtj|dfWd|S1sqwY|S|rtd ||ftd ) NcSsg|]}|jr|qSr!)rL)rYdr!r!r" s z*PackageIndex.gen_setup..r3r)samefilezsetup.pywzIfrom setuptools import setup setup(name=%r, version=%r, py_modules=[%r]) zCan't unambiguously interpret project/version identifier %r; any dashes in the name or version should be escaped using underscores. %rzpCan't process plain .py files without an '#egg=name-version' suffix to enable automatic setup script generation.)rCrDrrErPrUr<rQdirnamer`Zsetuptools.command.easy_installrshutilcopy2rwriterKrLsplitextr) r~rVr?r rDrrQdstrrr!r!r"rsF          zPackageIndex.gen_setupi c Cs2|d|d}zt|}||}t|tjjr%td||j |j f|}d}|j }d}d|vrI| d} t tt| }||||||t|d1} ||} | ro|| | | |d 7}||||||nnqP|||| Wdn1swY|W|r|SS|r|ww) NzDownloading %szCan't download %s: %s %srr/zcontent-lengthzContent-LengthwbTr3)rrrrrr4rrrrr dl_blocksizeget_allmaxrmint reporthookrrrrrr) r~r8rVfprrblocknumbssizesizesrrr!r!r" _download_tosF            zPackageIndex._download_tocCsdSrar!)r~r8rVr(Zblksizer*r!r!r"r&zPackageIndex.reporthookc Cs|dr t|Szt||jWSttjjfyD}z$ddd|j D}|r0| ||n t d||f|WYd}~dSd}~wt j jyY}z|WYd}~Sd}~wt j jy}z|rl| ||jn t d||jf|WYd}~dSd}~wtjjy}z|r| ||jn t d||jf|WYd}~dSd}~wtjjtj fy}z|r| ||n t d||f|WYd}~dSd}~ww)Nr cSsg|]}t|qSr!)rn)rYargr!r!r"rsz)PackageIndex.open_url..z%s %szDownload error for %s: %sz;%s returned a bad status line. The server might be down, %s)r) local_openopen_with_authrrhttpclient InvalidURLr`rbrrr4rrURLErrorreason BadStatusLineline HTTPExceptionsocket)r~r8warningvrr!r!r"rs^ zPackageIndex.open_urlcCst|\}}|rd|vr|dddd}d|vs nd}|dr(|dd}tj||}|dks8|d r>|||S|d ksG|d rM|||S|d rX| ||S|d krht j t j |dS||d|||S)Nz...\_Z__downloaded__rHr&svnzsvn+gitzgit+zhg+rr\T)r@replacer(rUr<r`r) _download_svn _download_git _download_hgr4r url2pathnamerr5r_attempt_download)r~r:r8r r*r?rVr!r!r"r s(         zPackageIndex._download_urlcCs||ddS)NT)rrr!r!r"r)rzPackageIndex.scan_urlcCs2|||}d|ddvr||||S|S)Nrrr)r,rr'_download_html)r~r8rVrr!r!r"rG,s zPackageIndex._attempt_downloadcCsjt|}|D]}|r%td|r#|t||||Snq|t|td|)Nz ([^- ]+ - )?Revision \d+:zUnexpected HTML page found at ) r���ro���rX���rt���r���rU���r���rC��r���)r~���r8���r���rV���r���r8��r!���r!���r"���rH��3��s���    zPackageIndex._download_htmlc�����������������C���s��t�dt�|ddd�}d}|�drqd|v�rqtj|\}}}}}} |sq|drqd |d d��v�rq|d d��d d\}}t |\} } | rqd | v�r]| d d\} } d | | f�}nd | �}| }|||||| f}tj |}|� d||�t d|||f��|S�)Nz"SVN download support is deprecatedr2���r3���r���r���zsvn:@z//r.���r\���:z --username=%s --password=%sz --username=z'Doing subversion checkout from %s to %szsvn checkout%s -q %s %s)warningsr��� UserWarningr7���r'���r)���r4���r���r5��� _splituser urlunparser���rU���system)r~���r8���rV���credsr:���netlocr<���rZ���qr���authhostuserpwr9���r!���r!���r"���rC��B��s&���   zPackageIndex._download_svnc�����������������C���sp���t�j|�\}}}}}|ddd�}|ddd�}d�}d|v�r)|dd\}}t�j||||df}�|�|fS�)N+r3���r/���r2���r���rI��r���)r4���r���urlsplitr7���rsplit urlunsplit)r8��� pop_prefixr:���rQ��r<���r>���r���revr!���r!���r"���_vcs_split_rev_from_urlX��s���z$PackageIndex._vcs_split_rev_from_urlc�����������������C���l���|�ddd�}|�j|dd\}}|�d||�td||f��|d�ur4|�d|�td ||f��|S�) Nr2���r3���r���Tr[��zDoing git clone from %s to %szgit clone --quiet %s %szChecking out %szgit -C %s checkout --quiet %sr7���r]��r���rU���rO��r~���r8���rV���r\��r!���r!���r"���rD��j����� zPackageIndex._download_gitc�����������������C���r^��) Nr2���r3���r���Tr_��zDoing hg clone from %s to %szhg clone --quiet %s %szUpdating to %szhg --cwd %s up -C -r %s -qr`��ra��r!���r!���r"���rE��z��rb��zPackageIndex._download_hgc�����������������G������t�j|g|R���d�S�ra���)r���r���r���r!���r!���r"���r��������zPackageIndex.debugc�����������������G���rc��ra���)r���r���r���r!���r!���r"���r�����rd��zPackageIndex.infoc�����������������G���rc��ra���)r���r���r���r!���r!���r"���r�����rd��zPackageIndex.warn)r���r���NT)Fra���)FFFN)FF))r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r��r���r���r0���r��r��r��r"��r,��r&��r���r��r���rG��rH��rC�� staticmethodr]��rD��rE��r���r���r��� __classcell__r!���r!���r���r"���r�����sT����  5       # L )$ # r���z!&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?c�����������������C���s���|��d}t|S�)Nr���)rE���r���unescape)rD���whatr!���r!���r"��� decode_entity��s���  ri��c�����������������C���s ���t�t|�S�)a�� Decode HTML entities in the given text. >>> htmldecode( ... 'https://../package_name-0.1.2.tar.gz' ... '?tokena=A&tokenb=B">package_name-0.1.2.tar.gz') 'https://../package_name-0.1.2.tar.gz?tokena=A&tokenb=B">package_name-0.1.2.tar.gz' ) entity_subri��)textr!���r!���r"���rr�����s��� rr���c��������������������s����fdd}|S�)Nc��������������������s����fdd}|S�)Nc��������������� ������s:���t��}t��z �|�i�|W�t�|�S�t�|�w�ra���)r:��getdefaulttimeoutsetdefaulttimeout)rb���rc���Z old_timeout)re���timeoutr!���r"���_socket_timeout��s ��� z@socket_timeout.<locals>._socket_timeout.<locals>._socket_timeoutr!���)re���ro��rn��rd���r"���ro����s���z'socket_timeout.<locals>._socket_timeoutr!���)rn��ro��r!���rp��r"���socket_timeout��s���  rq��c�����������������C���s2���t�j|�}|�}t|}|�}|ddS�)a9�� Encode auth from a URL suitable for an HTTP header. >>> str(_encode_auth('username%3Apassword')) 'dXNlcm5hbWU6cGFzc3dvcmQ=' Long auth strings should not cause a newline to be inserted. >>> long_auth = 'username:' + 'password'*10 >>> chr(10) in str(_encode_auth(long_auth)) False  r���)r4���r���r6���encodebase64 b64encoder���rB��)rS��Zauth_sZ auth_bytesZ encoded_bytesencodedr!���r!���r"��� _encode_auth��s ���   rw��c�������������������@���rz���) Credentialz: A username/password pair. Use like a namedtuple. c�����������������C���s���||�_�||�_d�S�ra���usernamepassword)r~���rz��r{��r!���r!���r"���r�����s��� zCredential.__init__c�����������������c���s����|�j�V��|�jV��d�S�ra���ry��r���r!���r!���r"���__iter__��s��� zCredential.__iter__c�����������������C���s ���dt�|��S�)Nz%(username)s:%(password)s)varsr���r!���r!���r"���__str__��s��� zCredential.__str__N)r���r���r���r���r���r|��r~��r!���r!���r!���r"���rx����s ���� rx��c�������������������@���s0���e�Zd�Zdd�Zedd�Zdd�Zdd�Zd S�) PyPIConfigc�����������������C���sR���t�g�dd}tj|�|�tjtjdd}tj |r'|� |�dS�dS�)z% Load from ~/.pypirc )rz��r{�� repositoryr���~z.pypircN) dictfromkeys configparserRawConfigParserr���rU���r<���r`��� expanduserr���r���)r~���defaultsrcr!���r!���r"���r�����s ��� zPyPIConfig.__init__c��������������������s&����fdd���D�}tt�j|S�)Nc��������������������s ���g�|�] }��|d��r|qS�)r��)r���ro���)rY���sectionr���r!���r"���r����s ����z2PyPIConfig.creds_by_repository.<locals>.<listcomp>)sectionsr��rm���_get_repo_cred)r~���Zsections_with_repositoriesr!���r���r"���creds_by_repository��s��� zPyPIConfig.creds_by_repositoryc�����������������C���s6���|��|d�}|t|��|d�|��|d�fS�)Nr��rz��r{��)r���ro���rx��)r~���r��repor!���r!���r"���r����s ���zPyPIConfig._get_repo_credc�����������������C���s*���|�j��D�] \}}||r|��S�qdS�)z If the URL indicated appears to be a repository defined in this config, return the credential for that repository. N)r��itemsr)���)r~���r8���r��credr!���r!���r"���find_credential��s ��� zPyPIConfig.find_credentialN)r���r���r���r���propertyr��r��r��r!���r!���r!���r"���r����s ����  r��c�����������������C���s:��t�j|�}|\}}}}}}|drtjd|dv�r$t|\} } nd} | sBt� |�} | rBt | } | j |�f} t j dg| R���| redt| �} || ||||f} t�j| }t�j|}|d| �nt�j|�}|dt�||}| rt�j|j\}}}}}}||kr|| kr||||||f} t�j| |_|S�) z4Open a urllib2 request, handling HTTP authenticationrJ��znonnumeric port: '')r2��httpsNz*Authenticating as %s for %s (from .pypirc)zBasic Authorizationz User-Agent)r4���r���r5���r(���r2��r3��r4��rM��r��r��rn���rz��r���r���rw��rN��r���Request add_header user_agentr8���)r8���r���parsedr:���rQ��r<���paramsr>���r���rS��addressr��r���r9���r���r���r'��s2h2Zpath2Zparam2Zquery2Zfrag2r!���r!���r"���r1����s8���          r1��c�����������������C���s$���|��d\}}}�|r||�fS�d|�fS�)zNsplituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.rI��N) rpartition)rT��rU��delimr!���r!���r"���rM��4��s���rM��c�����������������C���s���|�S�ra���r!���)r8���r!���r!���r"��� fix_sf_url?��r-��r��c�������������� ���C���s*��t�j|�\}}}}}}t�j|}tj|rt�j|�S�| dr}tj |r}g�}t |D�];} tj || } | dkrXt | d } | �} W�d���n1�sQw���Y���n tj | rb| d7�} |dj| d�q0d} | j|�d |d } d \}}nd \}}} d d i}t| }t�j|�||||S�)z7Read a local path, with special support for directoriesr.���z index.htmlrNz<a href="{name}">{name}</a>)r*���zB<html><head><title>{url}{files}rr)r8files)OK)rzPath not foundz Not foundrz text/html)r4rr5rrFrUr<isfilerr(rrr`rrrformatioStringIOrr)r8r:r;r<paramr>rrVrrfilepathr'bodyrstatusmessagerZ body_streamr!r!r"r0Cs0         r0ra)r)YrsysrUrXrrr:rtrrrKrr http.clientr2 urllib.parser4urllib.request urllib.error functoolsrr pkg_resourcesrrrrrr r r r r rrr distutilsrdistutils.errorsrfnmatchrZsetuptools.wheelrZ setuptools.extern.more_itertoolsrrrCIrprrDrr7rO__all__Z_SOCKET_TIMEOUTZ_tmplr version_inforr#rr@rrBrWrrgriryr{rrrrjrirrrqrwrxrrrrr1rMrr0r!r!r!r"s <          ! #  !  &/  PKH]^YIpython3.10/site-packages/setuptools/__pycache__/extension.cpython-310.pycnu[o Xai@spddlZddlZddlZddlZddlZddlmZddZeZ eej j Z Gddde Z Gdd d e Z dS) N) get_unpatchedcCs0d}z t|dgdjWdStyYdSw)z0 Return True if Cython can be imported. zCython.Distutils.build_ext build_ext)fromlistTF) __import__r Exception)Z cython_implr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/extension.py _have_cython s r c@s eZdZdZddZddZdS) Extensionz7Extension that uses '.c' files in place of '.pyx' filescOs.|dd|_tj|||g|Ri|dS)Npy_limited_apiF)popr _Extension__init__)selfnamesourcesargskwrrr r!s zExtension.__init__cCsNtrdS|jp d}|dkrdnd}ttjd|}tt||j |_ dS)z Replace sources with .pyx extensions to sources with the target language extension. This mechanism allows language authors to supply pre-converted sources but to prefer the .pyx sources. Nzc++z.cppz.cz.pyx$) r languagelower functoolspartialresublistmapr)rlangZ target_extrrrr _convert_pyx_sources_to_lang's  z&Extension._convert_pyx_sources_to_langN)__name__ __module__ __qualname____doc__rrrrrr r s r c@seZdZdZdS)Libraryz=Just like a regular Extension, but built as a library insteadN)r r!r"r#rrrr r$6sr$)rrdistutils.core distutilsdistutils.errorsdistutils.extensionZmonkeyrr Z have_pyrexcorer rr$rrrr s  PKH]!e==Gpython3.10/site-packages/setuptools/__pycache__/sandbox.cpython-310.pycnu[o Xai 8@sddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z ddl mZejdrRddlmmmmZnejejZzeZWn eygdZYnweZgdZd-ddZejd-dd Z ejd d Z!ejd d Z"ejddZ#Gddde$Z%GdddZ&ejddZ'ddZ(ejddZ)ejddZ*hdZ+ddZ,dd Z-d!d"Z.Gd#d$d$Z/e0ed%rej1gZ2ngZ2Gd&d'd'e/Z3e4ej5d(d)d*6DZ7Gd+d,d,e Z8dS).N)DistutilsError) working_setjava)AbstractSandboxDirectorySandboxSandboxViolation run_setupcCs^d}t|| }|}Wdn1swY|dur!|}t||d}t|||dS)z. Python 3 implementation of execfile. rbNexec)openreadcompiler )filenameglobalslocalsmodestreamscriptcoder/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/sandbox.py _execfile$s   rc csRtjdd}|dur|tjdd<z |VW|tjdd<dS|tjdd<wN)sysargv)replsavedrrr save_argv1s"rc cs<tjdd}z |VW|tjdd<dS|tjdd<wr)rpathrrrr save_path<s "r ccs8tj|ddtj}|t_z dVW|t_dS|t_w)zL Monkey-patch tempfile.tempdir with replacement, ensuring it exists T)exist_okN)osmakedirstempfiletempdir) replacementrrrr override_tempEsr'c cs8t}t|z |VWt|dSt|wr)r"getcwdchdir)targetrrrrpushdVs  r+c@seZdZdZeddZdS)UnpickleableExceptionzP An exception representing another Exception that could not be pickled. c CsJz t|t|fWSty$ddlm}|||t|YSw)z Always return a dumped (pickled) type and exc. If exc can't be pickled, wrap it in UnpickleableException first. r)r,)pickledumps Exceptionsetuptools.sandboxr,dumprepr)typeexcclsrrrr1es   zUnpickleableException.dumpN)__name__ __module__ __qualname____doc__ staticmethodr1rrrrr,`sr,c@s(eZdZdZddZddZddZdS) ExceptionSaverz^ A Context Manager that will save an exception, serialized, and restore it later. cCs|Srrselfrrr __enter__zszExceptionSaver.__enter__cCs |sdSt|||_||_dSNT)r,r1_saved_tb)r=r3r4tbrrr__exit__}s zExceptionSaver.__exit__cCs.dt|vrdSttj|j\}}||j)z"restore and re-raise any exceptionr@N)varsmapr-loadsr@with_tracebackrA)r=r3r4rrrresumes  zExceptionSaver.resumeN)r6r7r8r9r>rCrHrrrrr;ts  r;c#sltjt }VWdn1swYtjfddtjD}t||dS)z Context in which imported modules are saved. Translates exceptions internal to the context into the equivalent exception outside the context. Nc3s&|]}|vr|ds|VqdS)z encodings.N startswith).0mod_namerrr szsave_modules..)rmodulescopyr;update_clear_modulesrH) saved_excZ del_modulesrrr save_moduless    rScCst|D]}tj|=qdSr)listrrN)Z module_namesrLrrrrQs  rQc cs.t}z |VWt|dSt|wr) pkg_resources __getstate__ __setstate__rrrrsave_pkg_resources_states rXc cs"tj|d}t|t`tMtt7t|#t |t ddVWdn1s6wYWdn1sEwYWdn1sTwYWdn1scwYWdn1srwYWddSWddS1swYdS)Ntemp setuptools) r"rjoinrXrSr hide_setuptoolsrr'r+ __import__) setup_dirtemp_dirrrr setup_contexts.  "r`>ZCythonrUrZ distutils_distutils_hackcCs|ddd}|tvS)aH >>> _needs_hiding('setuptools') True >>> _needs_hiding('pkg_resources') True >>> _needs_hiding('setuptools_plugin') False >>> _needs_hiding('setuptools.__init__') True >>> _needs_hiding('distutils') True >>> _needs_hiding('os') False >>> _needs_hiding('Cython') True .r)split_MODULES_TO_HIDE)rL base_modulerrr _needs_hidingsrhcCs6tjdd}|dur|tttj}t|dS)a% Remove references to setuptools' modules from sys.modules to allow the invocation to import the most appropriate setuptools. This technique is necessary to avoid issues such as #315 where setuptools upgrading itself would fail to find a function declared in the metadata. rbN)rrNgetZ remove_shimfilterrhrQ)rbrNrrrr\s   r\c Cs tjtj|}t|mz@|gt|tjdd<tjd|t t j ddt |t|dd}t||Wdn1sIwYWntyj}z|jr`|jdr`WYd}~n d}~wwWddSWddS1s~wYdS)z8Run a distutils setup script, sandboxed in its directoryNrcSs|Sr)activate)distrrrszrun_setup..__main__)__file__r6)r"rabspathdirnamer`rTrrinsertr__init__ callbacksappendrdictr SystemExitargs)Z setup_scriptrxr^nsvrrrrs*    "rc@seZdZdZdZddZddZddZd d Zd d Z d dZ dD]Z e e e r0e e ee <q"d$ddZer=edeZedeZdD]Z e e e rRee ee <qDddZdD]Z e e e rgee ee <qYddZdD]Z e e e r|ee ee <qnddZddZd d!Zd"d#ZdS)%rzDWrap 'os' module and 'open()' builtin for virtualizing setup scriptsFcsfddttD_dS)Ncs$g|]}|dst|r|qS)_)rJhasattr)rKnamer<rr sz,AbstractSandbox.__init__..)dir_os_attrsr<rr<rrss  zAbstractSandbox.__init__cCs"|jD] }tt|t||qdSr)rsetattrr"getattr)r=sourcer}rrr_copys zAbstractSandbox._copycCs(||tr |jt_|jt_d|_dSr?)r_filebuiltinsfile_openr _activer<rrrr>s  zAbstractSandbox.__enter__cCs$d|_trtt_tt_|tdSNF)rrrrrr rr)r=exc_type exc_value tracebackrrrrC!s zAbstractSandbox.__exit__cCs.| |WdS1swYdS)zRun 'func' under os sandboxingNr)r=funcrrrrun(s$zAbstractSandbox.runcttfdd}|S)Ncs>|jr|j||g|Ri|\}}||g|Ri|Sr)r _remap_pair)r=srcdstrxkwr}originalrrwrap0s z3AbstractSandbox._mk_dual_path_wrapper..wraprrr}rrrr_mk_dual_path_wrapper-s z%AbstractSandbox._mk_dual_path_wrapper)renamelinksymlinkNcs pttfdd}|S)Ncs6|jr|j|g|Ri|}|g|Ri|Sr)r _remap_inputr=rrxrrrrr>sz5AbstractSandbox._mk_single_path_wrapper..wrapr)r}rrrrr_mk_single_path_wrapper;sz'AbstractSandbox._mk_single_path_wrapperrr )statlistdirr)r chmodchownmkdirremoveunlinkrmdirutimelchownchrootlstatZ startfilemkfifomknodpathconfaccesscr)NcsT|jr|j|g|Ri|}||g|Ri|S|g|Ri|Sr)rr _remap_outputrrrrrcsz4AbstractSandbox._mk_single_with_return..wraprrrrr_mk_single_with_return` z&AbstractSandbox._mk_single_with_return)readlinktempnamcr)Ncs$|i|}|jr||S|Sr)rr)r=rxrretvalrrrrrs z'AbstractSandbox._mk_query..wraprrrrr _mk_queryorzAbstractSandbox._mk_query)r(tmpnamcCs|S)z=Called to remap or validate any path, whether input or outputr)r=rrrr_validate_path~szAbstractSandbox._validate_pathcO ||SzCalled for path inputsrr= operationrrxrrrrr zAbstractSandbox._remap_inputcCr)zCalled for path outputsr)r=rrrrrrrzAbstractSandbox._remap_outputcOs<|j|d|g|Ri||j|d|g|Ri|fS)?Called for path pairs like rename, link, and symlink operationsz-fromz-to)rr=rrrrxrrrrrszAbstractSandbox._remap_pairr)r6r7r8r9rrsrr>rCrrr}r|rrrrrrrrrrrrrrrr sF        rdevnullc@seZdZdZegdZgZ efddZ ddZ e r!ddd Z dd d Z d d Z ddZddZddZddZdddZdS)rz.) r"rrr_sandboxr[_prefix _exceptionsrrs)r=Zsandbox exceptionsrrrrss zDirectorySandbox.__init__cOsddlm}||||)Nr)r)r0r)r=rrxrrrrr _violations  zDirectorySandbox._violationrcOF|dvr||s|jd||g|Ri|t||g|Ri|S)Nrrtr ZrUUr)_okrrr=rrrxrrrrrzDirectorySandbox._filecOr)Nrr )rrrrrrrrrzDirectorySandbox._opencCs|ddS)Nr)rr<rrrrszDirectorySandbox.tmpnamcCsR|j}z!d|_tjtj|}||p ||jkp ||jW||_S||_wr) rr"rrr _exemptedrrJr)r=ractiverrrrrs  zDirectorySandbox._okcs<fdd|jD}fdd|jD}t||}t|S)Nc3s|]}|VqdSrrI)rK exceptionfilepathrrrMs  z-DirectorySandbox._exempted..c3s|] }t|VqdSr)rematch)rKpatternrrrrMs  )r_exception_patterns itertoolschainany)r=rZ start_matchesZpattern_matches candidatesrrrrs   zDirectorySandbox._exemptedcOs:||jvr||s|j|tj|g|Ri||Sr) write_opsrrr"rrrrrrrs"zDirectorySandbox._remap_inputcOs8||r ||s|j|||g|Ri|||fS)r)rrrrrrrszDirectorySandbox._remap_paircOsL|t@r||s|jd|||g|Ri|tj|||g|Ri|S)zCalled for low-level os.open()zos.open) WRITE_FLAGSrrrr )r=rflagsrrxrrrrr szDirectorySandbox.openN)r)r)r6r7r8r9rvfromkeysrr _EXCEPTIONSrsrrrrrrrrr rrrrrs$     rcCsg|]}tt|dqS)rr)rKarrrr~s r~z4O_WRONLY O_RDWR O_APPEND O_CREAT O_TRUNC O_TEMPORARYc@s&eZdZdZedZddZdS)rzEA setup script attempted to modify the filesystem outside the sandboxa SandboxViolation: {cmd}{args!r} {kwargs} The package setup script has attempted to modify files on your system that are not within the EasyInstall build area, and has been aborted. This package cannot be safely installed by EasyInstall, and may not support alternate installation locations even if you run its setup script by hand. Please inform the package's author and the EasyInstall maintainers to find out if a fix or workaround is available. cCs |j\}}}|jjditS)Nr)rxtmplformatr)r=cmdrxkwargsrrr__str__s zSandboxViolation.__str__N) r6r7r8r9textwrapdedentlstriprrrrrrrs  rr)9r"rr$operator functoolsrr contextlibr-rrrUdistutils.errorsrrplatformrJZ$org.python.modules.posix.PosixModulepythonrNposixZ PosixModulerr}rr NameErrorr r__all__rcontextmanagerrr r'r+r/r,r;rSrQrXr`rfrhr\rrr|rrrreduceor_rerrrrrrsv                 ^ PKH]{ѳJpython3.10/site-packages/setuptools/__pycache__/py34compat.cpython-310.pycnu[o Xai@sTddlZzddlZWn eyYnwzejjZWdSey)ddZYdSw)NcCs|j|jS)N)loader load_modulename)specr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/py34compat.pymodule_from_spec sr) importlibimportlib.util ImportErrorutilrAttributeErrorrrrrs   PKH]YSSDpython3.10/site-packages/setuptools/__pycache__/_imp.cpython-310.pycnu[o XaiX @sddZddlZddlZddlZddlmZdZdZdZ dZ dZ d d Z dd d Z dd dZddZdS)zX Re-implementation of find_module and get_frozen_object from the deprecated imp module. N)module_from_speccCs(t|tr tjjntjj}|||SN) isinstancelist importlib machinery PathFinder find_specutil)modulepathsfinderr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_imp.pyrs  rc CsJt||}|durtd||jst|drtjd|j}d}d}t|jt }|j dks8|rAt |jtj j rAt}d}d}}n\|j dksP|rYt |jtj jrYt}d}d}}nD|jr|j }tj|d }|tj jvrod nd }|tj jvrzt}n|tj jvrt}n|tj jvrt}|tthvrt||}nd}d}}|||||ffS) z7Just like 'imp.find_module()', but with package supportN Can't find %ssubmodule_search_locationsz __init__.pyfrozenzbuilt-inrrrb)r ImportError has_locationhasattrr rspec_from_loaderloaderr typeorigin issubclassr FrozenImporter PY_FROZENBuiltinImporter C_BUILTINospathsplitextSOURCE_SUFFIXES PY_SOURCEBYTECODE_SUFFIXES PY_COMPILEDEXTENSION_SUFFIXES C_EXTENSIONopen) rrspeckindfileZstaticr)suffixmoderrr find_modulesH            r7cCs&t||}|s td||j|SNr)rrr get_code)rrr2rrrget_frozen_objectGs   r:cCs"t||}|s td|t|Sr8)rrr)rrinfor2rrr get_moduleNs  r<r)__doc__r(importlib.utilr importlib.machineryZ py34compatrr,r.r0r'r%rr7r:r<rrrrs  * PKH]|]xܐHpython3.10/site-packages/setuptools/__pycache__/dep_util.cpython-310.pycnu[o Xai@sddlmZddZdS)) newer_groupcCsht|t|kr tdg}g}tt|D]}t||||r/||||||q||fS)zWalk both arguments in parallel, testing if each source group is newer than its corresponding target. Returns a pair of lists (sources_groups, targets) where sources is newer than target, according to the semantics of 'newer_group()'. z5'sources_group' and 'targets' must be the same length)len ValueErrorrangerappend)Zsources_groupstargets n_sources n_targetsir /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/dep_util.pynewer_pairwise_groupsr N)distutils.dep_utilrr r r r r s PKH]A&Epython3.10/site-packages/setuptools/__pycache__/wheel.cpython-310.pycnu[o Xai` @sdZddlmZddlmZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl m Z ddlmZddlmZddlmZe d e jjZd Zd d ZGd ddZdS)zWheels support.) get_platform)logN) parse_version)sys_tags)canonicalize_name)write_requirementsz^(?P.+?)-(?P\d.*?) ((-(?P\d.*?))?-(?P.+?)-(?P.+?)-(?P.+?) )\.whl$z8__import__('pkg_resources').declare_namespace(__name__) c Cst|D]Q\}}}tj||}|D]}tj||}tj|||}t||qttt|D]"\} } tj|| }tj||| }tj |sUt|||| =q3qtj|ddD]\}}}|rgJt |q^dS)zDMove everything under `src_dir` to `dst_dir`, and delete the former.T)topdownN) oswalkpathrelpathjoinrenamesreversedlist enumerateexistsrmdir) src_dirZdst_dirdirpathdirnames filenamessubdirfsrcdstndr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/wheel.pyunpacks$    r c@sheZdZddZddZddZddZd d Zd d Zd dZ e ddZ e ddZ e ddZ dS)WheelcCsPttj|}|durtd|||_|D] \}}t|||qdS)Nzinvalid wheel name: %r) WHEEL_NAMEr r basename ValueErrorfilename groupdictitemssetattr)selfr%matchkvrrr__init__6s zWheel.__init__cCs&t|jd|jd|jdS)z>List tags (py_version, abi, platform) supported by this wheel..) itertoolsproduct py_versionsplitabiplatformr)rrrtags>s    z Wheel.tagscs0tddtDtfdd|DdS)z5Is the wheel is compatible with the current platform?css |] }|j|j|jfVqdSN) interpreterr3r4.0trrr Hs z&Wheel.is_compatible..c3s|] }|vrdVqdS)TNrr9supported_tagsrrr<JsF)setrnextr6r5rr=r is_compatibleFszWheel.is_compatiblecCs,tj|j|j|jdkr dntddS)Nany) project_nameversionr4z.egg) pkg_resources DistributionrCrDr4regg_namer5rrrrGLs zWheel.egg_namecCsF|D]}t|}|drt|t|jr|Sqtd)Nz .dist-infoz.unsupported wheel format. .dist-info not found)namelist posixpathdirnameendswithr startswithrCr$)r)zfmemberrJrrr get_dist_infoRs   zWheel.get_dist_infocCs>t|j}|||WddS1swYdS)z"Install wheel as an egg directory.N)zipfileZipFiler%_install_as_egg)r)destination_eggdirrMrrrinstall_as_egg\s"zWheel.install_as_eggcCs\d|j|jf}||}d|}tj|d}|||||||||||dS)Nz%s-%sz%s.dataEGG-INFO) rCrDrOr r r _convert_metadata_move_data_entries_fix_namespace_packages)r)rSrMZ dist_basename dist_info dist_dataegg_inforrrrRas  zWheel._install_as_eggc sTfdd}|d}t|d}td|kotdkn}|s*td|t||tj|tj j |t |dd d t t tfd d jD}t|ttj|d tj|dtj t|dd} tjj} ttjzt| ddtj|dWt| dSt| w)NcsTt|}|d}tj|WdS1s#wYdS)Nzutf-8) openrIr readdecodeemailparserParserparsestr)namefpvalue)rYrMrr get_metadatams$z-Wheel._convert_metadata..get_metadataZWHEELz Wheel-Versionz1.0z2.0dev0z$unsupported wheel format version: %s)metadatacSsd|_t|Sr7)markerstr)reqrrrraw_reqsz(Wheel._convert_metadata..raw_reqc s2i|]}|tfddt|fDqS)c3s|] }|vr|VqdSr7r)r:rj)install_requiresrrr<sz5Wheel._convert_metadata...)sortedmaprequires)r:extra)distrlrkrr s z+Wheel._convert_metadata..METADATAzPKG-INFO)rlextras_require)attrsr[z requires.txt)rgetr$r mkdir extractallr r rErF from_location PathMetadatarrmrnroextrasrename setuptoolsdictr _global_log threshold set_thresholdWARNrget_command_obj) rMrSrYr[rfwheel_metadata wheel_versionZwheel_v1rtZ setup_distZ log_thresholdr)rqrYrlrkrMrrVksR        zWheel._convert_metadatacstj|tjd}tj|rNtj|dd}t|t|D]"}|dr8ttj||q&ttj||tj||q&t |t tjjfdddDD]}t ||q\tjrqt dSdS)z,Move data entries to their correct location.scriptsrUz.pycc3s|] }tj|VqdSr7)r r r )r:rrZrrr<s  z+Wheel._move_data_entries..)dataheaderspurelibplatlibN) r r r rrwlistdirrKunlinkr|rfilterr )rSrZZdist_data_scriptsZegg_info_scriptsentryrrrrrWs,        zWheel._move_data_entriesc Cstj|d}tj|rkt|}|}Wdn1s"wY|D]C}tjj|g|dR}tj|d}tj|sJt|tj|sjt|d }|t Wdn1sewYq)dSdS)Nznamespace_packages.txtr.z __init__.pyw) r r r rr\r]r2rwwriteNAMESPACE_PACKAGE_INIT)r[rSZnamespace_packagesrdmodZmod_dirZmod_initrrrrXs&       zWheel._fix_namespace_packagesN)__name__ __module__ __qualname__r-r6rArGrOrTrR staticmethodrVrWrXrrrrr!4s  ? r!)__doc__distutils.utilr distutilsrr_r/r rIrerPrEr}rZ setuptools.extern.packaging.tagsrZ!setuptools.extern.packaging.utilsrZsetuptools.command.egg_inforcompileVERBOSEr*r"rr r!rrrrs2      PKH]N7((((1python3.10/site-packages/setuptools/build_meta.pynu["""A PEP 517 interface to setuptools Previously, when a user or a command line tool (let's call it a "frontend") needed to make a request of setuptools to take a certain action, for example, generating a list of installation requirements, the frontend would would call "setup.py egg_info" or "setup.py bdist_wheel" on the command line. PEP 517 defines a different method of interfacing with setuptools. Rather than calling "setup.py" directly, the frontend should: 1. Set the current directory to the directory with a setup.py file 2. Import this module into a safe python interpreter (one in which setuptools can potentially set global variables or crash hard). 3. Call one of the functions defined in PEP 517. What each function does is defined in PEP 517. However, here is a "casual" definition of the functions (this definition should not be relied on for bug reports or API stability): - `build_wheel`: build a wheel in the folder and return the basename - `get_requires_for_build_wheel`: get the `setup_requires` to build - `prepare_metadata_for_build_wheel`: get the `install_requires` - `build_sdist`: build an sdist in the folder and return the basename - `get_requires_for_build_sdist`: get the `setup_requires` to build Again, this is not a formal definition! Just a "taste" of the module. """ import io import os import sys import tokenize import shutil import contextlib import tempfile import setuptools import distutils from pkg_resources import parse_requirements __all__ = ['get_requires_for_build_sdist', 'get_requires_for_build_wheel', 'prepare_metadata_for_build_wheel', 'build_wheel', 'build_sdist', '__legacy__', 'SetupRequirementsError'] class SetupRequirementsError(BaseException): def __init__(self, specifiers): self.specifiers = specifiers class Distribution(setuptools.dist.Distribution): def fetch_build_eggs(self, specifiers): specifier_list = list(map(str, parse_requirements(specifiers))) raise SetupRequirementsError(specifier_list) @classmethod @contextlib.contextmanager def patch(cls): """ Replace distutils.dist.Distribution with this class for the duration of this context. """ orig = distutils.core.Distribution distutils.core.Distribution = cls try: yield finally: distutils.core.Distribution = orig @contextlib.contextmanager def no_install_setup_requires(): """Temporarily disable installing setup_requires Under PEP 517, the backend reports build dependencies to the frontend, and the frontend is responsible for ensuring they're installed. So setuptools (acting as a backend) should not try to install them. """ orig = setuptools._install_setup_requires setuptools._install_setup_requires = lambda attrs: None try: yield finally: setuptools._install_setup_requires = orig def _get_immediate_subdirectories(a_dir): return [name for name in os.listdir(a_dir) if os.path.isdir(os.path.join(a_dir, name))] def _file_with_extension(directory, extension): matching = ( f for f in os.listdir(directory) if f.endswith(extension) ) try: file, = matching except ValueError: raise ValueError( 'No distribution was found. Ensure that `setup.py` ' 'is not empty and that it calls `setup()`.') return file def _open_setup_script(setup_script): if not os.path.exists(setup_script): # Supply a default setup.py return io.StringIO(u"from setuptools import setup; setup()") return getattr(tokenize, 'open', open)(setup_script) class _BuildMetaBackend(object): def _fix_config(self, config_settings): config_settings = config_settings or {} config_settings.setdefault('--global-option', []) return config_settings def _get_build_requires(self, config_settings, requirements): config_settings = self._fix_config(config_settings) sys.argv = sys.argv[:1] + ['egg_info'] + \ config_settings["--global-option"] try: with Distribution.patch(): self.run_setup() except SetupRequirementsError as e: requirements += e.specifiers return requirements def run_setup(self, setup_script='setup.py'): # Note that we can reuse our build directory between calls # Correctness comes first, then optimization later __file__ = setup_script __name__ = '__main__' with _open_setup_script(__file__) as f: code = f.read().replace(r'\r\n', r'\n') exec(compile(code, __file__, 'exec'), locals()) def get_requires_for_build_wheel(self, config_settings=None): config_settings = self._fix_config(config_settings) return self._get_build_requires( config_settings, requirements=['wheel']) def get_requires_for_build_sdist(self, config_settings=None): config_settings = self._fix_config(config_settings) return self._get_build_requires(config_settings, requirements=[]) def prepare_metadata_for_build_wheel(self, metadata_directory, config_settings=None): sys.argv = sys.argv[:1] + [ 'dist_info', '--egg-base', metadata_directory] with no_install_setup_requires(): self.run_setup() dist_info_directory = metadata_directory while True: dist_infos = [f for f in os.listdir(dist_info_directory) if f.endswith('.dist-info')] if ( len(dist_infos) == 0 and len(_get_immediate_subdirectories(dist_info_directory)) == 1 ): dist_info_directory = os.path.join( dist_info_directory, os.listdir(dist_info_directory)[0]) continue assert len(dist_infos) == 1 break # PEP 517 requires that the .dist-info directory be placed in the # metadata_directory. To comply, we MUST copy the directory to the root if dist_info_directory != metadata_directory: shutil.move( os.path.join(dist_info_directory, dist_infos[0]), metadata_directory) shutil.rmtree(dist_info_directory, ignore_errors=True) return dist_infos[0] def _build_with_temp_dir(self, setup_command, result_extension, result_directory, config_settings): config_settings = self._fix_config(config_settings) result_directory = os.path.abspath(result_directory) # Build in a temporary directory, then copy to the target. os.makedirs(result_directory, exist_ok=True) with tempfile.TemporaryDirectory(dir=result_directory) as tmp_dist_dir: sys.argv = (sys.argv[:1] + setup_command + ['--dist-dir', tmp_dist_dir] + config_settings["--global-option"]) with no_install_setup_requires(): self.run_setup() result_basename = _file_with_extension( tmp_dist_dir, result_extension) result_path = os.path.join(result_directory, result_basename) if os.path.exists(result_path): # os.rename will fail overwriting on non-Unix. os.remove(result_path) os.rename(os.path.join(tmp_dist_dir, result_basename), result_path) return result_basename def build_wheel(self, wheel_directory, config_settings=None, metadata_directory=None): return self._build_with_temp_dir(['bdist_wheel'], '.whl', wheel_directory, config_settings) def build_sdist(self, sdist_directory, config_settings=None): return self._build_with_temp_dir(['sdist', '--formats', 'gztar'], '.tar.gz', sdist_directory, config_settings) class _BuildMetaLegacyBackend(_BuildMetaBackend): """Compatibility backend for setuptools This is a version of setuptools.build_meta that endeavors to maintain backwards compatibility with pre-PEP 517 modes of invocation. It exists as a temporary bridge between the old packaging mechanism and the new packaging mechanism, and will eventually be removed. """ def run_setup(self, setup_script='setup.py'): # In order to maintain compatibility with scripts assuming that # the setup.py script is in a directory on the PYTHONPATH, inject # '' into sys.path. (pypa/setuptools#1642) sys_path = list(sys.path) # Save the original path script_dir = os.path.dirname(os.path.abspath(setup_script)) if script_dir not in sys.path: sys.path.insert(0, script_dir) # Some setup.py scripts (e.g. in pygame and numpy) use sys.argv[0] to # get the directory of the source code. They expect it to refer to the # setup.py script. sys_argv_0 = sys.argv[0] sys.argv[0] = setup_script try: super(_BuildMetaLegacyBackend, self).run_setup(setup_script=setup_script) finally: # While PEP 517 frontends should be calling each hook in a fresh # subprocess according to the standard (and thus it should not be # strictly necessary to restore the old sys.path), we'll restore # the original path so that the path manipulation does not persist # within the hook after run_setup is called. sys.path[:] = sys_path sys.argv[0] = sys_argv_0 # The primary backend _BACKEND = _BuildMetaBackend() get_requires_for_build_wheel = _BACKEND.get_requires_for_build_wheel get_requires_for_build_sdist = _BACKEND.get_requires_for_build_sdist prepare_metadata_for_build_wheel = _BACKEND.prepare_metadata_for_build_wheel build_wheel = _BACKEND.build_wheel build_sdist = _BACKEND.build_sdist # The legacy backend __legacy__ = _BuildMetaLegacyBackend() PKH]VD1python3.10/site-packages/setuptools/py34compat.pynu[import importlib try: import importlib.util except ImportError: pass try: module_from_spec = importlib.util.module_from_spec except AttributeError: def module_from_spec(spec): return spec.loader.load_module(spec.name) PKH]Q 8 8.python3.10/site-packages/setuptools/sandbox.pynu[import os import sys import tempfile import operator import functools import itertools import re import contextlib import pickle import textwrap import builtins import pkg_resources from distutils.errors import DistutilsError from pkg_resources import working_set if sys.platform.startswith('java'): import org.python.modules.posix.PosixModule as _os else: _os = sys.modules[os.name] try: _file = file except NameError: _file = None _open = open __all__ = [ "AbstractSandbox", "DirectorySandbox", "SandboxViolation", "run_setup", ] def _execfile(filename, globals, locals=None): """ Python 3 implementation of execfile. """ mode = 'rb' with open(filename, mode) as stream: script = stream.read() if locals is None: locals = globals code = compile(script, filename, 'exec') exec(code, globals, locals) @contextlib.contextmanager def save_argv(repl=None): saved = sys.argv[:] if repl is not None: sys.argv[:] = repl try: yield saved finally: sys.argv[:] = saved @contextlib.contextmanager def save_path(): saved = sys.path[:] try: yield saved finally: sys.path[:] = saved @contextlib.contextmanager def override_temp(replacement): """ Monkey-patch tempfile.tempdir with replacement, ensuring it exists """ os.makedirs(replacement, exist_ok=True) saved = tempfile.tempdir tempfile.tempdir = replacement try: yield finally: tempfile.tempdir = saved @contextlib.contextmanager def pushd(target): saved = os.getcwd() os.chdir(target) try: yield saved finally: os.chdir(saved) class UnpickleableException(Exception): """ An exception representing another Exception that could not be pickled. """ @staticmethod def dump(type, exc): """ Always return a dumped (pickled) type and exc. If exc can't be pickled, wrap it in UnpickleableException first. """ try: return pickle.dumps(type), pickle.dumps(exc) except Exception: # get UnpickleableException inside the sandbox from setuptools.sandbox import UnpickleableException as cls return cls.dump(cls, cls(repr(exc))) class ExceptionSaver: """ A Context Manager that will save an exception, serialized, and restore it later. """ def __enter__(self): return self def __exit__(self, type, exc, tb): if not exc: return # dump the exception self._saved = UnpickleableException.dump(type, exc) self._tb = tb # suppress the exception return True def resume(self): "restore and re-raise any exception" if '_saved' not in vars(self): return type, exc = map(pickle.loads, self._saved) raise exc.with_traceback(self._tb) @contextlib.contextmanager def save_modules(): """ Context in which imported modules are saved. Translates exceptions internal to the context into the equivalent exception outside the context. """ saved = sys.modules.copy() with ExceptionSaver() as saved_exc: yield saved sys.modules.update(saved) # remove any modules imported since del_modules = ( mod_name for mod_name in sys.modules if mod_name not in saved # exclude any encodings modules. See #285 and not mod_name.startswith('encodings.') ) _clear_modules(del_modules) saved_exc.resume() def _clear_modules(module_names): for mod_name in list(module_names): del sys.modules[mod_name] @contextlib.contextmanager def save_pkg_resources_state(): saved = pkg_resources.__getstate__() try: yield saved finally: pkg_resources.__setstate__(saved) @contextlib.contextmanager def setup_context(setup_dir): temp_dir = os.path.join(setup_dir, 'temp') with save_pkg_resources_state(): with save_modules(): with save_path(): hide_setuptools() with save_argv(): with override_temp(temp_dir): with pushd(setup_dir): # ensure setuptools commands are available __import__('setuptools') yield _MODULES_TO_HIDE = { 'setuptools', 'distutils', 'pkg_resources', 'Cython', '_distutils_hack', } def _needs_hiding(mod_name): """ >>> _needs_hiding('setuptools') True >>> _needs_hiding('pkg_resources') True >>> _needs_hiding('setuptools_plugin') False >>> _needs_hiding('setuptools.__init__') True >>> _needs_hiding('distutils') True >>> _needs_hiding('os') False >>> _needs_hiding('Cython') True """ base_module = mod_name.split('.', 1)[0] return base_module in _MODULES_TO_HIDE def hide_setuptools(): """ Remove references to setuptools' modules from sys.modules to allow the invocation to import the most appropriate setuptools. This technique is necessary to avoid issues such as #315 where setuptools upgrading itself would fail to find a function declared in the metadata. """ _distutils_hack = sys.modules.get('_distutils_hack', None) if _distutils_hack is not None: _distutils_hack.remove_shim() modules = filter(_needs_hiding, sys.modules) _clear_modules(modules) def run_setup(setup_script, args): """Run a distutils setup script, sandboxed in its directory""" setup_dir = os.path.abspath(os.path.dirname(setup_script)) with setup_context(setup_dir): try: sys.argv[:] = [setup_script] + list(args) sys.path.insert(0, setup_dir) # reset to include setup dir, w/clean callback list working_set.__init__() working_set.callbacks.append(lambda dist: dist.activate()) with DirectorySandbox(setup_dir): ns = dict(__file__=setup_script, __name__='__main__') _execfile(setup_script, ns) except SystemExit as v: if v.args and v.args[0]: raise # Normal exit, just return class AbstractSandbox: """Wrap 'os' module and 'open()' builtin for virtualizing setup scripts""" _active = False def __init__(self): self._attrs = [ name for name in dir(_os) if not name.startswith('_') and hasattr(self, name) ] def _copy(self, source): for name in self._attrs: setattr(os, name, getattr(source, name)) def __enter__(self): self._copy(self) if _file: builtins.file = self._file builtins.open = self._open self._active = True def __exit__(self, exc_type, exc_value, traceback): self._active = False if _file: builtins.file = _file builtins.open = _open self._copy(_os) def run(self, func): """Run 'func' under os sandboxing""" with self: return func() def _mk_dual_path_wrapper(name): original = getattr(_os, name) def wrap(self, src, dst, *args, **kw): if self._active: src, dst = self._remap_pair(name, src, dst, *args, **kw) return original(src, dst, *args, **kw) return wrap for name in ["rename", "link", "symlink"]: if hasattr(_os, name): locals()[name] = _mk_dual_path_wrapper(name) def _mk_single_path_wrapper(name, original=None): original = original or getattr(_os, name) def wrap(self, path, *args, **kw): if self._active: path = self._remap_input(name, path, *args, **kw) return original(path, *args, **kw) return wrap if _file: _file = _mk_single_path_wrapper('file', _file) _open = _mk_single_path_wrapper('open', _open) for name in [ "stat", "listdir", "chdir", "open", "chmod", "chown", "mkdir", "remove", "unlink", "rmdir", "utime", "lchown", "chroot", "lstat", "startfile", "mkfifo", "mknod", "pathconf", "access", ]: if hasattr(_os, name): locals()[name] = _mk_single_path_wrapper(name) def _mk_single_with_return(name): original = getattr(_os, name) def wrap(self, path, *args, **kw): if self._active: path = self._remap_input(name, path, *args, **kw) return self._remap_output(name, original(path, *args, **kw)) return original(path, *args, **kw) return wrap for name in ['readlink', 'tempnam']: if hasattr(_os, name): locals()[name] = _mk_single_with_return(name) def _mk_query(name): original = getattr(_os, name) def wrap(self, *args, **kw): retval = original(*args, **kw) if self._active: return self._remap_output(name, retval) return retval return wrap for name in ['getcwd', 'tmpnam']: if hasattr(_os, name): locals()[name] = _mk_query(name) def _validate_path(self, path): """Called to remap or validate any path, whether input or output""" return path def _remap_input(self, operation, path, *args, **kw): """Called for path inputs""" return self._validate_path(path) def _remap_output(self, operation, path): """Called for path outputs""" return self._validate_path(path) def _remap_pair(self, operation, src, dst, *args, **kw): """Called for path pairs like rename, link, and symlink operations""" return ( self._remap_input(operation + '-from', src, *args, **kw), self._remap_input(operation + '-to', dst, *args, **kw), ) if hasattr(os, 'devnull'): _EXCEPTIONS = [os.devnull] else: _EXCEPTIONS = [] class DirectorySandbox(AbstractSandbox): """Restrict operations to a single subdirectory - pseudo-chroot""" write_ops = dict.fromkeys( [ "open", "chmod", "chown", "mkdir", "remove", "unlink", "rmdir", "utime", "lchown", "chroot", "mkfifo", "mknod", "tempnam", ] ) _exception_patterns = [] "exempt writing to paths that match the pattern" def __init__(self, sandbox, exceptions=_EXCEPTIONS): self._sandbox = os.path.normcase(os.path.realpath(sandbox)) self._prefix = os.path.join(self._sandbox, '') self._exceptions = [ os.path.normcase(os.path.realpath(path)) for path in exceptions ] AbstractSandbox.__init__(self) def _violation(self, operation, *args, **kw): from setuptools.sandbox import SandboxViolation raise SandboxViolation(operation, args, kw) if _file: def _file(self, path, mode='r', *args, **kw): if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path): self._violation("file", path, mode, *args, **kw) return _file(path, mode, *args, **kw) def _open(self, path, mode='r', *args, **kw): if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path): self._violation("open", path, mode, *args, **kw) return _open(path, mode, *args, **kw) def tmpnam(self): self._violation("tmpnam") def _ok(self, path): active = self._active try: self._active = False realpath = os.path.normcase(os.path.realpath(path)) return ( self._exempted(realpath) or realpath == self._sandbox or realpath.startswith(self._prefix) ) finally: self._active = active def _exempted(self, filepath): start_matches = ( filepath.startswith(exception) for exception in self._exceptions ) pattern_matches = ( re.match(pattern, filepath) for pattern in self._exception_patterns ) candidates = itertools.chain(start_matches, pattern_matches) return any(candidates) def _remap_input(self, operation, path, *args, **kw): """Called for path inputs""" if operation in self.write_ops and not self._ok(path): self._violation(operation, os.path.realpath(path), *args, **kw) return path def _remap_pair(self, operation, src, dst, *args, **kw): """Called for path pairs like rename, link, and symlink operations""" if not self._ok(src) or not self._ok(dst): self._violation(operation, src, dst, *args, **kw) return (src, dst) def open(self, file, flags, mode=0o777, *args, **kw): """Called for low-level os.open()""" if flags & WRITE_FLAGS and not self._ok(file): self._violation("os.open", file, flags, mode, *args, **kw) return _os.open(file, flags, mode, *args, **kw) WRITE_FLAGS = functools.reduce( operator.or_, [ getattr(_os, a, 0) for a in "O_WRONLY O_RDWR O_APPEND O_CREAT O_TRUNC O_TEMPORARY".split() ], ) class SandboxViolation(DistutilsError): """A setup script attempted to modify the filesystem outside the sandbox""" tmpl = textwrap.dedent( """ SandboxViolation: {cmd}{args!r} {kwargs} The package setup script has attempted to modify files on your system that are not within the EasyInstall build area, and has been aborted. This package cannot be safely installed by EasyInstall, and may not support alternate installation locations even if you run its setup script by hand. Please inform the package's author and the EasyInstall maintainers to find out if a fix or workaround is available. """ ).lstrip() def __str__(self): cmd, args, kwargs = self.args return self.tmpl.format(**locals()) PKH]Ԕ0python3.10/site-packages/setuptools/extension.pynu[import re import functools import distutils.core import distutils.errors import distutils.extension from .monkey import get_unpatched def _have_cython(): """ Return True if Cython can be imported. """ cython_impl = 'Cython.Distutils.build_ext' try: # from (cython_impl) import build_ext __import__(cython_impl, fromlist=['build_ext']).build_ext return True except Exception: pass return False # for compatibility have_pyrex = _have_cython _Extension = get_unpatched(distutils.core.Extension) class Extension(_Extension): """Extension that uses '.c' files in place of '.pyx' files""" def __init__(self, name, sources, *args, **kw): # The *args is needed for compatibility as calls may use positional # arguments. py_limited_api may be set only via keyword. self.py_limited_api = kw.pop("py_limited_api", False) _Extension.__init__(self, name, sources, *args, **kw) def _convert_pyx_sources_to_lang(self): """ Replace sources with .pyx extensions to sources with the target language extension. This mechanism allows language authors to supply pre-converted sources but to prefer the .pyx sources. """ if _have_cython(): # the build has Cython, so allow it to compile the .pyx files return lang = self.language or '' target_ext = '.cpp' if lang.lower() == 'c++' else '.c' sub = functools.partial(re.sub, '.pyx$', target_ext) self.sources = list(map(sub, self.sources)) class Library(Extension): """Just like a regular Extension, but built as a library instead""" PKH]Mj3python3.10/site-packages/setuptools/archive_util.pynu["""Utilities for extracting common archive formats""" import zipfile import tarfile import os import shutil import posixpath import contextlib from distutils.errors import DistutilsError from pkg_resources import ensure_directory __all__ = [ "unpack_archive", "unpack_zipfile", "unpack_tarfile", "default_filter", "UnrecognizedFormat", "extraction_drivers", "unpack_directory", ] class UnrecognizedFormat(DistutilsError): """Couldn't recognize the archive type""" def default_filter(src, dst): """The default progress/filter callback; returns True for all files""" return dst def unpack_archive( filename, extract_dir, progress_filter=default_filter, drivers=None): """Unpack `filename` to `extract_dir`, or raise ``UnrecognizedFormat`` `progress_filter` is a function taking two arguments: a source path internal to the archive ('/'-separated), and a filesystem path where it will be extracted. The callback must return the desired extract path (which may be the same as the one passed in), or else ``None`` to skip that file or directory. The callback can thus be used to report on the progress of the extraction, as well as to filter the items extracted or alter their extraction paths. `drivers`, if supplied, must be a non-empty sequence of functions with the same signature as this function (minus the `drivers` argument), that raise ``UnrecognizedFormat`` if they do not support extracting the designated archive type. The `drivers` are tried in sequence until one is found that does not raise an error, or until all are exhausted (in which case ``UnrecognizedFormat`` is raised). If you do not supply a sequence of drivers, the module's ``extraction_drivers`` constant will be used, which means that ``unpack_zipfile`` and ``unpack_tarfile`` will be tried, in that order. """ for driver in drivers or extraction_drivers: try: driver(filename, extract_dir, progress_filter) except UnrecognizedFormat: continue else: return else: raise UnrecognizedFormat( "Not a recognized archive type: %s" % filename ) def unpack_directory(filename, extract_dir, progress_filter=default_filter): """"Unpack" a directory, using the same interface as for archives Raises ``UnrecognizedFormat`` if `filename` is not a directory """ if not os.path.isdir(filename): raise UnrecognizedFormat("%s is not a directory" % filename) paths = { filename: ('', extract_dir), } for base, dirs, files in os.walk(filename): src, dst = paths[base] for d in dirs: paths[os.path.join(base, d)] = src + d + '/', os.path.join(dst, d) for f in files: target = os.path.join(dst, f) target = progress_filter(src + f, target) if not target: # skip non-files continue ensure_directory(target) f = os.path.join(base, f) shutil.copyfile(f, target) shutil.copystat(f, target) def unpack_zipfile(filename, extract_dir, progress_filter=default_filter): """Unpack zip `filename` to `extract_dir` Raises ``UnrecognizedFormat`` if `filename` is not a zipfile (as determined by ``zipfile.is_zipfile()``). See ``unpack_archive()`` for an explanation of the `progress_filter` argument. """ if not zipfile.is_zipfile(filename): raise UnrecognizedFormat("%s is not a zip file" % (filename,)) with zipfile.ZipFile(filename) as z: for info in z.infolist(): name = info.filename # don't extract absolute paths or ones with .. in them if name.startswith('/') or '..' in name.split('/'): continue target = os.path.join(extract_dir, *name.split('/')) target = progress_filter(name, target) if not target: continue if name.endswith('/'): # directory ensure_directory(target) else: # file ensure_directory(target) data = z.read(info.filename) with open(target, 'wb') as f: f.write(data) unix_attributes = info.external_attr >> 16 if unix_attributes: os.chmod(target, unix_attributes) def _resolve_tar_file_or_dir(tar_obj, tar_member_obj): """Resolve any links and extract link targets as normal files.""" while tar_member_obj is not None and ( tar_member_obj.islnk() or tar_member_obj.issym()): linkpath = tar_member_obj.linkname if tar_member_obj.issym(): base = posixpath.dirname(tar_member_obj.name) linkpath = posixpath.join(base, linkpath) linkpath = posixpath.normpath(linkpath) tar_member_obj = tar_obj._getmember(linkpath) is_file_or_dir = ( tar_member_obj is not None and (tar_member_obj.isfile() or tar_member_obj.isdir()) ) if is_file_or_dir: return tar_member_obj raise LookupError('Got unknown file type') def _iter_open_tar(tar_obj, extract_dir, progress_filter): """Emit member-destination pairs from a tar archive.""" # don't do any chowning! tar_obj.chown = lambda *args: None with contextlib.closing(tar_obj): for member in tar_obj: name = member.name # don't extract absolute paths or ones with .. in them if name.startswith('/') or '..' in name.split('/'): continue prelim_dst = os.path.join(extract_dir, *name.split('/')) try: member = _resolve_tar_file_or_dir(tar_obj, member) except LookupError: continue final_dst = progress_filter(name, prelim_dst) if not final_dst: continue if final_dst.endswith(os.sep): final_dst = final_dst[:-1] yield member, final_dst def unpack_tarfile(filename, extract_dir, progress_filter=default_filter): """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` Raises ``UnrecognizedFormat`` if `filename` is not a tarfile (as determined by ``tarfile.open()``). See ``unpack_archive()`` for an explanation of the `progress_filter` argument. """ try: tarobj = tarfile.open(filename) except tarfile.TarError as e: raise UnrecognizedFormat( "%s is not a compressed or uncompressed tar file" % (filename,) ) from e for member, final_dst in _iter_open_tar( tarobj, extract_dir, progress_filter, ): try: # XXX Ugh tarobj._extract_member(member, final_dst) except tarfile.ExtractError: # chown/chmod/mkfifo/mknode/makedev failed pass return True extraction_drivers = unpack_directory, unpack_zipfile, unpack_tarfile PKH] 6python3.10/site-packages/setuptools/windows_support.pynu[import platform import ctypes def windows_only(func): if platform.system() != 'Windows': return lambda *args, **kwargs: None return func @windows_only def hide_file(path): """ Set the hidden attribute on a file or directory. From http://stackoverflow.com/questions/19622133/ `path` must be text. """ __import__('ctypes.wintypes') SetFileAttributes = ctypes.windll.kernel32.SetFileAttributesW SetFileAttributes.argtypes = ctypes.wintypes.LPWSTR, ctypes.wintypes.DWORD SetFileAttributes.restype = ctypes.wintypes.BOOL FILE_ATTRIBUTE_HIDDEN = 0x02 ret = SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN) if not ret: raise ctypes.WinError() PKH]Eaa-python3.10/site-packages/setuptools/monkey.pynu[""" Monkey patching of distutils. """ import sys import distutils.filelist import platform import types import functools from importlib import import_module import inspect import setuptools __all__ = [] """ Everything is private. Contact the project team if you think you need this functionality. """ def _get_mro(cls): """ Returns the bases classes for cls sorted by the MRO. Works around an issue on Jython where inspect.getmro will not return all base classes if multiple classes share the same name. Instead, this function will return a tuple containing the class itself, and the contents of cls.__bases__. See https://github.com/pypa/setuptools/issues/1024. """ if platform.python_implementation() == "Jython": return (cls,) + cls.__bases__ return inspect.getmro(cls) def get_unpatched(item): lookup = ( get_unpatched_class if isinstance(item, type) else get_unpatched_function if isinstance(item, types.FunctionType) else lambda item: None ) return lookup(item) def get_unpatched_class(cls): """Protect against re-patching the distutils if reloaded Also ensures that no other distutils extension monkeypatched the distutils first. """ external_bases = ( cls for cls in _get_mro(cls) if not cls.__module__.startswith('setuptools') ) base = next(external_bases) if not base.__module__.startswith('distutils'): msg = "distutils has already been patched by %r" % cls raise AssertionError(msg) return base def patch_all(): # we can't patch distutils.cmd, alas distutils.core.Command = setuptools.Command has_issue_12885 = sys.version_info <= (3, 5, 3) if has_issue_12885: # fix findall bug in distutils (http://bugs.python.org/issue12885) distutils.filelist.findall = setuptools.findall needs_warehouse = ( sys.version_info < (2, 7, 13) or (3, 4) < sys.version_info < (3, 4, 6) or (3, 5) < sys.version_info <= (3, 5, 3) ) if needs_warehouse: warehouse = 'https://upload.pypi.org/legacy/' distutils.config.PyPIRCCommand.DEFAULT_REPOSITORY = warehouse _patch_distribution_metadata() # Install Distribution throughout the distutils for module in distutils.dist, distutils.core, distutils.cmd: module.Distribution = setuptools.dist.Distribution # Install the patched Extension distutils.core.Extension = setuptools.extension.Extension distutils.extension.Extension = setuptools.extension.Extension if 'distutils.command.build_ext' in sys.modules: sys.modules['distutils.command.build_ext'].Extension = ( setuptools.extension.Extension ) patch_for_msvc_specialized_compiler() def _patch_distribution_metadata(): """Patch write_pkg_file and read_pkg_file for higher metadata standards""" for attr in ('write_pkg_file', 'read_pkg_file', 'get_metadata_version'): new_val = getattr(setuptools.dist, attr) setattr(distutils.dist.DistributionMetadata, attr, new_val) def patch_func(replacement, target_mod, func_name): """ Patch func_name in target_mod with replacement Important - original must be resolved by name to avoid patching an already patched function. """ original = getattr(target_mod, func_name) # set the 'unpatched' attribute on the replacement to # point to the original. vars(replacement).setdefault('unpatched', original) # replace the function in the original module setattr(target_mod, func_name, replacement) def get_unpatched_function(candidate): return getattr(candidate, 'unpatched') def patch_for_msvc_specialized_compiler(): """ Patch functions in distutils to use standalone Microsoft Visual C++ compilers. """ # import late to avoid circular imports on Python < 3.5 msvc = import_module('setuptools.msvc') if platform.system() != 'Windows': # Compilers only available on Microsoft Windows return def patch_params(mod_name, func_name): """ Prepare the parameters for patch_func to patch indicated function. """ repl_prefix = 'msvc9_' if 'msvc9' in mod_name else 'msvc14_' repl_name = repl_prefix + func_name.lstrip('_') repl = getattr(msvc, repl_name) mod = import_module(mod_name) if not hasattr(mod, func_name): raise ImportError(func_name) return repl, mod, func_name # Python 2.7 to 3.4 msvc9 = functools.partial(patch_params, 'distutils.msvc9compiler') # Python 3.5+ msvc14 = functools.partial(patch_params, 'distutils._msvccompiler') try: # Patch distutils.msvc9compiler patch_func(*msvc9('find_vcvarsall')) patch_func(*msvc9('query_vcvarsall')) except ImportError: pass try: # Patch distutils._msvccompiler._get_vc_env patch_func(*msvc14('_get_vc_env')) except ImportError: pass try: # Patch distutils._msvccompiler.gen_lib_options for Numpy patch_func(*msvc14('gen_lib_options')) except ImportError: pass PKH]2S,,-python3.10/site-packages/setuptools/launch.pynu[""" Launch the Python script on the command line after setuptools is bootstrapped via import. """ # Note that setuptools gets imported implicitly by the # invocation of this script using python -m setuptools.launch import tokenize import sys def run(): """ Run the script in sys.argv[1] as if it had been invoked naturally. """ __builtins__ script_name = sys.argv[1] namespace = dict( __file__=script_name, __name__='__main__', __doc__=None, ) sys.argv[:] = sys.argv[1:] open_ = getattr(tokenize, 'open', open) with open_(script_name) as fid: script = fid.read() norm_script = script.replace('\\r\\n', '\\n') code = compile(norm_script, script_name, 'exec') exec(code, namespace) if __name__ == '__main__': run() PKH]Hn4python3.10/site-packages/setuptools/command/sdist.pynu[from distutils import log import distutils.command.sdist as orig import os import sys import io import contextlib from .py36compat import sdist_add_defaults import pkg_resources _default_revctrl = list def walk_revctrl(dirname=''): """Find all files under revision control""" for ep in pkg_resources.iter_entry_points('setuptools.file_finders'): for item in ep.load()(dirname): yield item class sdist(sdist_add_defaults, orig.sdist): """Smart sdist that finds anything supported by revision control""" user_options = [ ('formats=', None, "formats for source distribution (comma-separated list)"), ('keep-temp', 'k', "keep the distribution tree around after creating " + "archive file(s)"), ('dist-dir=', 'd', "directory to put the source distribution archive(s) in " "[default: dist]"), ('owner=', 'u', "Owner name used when creating a tar file [default: current user]"), ('group=', 'g', "Group name used when creating a tar file [default: current group]"), ] negative_opt = {} README_EXTENSIONS = ['', '.rst', '.txt', '.md'] READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS) def run(self): self.run_command('egg_info') ei_cmd = self.get_finalized_command('egg_info') self.filelist = ei_cmd.filelist self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt')) self.check_readme() # Run sub commands for cmd_name in self.get_sub_commands(): self.run_command(cmd_name) self.make_distribution() dist_files = getattr(self.distribution, 'dist_files', []) for file in self.archive_files: data = ('sdist', '', file) if data not in dist_files: dist_files.append(data) def initialize_options(self): orig.sdist.initialize_options(self) self._default_to_gztar() def _default_to_gztar(self): # only needed on Python prior to 3.6. if sys.version_info >= (3, 6, 0, 'beta', 1): return self.formats = ['gztar'] def make_distribution(self): """ Workaround for #516 """ with self._remove_os_link(): orig.sdist.make_distribution(self) @staticmethod @contextlib.contextmanager def _remove_os_link(): """ In a context, remove and restore os.link if it exists """ class NoValue: pass orig_val = getattr(os, 'link', NoValue) try: del os.link except Exception: pass try: yield finally: if orig_val is not NoValue: setattr(os, 'link', orig_val) def _add_defaults_optional(self): super()._add_defaults_optional() if os.path.isfile('pyproject.toml'): self.filelist.append('pyproject.toml') def _add_defaults_python(self): """getting python files""" if self.distribution.has_pure_modules(): build_py = self.get_finalized_command('build_py') self.filelist.extend(build_py.get_source_files()) self._add_data_files(self._safe_data_files(build_py)) def _safe_data_files(self, build_py): """ Extracting data_files from build_py is known to cause infinite recursion errors when `include_package_data` is enabled, so suppress it in that case. """ if self.distribution.include_package_data: return () return build_py.data_files def _add_data_files(self, data_files): """ Add data files as found in build_py.data_files. """ self.filelist.extend( os.path.join(src_dir, name) for _, src_dir, _, filenames in data_files for name in filenames ) def _add_defaults_data_files(self): try: super()._add_defaults_data_files() except TypeError: log.warn("data_files contains unexpected objects") def check_readme(self): for f in self.READMES: if os.path.exists(f): return else: self.warn( "standard file not found: should have one of " + ', '.join(self.READMES) ) def make_release_tree(self, base_dir, files): orig.sdist.make_release_tree(self, base_dir, files) # Save any egg_info command line options used to create this sdist dest = os.path.join(base_dir, 'setup.cfg') if hasattr(os, 'link') and os.path.exists(dest): # unlink and re-copy, since it might be hard-linked, and # we don't want to change the source version os.unlink(dest) self.copy_file('setup.cfg', dest) self.get_finalized_command('egg_info').save_version_info(dest) def _manifest_is_not_generated(self): # check for special comment used in 2.7.1 and higher if not os.path.isfile(self.manifest): return False with io.open(self.manifest, 'rb') as fp: first_line = fp.readline() return (first_line != '# file GENERATED by distutils, do NOT edit\n'.encode()) def read_manifest(self): """Read the manifest file (named by 'self.manifest') and use it to fill in 'self.filelist', the list of files to include in the source distribution. """ log.info("reading manifest file '%s'", self.manifest) manifest = open(self.manifest, 'rb') for line in manifest: # The manifest must contain UTF-8. See #303. try: line = line.decode('UTF-8') except UnicodeDecodeError: log.warn("%r not UTF-8 decodable -- skipping" % line) continue # ignore comments and blank lines line = line.strip() if line.startswith('#') or not line: continue self.filelist.append(line) manifest.close() PKH]ut@@8python3.10/site-packages/setuptools/command/bdist_egg.pynu["""setuptools.command.bdist_egg Build .egg distributions""" from distutils.dir_util import remove_tree, mkpath from distutils import log from types import CodeType import sys import os import re import textwrap import marshal from pkg_resources import get_build_platform, Distribution, ensure_directory from setuptools.extension import Library from setuptools import Command from sysconfig import get_path, get_python_version def _get_purelib(): return get_path("purelib") def strip_module(filename): if '.' in filename: filename = os.path.splitext(filename)[0] if filename.endswith('module'): filename = filename[:-6] return filename def sorted_walk(dir): """Do os.walk in a reproducible way, independent of indeterministic filesystem readdir order """ for base, dirs, files in os.walk(dir): dirs.sort() files.sort() yield base, dirs, files def write_stub(resource, pyfile): _stub_template = textwrap.dedent(""" def __bootstrap__(): global __bootstrap__, __loader__, __file__ import sys, pkg_resources, importlib.util __file__ = pkg_resources.resource_filename(__name__, %r) __loader__ = None; del __bootstrap__, __loader__ spec = importlib.util.spec_from_file_location(__name__,__file__) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) __bootstrap__() """).lstrip() with open(pyfile, 'w') as f: f.write(_stub_template % resource) class bdist_egg(Command): description = "create an \"egg\" distribution" user_options = [ ('bdist-dir=', 'b', "temporary directory for creating the distribution"), ('plat-name=', 'p', "platform name to embed in generated filenames " "(default: %s)" % get_build_platform()), ('exclude-source-files', None, "remove all .py files from the generated egg"), ('keep-temp', 'k', "keep the pseudo-installation tree around after " + "creating the distribution archive"), ('dist-dir=', 'd', "directory to put final built distributions in"), ('skip-build', None, "skip rebuilding everything (for testing/debugging)"), ] boolean_options = [ 'keep-temp', 'skip-build', 'exclude-source-files' ] def initialize_options(self): self.bdist_dir = None self.plat_name = None self.keep_temp = 0 self.dist_dir = None self.skip_build = 0 self.egg_output = None self.exclude_source_files = None def finalize_options(self): ei_cmd = self.ei_cmd = self.get_finalized_command("egg_info") self.egg_info = ei_cmd.egg_info if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'egg') if self.plat_name is None: self.plat_name = get_build_platform() self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) if self.egg_output is None: # Compute filename of the output egg basename = Distribution( None, None, ei_cmd.egg_name, ei_cmd.egg_version, get_python_version(), self.distribution.has_ext_modules() and self.plat_name ).egg_name() self.egg_output = os.path.join(self.dist_dir, basename + '.egg') def do_install_data(self): # Hack for packages that install data to install's --install-lib self.get_finalized_command('install').install_lib = self.bdist_dir site_packages = os.path.normcase(os.path.realpath(_get_purelib())) old, self.distribution.data_files = self.distribution.data_files, [] for item in old: if isinstance(item, tuple) and len(item) == 2: if os.path.isabs(item[0]): realpath = os.path.realpath(item[0]) normalized = os.path.normcase(realpath) if normalized == site_packages or normalized.startswith( site_packages + os.sep ): item = realpath[len(site_packages) + 1:], item[1] # XXX else: raise ??? self.distribution.data_files.append(item) try: log.info("installing package data to %s", self.bdist_dir) self.call_command('install_data', force=0, root=None) finally: self.distribution.data_files = old def get_outputs(self): return [self.egg_output] def call_command(self, cmdname, **kw): """Invoke reinitialized command `cmdname` with keyword args""" for dirname in INSTALL_DIRECTORY_ATTRS: kw.setdefault(dirname, self.bdist_dir) kw.setdefault('skip_build', self.skip_build) kw.setdefault('dry_run', self.dry_run) cmd = self.reinitialize_command(cmdname, **kw) self.run_command(cmdname) return cmd def run(self): # noqa: C901 # is too complex (14) # FIXME # Generate metadata first self.run_command("egg_info") # We run install_lib before install_data, because some data hacks # pull their data path from the install_lib command. log.info("installing library code to %s", self.bdist_dir) instcmd = self.get_finalized_command('install') old_root = instcmd.root instcmd.root = None if self.distribution.has_c_libraries() and not self.skip_build: self.run_command('build_clib') cmd = self.call_command('install_lib', warn_dir=0) instcmd.root = old_root all_outputs, ext_outputs = self.get_ext_outputs() self.stubs = [] to_compile = [] for (p, ext_name) in enumerate(ext_outputs): filename, ext = os.path.splitext(ext_name) pyfile = os.path.join(self.bdist_dir, strip_module(filename) + '.py') self.stubs.append(pyfile) log.info("creating stub loader for %s", ext_name) if not self.dry_run: write_stub(os.path.basename(ext_name), pyfile) to_compile.append(pyfile) ext_outputs[p] = ext_name.replace(os.sep, '/') if to_compile: cmd.byte_compile(to_compile) if self.distribution.data_files: self.do_install_data() # Make the EGG-INFO directory archive_root = self.bdist_dir egg_info = os.path.join(archive_root, 'EGG-INFO') self.mkpath(egg_info) if self.distribution.scripts: script_dir = os.path.join(egg_info, 'scripts') log.info("installing scripts to %s", script_dir) self.call_command('install_scripts', install_dir=script_dir, no_ep=1) self.copy_metadata_to(egg_info) native_libs = os.path.join(egg_info, "native_libs.txt") if all_outputs: log.info("writing %s", native_libs) if not self.dry_run: ensure_directory(native_libs) libs_file = open(native_libs, 'wt') libs_file.write('\n'.join(all_outputs)) libs_file.write('\n') libs_file.close() elif os.path.isfile(native_libs): log.info("removing %s", native_libs) if not self.dry_run: os.unlink(native_libs) write_safety_flag( os.path.join(archive_root, 'EGG-INFO'), self.zip_safe() ) if os.path.exists(os.path.join(self.egg_info, 'depends.txt')): log.warn( "WARNING: 'depends.txt' will not be used by setuptools 0.6!\n" "Use the install_requires/extras_require setup() args instead." ) if self.exclude_source_files: self.zap_pyfiles() # Make the archive make_zipfile(self.egg_output, archive_root, verbose=self.verbose, dry_run=self.dry_run, mode=self.gen_header()) if not self.keep_temp: remove_tree(self.bdist_dir, dry_run=self.dry_run) # Add to 'Distribution.dist_files' so that the "upload" command works getattr(self.distribution, 'dist_files', []).append( ('bdist_egg', get_python_version(), self.egg_output)) def zap_pyfiles(self): log.info("Removing .py files from temporary directory") for base, dirs, files in walk_egg(self.bdist_dir): for name in files: path = os.path.join(base, name) if name.endswith('.py'): log.debug("Deleting %s", path) os.unlink(path) if base.endswith('__pycache__'): path_old = path pattern = r'(?P.+)\.(?P[^.]+)\.pyc' m = re.match(pattern, name) path_new = os.path.join( base, os.pardir, m.group('name') + '.pyc') log.info( "Renaming file from [%s] to [%s]" % (path_old, path_new)) try: os.remove(path_new) except OSError: pass os.rename(path_old, path_new) def zip_safe(self): safe = getattr(self.distribution, 'zip_safe', None) if safe is not None: return safe log.warn("zip_safe flag not set; analyzing archive contents...") return analyze_egg(self.bdist_dir, self.stubs) def gen_header(self): return 'w' def copy_metadata_to(self, target_dir): "Copy metadata (egg info) to the target_dir" # normalize the path (so that a forward-slash in egg_info will # match using startswith below) norm_egg_info = os.path.normpath(self.egg_info) prefix = os.path.join(norm_egg_info, '') for path in self.ei_cmd.filelist.files: if path.startswith(prefix): target = os.path.join(target_dir, path[len(prefix):]) ensure_directory(target) self.copy_file(path, target) def get_ext_outputs(self): """Get a list of relative paths to C extensions in the output distro""" all_outputs = [] ext_outputs = [] paths = {self.bdist_dir: ''} for base, dirs, files in sorted_walk(self.bdist_dir): for filename in files: if os.path.splitext(filename)[1].lower() in NATIVE_EXTENSIONS: all_outputs.append(paths[base] + filename) for filename in dirs: paths[os.path.join(base, filename)] = (paths[base] + filename + '/') if self.distribution.has_ext_modules(): build_cmd = self.get_finalized_command('build_ext') for ext in build_cmd.extensions: if isinstance(ext, Library): continue fullname = build_cmd.get_ext_fullname(ext.name) filename = build_cmd.get_ext_filename(fullname) if not os.path.basename(filename).startswith('dl-'): if os.path.exists(os.path.join(self.bdist_dir, filename)): ext_outputs.append(filename) return all_outputs, ext_outputs NATIVE_EXTENSIONS = dict.fromkeys('.dll .so .dylib .pyd'.split()) def walk_egg(egg_dir): """Walk an unpacked egg's contents, skipping the metadata directory""" walker = sorted_walk(egg_dir) base, dirs, files = next(walker) if 'EGG-INFO' in dirs: dirs.remove('EGG-INFO') yield base, dirs, files for bdf in walker: yield bdf def analyze_egg(egg_dir, stubs): # check for existing flag in EGG-INFO for flag, fn in safety_flags.items(): if os.path.exists(os.path.join(egg_dir, 'EGG-INFO', fn)): return flag if not can_scan(): return False safe = True for base, dirs, files in walk_egg(egg_dir): for name in files: if name.endswith('.py') or name.endswith('.pyw'): continue elif name.endswith('.pyc') or name.endswith('.pyo'): # always scan, even if we already know we're not safe safe = scan_module(egg_dir, base, name, stubs) and safe return safe def write_safety_flag(egg_dir, safe): # Write or remove zip safety flag file(s) for flag, fn in safety_flags.items(): fn = os.path.join(egg_dir, fn) if os.path.exists(fn): if safe is None or bool(safe) != flag: os.unlink(fn) elif safe is not None and bool(safe) == flag: f = open(fn, 'wt') f.write('\n') f.close() safety_flags = { True: 'zip-safe', False: 'not-zip-safe', } def scan_module(egg_dir, base, name, stubs): """Check whether module possibly uses unsafe-for-zipfile stuff""" filename = os.path.join(base, name) if filename[:-1] in stubs: return True # Extension module pkg = base[len(egg_dir) + 1:].replace(os.sep, '.') module = pkg + (pkg and '.' or '') + os.path.splitext(name)[0] if sys.version_info < (3, 7): skip = 12 # skip magic & date & file size else: skip = 16 # skip magic & reserved? & date & file size f = open(filename, 'rb') f.read(skip) code = marshal.load(f) f.close() safe = True symbols = dict.fromkeys(iter_symbols(code)) for bad in ['__file__', '__path__']: if bad in symbols: log.warn("%s: module references %s", module, bad) safe = False if 'inspect' in symbols: for bad in [ 'getsource', 'getabsfile', 'getsourcefile', 'getfile' 'getsourcelines', 'findsource', 'getcomments', 'getframeinfo', 'getinnerframes', 'getouterframes', 'stack', 'trace' ]: if bad in symbols: log.warn("%s: module MAY be using inspect.%s", module, bad) safe = False return safe def iter_symbols(code): """Yield names and strings used by `code` and its nested code objects""" for name in code.co_names: yield name for const in code.co_consts: if isinstance(const, str): yield const elif isinstance(const, CodeType): for name in iter_symbols(const): yield name def can_scan(): if not sys.platform.startswith('java') and sys.platform != 'cli': # CPython, PyPy, etc. return True log.warn("Unable to analyze compiled code on this platform.") log.warn("Please ask the author to include a 'zip_safe'" " setting (either True or False) in the package's setup.py") # Attribute names of options for commands that might need to be convinced to # install to the egg build directory INSTALL_DIRECTORY_ATTRS = [ 'install_lib', 'install_dir', 'install_data', 'install_base' ] def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=True, mode='w'): """Create a zip file from all the files under 'base_dir'. The output zip file will be named 'base_dir' + ".zip". Uses either the "zipfile" Python module (if available) or the InfoZIP "zip" utility (if installed and found on the default search path). If neither tool is available, raises DistutilsExecError. Returns the name of the output zip file. """ import zipfile mkpath(os.path.dirname(zip_filename), dry_run=dry_run) log.info("creating '%s' and adding '%s' to it", zip_filename, base_dir) def visit(z, dirname, names): for name in names: path = os.path.normpath(os.path.join(dirname, name)) if os.path.isfile(path): p = path[len(base_dir) + 1:] if not dry_run: z.write(path, p) log.debug("adding '%s'", p) compression = zipfile.ZIP_DEFLATED if compress else zipfile.ZIP_STORED if not dry_run: z = zipfile.ZipFile(zip_filename, mode, compression=compression) for dirname, dirs, files in sorted_walk(base_dir): visit(z, dirname, files) z.close() else: for dirname, dirs, files in sorted_walk(base_dir): visit(None, dirname, files) return zip_filename PKH]+_mNpython3.10/site-packages/setuptools/command/__pycache__/setopt.cpython-310.pycnu[o Xai@sddlmZddlmZddlmZddlZddlZddlZddlm Z gdZ ddd Z dd d Z Gd dde Z Gddde ZdS)) convert_path)log)DistutilsOptionErrorN)Command) config_file edit_config option_basesetoptlocalcCsd|dkrdS|dkrtjtjtjdS|dkr-tjdkr!dp"d}tjtd |St d |) zGet the filename of the distutils, local, global, or per-user config `kind` must be one of "local", "global", or "user" r z setup.cfgglobalz distutils.cfguserposix.z~/%spydistutils.cfgz7config_file() type must be 'local', 'global', or 'user') ospathjoindirname distutils__file__name expanduserr ValueError)kinddotr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/setopt.pyr srFc CsHtd|t}dd|_||g|D]c\}}|dur.td||||q| |s?td||| ||D]8\}}|durktd|||| ||| |sjtd||||qCtd ||||| |||qCqtd ||st|d }||WddS1swYdSdS) aYEdit a configuration file to include `settings` `settings` is a dictionary of dictionaries or ``None`` values, keyed by command/section name. A ``None`` value means to delete the entire section, while a dictionary lists settings to be changed or deleted in that section. A setting of ``None`` means to delete that setting. zReading configuration from %scSs|SNr)xrrr*szedit_config..NzDeleting section [%s] from %szAdding new section [%s] to %szDeleting %s.%s from %sz#Deleting empty [%s] section from %szSetting %s.%s to %r in %sz Writing %sw)rdebug configparserRawConfigParser optionxformreaditemsinforemove_section has_section add_section remove_optionoptionssetopenwrite) filenamesettingsdry_runoptssectionr,optionvaluefrrrr sH            "rc@s0eZdZdZgdZddgZddZddZd S) rzrrrr@s  zsetopt.initialize_optionscCsFt||jdus|jdurtd|jdur|js!tddSdS)Nz%Must specify --command *and* --optionz$Must specify --set-value or --remove)rrErQr5rrRrOr>rrrrEs zsetopt.finalize_optionscCs*t|j|j|jdd|jii|jdS)N-_)rr0rQr5replacerRr2r>rrrruns z setopt.runN) rFrGrHrI descriptionrrJrKr@rErVrrrrr ss  r )r )F)distutils.utilrrrdistutils.errorsrrr" setuptoolsr__all__rrrr rrrrs     ,'PKH]7j@@Opython3.10/site-packages/setuptools/command/__pycache__/develop.cpython-310.pycnu[o Xaid@sddlmZddlmZddlmZmZddlZddlZddl Z ddl Z ddl m Z ddl mZddl Z Gdddeje ZGd d d ZdS) ) convert_path)log)DistutilsErrorDistutilsOptionErrorN) easy_install) namespacesc@sveZdZdZdZejddgZejdgZdZddZ d d Z d d Z e d dZ ddZddZddZddZdS)developzSet up package for developmentz%install package in 'development mode') uninstalluzUninstall this source package)z egg-path=Nz-Set the path to be used in the .egg-link filer FcCs2|jrd|_||n||dS)NT)r Z multi_versionuninstall_linkZuninstall_namespacesinstall_for_developmentZwarn_deprecated_optionsselfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/develop.pyruns   z develop.runcCs&d|_d|_t|d|_d|_dS)N.)r egg_pathrinitialize_options setup_pathZalways_copy_fromr rrrr%s   zdevelop.initialize_optionscCs|d}|jrd}|j|jf}t|||jg|_t||| |j t d|jd}t j|j||_|j|_|jdurPt j|j|_t|j}tt j|j|j}||krltd|tj|t|t j|j|jd|_||j|j|j|_dS)Negg_infoz-Please rename %r to %r before using 'develop'z*.eggz .egg-linkzA--egg-path must be a relative path from the install directory to  project_name)get_finalized_commandZbroken_egg_inforregg_nameargsrfinalize_optionsexpand_basedirs expand_dirsZ package_indexscanglobospathjoin install_diregg_linkegg_baserabspath pkg_resourcesnormalize_pathr Distribution PathMetadatadist_resolve_setup_pathr)reitemplaterZ egg_link_fntargetrrrrr,sF         zdevelop.finalize_optionscCsn|tjdd}|tjkrd|dd}ttj |||}|ttjkr5t d|ttj|S)z Generate a path from egg_base back to '.' where the setup script resides and ensure that path points to the setup path from $install_dir/$egg_path. /z../zGCan't get a consistent path to setup script from installation directory) replacer!seprstripcurdircountr(r)r"r#r)r&r$rZ path_to_setupresolvedrrrr-Ws  zdevelop._resolve_setup_pathcCs|d|jddd|dtjr|tjdt_|td|j|j |j sNt |jd}| |j d|jWdn1sIwY|d|j|j dS)Nr build_extr2)ZinplacezCreating %s (link to %s)w ) run_commandreinitialize_command setuptoolsZbootstrap_install_fromrZinstall_namespacesrinfor%r&dry_runopenwriterrZprocess_distributionr,no_deps)rfrrrr ms   zdevelop.install_for_developmentcCstj|jr=td|j|jt|j}dd|D}|||j g|j |j gfvr4t d|dS|j s=t |j|j sF||j|jjrQt ddSdS)NzRemoving %s (link to %s)cSsg|]}|qSr)r5).0linerrr sz*develop.uninstall_link..z$Link points to %s: uninstall abortedz5Note: you must uninstall or replace scripts manually!)r!r"existsr%rr?r&rAcloserrwarnr@unlinkZ update_pthr, distributionscripts)rZ egg_link_filecontentsrrrr s    zdevelop.uninstall_linkc Cs||jur t||S|||jjpgD]1}tjt |}tj |}t | }| }Wdn1s:wY|||||qdSN)r,rinstall_egg_scriptsinstall_wrapper_scriptsrLrMr!r"r'rbasenameiorAreadZinstall_script)rr, script_nameZ script_pathstrm script_textrrrrPs      zdevelop.install_egg_scriptscCst|}t||SrO)VersionlessRequirementrrQrr,rrrrQs zdevelop.install_wrapper_scriptsN)__name__ __module__ __qualname____doc__ descriptionr user_optionsboolean_optionsZcommand_consumes_argumentsrrr staticmethodr-r r rPrQrrrrrs$  +  rc@s(eZdZdZddZddZddZdS) rXa Adapt a pkg_resources.Distribution to simply return the project name as the 'requirement' so that scripts will work across multiple versions. >>> from pkg_resources import Distribution >>> dist = Distribution(project_name='foo', version='1.0') >>> str(dist.as_requirement()) 'foo==1.0' >>> adapted_dist = VersionlessRequirement(dist) >>> str(adapted_dist.as_requirement()) 'foo' cCs ||_dSrO)_VersionlessRequirement__distrYrrr__init__s zVersionlessRequirement.__init__cCs t|j|SrO)getattrrb)rnamerrr __getattr__s z"VersionlessRequirement.__getattr__cCs|jSrOrr rrras_requirementsz%VersionlessRequirement.as_requirementN)rZr[r\r]rcrfrgrrrrrXs  rX)distutils.utilr distutilsrdistutils.errorsrrr!r rSr(Zsetuptools.command.easy_installrr>rZDevelopInstallerrrXrrrrs   PKH]pt Wpython3.10/site-packages/setuptools/command/__pycache__/install_scripts.cpython-310.pycnu[o Xai! @sdddlmZddlmmZddlmZddlZddl Z ddl m Z m Z m Z GdddejZdS))logN)DistutilsModuleError) Distribution PathMetadataensure_directoryc@s*eZdZdZddZddZd ddZd S) install_scriptsz;Do normal script install, plus any egg_info wrapper scriptscCstj|d|_dS)NF)origrinitialize_optionsno_ep)selfr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/install_scripts.pyr s  z"install_scripts.initialize_optionsc Csddlmm}|d|jjrtj|ng|_ |j r!dS| d}t |j t|j |j|j|j}| d}t|dd}z | d}t|dd}Wn ttfyZd}Ynw|j}|red}|j}|tjkrm|g}|}|j|} ||| D]} |j| qdS) Nregg_info build_scripts executableZ bdist_wininstZ _is_runningFz python.exe)setuptools.command.easy_installcommand easy_install run_command distributionscriptsrrrunoutfilesr get_finalized_commandrZegg_baserregg_nameZ egg_versiongetattr ImportErrorrZ ScriptWriterZWindowsScriptWritersysrbestZcommand_spec_class from_paramget_argsZ as_header write_script) r eiZei_cmddistZbs_cmdZ exec_paramZbw_cmdZ is_wininstwritercmdargsr r r rs>       zinstall_scripts.runtc Gsddlm}m}td||jtj|j|}|j ||}|j sAt |t |d|} | || ||d|dSdS)z1Write an executable file to the scripts directoryr)chmod current_umaskzInstalling %s script to %swiN)rr(r)rinfoZ install_dirospathjoinrappenddry_runropenwriteclose) r script_namecontentsmodeZignoredr(r)targetmaskfr r r r!7s  zinstall_scripts.write_scriptN)r')__name__ __module__ __qualname____doc__r rr!r r r r r s &r) distutilsrZ!distutils.command.install_scriptsrrrdistutils.errorsrr,r pkg_resourcesrrrr r r r s  PKH]eeNpython3.10/site-packages/setuptools/command/__pycache__/upload.cpython-310.pycnu[o Xai@s:ddlmZddlmZddlmZGdddejZdS))log)upload)RemovedCommandErrorc@seZdZdZddZdS)rz)Formerly used to upload packages to PyPI.cCsd}|d|tjt|)Nz[The upload command has been removed, use twine to upload instead (https://pypi.org/p/twine)zERROR: )announcerERRORr)selfmsgr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/upload.pyrun sz upload.runN)__name__ __module__ __qualname____doc__r r r r r rs rN) distutilsrdistutils.commandrorigZsetuptools.errorsrr r r r s  PKH]HszInfoCommon._maybe_tagcCs,d}|jr ||j7}|jr|td7}|S)Nrz-%Y%m%d) tag_buildtag_datetimestrftimerCr4r4r5tagss  zInfoCommon.tags) __name__ __module__ __qualname__rErFpropertyr=r@r>rIrAr4r4r4r5r7vs  r7c@seZdZdZgdZdgZddiZddZeddZ e j d dZ d d Z d d Z dddZ ddZddZddZddZddZdS)egg_infoz+create a distribution's .egg-info directory))z egg-base=ezLdirectory containing .egg-info directories (default: top of the source tree))tag-datedz0Add date stamp (e.g. 20050528) to version number)z tag-build=bz-Specify explicit tag to add to version number)no-dateDz"Don't include date stamp [default]rPrScCs"d|_d|_d|_d|_d|_dS)NF)egg_baseegg_namerN egg_versionbroken_egg_infor;r4r4r5initialize_optionss  zegg_info.initialize_optionscCdSr8r4r;r4r4r5tag_svn_revisionzegg_info.tag_svn_revisioncCrZr8r4)r<valuer4r4r5r[r\cCs0t}||d<d|d<t|t|ddS)z Materialize the value of date into the build tag. Install build keys in a deterministic order to avoid arbitrary reordering on subsequent builds. rErrF)rNN) collections OrderedDictrIr dict)r<filenamerNr4r4r5save_version_infos zegg_info.save_version_infoc CsL|j|_||_t|j}zt|tjj}|rdnd}t t ||j|jfWnt yB}z t j d|j|jf|d}~ww|jdurV|jj}|pOidtj|_|dt|jd|_|jtjkrstj|j|j|_d|jvr|||j|jj_|jj}|dur|j|jkr|j|_t|j|_ d|j_dSdSdS)Nz%s==%sz%s===%sz2Invalid distribution name or version syntax: %s-%srrU .egg-info-)!r=rVr@rWr isinstancerrDVersionlistr ValueError distutilserrorsDistutilsOptionErrorrUr9 package_dirgetr!curdirensure_dirnamerrNr"joincheck_broken_egg_infometadataZ _patched_distkeylower_version_parsed_version)r<parsed_versionZ is_versionspecrOdirspdr4r4r5finalize_optionssH           zegg_info.finalize_optionsFcCsR|r ||||dStj|r'|dur |s td||dS||dSdS)aWrite `data` to `filename` or delete if empty If `data` is non-empty, this routine is the same as ``write_file()``. If `data` is empty but not ``None``, this is the same as calling ``delete_file(filename)`. If `data` is ``None``, then this is a no-op unless `filename` exists, in which case a warning is issued about the orphaned file (if `force` is false), or deleted (if `force` is true). Nz$%s not set in setup(), but %s exists) write_filer!r"existsrwarn delete_file)r<whatradataforcer4r4r5write_or_delete_files   zegg_info.write_or_delete_filecCsBtd|||d}|jst|d}|||dSdS)zWrite `data` to `filename` (if not a dry run) after announcing it `what` is used in a log message to identify what is being written to the file. zwriting %s to %sutf-8wbN)rinfoencodedry_runopenwriteclose)r<rrarfr4r4r5r| s    zegg_info.write_filecCs$td||jst|dSdS)z8Delete `filename` (if not a dry run) after announcing itz deleting %sN)rrrr!unlink)r<rar4r4r5rs zegg_info.delete_filecCs||jt|jd|jj}tdD]}|j|d|}|||j tj |j|j qtj |jd}tj |rC| ||dS)Nzegg_info.writers) installerznative_libs.txt)mkpathrNr!utimer9Zfetch_build_eggrrequireresolver=r"rpr}r find_sources)r<repwriternlr4r4r5runs      z egg_info.runcCs4tj|jd}t|j}||_||j|_dS)z"Generate SOURCES.txt manifest filez SOURCES.txtN) r!r"rprNmanifest_makerr9manifestrfilelist)r<Zmanifest_filenamemmr4r4r5r-s   zegg_info.find_sourcescCsX|jd}|jtjkrtj|j|}tj|r*td||j |j |_ ||_ dSdS)NrcaB------------------------------------------------------------------------------ Note: Your current .egg-info directory has a '-' in its name; this will not work correctly with "setup.py develop". Please rename %s to %s to correct this problem. ------------------------------------------------------------------------------) rVrUr!rnr"rpr}rr~rNrX)r<Zbeir4r4r5rq5s    zegg_info.check_broken_egg_infoNF)rJrKrL description user_optionsboolean_options negative_optrYrMr[setterrbr{rr|rrrrqr4r4r4r5rNs&   1  rNc@s|eZdZddZddZddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZddZddZdS)rc Cs||\}}}}|j|j|j|jt|j|t|j||j |j d}dddddddd d}z||}Wnt yDt d j |d w|d } |d vrQ|g}| rV|fnd} ||} |d|g| rg|gng||D]} || stj| | g| RqpdS)N)includeexcludezglobal-includezglobal-excludezrecursive-includezrecursive-excludegraftprunez%warning: no files found matching '%s'z9warning: no previously-included files found matching '%s'z>warning: no files found matching '%s' anywhere in distributionzRwarning: no previously-included files matching '%s' found anywhere in distributionz:warning: no files found matching '%s' under directory '%s'zNwarning: no previously-included files matching '%s' found under directory '%s'z+warning: no directories found matching '%s'z6no previously-included directories found matching '%s'z/this cannot happen: invalid action '{action!s}')actionz recursive->rrr4 )Z_parse_template_linerrglobal_includeglobal_exclude functoolspartialrecursive_includerecursive_excluderrKeyErrorrformat startswith debug_printrprr~) r<linerpatternsdirZ dir_patternZ action_mapZlog_mapZprocess_actionZaction_is_recursiveZextra_log_argsZlog_tmplpatternr4r4r5process_template_lineHsf    zFileList.process_template_linecCsRd}tt|jdddD]}||j|r&|d|j||j|=d}q |S)z Remove all files from the file list that match the predicate. Return True if any matching files were removed Frz removing T)ranger'filesr)r< predicatefoundr0r4r4r5 _remove_filesszFileList._remove_filescC$ddt|D}||t|S)z#Include files that match 'pattern'.cSg|] }tj|s|qSr4r!r"isdir.0rr4r4r5 sz$FileList.include..rextendboolr<rrr4r4r5rs zFileList.includecCst|}||jS)z#Exclude files that match 'pattern'.)r6rmatchr<rrr4r4r5rs zFileList.excludecCs8tj|d|}ddt|ddD}||t|S)zN Include all files anywhere in 'dir/' that match the pattern. rcSrr4rrr4r4r5rs  z.FileList.recursive_include..T) recursive)r!r"rprrr)r<rrZ full_patternrr4r4r5rs zFileList.recursive_includecCs ttj|d|}||jS)zM Exclude any file anywhere in 'dir/' that match the pattern. rr6r!r"rprr)r<rrrr4r4r5rs zFileList.recursive_excludecCr)zInclude all files from 'dir/'.cSs"g|] }tj|D]}|q qSr4)rirfindall)rZ match_diritemr4r4r5rs z"FileList.graft..r)r<rrr4r4r5rs  zFileList.graftcCsttj|d}||jS)zFilter out files from 'dir/'.rr)r<rrr4r4r5rs zFileList.prunecsJ|jdur |ttjd|fdd|jD}||t|S)z Include all files anywhere in the current directory that match the pattern. This is very inefficient on large file trees. Nrcsg|] }|r|qSr4rrrr4r5rsz+FileList.global_include..)allfilesrr6r!r"rprrrr4rr5rs  zFileList.global_includecCsttjd|}||jS)zD Exclude all files anywhere that match the pattern. rrrr4r4r5rs zFileList.global_excludecCs<|dr |dd}t|}||r|j|dSdS)N r)rBr _safe_pathrappend)r<rr"r4r4r5rs   zFileList.appendcCs|jt|j|dSr8)rrfilterr)r<pathsr4r4r5rszFileList.extendcCstt|j|j|_dS)z Replace self.files with only safe paths Because some owners of FileList manipulate the underlying ``files`` attribute directly, this method must be called to repair those paths. N)rgrrrr;r4r4r5_repairszFileList._repairc Csd}t|}|durtd|dSt|d}|dur't||ddSztj|s4tj|r7WdSWdStyLt||t YdSw)Nz!'%s' not %s encodable -- skippingz''%s' in unexpected encoding -- skippingFrT) unicode_utilsfilesys_decoderr~Z try_encoder!r"r}UnicodeEncodeErrorsysgetfilesystemencoding)r<r"Zenc_warnZu_pathZ utf8_pathr4r4r5rs    zFileList._safe_pathN)rJrKrLrrrrrrrrrrrrrrr4r4r4r5rEsM     rc@sdeZdZdZddZddZddZdd Zd d Zd d Z e ddZ ddZ ddZ ddZdS)rz MANIFEST.incCsd|_d|_d|_d|_dS)Nr)Z use_defaultsrZ manifest_onlyZforce_manifestr;r4r4r5rYs z!manifest_maker.initialize_optionscCrZr8r4r;r4r4r5r{szmanifest_maker.finalize_optionscCslt|_tj|js||tj|jr| | | |j |j |dSr8)rrr!r"r}rwrite_manifest add_defaultstemplateZ read_templateadd_license_filesprune_file_listsortZremove_duplicatesr;r4r4r5rs   zmanifest_maker.runcCst|}|tjdS)N/)rrreplacer!r#)r<r"r4r4r5_manifest_normalize&s z"manifest_maker._manifest_normalizecsBjfddjjD}dj}tj|f|dS)zo Write the file list in 'self.filelist' to the manifest file named by 'self.manifest'. csg|]}|qSr4)rrr;r4r5r2sz1manifest_maker.write_manifest..zwriting manifest file '%s'N)rrrrexecuter|)r<rmsgr4r;r5r*s  zmanifest_maker.write_manifestcCs||s t||dSdSr8)_should_suppress_warningrr~)r<rr4r4r5r~6s zmanifest_maker.warncCs td|S)z; suppress missing-file warnings from sdist zstandard file .*not found)r$r)rr4r4r5r:s z'manifest_maker._should_suppress_warningcCst||j|j|j|jtt}|r!|j|n t j |jr,| t j dr8|jd| d}|j|jdS)Nzsetup.pyrN)rrrrrrrgrrr!r"r}Z read_manifestget_finalized_commandrrN)r<ZrcfilesZei_cmdr4r4r5rAs     zmanifest_maker.add_defaultscCs4|jjjpg}|D]}td|q |j|dS)Nzadding license file '%s')r9rr license_filesrrrr)r<rlfr4r4r5rSs  z manifest_maker.add_license_filescCsZ|d}|j}|j|j|j|ttj }|jj d|d|dddS)Nbuildz(^|z)(RCS|CVS|\.svn)r)Zis_regex) rr9 get_fullnamerr build_baser$r%r!r#Zexclude_pattern)r<rbase_dirr#r4r4r5rZs     zmanifest_maker.prune_file_listN)rJrKrLrrYr{rrrr~ staticmethodrrrrr4r4r4r5r s    rcCsNd|}|d}t|d}||WddS1s wYdS)z{Create a file with the specified name and write 'contents' (a sequence of strings without line terminators) to it.  rrN)rprrr)racontentsrr4r4r5r|ds    "r|c Cstd||jsE|jj}|j|j|_}|j|j|_}z| |j W|||_|_n|||_|_wt |jdd}t |j |dSdS)Nz writing %sZzip_safe)rrrr9rrrWrDrVr=write_pkg_inforNgetattrr Zwrite_safety_flag)cmdbasenamerarrZoldverZoldnamesafer4r4r5rqs  rcCstj|r tddSdS)NzsWARNING: 'depends.txt' is not used by setuptools 0.6! Use the install_requires/extras_require setup() args instead.)r!r"r}rr~rrrar4r4r5warn_depends_obsoletes rcCs,t|pd}dd}t||}||dS)Nr4cSs|dS)Nrr4)rr4r4r5 append_crsz&_write_requirements..append_cr)rmap writelines)streamreqslinesrr4r4r5_write_requirementss  rcCsn|j}t}t||j|jpi}t|D]}|djdit t|||q| d|| dS)Nz [{extra}] requirementsr4) r9ioStringIOrZinstall_requiresextras_requiresortedrrvarsrgetvalue)rrradistrrextrar4r4r5write_requirementss   rcCs,t}t||jj|d||dS)Nzsetup-requirements)rrrr9Zsetup_requiresrr)rrrarr4r4r5write_setup_requirementssr cCs:tdd|jD}|d|dt|ddS)NcSsg|] }|dddqS).rr)r )rkr4r4r5rsz(write_toplevel_names..ztop-level namesr)r`fromkeysr9Ziter_distribution_namesr|rpr)rrrapkgsr4r4r5write_toplevel_namess  rcCst|||ddS)NT) write_argrr4r4r5 overwrite_argsrFcCsHtj|d}t|j|d}|durd|d}|||||dS)Nrr)r!r"splitextrr9rpr)rrrarargnamer]r4r4r5rs rcCs|jj}t|ts |dur|}n6|durFg}t|D]$\}}t|ts7t||}dtt t| }| d||fqd|}| d||ddS)Nrz [%s] %s rz entry pointsT) r9Z entry_pointsrestrritemsr parse_grouprprvaluesrr)rrrarrsectionrr4r4r5 write_entriess   rcCstdttjdr?td&}|D]}t d|}|r.t | dWdSqWddS1s:wYdS)zd Get a -r### off of PKG-INFO Version in case this is an sdist of a subversion revision. z$get_pkg_info_revision is deprecated.zPKG-INFOzVersion:.*-r(\d+)\s*$rNr) warningsr~EggInfoDeprecationWarningr!r"r}rrr$rintgroup)rrrr4r4r5get_pkg_info_revisions     rc@seZdZdZdS)rz?Deprecated behavior warning for EggInfo, bypassing suppression.N)rJrKrL__doc__r4r4r4r5rsrr);rdistutils.filelistrZ _FileListdistutils.errorsrdistutils.utilrrirrr!r$rrrrGr^ setuptoolsrZsetuptools.command.sdistrrZsetuptools.command.setoptr Zsetuptools.commandr pkg_resourcesr r r rrrrrZsetuptools.unicode_utilsrZsetuptools.globrZsetuptools.externrrr6r7rNrr|rrrrr rrrrrrr4r4r4r5sX         (    S1IW    PKH] +Ppython3.10/site-packages/setuptools/command/__pycache__/__init__.cpython-310.pycnu[o Xai@s<ddlmZddlZdejvrdejd<ejd[[dS))bdistNegg)Z bdist_eggzPython .egg file)Zdistutils.command.bdistrsysZformat_commandsZformat_commandappendrr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/__init__.pys    PKH]YΕhSpython3.10/site-packages/setuptools/command/__pycache__/install_lib.cpython-310.pycnu[o Xai#@sHddlZddlZddlmZmZddlmmZGdddejZdS)N)productstarmapc@s\eZdZdZddZddZddZedd Zd d Z ed d Z dddZ ddZ dS) install_libz9Don't add compiled flags to filenames of non-Python filescCs*||}|dur||dSdSN)buildinstall byte_compile)selfoutfilesr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/install_lib.pyrun s zinstall_lib.runcs4fddD}t|}ttj|S)z Return a collections.Sized collections.Container of paths to be excluded for single_version_externally_managed installations. c3s$|] }|D]}|Vq qdSr) _all_packages).0Zns_pkgpkgr r r s z-install_lib.get_exclusions..)_get_SVEM_NSPsr_gen_exclusion_pathssetr_exclude_pkg_path)r Z all_packagesZ excl_specsr rr get_exclusionss zinstall_lib.get_exclusionscCs&|d|g}tjj|jg|RS)zw Given a package name and exclusion path within that package, compute the full exclusion path. .)splitospathjoinZ install_dir)r rZexclusion_pathpartsr r r rszinstall_lib._exclude_pkg_pathccs(|r|V|d\}}}|sdSdS)zn >>> list(install_lib._all_packages('foo.bar.baz')) ['foo.bar.baz', 'foo.bar', 'foo'] rN) rpartition)pkg_namesepchildr r r r's  zinstall_lib._all_packagescCs,|jjsgS|d}|j}|r|jjSgS)z Get namespace packages (list) but only for single_version_externally_managed installations and empty otherwise. r) distributionZnamespace_packagesget_finalized_commandZ!single_version_externally_managed)r Z install_cmdZsvemr r r r1s  zinstall_lib._get_SVEM_NSPsccsddVdVdVttdsdStjddtjj}|dV|d V|d V|d VdS) zk Generate file paths to be excluded for namespace packages (bytecode cache files). z __init__.pyz __init__.pycz __init__.pyoimplementationN __pycache__z __init__.z.pycz.pyoz .opt-1.pycz .opt-2.pyc)hasattrsysrrrr$ cache_tag)baser r r rAs     z install_lib._gen_exclusion_pathsrc sh|r|r|rJ|stj|||Sddlm}ddlmgfdd}||||S)Nr)unpack_directory)logcs<|vr d|dSd|tj|||S)Nz/Skipping installation of %s (namespace package)Fzcopying %s -> %s)warninforrdirnameappend)srcdstexcluder,r r r pfhs z!install_lib.copy_tree..pf)rorigr copy_treeZsetuptools.archive_utilr+ distutilsr,) r infileoutfile preserve_modepreserve_timespreserve_symlinkslevelr+r5r r3r r7Ws   zinstall_lib.copy_treecs.tj|}|rfdd|DS|S)Ncsg|]}|vr|qSr r )rfr4r r ysz+install_lib.get_outputs..)r6r get_outputsr)r outputsr r@r rBus zinstall_lib.get_outputsN)r*r*rr*) __name__ __module__ __qualname____doc__r rr staticmethodrrrr7rBr r r r rs    r) rr' itertoolsrrZdistutils.command.install_libcommandrr6r r r r s PKH]}VVMpython3.10/site-packages/setuptools/command/__pycache__/sdist.cpython-310.pycnu[o Xai@sxddlmZddlmmZddlZddlZddlZddl Z ddl m Z ddl Z e Zd ddZGdd d e ejZdS) )logN)sdist_add_defaultsccs.tdD]}||D]}|VqqdS)z%Find all files under revision controlzsetuptools.file_findersN) pkg_resourcesiter_entry_pointsload)dirnameepitemr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/sdist.py walk_revctrls rcseZdZdZgdZiZgdZeddeDZddZ dd Z d d Z d d Z e ejddZfddZddZddZddZfddZddZddZddZd d!ZZS)"sdistz=Smart sdist that finds anything supported by revision control))zformats=Nz6formats for source distribution (comma-separated list))z keep-tempkz@keep the distribution tree around after creating archive file(s))z dist-dir=dzFdirectory to put the source distribution archive(s) in [default: dist])zowner=uz@Owner name used when creating a tar file [default: current user])zgroup=gzAGroup name used when creating a tar file [default: current group])rz.rstz.txtz.mdccs|]}d|VqdS)z README{0}N)format).0extr r r +szsdist.cCs|d|d}|j|_|jtj|jd|| D]}||q"| t |j dg}|j D]}dd|f}||vrH||q8dS)Negg_infoz SOURCES.txt dist_filesrr) run_commandget_finalized_commandfilelistappendospathjoinr check_readmeget_sub_commandsmake_distributiongetattr distributionZ archive_files)selfZei_cmdcmd_namerfiledatar r r run-s       z sdist.runcCstj||dSN)origrinitialize_options_default_to_gztarr&r r r r-@s  zsdist.initialize_optionscCstjdkrdSdg|_dS)N)rbetargztar)sys version_infoformatsr/r r r r.Es  zsdist._default_to_gztarcCs:|tj|WddS1swYdS)z% Workaround for #516 N)_remove_os_linkr,rr#r/r r r r#Ks "zsdist.make_distributionc csvGddd}ttd|}zt`Wn tyYnwzdVW||ur-ttd|dSdS||ur:ttd|ww)zG In a context, remove and restore os.link if it exists c@s eZdZdS)z&sdist._remove_os_link..NoValueN)__name__ __module__ __qualname__r r r r NoValueYsr;linkN)r$rr< Exceptionsetattr)r;Zorig_valr r r r7Rs   zsdist._remove_os_linkcs*ttjdr|jddSdS)Nzpyproject.toml)super_add_defaults_optionalrrisfilerrr/ __class__r r r@gs  zsdist._add_defaults_optionalcCs<|jr|d}|j||||dSdS)zgetting python filesbuild_pyN)r%has_pure_modulesrrextendZget_source_files_add_data_files_safe_data_filesr&rDr r r _add_defaults_pythonls  zsdist._add_defaults_pythoncCs|jjrdS|jS)z Extracting data_files from build_py is known to cause infinite recursion errors when `include_package_data` is enabled, so suppress it in that case. r )r%Zinclude_package_data data_filesrIr r r rHsszsdist._safe_data_filescCs|jdd|DdS)zA Add data files as found in build_py.data_files. css0|]\}}}}|D] }tj||Vq qdSr+)rrr )r_src_dir filenamesnamer r r rs  z(sdist._add_data_files..N)rrF)r&rKr r r rG}s  zsdist._add_data_filescs0ztWdStytdYdSw)Nz&data_files contains unexpected objects)r?_add_defaults_data_files TypeErrorrwarnr/rBr r rPs  zsdist._add_defaults_data_filescCs8|jD] }tj|rdSq|dd|jdS)Nz,standard file not found: should have one of z, )READMESrrexistsrRr )r&fr r r r!s   zsdist.check_readmecCs^tj|||tj|d}ttdr%tj|r%t|| d|| d |dS)Nz setup.cfgr<r) r,rmake_release_treerrr hasattrrTunlink copy_filerZsave_version_info)r&base_dirfilesdestr r r rVs   zsdist.make_release_treecCsTtj|js dSt|jd }|}Wdn1swY|dkS)NFrbz+# file GENERATED by distutils, do NOT edit )rrrAmanifestioopenreadlineencode)r&fp first_liner r r _manifest_is_not_generateds z sdist._manifest_is_not_generatedc Cstd|jt|jd}|D],}z|d}Wnty(td|Yqw|}|ds4|s5q|j |q| dS)zRead the manifest file (named by 'self.manifest') and use it to fill in 'self.filelist', the list of files to include in the source distribution. zreading manifest file '%s'r]zUTF-8z"%r not UTF-8 decodable -- skipping#N) rinfor^r`decodeUnicodeDecodeErrorrRstrip startswithrrclose)r&r^liner r r read_manifests   zsdist.read_manifest)r8r9r:__doc__ user_options negative_optZREADME_EXTENSIONStuplerSr*r-r.r# staticmethod contextlibcontextmanagerr7r@rJrHrGrPr!rVrern __classcell__r r rBr rs,      r)r) distutilsrZdistutils.command.sdistcommandrr,rr4r_rtZ py36compatrrlistZ_default_revctrlrr r r r s   PKH]Lb&&Qpython3.10/site-packages/setuptools/command/__pycache__/build_ext.cpython-310.pycnu[o Xai3@szddlZddlZddlZddlmZddlmZddlm Z ddl m Z ddl m Z mZddlmZddlmZdd lmZz ddlmZed Wn eyUeZYnwed dd l mZd dZdZdZdZejdkrrdZnej dkrz ddl!Z!e"e!dZZWn eyYnwddZ#ddZ$GdddeZesej dkr    dddZ%dSdZ    dddZ%dS) NEXTENSION_SUFFIXES) build_ext) copy_file) new_compiler)customize_compilerget_config_var)DistutilsError)log)LibraryzCython.Compiler.MainLDSHARED) _config_varsc Csltjdkr0t}zdtd<dtd<dtd<t|Wtt|dStt|wt|dS)Ndarwinz0gcc -Wl,-x -dynamiclib -undefined dynamic_lookupr z -dynamiclibCCSHAREDz.dylibSO)sysplatform _CONFIG_VARScopyrclearupdate)compilertmpr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/build_ext.py_customize_compiler_for_shlibs    rFZsharedrTntRTLD_NOWcCs tr|SdS)N) have_rtld)srrrif_dl>s r!cCs.tD]}d|vr |S|dkr|SqdS)z;Return the file extension for an abi3-compliant Extension()z.abi3z.pydNr)suffixrrrget_abi3_suffixBsr#c@sveZdZddZddZddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZdddZdS)rcCs2|jd}|_t|||_|r|dSdS)z;Build extensions in build directory, then copy if --inplacerN)Zinplace _build_extruncopy_extensions_to_source)selfZ old_inplacerrrr%Ls   z build_ext.runc Cs|d}|jD]J}||j}||}|d}d|dd}||}tj |tj |}tj |j |} t | ||j |jd|jrR||pNtj|dqdS)Nbuild_py.)verbosedry_runT)get_finalized_command extensionsget_ext_fullnamenameget_ext_filenamesplitjoinZget_package_dirospathbasename build_librr+r, _needs_stub write_stubcurdir) r'r(extfullnamefilenamemodpathpackage package_dirZ dest_filenameZ src_filenamerrrr&Ts&       z#build_ext.copy_extensions_to_sourcecCstd}|rtjj|d|}n t||}td}||jvrk|j|}t |do.t }|rA|dt | }t }||}t |t rUtj|\}}|j|tStrk|jrktj|\}}tj|d|S|S)NZSETUPTOOLS_EXT_SUFFIXr) EXT_SUFFIXZpy_limited_apizdl-)r4getenvr5r3r2r$r1rext_mapgetattrr#len isinstancer splitextshlib_compilerlibrary_filenamelibtype use_stubs_links_to_dynamic)r'r<Zso_extr=r;Zuse_abi3fndrrrr1js&      zbuild_ext.get_ext_filenamecCs t|d|_g|_i|_dSN)r$initialize_optionsrHshlibsrCr'rrrrPs  zbuild_ext.initialize_optionscCs(t||jp g|_||jdd|jD|_|jr!||jD] }||j|_q$|jD]`}|j}||j |<||j | dd<|jrM| |pNd}|oXt oXt |t }||_||_||}|_tjtj|j|}|r||jvr|j||rt rtj|jvr|jtjq1dS)NcSsg|] }t|tr|qSr)rFr .0r;rrr s z.build_ext.finalize_options..r)r*F)r$finalize_optionsr.Zcheck_extensions_listrQsetup_shlib_compilerr/r0 _full_namerCr2links_to_dynamicrKrFr rLr8r1 _file_namer4r5dirnamer3r7 library_dirsappendr:runtime_library_dirs)r'r;r<Zltdnsr=libdirrrrrVs0       zbuild_ext.finalize_optionscCst|j|j|jd}|_t||jdur||j|jdur/|jD] \}}| ||q$|j dur?|j D]}| |q7|j durJ| |j |jdurU||j|jdur`||j|jdurk||jt||_dS)N)rr,force)rrr,rarHr include_dirsZset_include_dirsZdefineZ define_macroZundefZundefine_macro librariesZ set_librariesr\Zset_library_dirsZrpathZset_runtime_library_dirsZ link_objectsZset_link_objectslink_shared_object__get__)r'rr0valueZmacrorrrrWs*                zbuild_ext.setup_shlib_compilercCst|tr|jSt||SrO)rFr export_symbolsr$get_export_symbolsr'r;rrrrhs  zbuild_ext.get_export_symbolscCsl||j}z*t|tr|j|_t|||jr,|dj }| ||W||_dSW||_dS||_w)Nr() Z_convert_pyx_sources_to_langrrFr rHr$build_extensionr8r-r7r9)r'r;Z _compilercmdrrrrjs    zbuild_ext.build_extensioncsPtdd|jDd|jddddgtfdd|jDS) z?Return true if 'ext' links to a dynamic lib in the same packagecSsg|]}|jqSr)rX)rTlibrrrrUsz.build_ext.links_to_dynamic..r)Nr*rc3s|] }|vVqdSrOr)rTZlibnameZlibnamespkgrr z-build_ext.links_to_dynamic..)dictfromkeysrQr3rXr2anyrcrirrmrrYs zbuild_ext.links_to_dynamiccCst||SrO)r$ get_outputs_build_ext__get_stubs_outputsrRrrrrtszbuild_ext.get_outputscs6fddjD}t|}tdd|DS)Nc3s4|]}|jrtjjjg|jdRVqdS)r)N)r8r4r5r3r7rXr2rSrRrrros z0build_ext.__get_stubs_outputs..css|] \}}||VqdSrOr)rTbaseZfnextrrrrorp)r. itertoolsproduct!_build_ext__get_output_extensionslist)r'Z ns_ext_basespairsrrRrZ__get_stubs_outputss zbuild_ext.__get_stubs_outputsccs(dVdV|djrdVdSdS)N.pyz.pycr(z.pyo)r-optimizerRrrrZ__get_output_extensionss   z!build_ext.__get_output_extensionsFcCs8td|j|tjj|g|jdRd}|r&tj|r&t|d|j s`t |d}| dddd t d d tj |jd d dt ddddt ddddddt ddddg||rddlm}||gdd|j d |d!j}|dkr||g|d|j d tj|r|j st|dSdSdSdS)"Nz writing stub loader for %s to %sr)r|z already exists! Please delete.w zdef __bootstrap__():z- global __bootstrap__, __file__, __loader__z0 import sys, os, pkg_resources, importlib.utilz, dlz: __file__ = pkg_resources.resource_filename(__name__,%r)z del __bootstrap__z if '__loader__' in globals():z del __loader__z# old_flags = sys.getdlopenflags()z old_dir = os.getcwd()z try:z( os.chdir(os.path.dirname(__file__))z$ sys.setdlopenflags(dl.RTLD_NOW)z3 spec = importlib.util.spec_from_file_location(z# __name__, __file__)z0 mod = importlib.util.module_from_spec(spec)z! spec.loader.exec_module(mod)z finally:z" sys.setdlopenflags(old_flags)z os.chdir(old_dir)z__bootstrap__()rr) byte_compileT)r}rar, install_lib)r inforXr4r5r3r2existsr r,openwriter!r6rZclosedistutils.utilrr-r}unlink)r' output_dirr;compileZ stub_filefrr}rrrr9sl       zbuild_ext.write_stubN)F)__name__ __module__ __qualname__r%r&r1rPrVrWrhrjrYrtruryr9rrrrrKs   rc Cs(||j||||||||| | | | dSrO)linkZSHARED_LIBRARY) r'objectsoutput_libnamerrcr\r^rgdebug extra_preargsextra_postargs build_temp target_langrrrrd$s rdZstaticc Cs^|dusJtj|\}} tj| \}}|ddr$|dd}|||||| dS)Nxrl)r4r5r2rGrI startswithZcreate_static_lib)r'rrrrcr\r^rgrrrrrr=r6r;rrrrd3s   ) NNNNNrNNNN)&r4rrwimportlib.machineryrZdistutils.command.build_extrZ _du_build_extdistutils.file_utilrZdistutils.ccompilerrdistutils.sysconfigrrdistutils.errorsr distutilsr Zsetuptools.extensionr ZCython.Distutils.build_extr$ __import__ ImportErrorr rrrrKrJrr0dlhasattrr!r#rdrrrrs`               W PKH]b&Tpython3.10/site-packages/setuptools/command/__pycache__/easy_install.cpython-310.pycnu[o XaiN@sdZddlmZddlmZddlmZmZddlmZmZm Z m Z ddl m Z m Z ddlmZmZddlmZdd lmZdd lZdd lZdd lZdd lZdd lZdd lZdd lZdd lZdd lZdd lZdd lZdd l Z dd l!Z!dd l"Z"dd l#Z#dd l$Z$dd l%Z%dd l&Z&dd l'm(Z(m)Z)dd l*m+Z+dd l*m,Z,ddl-m.Z.ddl/m0Z0ddl1m2Z2ddl3m4Z4m5Z5m6Z6ddl/m7Z7m8Z8ddl9m:Z:ddl;mZ>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJdd l;Z;ejKde;jLdgdZMddZNddZOddZPddZQd d!ZRGd"d#d#e,ZSd$d%ZTd&d'ZUd(d)ZVd*d+ZWd,d-ZXGd.d/d/eBZYGd0d1d1eYZZej[\d2d3d4krBeZZYd5d6Z]d7d8Z^d9d:Z_d;d<Z`did=d>Zad?d@ZbdAdBZcdCejdvrhecZendDdEZedjdGdHZfdIdJZgdKdLZhdMdNZizddOlmjZkWnelydPdQZkYnwdRdSZjGdTdUdUemZnenoZpGdVdWdWenZqGdXdYdYZrGdZd[d[erZsGd\d]d]esZterjuZuerjvZvd^d_Zwd`daZxdbe^fdcddZydedfZzGdgdhdhe+Z{d S)ka0 Easy Install ------------ A tool for doing automatic download/extract/build of distutils-based Python packages. For detailed documentation, see the accompanying EasyInstall.txt file, or visit the `EasyInstall home page`__. __ https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html )glob) get_platform) convert_path subst_vars)DistutilsArgErrorDistutilsOptionErrorDistutilsErrorDistutilsPlatformError)INSTALL_SCHEMES SCHEME_KEYS)logdir_util) first_line_re)find_executableN)get_config_varsget_path)SetuptoolsDeprecationWarning)Command) run_setup)setopt)unpack_archive) PackageIndexparse_requirement_arg URL_SCHEME) bdist_eggegg_info)Wheel) yield_linesnormalize_pathresource_stringensure_directoryget_distributionfind_distributions Environment Requirement Distribution PathMetadata EggMetadata WorkingSetDistributionNotFoundVersionConflict DEVELOP_DISTdefault)category)samefile easy_installPthDistributionsextract_wininst_cfgget_exe_prefixescCstddkS)NP)structcalcsizer7r7/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/easy_install.pyis_64bitJr9cCsjtj|o tj|}ttjdo|}|rtj||Stjtj|}tjtj|}||kS)z Determine if two paths reference the same file. Augments os.path.samefile to work on Windows and suppresses errors if the path doesn't exist. r.)ospathexistshasattrr.normpathnormcase)p1p2Z both_existZ use_samefileZnorm_p1Znorm_p2r7r7r8r.Nsr.cCs |dS)Nutf8)encodesr7r7r8 _to_bytes^s rGcCs&z|dWdStyYdSw)NasciiTF)rD UnicodeErrorrEr7r7r8isasciibs   rJcCst|ddS)N z; )textwrapdedentstripreplace)textr7r7r8 _one_linerjsrQc@szeZdZdZdZdZdddddd d d d d ddddddddddddddejfgZgdZ ddiZ e Z dd Z d!d"Zd#d$Zed%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zdd1d2Zd3d4Zd5d6Zd7d8Zed9Zed:Zed;Z dd?Z"d@dAZ#dBdCZ$dDdEZ%dFdGZ&e'j(dHdIZ)ddKdLZ*ddMdNZ+dOdPZ, ddQdRZ-dSdTZ.dUdVZ/dWdXZ0ddYdZZ1ed[d\Z2dd_d`Z3dadbZ4dcddZ5dedfZ6dgdhZ7didjZ8dkdlZ9edmZ:ednZ;ddpdqZdudvZ?dwdxZ@dydzZAd{d|ZBd}d~ZCddZDddZEedFZGddZHeIeIddddZJeIdddZKddZLdS)r/z'Manage a download/build/install processz Find/get/install Python packagesT)zprefix=Nzinstallation prefix)zip-okzzinstall package as a zipfile) multi-versionmz%make apps have to require() a version)upgradeUz1force upgrade (searches PyPI for latest versions))z install-dir=dzinstall package to DIR)z script-dir=rFzinstall scripts to DIR)exclude-scriptsxzDon't install scripts) always-copyaz'Copy all needed packages to install dir)z index-url=iz base URL of Python Package Index)z find-links=fz(additional URL(s) to search for packages)zbuild-directory=bz/download/extract/build in DIR; keep the results)z optimize=Ozlalso compile with optimization: -O1 for "python -O", -O2 for "python -OO", and -O0 to disable [default: -O0])zrecord=Nz3filename in which to record list of installed files) always-unzipZz*don't install as a zipfile, no matter what)z site-dirs=Sz)list of directories where .pth files work)editableez+Install specified packages in editable form)no-depsNzdon't install dependencies)z allow-hosts=Hz$pattern(s) that hostnames must match)local-snapshots-oklz(allow building eggs from local checkouts)versionNz"print version information and exit)z no-find-linksNz9Don't load find-links defined in packages being installeduserNz!install in user site-package '%s') rRrTrYrVr[rdrfrirkrlrarRcCs2tdtd|_d|_|_d|_|_|_d|_ d|_ d|_ d|_ d|_ |_d|_|_|_d|_|_|_d|_|_|_d|_d|_d|_d|_d|_d|_d|_d|_d|_ t!j"rlt!j#|_$t!j%|_&nd|_$d|_&d|_'d|_(d|_)|_*d|_+i|_,d|_-|j.j/|_/|j.0||j.1ddS)NzVeasy_install command is deprecated. Use build and pip and other standards-based tools.rr/)2warningswarnEasyInstallDeprecationWarningrlzip_oklocal_snapshots_ok install_dir script_direxclude_scripts index_url find_linksbuild_directoryargsoptimizerecordrV always_copy multi_versionrdno_deps allow_hostsrootprefix no_reportrkinstall_purelibinstall_platlibinstall_headers install_libinstall_scripts install_data install_baseinstall_platbasesiteENABLE_USER_SITE USER_BASEinstall_userbase USER_SITEinstall_usersite no_find_links package_indexpth_filealways_copy_from site_dirsinstalled_projects_dry_run distributionverbose_set_command_optionsget_option_dictselfr7r7r8initialize_optionssN      zeasy_install.initialize_optionscCs"dd|D}tt|j|dS)Ncss,|]}tj|stj|r|VqdSN)r;r<r=islink).0filenamer7r7r8 s   z/easy_install.delete_blockers..)listmap _delete_path)rblockersZextant_blockersr7r7r8delete_blockersszeasy_install.delete_blockerscCsJtd||jr dStj|otj| }|rtntj}||dS)Nz Deleting %s) r infodry_runr;r<isdirrrmtreeunlink)rr<Zis_treeZremoverr7r7r8rs  zeasy_install._delete_pathcCs4djtj}td}d}t|jditt)zT Render the Setuptools version and installation details, then exit. {}.{} setuptoolsz=setuptools {dist.version} from {dist.location} (Python {ver})Nr7)formatsys version_infor!printlocals SystemExit)verdisttmplr7r7r8_render_versions zeasy_install._render_versionc Csl|jo|tjd}tdd\}}|j|j|j||dd|d|d||||t tddd |_ t j rK|j |j d <|j|j d <n|jrStd ||||d d dd|jdurp|j|_|jdurxd|_|dd|dd|jr|jr|j|_|j|_|ddtttj}t|_ |j!durdd|j!dD}|D]#}t"j#|std|qt||vrt$|d|j %t|q|j&s|'|j(pd|_(|j dd|_)|jt|jfD]}||j)vr|j)*d|q|j+durdd|j+dD}ndg}|j,dur+|j-|j(|j)|d|_,t.|j)tj|_/|j0durHt1|j0t2rG|j0|_0ng|_0|j3rY|j,4|j)tj|jsd|j,5|j0|dd t1|j6t7szt7|j6|_6d|j6krdkst8t8Wnt8y} zt$d!| d} ~ ww|j&r|j9st:d"|j;st:d#g|_-sz1easy_install.finalize_options..,z"%s (in --site-dirs) does not existz$ (in --site-dirs) is not on sys.pathzhttps://pypi.org/simple/cSsg|]}|qSr7)rNrr7r7r8rC*) search_pathhosts)ryryz--optimize must be 0, 1, or 2z9Must specify a build directory (-b) when using --editablez:No urls, filenames, or requirements specified (see --help))=rkrrsplitrrget_name get_version get_fullnamegetattr config_varsrrrrrlr rn_fix_install_dir_for_user_siteexpand_basedirs expand_dirs_expandrsrrrset_undefined_optionsrrrrr< get_site_dirs all_site_dirsrr;rrappendrdcheck_site_dirru shadow_pathinsertr~r create_indexr# local_indexrv isinstancestrrqZscan_egg_linksadd_find_linksryint ValueErrorrwrrxoutputs) rrrrr?rrX path_itemrrer7r7r8finalize_optionss                        zeasy_install.finalize_optionscCs\|jrtjsdS||jdurd}t||j|_|_tj ddd}| |dS)z; Fix the install_dir if "--user" was used. Nz$User base directory is not specifiedposixunix_user) rlrrcreate_home_pathrr rrr;namerO select_scheme)rmsg scheme_namer7r7r8rjs  z+easy_install._fix_install_dir_for_user_sitecCsX|D]'}t||}|dur)tjdkstjdkrtj|}t||j}t|||qdS)Nrnt)rr;rr<rrrsetattr)rattrsattrvalr7r7r8 _expand_attrsys    zeasy_install._expand_attrscCs|gddS)zNCalls `os.path.expanduser` on install_base, install_platbase and root.)rrrNrrr7r7r8rszeasy_install.expand_basedirscCsgd}||dS)z+Calls `os.path.expanduser` on install dirs.)rrrrrrNr)rdirsr7r7r8rszeasy_install.expand_dirsc Cs|r |dtj|j|jjkrt|jzQ|jD] }|||j q|j rZ|j }|j rFt |j }t t |D] }|||d||<q9ddlm}||j|j |fd|j |Wt|jjdSt|jjw)NzXWARNING: The easy_install command is deprecated and will be removed in a future version.r) file_utilz'writing list of installed files to '%s')announcer WARNrr set_verbosityrxr/r}rzrrlenrange distutilsrexecute write_filewarn_deprecated_options)rZshow_deprecationspecrroot_lencounterrr7r7r8runs2      "zeasy_install.runcCsBzt}Wntytdtj}Ynwtj|j d|S)zReturn a pseudo-tempname base in the install directory. This code is intentionally naive; if a malicious party can write to the target directory you're already in deep doodoo. rztest-easy-install-%s) r;getpid Exceptionrandomrandintrmaxsizer<joinrr)rpidr7r7r8pseudo_tempnames   zeasy_install.pseudo_tempnamecCdSrr7rr7r7r8rz$easy_install.warn_deprecated_optionsc CsBt|j}tj|d}tj|s)zt|Wnttfy(| Ynw||j v}|s8|j s8| }n1| d}tj|}z|rLt|t|dt|Wnttfyh| Ynw|s~|j s~tjdd}t|j|j||r|jdurt||j |_nd|_|j rtj|sd|_||_dS)z;Verify that self.install_dir is .pth-capable dir, if neededeasy-install.pthz .write-testw PYTHONPATHrN)rrrr;r<rr=makedirsOSErrorIOErrorcant_write_to_targetrr|check_pth_processingrropencloseenvirongetr rn_easy_install__no_default_msgrr0)rinstdirrZ is_site_dirZtestfileZ test_exists pythonpathr7r7r8rs@             zeasy_install.check_site_diraS can't create or remove files in install directory The following error occurred while trying to add or remove files in the installation directory: %s The installation directory you specified (via --install-dir, --prefix, or the distutils default setting) was: %s z This directory does not currently exist. Please create it and try again, or choose a different installation directory (using the -d or --install-dir option). a Perhaps your account does not have write access to this directory? If the installation directory is a system-owned directory, you may need to sign in as the administrator or "root" account. If you do not have administrative access to this machine, you may wish to choose a different installation directory, preferably one that is listed in your PYTHONPATH environment variable. For information on other options, you may wish to consult the documentation at: https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html Please make the appropriate changes for your system and try again. cCsR|jtd|jf}tj|js|d|j7}t ||d|j7}t |)NrK) _easy_install__cant_write_msgrexc_inforrr;r<r=_easy_install__not_exists_id_easy_install__access_msgr)rrr7r7r8rs z!easy_install.cant_write_to_targetc Cs|j}td||d}|d}tj|}tdd}z|r't|tj |}tj |ddt |d}Wnt t fyI|Ynwz||jdit|d }tj}tjd krtj|\}} tj|d } | d kotj| } | r| }d dlm} | |dddgd tj|rtd|W|r|tj|rt|tj|rt|dSdSW|r|tj|rt|tj|rt|n|r|tj|rt|tj|rt|ww|jstd|dS)z@Empirically verify whether .pth files are supported in inst. dirz Checking .pth file support in %s.pthz.okzz import os f = open({ok_file!r}, 'w') f.write('OK') f.close() rKT)exist_okrNr pythonw.exe python.exer)spawnz-Ez-cpassz-TEST PASSED: %s appears to support .pth filesz+TEST FAILED: %s does NOT support .pth filesFr7)rrr rrr;r<r=rQrdirnamerrrrrwriterrrr executablerrrlowerdistutils.spawnr-r|rn) rr"rZok_fileZ ok_existsrr/r^r1basenameZaltZuse_altr-r7r7r8rs~                       z!easy_install.check_pth_processingc CsV|js$|dr$|dD]}|d|rq ||||d|q ||dS)z=Write all the scripts for `dist`, unless scripts are excludedscriptszscripts/N)rtmetadata_isdirmetadata_listdirinstall_script get_metadatainstall_wrapper_scripts)rr script_namer7r7r8install_egg_scriptsSs z easy_install.install_egg_scriptscCsVtj|r#t|D]\}}}|D] }|jtj||qq dS|j|dSr)r;r<rwalkrrr)rr<baserfilesrr7r7r8 add_outputas zeasy_install.add_outputcCs|jr td|fdS)NzjInvalid argument %r: you can't use filenames or URLs with --editable (except via the --find-links option).)rdrrrr7r7r8 not_editableiszeasy_install.not_editablecCs<|jsdStjtj|j|jrtd|j|jfdS)Nz2%r already exists in %s; can't do a checkout there)rdr;r<r=rrwkeyrrAr7r7r8check_editableqs zeasy_install.check_editablec csTtjdd}zt|VWtj|ot|dSdStj|o(t|ww)Nz easy_install-)r)tempfilemkdtemprr;r<r=r)rtmpdirr7r7r8_tmpdir{s   8zeasy_install._tmpdirFc CsB|}t|tsIt|r*|||j||}|d|||dWdStj |rE|||d|||dWdSt |}| ||j |||j|j|j |j}|durqd|}|jrm|d7}t||jtkr||||d|WdS|||j||WdS1swYdS)NTz+Could not find suitable distribution for %rz2 (--always-copy skips system and development eggs)Using)rHrr$rrBrdownload install_itemr;r<r=rrDZfetch_distributionrVrdr{rr precedencer+process_distributionlocation)rrdepsrGdlrrr7r7r8r/s8         $zeasy_install.easy_installcCs |p|j}|ptj||k}|p|d }|p*|jduo*tjt|t|jk}|rA|sA|j|jD] }|j |kr>nq5d}t dtj ||ra| |||}|D] }||||qVn||g}|||d|d|dur|D] }||vr|SqwdSdS)N.eggTz Processing %srrI)r{r;r<r/endswithrrr project_namerNr rr4 install_eggsrMegg_distribution)rrrJrGrOZinstall_neededrdistsr7r7r8rKs<    zeasy_install.install_itemcCs<t|}tD]}d|}t||durt||||qdS)z=Sets the install directories by applying the install schemes.install_N)r r rr)rrschemerCattrnamer7r7r8rszeasy_install.select_schemec Gs|||j|||j|jvr|j||j|||||j|j<t |j ||g|R| drH|j sH|j |d|sO|jsOdS|dura|j|jkratd|dS|dusi||vrs|}tt|}t d|ztg|g|j|j}Wn%ty}ztt||d}~wty}zt||d}~ww|js|jr|D]}|j|jvr||qt d|dS)Nzdependency_links.txtzSkipping dependencies for %szProcessing dependencies for %sz'Finished processing dependencies for %s) update_pthraddrrCremover<rr rinstallation_report has_metadatarrget_metadata_linesr{rnas_requirementr$rr(resolver/r)rr*reportr)r requirementrrOrZdistreqZdistrosrer7r7r8rMsP              z!easy_install.process_distributioncCs2|jdur |j S|drdS|dsdSdS)Nz not-zip-safeTzzip-safeF)rpr^rrr7r7r8 should_unzips   zeasy_install.should_unzipcCstj|j|j}tj|rd}t||j|j||Stj|r&|}n)tj ||kr3t |t |}t |dkrOtj||d}tj|rO|}t |t|||S)Nz<%r already exists in %s; build directory %s will not be keptr$r)r;r<rrwrCr=r rnrr/rlistdirrr shutilmove)rr dist_filename setup_basedstrcontentsr7r7r8 maybe_moves$       zeasy_install.maybe_movecCs,|jrdSt|D]}|j|q dSr)rt ScriptWriterbestget_args write_script)rrrxr7r7r8r:s  z$easy_install.install_wrapper_scriptscCsNt|}t||}|r||t}t||}||t|ddS)z/Generate a legacy script wrapper and install itr_N) rr`is_python_script_load_templaterrn get_headerrqrG)rrr; script_textdev_pathrZ is_scriptbodyr7r7r8r8"s  zeasy_install.install_scriptcCs(d}|r |dd}td|}|dS)z There are a couple of template scripts in the package. This function loads one of them and prepares it for use. z script.tmplz.tmplz (dev).tmplrutf-8)rOrdecode)rvrZ raw_bytesr7r7r8rs,s    zeasy_install._load_templatetr7csfdd|Dtd|jtjj|}|jr&dSt }t |tj |r8t |t |d| }||Wdn1sOwYt|d|dS)z1Write an executable file to the scripts directorycsg|] }tjj|qSr7)r;r<rrsrrZrr7r8r>z-easy_install.write_script..zInstalling %s script to %sNri)rr rrsr;r<rr@r current_umaskr r=rrr0chmod)rr;rlmodertargetmaskr^r7rr8rq;s     zeasy_install.write_scriptc CsH|j|j|jd}z ||dd}Wn tyYnw|||gS|}tj|r:|ds:t |||j n tj |rFtj |}| |rY|jrY|durY||||}tj|d}tj|sttj|dd}|s|tdtj |t|dkrtdtj ||d }|jrt|||gS|||S) N)rQ.exez.whl.pyzsetup.pyrz"Couldn't find a setup script in %sr$zMultiple setup scripts in %sr) install_egg install_exe install_wheelr2KeyErrorr;r<isfilerRrunpack_progressrabspath startswithrwrmrr=rrrrdr rreport_editablebuild_and_install) rrrirGZ installer_mapZ install_distrj setup_scriptZsetupsr7r7r8rTOsT          zeasy_install.install_eggscCs>tj|rt|tj|d}ntt|}tj ||dS)NEGG-INFO)metadata) r;r<rr&rr' zipimport zipimporterr% from_filename)regg_pathrr7r7r8rUs  zeasy_install.egg_distributionc Cstj|jtj|}tj|}|jst|||}t ||stj |r8tj |s8t j ||jdntj|rI|tj|fd|z_d}tj |re||r^tjd}}n,tjd}}n%||rv|||jd}}nd}||rtjd}}ntjd}}||||f|dtj|tj|ft||d Wntyt|dd w||||S) Nr Removing FZMovingZCopyingZ ExtractingTz %s to %sfix_zipimporter_caches)r;r<rrrr4rrr rUr.rrr remove_treer=rrrrgrhcopytreeremkpathunpack_and_compilecopy2r/update_dist_cachesr r@)rrrG destinationrZnew_dist_is_zippedr^rUr7r7r8rs`                 zeasy_install.install_eggc sNt|}|durtd|td|dd|ddtd}tj||d}||_ |d}tj|d}tj|d }t |t |||_ | ||tj|st|d } | d |dD]\} } | d kr{| d | dd| fqd| tj|d|fddt|Dtj|||j|jd|||S)Nz(%s is not a valid distutils Windows .exerrrk)rSrkplatformrQz.tmprPKG-INFOrzMetadata-Version: 1.0 target_versionz%s: %s _-r5csg|] }tj|dqS)r)r;r<r)rrxrsr7r8rsz,easy_install.install_exe..)rr)r1rr%r rr;r<regg_namerNr r& _provider exe_to_eggr=rr0itemsrOtitlerrrnrpr make_zipfilerrr) rrirGcfgrregg_tmpZ _egg_infoZpkg_infr^kvr7rr8rsD        zeasy_install.install_exec s8t|ggifdd}t||g}D]7}|drU|d}|d}t|dd|d<tjj g|R} || |t ||q| t tj dt|dD]-} t| rtj d| d } tj| st| d } | d t| d | qld S) z;Extract a bdist_wininst to the directories an egg would usecs|}D]l\}}||rr||t|d}|d}tjjg|R}|}|ds6|drTt |d|d<dtj |dd< ||S|drn|dkrndtj |dd< ||Sq|d s~t d |dS) N/.pyd.dllr$rrSCRIPTS/r)zWARNING: can't process %s)r2rrrr;r<rrRr strip_modulesplitextrr rn)srcrkrFoldnewpartsrPr native_libsprefixes to_compile top_levelr7r8processs(      z(easy_install.exe_to_egg..processrrrrr)rrz.txtrrKN)r2rr2rRrrrr;r<rrZ write_stub byte_compileZwrite_safety_flagZ analyze_eggrr=rr0r) rrirrZstubsresrresourceZpyfilertxtr^r7rr8rs>           zeasy_install.exe_to_eggc Cst|}|s Jtj|j|}tj|}|js!t |tj |r6tj |s6t j ||jdntj|rG|tj|fd|z||j|fdtj|tj|fWt|ddnt|ddw||||S)NrrzInstalling %s to %sFr)r is_compatibler;r<rrrrrrr rrr rr=rrZinstall_as_eggr4r/rr@rU)r wheel_pathrGwheelrr7r7r8r$s4       zeasy_install.install_wheela( Because this distribution was installed --multi-version, before you can import modules from this package in an application, you will need to 'import pkg_resources' and then use a 'require()' call similar to one of these examples, in order to select the desired version: pkg_resources.require("%(name)s") # latest installed version pkg_resources.require("%(name)s==%(version)s") # this exact version pkg_resources.require("%(name)s>=%(version)s") # this version or higher z Note also that the installation directory must be on sys.path at runtime for this to work. (e.g. by being the application's script directory, by being on PYTHONPATH, or by being added to sys.path by your code.) Installedc Cs^d}|jr|js|d|j7}|jtttjvr|d|j7}|j }|j }|j }d}|t S)z9Helpful installation message for display to package usersz %(what)s %(eggloc)s%(extras)srKr) r|r_easy_install__mv_warningrrrrrr<_easy_install__id_warningrNrSrkr) rreqrwhatrZegglocrrkextrasr7r7r8r]Rs  z easy_install.installation_reportaR Extracted editable version of %(spec)s to %(dirname)s If it uses setuptools in its setup script, you can activate it in "development" mode by going to that directory and running:: %(python)s setup.py develop See the setuptools documentation for the "develop" command for more info. cCs"tj|}tj}d|jtS)NrK)r;r<r/rr1_easy_install__editable_msgr)rrrr/pythonr7r7r8rks zeasy_install.report_editablec Cstjdttjdtt|}|jdkr'd|jd}|dd|n |jdkr2|dd|jr;|dd t d |t |ddd |zt ||WdStyl}z td |jdf|d}~ww) Nzdistutils.command.bdist_eggzdistutils.command.egg_inforrr$rrz-qz-nz Running %s %s zSetup script exited with %s)rmodules setdefaultrrrrrrr rrrrrrrx)rrrjrxrr7r7r8rps.    zeasy_install.run_setupc Csddg}tjdtj|d}zJ|tj|||||||t|g}g}|D]}||D] }|| |j |q4q.|sM|j sMt d||Wt|t |jSt|t |jw)Nrz --dist-dirz egg-dist-tmp-)rdirz+No eggs found in %s (setup script problem?))rErFr;r<r/_set_fetcher_optionsrrr#rrNrr rnrrr) rrrjrxdist_dirZall_eggseggsrCrr7r7r8rs.     zeasy_install.build_and_installc Csh|jd}d}i}|D]\}}||vrq|d||<qt|d}tj|d}t ||dS)a When easy_install is about to run bdist_egg on a source dist, that source dist might have 'setup_requires' directives, requiring additional fetching. Ensure the fetcher options given to easy_install are available to that command as well. r/)rvrruryr~r$)r/z setup.cfgN) rrcopyrdictr;r<rrZ edit_config) rr>Zei_optsZfetch_directivesZ fetch_optionsrCrsettingsZ cfg_filenamer7r7r8rs  z!easy_install._set_fetcher_optionscCsJ|jdurdS|j|jD]%}|js|j|jkrq td||j||j|jvr2|j|jq |js]|j|jjvrDtd|ntd||j ||j|jvr]|j |j|j rbdS|j |jdkrndSt j|jd}t j|rt |t|d}||j|jdWddS1swYdS)Nz&Removing %s from easy-install.pth filez4%s is already the active version in easy-install.pthz"Adding %s to easy-install.pth filersetuptools.pthwtrK)rrCr|rNr rr\rpathsr[rrsaver;r<rrrrrrr0 make_relative)rrrXrr^r7r7r8rZs>            "zeasy_install.update_pthcCstd|||S)NzUnpacking %s to %s)r debug)rrrkr7r7r8rszeasy_install.unpack_progresscshggfdd}t|||js0D]}t|tjdBd@}t||qdSdS)NcsZ|dr|ds|n|ds|dr|||j r+|p,dS)Nr EGG-INFO/rz.so)rRrrrr)rrkrZto_chmodrr7r8pfs    z+easy_install.unpack_and_compile..pfimi)rrrr;statST_MODEr~)rrrrr^rr7rr8rs   zeasy_install.unpack_and_compilec CstjrdSddlm}z0t|jd||dd|jd|jr3|||jd|jdWt|jdSWt|jdSt|jw)Nr)rr$)ryforcer) rdont_write_bytecodedistutils.utilrr rrrry)rrrr7r7r8rs zeasy_install.byte_compilea bad install directory or PYTHONPATH You are attempting to install a package to a directory that is not on PYTHONPATH and which Python does not read ".pth" files from. The installation directory you specified (via --install-dir, --prefix, or the distutils default setting) was: %s and your PYTHONPATH environment variable currently contains: %r Here are some of your options for correcting the problem: * You can choose a different installation directory, i.e., one that is on PYTHONPATH or supports .pth files * You can add the installation directory to the PYTHONPATH environment variable. (It must then also be on PYTHONPATH whenever you run Python and want to use the package(s) you are installing.) * You can set up the installation directory to support ".pth" files by using one of the approaches described here: https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html#custom-installation-locations Please make the appropriate changes for your system and try again. cCsb|jsdSttjd}|jD]\}}||r.tj|s.| d|t |dqdS)zCreate directories under ~.N~zos.makedirs('%s', 0o700)i) rlrr;r<rrrrr debug_printr)rhomerr<r7r7r8r)s zeasy_install.create_home_pathz/$base/lib/python$py_version_short/site-packagesz $base/binrrz$base/Lib/site-packagesz $base/ScriptscGs|dj}|jr2|}|j|d<|jtj|j}| D]\}}t ||ddur1t |||qddl m }|D]!}t ||}|dur[|||}tjdkrUtj|}t |||q:dS)Nrr>r)rr)get_finalized_commandrrrr r r;rDEFAULT_SCHEMErrrrrr<r)rrrrXrrrr7r7r8r?s&         zeasy_install._expand)T)Fr)rzr7)r)M__name__ __module__ __qualname____doc__ descriptionZcommand_consumes_argumentsrr user_optionsboolean_options negative_optrrrrr staticmethodrrrrrrr rrrrLrMlstripr%r'r(rrr<r@rBrD contextlibcontextmanagerrHr/rKrrMrermr:r8rsrqrTrUrrrrrrr]rrrrrrZrrrrNr!rrr rrr7r7r7r8r/ns5     -  ;   !$ )    3 6.5    )   r/cCs tjddtj}td|S)Nrr)r;rr rpathsepfilter)rr7r7r8 _pythonpathVs rc sgttjg}tjtjkr|tj|D]h}|sqtjdvr0tj |ddn+tj dkrNtj |ddj tj dtj |ddgn |tj |ddgtjdkraqd |vrfqtj d }|soqtj |d d d j tj d}|qtdtdf}fdd|DtjrtjtttWdn1swYtttS)z& Return a list of 'site' dirs )Zos2emxZriscosLibz site-packagesrlibz python{}.{}z site-pythondarwinzPython.frameworkHOMELibraryPythonrpurelibplatlibc3s|] }|vr|VqdSrr7rsitedirsr7r8rsz get_site_dirs..N)extendrrrrrrr;r<rseprrrr rrrrrsuppressAttributeErrorgetsitepackagesrrr)rrrZhome_spZ lib_pathsr7rr8r[s`             rccsi}|D]l}t|}||vrqd||<tj|sqt|}||fV|D]I}|ds/q'|dvr4q'ttj||}tt |}| |D]&}| drQqIt| }||vr\qId||<tj|sgqI|t|fVqIq'qdS)zBYield sys.path directories that might contain "old-style" packagesr$r))rrimportN) rr;r<rrfrRrrrrrrrstrip)inputsseenr/r?rr^linesliner7r7r8 expand_pathss@        rc CsTt|d}zt|}|durW|dS|d|d|d}|dkr-W|dS||dtd|d\}}}|dvrKW|dS||d|d d d }t |}z||} | d d d } | t } |t| WntjyYW|dSw|dr|dsW|dS|W|S|w)znExtract configuration data from a bdist_wininst .exe Returns a configparser.RawConfigParser, or None rbN  zegg path translations for a given .exe file))zPURELIB/r)zPLATLIB/pywin32_system32r)zPLATLIB/r)rzEGG-INFO/scripts/)zDATA/lib/site-packagesrrrrrr$z .egg-inforNrr)z -nspkg.pth)ZPURELIBZPLATLIB\r z%s/%s/rcSsg|] \}}||fqSr7)r2)rrZyr7r7r8rr|z$get_exe_prefixes..)rZipFileinfolistrrrrRrrupperrryrrNrOrrrsortreverse)Z exe_filenamerrSrrrrlpthr7r7r8r2s4      r2c@sReZdZdZdZdddZddZdd Zed d Z d d Z ddZ ddZ dS)r0z)A .pth file with Distribution paths in itFr7cCsl||_ttt||_ttj|j|_| t |gddt |j D] }tt|jt|dq&dS)NT)rrrrrr;r<r/basedir_loadr#__init__rrr[r")rrrr<r7r7r8r7"szPthDistributions.__init__cCsg|_d}t|j}tj|jret|jd}|D]F}| dr$d}q| }|j || r9| dr:qt tj|j|}|jd<tj|rS||vr\|jd|_qd||<q||jrm|smd|_|jr|jd s|j|jr|jd rwdSdSdSdS)NFrtr T#rr$)rrfromkeysrr;r<rrrrrrrNrrr5r=popdirtyr)rZ saw_importrr^rr<r7r7r8r6+s6        $zPthDistributions._loadcCs|jsdStt|j|j}|rLtd|j||}d |d}t j |jr0t |jt|jd }||Wdn1sFwYnt j |jr`td|jt |jd|_dS)z$Write changed .pth file back to diskNz Saving %srKrzDeleting empty %sF)r<rrrrr rr _wrap_linesrr;r<rrrr0r=)rZ rel_pathsrdatar^r7r7r8rJs"     zPthDistributions.savecC|Srr7)rr7r7r8r=`szPthDistributions._wrap_linescCsN|j|jvo|j|jvp|jtk}|r|j|jd|_t||dS)z"Add `dist` to the distribution mapTN) rNrrr;getcwdrr<r#r[)rrnew_pathr7r7r8r[ds   zPthDistributions.addcCs<|j|jvr|j|jd|_|j|jvst||dS)z'Remove `dist` from the distribution mapTN)rNrr\r<r#rdr7r7r8r\rs  zPthDistributions.removecCstjt|\}}t|j}|g}tjdkrdptj}t||krI||jkr6|tj | | |Stj|\}}||t||ks"|S)Nr) r;r<rrrr5altsepr rcurdirr3r)rr<npathlastZbaselenrr r7r7r8rys       zPthDistributions.make_relativeN)r7) rrrrr<r7r6rrr=r[r\rr7r7r7r8r0s    r0c@s(eZdZeddZedZedZdS)RewritePthDistributionsccs&|jV|D]}|Vq|jVdSr)preludepostlude)clsrrr7r7r8r=s  z#RewritePthDistributions._wrap_linesz? import sys sys.__plen = len(sys.path) z import sys new = sys.path[sys.__plen:] del sys.path[sys.__plen:] p = getattr(sys, '__egginsert', 0) sys.path[p:p] = new sys.__egginsert = p + len(new) N)rrr classmethodr=rQrGrHr7r7r7r8rFs   rFZSETUPTOOLS_SYS_PATH_TECHNIQUErawZrewritecCs ttjtrtSttjS)z_ Return a regular expression based on first_line_re suitable for matching strings. )rrpatternrrecompileryr7r7r7r8_first_line_res rOcCsX|tjtjfvrtjdkrt|tj||St\}}}|d|dd||ff)Nrrr$z %s %s) r;rr\rr~rS_IWRITErr&)funcargexcetZevrr7r7r8 auto_chmods  rUcCs0t|}t|tj|rt|dSt|dS)aa Fix any globally cached `dist_path` related data `dist_path` should be a path of a newly installed egg distribution (zipped or unzipped). sys.path_importer_cache contains finder objects that have been cached when importing data from the original distribution. Any such finders need to be cleared since the replacement distribution might be packaged differently, e.g. a zipped egg distribution might get replaced with an unzipped egg folder or vice versa. Having the old finders cached may then cause Python to attempt loading modules from the replacement distribution using an incorrect loader. zipimport.zipimporter objects are Python loaders charged with importing data packaged inside zip archives. If stale loaders referencing the original distribution, are left behind, they can fail to load modules from the replacement distribution. E.g. if an old zipimport.zipimporter instance is used to load data from a new zipped egg archive, it may cause the operation to attempt to locate the requested data in the wrong location - one indicated by the original distribution's zip archive directory information. Such an operation may then fail outright, e.g. report having read a 'bad local file header', or even worse, it may fail silently & return invalid data. zipimport._zip_directory_cache contains cached zip archive directory information for all existing zipimport.zipimporter instances and all such instances connected to the same archive share the same cached directory information. If asked, and the underlying Python implementation allows it, we can fix all existing zipimport.zipimporter instances instead of having to track them down and remove them one by one, by updating their shared cached zip archive directory information. This, of course, assumes that the replacement distribution is packaged as a zipped egg. If not asked to fix existing zipimport.zipimporter instances, we still do our best to clear any remaining zipimport.zipimporter related cached data that might somehow later get used when attempting to load data from the new distribution and thus cause such load operations to fail. Note that when tracking down such remaining stale data, we can not catch every conceivable usage from here, and we clear only those that we know of and have found to cause problems if left alive. Any remaining caches should be updated by whomever is in charge of maintaining them, i.e. they should be ready to handle us replacing their zip archives with new distributions at runtime. N)r_uncacherpath_importer_cache!_replace_zip_directory_cache_data*_remove_and_clear_zip_directory_cache_data) dist_pathrnormalized_pathr7r7r8rs <   rcCsPg}t|}|D]}t|}||r%|||dtjdfvr%||q|S)ap Return zipimporter cache entry keys related to a given normalized path. Alternative path spellings (e.g. those using different character case or those using alternative path separators) related to the same path are included. Any sub-path entries are included as well, i.e. those corresponding to zip archives embedded in other zip archives. r$r)rrrr;r r)r[cacheresult prefix_lenpnpr7r7r8"_collect_zipimporter_cache_entries s   racCs@t||D]}||}||=|o|||}|dur|||<qdS)a Update zipimporter cache data for a given normalized path. Any sub-path entries are processed as well, i.e. those corresponding to zip archives embedded in other zip archives. Given updater is a callable taking a cache entry key and the original entry (after already removing the entry from the cache), and expected to update the entry and possibly return a new one to be inserted in its place. Returning None indicates that the entry should not be replaced with a new one. If no updater is given, the cache entries are simply removed without any additional processing, the same as if the updater simply returned None. N)ra)r[r\updaterr_ old_entryZ new_entryr7r7r8_update_zipimporter_caches rdcCst||dSr)rd)r[r\r7r7r8rV>r:rVcCdd}t|tj|ddS)NcSs |dSr)clearr<rcr7r7r82clear_and_remove_cached_zip_archive_directory_dataCs zf_remove_and_clear_zip_directory_cache_data..clear_and_remove_cached_zip_archive_directory_datarbrdr_zip_directory_cache)r[rhr7r7r8rYBs  rYZ__pypy__cCre)NcSs&|t||tj||Sr)rfrrupdaterkrgr7r7r8)replace_cached_zip_archive_directory_dataYs zT_replace_zip_directory_cache_data..replace_cached_zip_archive_directory_datarirj)r[rmr7r7r8rXXs   rXc Cs,z t||dWdSttfyYdSw)z%Is this string a valid Python script?execFT)rN SyntaxError TypeError)rPrr7r7r8 is_pythonks rrc Cshz&tj|dd }|d}Wdn 1swYW|dkSW|dkSttfy3|YSw)zCDetermine if the specified executable is a .sh (contains a #! line)zlatin-1)encodingrN#!)r$rrrr)r1fpmagicr7r7r8is_shus rwcCs t|gS)z@Quote a command line argument according to Windows parsing rules subprocess list2cmdline)rRr7r7r8 nt_quote_args r{cCsH|ds |dr dSt||rdS|dr"d|dvSdS)zMIs this text, as a whole, a Python script? (as opposed to shell/bat/etc. r.pywTrtrrF)rRrrr splitlinesr2)rurr7r7r8rrs  rr)r~cGrrr7)rxr7r7r8_chmodrr~c CsTtd||zt||WdStjy)}z td|WYd}~dSd}~ww)Nzchanging mode of %s to %ozchmod failed: %s)r rr~r;error)r<rrer7r7r8r~sr~c@seZdZdZgZeZeddZeddZ eddZ edd Z ed d Z d d Z eddZddZeddZeddZdS) CommandSpeczm A command spec for a #! header, specified as a list of arguments akin to those passed to Popen. cCr?)zV Choose the best CommandSpec class based on environmental conditions. r7rIr7r7r8roszCommandSpec.bestcCstjtj}tjd|S)N__PYVENV_LAUNCHER__)r;r<r?rr1rr )rI_defaultr7r7r8_sys_executableszCommandSpec._sys_executablecCs:t||r|St|tr||S|dur|S||S)zg Construct a CommandSpec from a parameter to build_scripts, which may be None. N)rrfrom_environment from_string)rIparamr7r7r8 from_params   zCommandSpec.from_paramcCs||gSr)rrr7r7r8rszCommandSpec.from_environmentcCstj|fi|j}||S)z} Construct a command spec from a simple string representing a command line parseable by shlex.split. )shlexr split_args)rIstringrr7r7r8rszCommandSpec.from_stringcCs<t|||_t|}t|sdg|jdd<dSdS)Nz-xr)rr_extract_optionsoptionsryrzrJ)rrucmdliner7r7r8install_optionss  zCommandSpec.install_optionscCs:|dd}t|}|r|dpdnd}|S)zH Extract any options from the first line of the script. rKrr$r)r}rOmatchgrouprN)Z orig_scriptfirstrrr7r7r8rs  zCommandSpec._extract_optionscCs||t|jSr)_renderrrrr7r7r8 as_headerszCommandSpec.as_headercCs6d}|D]}||r||r|ddSq|S)Nz"'r$r)rrR)itemZ_QUOTESqr7r7r8 _strip_quotess zCommandSpec._strip_quotescCs tdd|D}d|dS)Ncss|] }t|VqdSr)rrrN)rrr7r7r8rs z&CommandSpec._render..rtrKrx)rrr7r7r8rs  zCommandSpec._renderN)rrrrrrrrJrorrrrrrrrrrr7r7r7r8rs,        rc@seZdZeddZdS)WindowsCommandSpecFrN)rrrrrr7r7r7r8rsrc@seZdZdZedZeZ e dddZ e dddZ e dd d Z ed d Ze d dZe ddZe ddZe dddZdS)rnz` Encapsulates behavior around writing entry point scripts for console and gui apps. aJ # EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r import re import sys # for compatibility with easy_install; see #2198 __requires__ = %(spec)r try: from importlib.metadata import distribution except ImportError: try: from importlib_metadata import distribution except ImportError: from pkg_resources import load_entry_point def importlib_load_entry_point(spec, group, name): dist_name, _, _ = spec.partition('==') matches = ( entry_point for entry_point in distribution(dist_name).entry_points if entry_point.group == group and entry_point.name == name ) return next(matches).load() globals().setdefault('load_entry_point', importlib_load_entry_point) if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) sys.exit(load_entry_point(%(spec)r, %(group)r, %(name)r)()) NFcCs6tdt|r tnt}|d||}|||S)Nz Use get_argsr)rmrnroWindowsScriptWriterrnroget_script_headerrp)rIrr1wininstwriterheaderr7r7r8get_script_args(s  zScriptWriter.get_script_argscCs$tjdtdd|r d}|||S)NzUse get_headerr) stacklevelr,)rmrnrort)rIrur1rr7r7r8r0s  zScriptWriter.get_script_headerc cs|dur |}t|}dD]-}|d}||D]\}}|||jt}|||||} | D]} | Vq7qqdS)z Yield write_script() argument tuples for a distribution's console_scripts and gui_scripts entry points. NconsoleguiZ_scripts) rtrr` get_entry_mapr_ensure_safe_nametemplater_get_script_args) rIrrrtype_rreprurxrr7r7r8rp9s   zScriptWriter.get_argscCstd|}|r tddS)z? Prevent paths in *_scripts entry point names. z[\\/]z+Path separators not allowed in script namesN)rMsearchr)rZ has_path_sepr7r7r8rKs zScriptWriter._ensure_safe_namecCs tdt|r tS|SNzUse best)rmrnrorro)rIZ force_windowsr7r7r8 get_writerTs zScriptWriter.get_writercCs*tjdkstjdkrtjdkrtS|S)zD Select the best ScriptWriter for this environment. win32javar)rrr;r_namerrorr7r7r8roZszScriptWriter.bestccs|||fVdSrr7)rIrrrrur7r7r8rdszScriptWriter._get_script_argsrcCs"|j|}|||S)z;Create a #! line, getting options (if any) from script_text)command_spec_classrorrr)rIrur1cmdr7r7r8rtis zScriptWriter.get_header)NFr)rN)rrrrrLrMrrrrrJrrrprrrrorrtr7r7r7r8rns,!#       rnc@sLeZdZeZeddZeddZeddZeddZ e d d Z d S) rcCstdt|Sr)rmrnrororr7r7r8rts zWindowsScriptWriter.get_writercCs"tt|d}tjdd}||S)zC Select the best ScriptWriter suitable for Windows )r1ZnaturalZSETUPTOOLS_LAUNCHERr1)rWindowsExecutableLauncherWriterr;rr )rIZ writer_lookuplauncherr7r7r8rozs zWindowsScriptWriter.bestc #stddd|}|tjddvr$djd it}t|t gd}| || ||}fdd |D}|||d |fVd S) z For Windows, add a .py extension.pyar|rPATHEXT;zK{ext} not listed in PATHEXT; scripts will not be recognized as executables.)rr -script.py.pyc.pyor|rcg|]}|qSr7r7r{rr7r8rrz8WindowsScriptWriter._get_script_args..rzNr7) rr;rr2rrrrmrn UserWarningr\_adjust_header) rIrrrruextrrrr7rr8rs   z$WindowsScriptWriter._get_script_argscCsNd}d}|dkr ||}}tt|tj}|j||d}||r%|S|S)z Make sure 'pythonw' is used for gui and 'python' is used for console (regardless of what sys.executable is). r+r,r)rrepl)rMrNescape IGNORECASEsub _use_header)rIrZ orig_headerrLrZ pattern_ob new_headerr7r7r8rs z"WindowsScriptWriter._adjust_headercCs$|ddd}tjdkpt|S)z Should _adjust_header use the replaced header? On non-windows systems, always use. On Windows systems, only use the replaced header if it resolves to an executable on the system. rr"r)rNrrr)rZ clean_headerr7r7r8rs zWindowsScriptWriter._use_headerN) rrrrrrJrrorrrrr7r7r7r8rqs     rc@seZdZeddZdS)rc #s|dkr d}d}dg}nd}d}gd}|||}fdd|D} |||d | fVd t|d fVtsJd } | td fVd Sd S)zG For Windows, add a .py extension and an .exe launcher rz -script.pywr|clir)rrrcrr7r7r{rr7r8rrzDWindowsExecutableLauncherWriter._get_script_args..rzrr_z .exe.manifestN)rget_win_launcherr9load_launcher_manifest) rIrrrruZ launcher_typerrhdrrZm_namer7rr8rs$  z0WindowsExecutableLauncherWriter._get_script_argsN)rrrrJrr7r7r7r8rsrcCsJd|}trtdkr|dd}n |dd}n|dd}td|S)z Load the Windows launcher (executable) suitable for launching a script. `type` should be either 'cli' or 'gui' Returns the executable as a byte string. z%s.exez win-arm64.z-arm64.z-64.z-32.r)r9rrOr)typeZ launcher_fnr7r7r8rs   rcCsttd}|dtS)Nzlauncher manifest.xmlrx) pkg_resourcesrrryvars)rmanifestr7r7r8rs rFcCst|||Sr)rgr)r< ignore_errorsonerrorr7r7r8rr:rcCstd}t||S)N)r;umask)tmpr7r7r8r}s  r}c@seZdZdZdS)rozF Warning for EasyInstall deprecations, bypassing suppression. N)rrrrr7r7r7r8rosror)rn)|rrrrrrdistutils.errorsrrrr distutils.command.installr r rr r Zdistutils.command.build_scriptsrr3rrr;rrgrErrMrr rLrmrr5rryrr$r  sysconfigrrrrrZsetuptools.sandboxrZsetuptools.commandrZsetuptools.archive_utilrZsetuptools.package_indexrrrrrZsetuptools.wheelrrrrrr r!r"r#r$r%r&r'r(r)r*r+filterwarnings PEP440Warning__all__r9r.rGrJrQr/rrrr1r2r0rFrr rOrUrrardrVrYbuiltin_module_namesrXrrrwr{rrr~r~ ImportErrorrrrZsys_executablerrnrrrrrrrr}ror7r7r7r8s         DqF.)%l  R       TtA PKH]LX^^Spython3.10/site-packages/setuptools/command/__pycache__/upload_docs.cpython-310.pycnu[o Xai2@sdZddlmZddlmZddlmZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlmZddlmZd d ZGd d d eZdS) z|upload_docs Implements a Distutils 'upload_docs' subcommand (upload documentation to sites other than PyPi such as devpi). )standard_b64encode)log)DistutilsOptionErrorN)iter_entry_points)uploadcCs |ddS)Nzutf-8surrogateescape)encode)sr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/upload_docs.py_encodes r c@seZdZdZdZdddejfddgZejZdd Zd efgZ d d Z d dZ ddZ ddZ eddZeddZddZdS) upload_docszhttps://pypi.python.org/pypi/z;Upload documentation to sites other than PyPi such as devpiz repository=rzurl of repository [default: %s])z show-responseNz&display full response text from server)z upload-dir=Nzdirectory to uploadcCs&|jdurtddD]}dSdSdS)Nzdistutils.commands build_sphinxT) upload_dirr)selfepr r r has_sphinx-s zupload_docs.has_sphinxrcCst|d|_d|_dS)N)rinitialize_optionsr target_dir)rr r r r4s  zupload_docs.initialize_optionscCst||jdur+|r|d}t|jd|_n|d}tj |j d|_n | d|j|_d|j vr>td|d|jdS) NrhtmlbuildZdocsrzpypi.python.orgzrrbasenamer usernamepasswordrdecoder`r!r#rINFOurllibparseurlparserdclientHTTPConnectionHTTPSConnectionAssertionErrorconnect putrequest putheaderstrr) endheaderssendsocketerrorERROR getresponsestatusreason getheader show_responseprint)rr.frbmetar\ credentialsauthbodyctmsgZschemanetlocurlparamsquery fragmentsconnr_erlocationr r r r?sh            zupload_docs.upload_fileN)__name__ __module__ __qualname__DEFAULT_REPOSITORY descriptionr user_optionsboolean_optionsr sub_commandsrrr7rD staticmethodrQ classmethodr`r?r r r r rs*    r)__doc__base64r distutilsrdistutils.errorsrrr~r%r:r@rXrT http.clientrd urllib.parserq pkg_resourcesrrr rr r r r s"     PKH]J! Mpython3.10/site-packages/setuptools/command/__pycache__/alias.cpython-310.pycnu[o XaiM @sDddlmZddlmZmZmZddZGdddeZddZd S) )DistutilsOptionError) edit_config option_base config_filecCs8dD] }||vrt|Sq||gkrt|S|S)z4Quote an argument for later parsing by shlex.split())"'\#)reprsplit)argcr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/alias.pyshquotes rc@sHeZdZdZdZdZdgejZejdgZddZ dd Z d d Z d S) aliasz3Define a shortcut that invokes one or more commandsz0define a shortcut to invoke one or more commandsT)removerzremove (unset) the aliasrcCst|d|_d|_dS)N)rinitialize_optionsargsrselfrrrrs  zalias.initialize_optionscCs.t||jrt|jdkrtddSdS)NzFMust specify exactly one argument (the alias name) when using --remove)rfinalize_optionsrlenrrrrrrr!s zalias.finalize_optionscCs|jd}|js tdtd|D] }tdt||qdSt|jdkrG|j\}|jr1d}n(||vr?tdt||dStd|dS|jd}dtt |jdd}t |j d||ii|j dS) NaliaseszCommand Aliasesz---------------zsetup.py aliasrz No alias definition found for %rr ) distributionget_option_dictrprint format_aliasrrjoinmaprrfilenamedry_run)rrrcommandrrrrun)s&   z alias.runN) __name__ __module__ __qualname____doc__ descriptionZcommand_consumes_argumentsr user_optionsboolean_optionsrrr&rrrrrs  rcCsZ||\}}|tdkrd}n|tdkrd}n |tdkr!d}nd|}||d|S) Nglobalz--global-config userz--user-config localz --filename=%rr)r)namersourcer%rrrr Ds    r N) distutils.errorsrZsetuptools.command.setoptrrrrrr rrrrs  4PKH]daPpython3.10/site-packages/setuptools/command/__pycache__/build_py.cpython-310.pycnu[o XaiT @sddlmZddlmZddlmmZddlZddlZddl Z ddl Z ddl Z ddl Z ddlZddlmZddZGdddejZd d ZdS) )glob) convert_pathN)unique_everseencCst|t|jtjBdSN)oschmodstatst_modeS_IWRITE)targetr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/build_py.py make_writablesrc@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZeddZd S)!build_pyaXEnhanced 'build_py' command that includes data files with packages The data files are specified via a 'package_data' argument to 'setup()'. See 'setuptools.dist.Distribution' for more details. Also, this version of the 'build_py' command allows you to specify both 'py_modules' and 'packages' in the same setup operation. cCs@tj||jj|_|jjpi|_d|jvr|jd=g|_dS)N data_files)origrfinalize_options distribution package_dataexclude_package_data__dict___build_py__updated_filesselfr r r rs    zbuild_py.finalize_optionscCsN|js|jsdS|jr||jr|||tjj|dddS)z?Build modules, packages, and copy data files to build directoryNr)Zinclude_bytecode) py_modulespackagesZ build_modulesZbuild_packagesbuild_package_data byte_compilerr get_outputsrr r r run$s z build_py.runcCs&|dkr ||_|jStj||S)zlazily compute data filesr)_get_data_filesrrr __getattr__)rattrr r r r!4s zbuild_py.__getattr__cCs.tj||||\}}|r|j|||fSr)rr build_modulerappend)rmoduleZ module_filepackageoutfilecopiedr r r r#;s zbuild_py.build_modulecCs|tt|j|jp dS)z?Generate list of '(package,src_dir,build_dir,filenames)' tuplesr )analyze_manifestlistmap_get_pkg_data_filesrrr r r r Aszbuild_py._get_data_filescsJ||tjj|jg|d}fdd||D}|||fS)N.csg|] }tj|qSr )rpathrelpath).0filesrc_dirr r Ns z0build_py._get_pkg_data_files..)get_package_dirrr.join build_libsplitfind_data_files)rr& build_dir filenamesr r2r r,Fs    zbuild_py._get_pkg_data_filescCsX||j||}tt|}tj|}ttj j |}t|j |g|}| |||S)z6Return filenames for package's data files in 'src_dir')_get_platform_patternsrr+r itertoolschain from_iterablefilterrr.isfilemanifest_filesgetexclude_data_files)rr&r3patternsZglobs_expandedZ globs_matchesZ glob_filesfilesr r r r9Ts   zbuild_py.find_data_filesc Cst|jD]4\}}}}|D]+}tj||}|tj|tj||}|||\}} t|tj|}q qdS)z$Copy data files into build directoryN) rrr.r6mkpathdirname copy_filerabspath) rr&r3r:r;filenamer srcfileoutfr(r r r reszbuild_py.build_package_datac Csi|_}|jjs dSi}|jpdD] }||t||<q|d|d}|jj D]N}t j t|\}}d}|} |ra||kra||vra|}t j |\}} t j | |}|ra||kra||vsF||vrz|dro|| kroq,|||g|q,dS)Nr egg_infoz.py)rBrZinclude_package_datarassert_relativer5 run_commandget_finalized_commandfilelistrFrr.r8r6endswith setdefaultr$) rZmfZsrc_dirsr&Zei_cmdr.dfprevZoldfZdfr r r r)ps.    zbuild_py.analyze_manifestcCsdSrr rr r r get_data_filesszbuild_py.get_data_filescCsz|j|WStyYnwtj|||}||j|<|r#|jjs%|S|jjD]}||ks6||dr8nq)|St |d }| }Wdn1sPwYd|vrbt j d|f|S)z8Check namespace packages' __init__ for declare_namespacer-rbNsdeclare_namespacezNamespace package problem: %s is a namespace package, but its __init__.py does not call declare_namespace()! Please fix it. (See the setuptools manual under "Namespace Packages" for details.) ")packages_checkedKeyErrorrr check_packagerZnamespace_packages startswithioopenread distutilserrorsDistutilsError)rr& package_dirZinit_pypkgrVcontentsr r r r\s0      zbuild_py.check_packagecCsi|_tj|dSr)rZrrinitialize_optionsrr r r rgszbuild_py.initialize_optionscCs0tj||}|jjdurtj|jj|S|Sr)rrr5rZsrc_rootrr.r6)rr&resr r r r5s zbuild_py.get_package_dircs\t||j||}fdd|D}tj|}t|fddD}tt|S)z6Filter filenames for package's data files in 'src_dir'c3s|] }t|VqdSr)fnmatchr@r0pattern)rFr r z.build_py.exclude_data_files..c3s|] }|vr|VqdSrr )r0fn)badr r rlrm)r*r<rr=r>r?setr)rr&r3rFrEZ match_groupsmatchesZkeepersr )rorFr rDs  zbuild_py.exclude_data_filescs.t|dg||g}fdd|DS)z yield platform-specific path patterns (suitable for glob or fn_match) from a glob-based spec (such as self.package_data or self.exclude_package_data) matching package in src_dir. c3s"|] }tjt|VqdSr)rr.r6rrjr2r r rls  z2build_py._get_platform_patterns..)r=r>rC)specr&r3Z raw_patternsr r2r r<s   zbuild_py._get_platform_patternsN)__name__ __module__ __qualname____doc__rrr!r#r r,r9rr)rXr\rgr5rD staticmethodr<r r r r rs$  rcCs6tj|s|Sddlm}td|}||)Nr)DistutilsSetupErrorz Error: setup script specifies an absolute path: %s setup() arguments must *always* be /-separated paths relative to the setup.py directory, *never* absolute paths. )rr.isabsdistutils.errorsrytextwrapdedentlstrip)r.rymsgr r r rOs    rO)rdistutils.utilrZdistutils.command.build_pycommandrrrrir|r^r{rar=rZ setuptools.extern.more_itertoolsrrrOr r r r s   EPKH]mmQpython3.10/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-310.pycnu[o Xai@s<ddlmmZddlZddlmZGdddejZdS)N)SetuptoolsDeprecationWarningc@s eZdZdZddZddZdS) bdist_rpma Override the default bdist_rpm behavior to do the following: 1. Run egg_info to ensure the name and version are properly calculated. 2. Always run 'install' using --single-version-externally-managed to disable eggs in RPM distributions. cCs&tdt|dtj|dS)Nzjbdist_rpm is deprecated and will be removed in a future version. Use bdist_wheel (wheel packages) instead.egg_info)warningswarnr run_commandorigrrun)selfr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/bdist_rpm.pyr s  z bdist_rpm.runcCstj|}dd|D}|S)NcSs g|] }|ddddqS)zsetup.py install z5setup.py install --single-version-externally-managed z%setupz&%setup -n %{name}-%{unmangled_version})replace).0liner r r sz-bdist_rpm._make_spec_file..)rr_make_spec_file)r specr r r rs  zbdist_rpm._make_spec_fileN)__name__ __module__ __qualname____doc__r rr r r r rs r)Zdistutils.command.bdist_rpmcommandrrr setuptoolsrr r r r s PKH]䷆Lpython3.10/site-packages/setuptools/command/__pycache__/test.cpython-310.pycnu[o Xai@sddlZddlZddlZddlZddlZddlZddlmZmZddl m Z ddlm Z ddl m Z mZmZmZmZmZmZmZddlmZddlmZGdd d e ZGd d d ZGd d d eZdS)N)DistutilsErrorDistutilsOptionError)log) TestLoader)resource_listdirresource_existsnormalize_path working_setevaluate_markeradd_activation_listenerrequire EntryPoint)Command)unique_everseenc@eZdZddZdddZdS)ScanningLoadercCst|t|_dSN)r__init__set_visitedselfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/test.pyrs  zScanningLoader.__init__NcCs||jvrdS|j|g}|t||t|dr$||t|dr`t|jdD]0}| drF|dkrF|jd|dd}nt |j|d rV|jd|}nq/|| |q/t |d krk| |S|d S) aReturn a suite of all tests cases contained in the given module If the module is a package, load tests from all the modules in it. If the module has an ``additional_tests`` function, call it and add the return value to the tests. Nadditional_tests__path__z.pyz __init__.py.z /__init__.pyr)raddappendrloadTestsFromModulehasattrrr__name__endswithrZloadTestsFromNamelenZ suiteClass)rmodulepatterntestsfile submodulerrrr"s$      z"ScanningLoader.loadTestsFromModuler)r$ __module__ __qualname__rr"rrrrrsrc@r)NonDataPropertycCs ||_dSrfget)rr0rrrrBs zNonDataProperty.__init__NcCs|dur|S||Srr/)robjZobjtyperrr__get__Es zNonDataProperty.__get__r)r$r,r-rr2rrrrr.Asr.c@seZdZdZdZgdZddZddZedd Z d d Z d d Z e j gfddZee j ddZeddZddZddZeddZeddZdS)testz.Command to run unit tests after in-place buildz0run unit tests after in-place build (deprecated)))z test-module=mz$Run 'test_suite' in specified module)z test-suite=sz9Run single test, case or suite (e.g. 'module.test_suite'))z test-runner=rzTest runner to usecCsd|_d|_d|_d|_dSr) test_suite test_module test_loader test_runnerrrrrinitialize_optionsZs ztest.initialize_optionscCs|jr |jr d}t||jdur"|jdur|jj|_n|jd|_|jdur/t|jdd|_|jdur7d|_|jdurFt|jdd|_dSdS)Nz1You may specify a module or a suite, but not bothz .test_suiter9z&setuptools.command.test:ScanningLoaderr:)r7r8r distributionr9getattrr:)rmsgrrrfinalize_options`s        ztest.finalize_optionscCs t|Sr)list _test_argsrrrr test_argss ztest.test_argsccs:|js tjdkr dV|jrdV|jr|jVdSdS)N)Zdiscoverz --verbose)r7sys version_infoverboserrrrrAws ztest._test_argscCs4| |WddS1swYdS)zI Backward compatibility for project_on_sys_path context. N)project_on_sys_path)rfuncrrrwith_project_on_sys_paths "ztest.with_project_on_sys_pathc csL|d|jddd|d|d}tjdd}tj}zkt|j}tj d|t t ddt d|j|jf||g dVWdn!1sXwYW|tjdd<tjtj|t dSW|tjdd<tjtj|t dS|tjdd<tjtj|t w) Negg_info build_extr)ZinplacercSs|Sr)activate)distrrrsz*test.project_on_sys_path..z%s==%s) run_commandreinitialize_commandget_finalized_commandrFpathmodulescopyrZegg_baseinsertr rr r egg_nameZ egg_versionpaths_on_pythonpathclearupdate)rZ include_distsZei_cmdold_pathZ old_modulesZ project_pathrrrrIs:               ztest.project_on_sys_pathc cst}tjd|}tjdd}z4tjt|}td||g}tj|}|r/|tjd<dVW||ur@tjdddS|tjd<dS||urStjddw|tjd<w)z Add the indicated paths to the head of the PYTHONPATH environment variable so that subprocesses will also see the packages at these paths. Do this in a context that restores the value on exit. PYTHONPATHrN) objectosenvirongetpathsepjoinrfilterpop)pathsZnothingZorig_pythonpathZcurrent_pythonpathprefixZto_joinnew_pathrrrrYs"   ztest.paths_on_pythonpathcCsD||j}||jp g}|dd|jD}t|||S)z Install the requirements indicated by self.distribution and return an iterable of the dists that were built. css2|]\}}|drt|ddr|VqdS):rN) startswithr ).0kvrrr s z%test.install_dists..)Zfetch_build_eggsZinstall_requiresZ tests_requireZextras_requireitems itertoolschain)rOZir_dZtr_dZer_drrr install_distss  ztest.install_distsc Cs|dtj||j}d|j}|jr|d|dS|d|tt d|}| |)| | Wdn1sGwYWddSWddS1s_wYdS)NzWARNING: Testing via this command is deprecated and will be removed in a future version. Users looking for a generic test entry point independent of test runner are encouraged to use tox. zskipping "%s" (dry run)z running "%s"location)announcerWARNrrr<rc_argvdry_runmapoperator attrgetterrYrI run_tests)rZinstalled_distscmdrfrrrruns$     "ztest.runcCsVtjdd|j||j||jdd}|js)d|j}||t j t |dS)NF)Z testLoaderZ testRunnerexitzTest failed: %s) unittestmainrw_resolve_as_epr9r:resultZ wasSuccessfulrurERRORr)rr3r>rrrr|s    ztest.run_testscCs dg|jS)Nr)rBrrrrrwrCz test._argvcCs$|durdStd|}|S)zu Load the indicated attribute value, called, as a as if it were specified as an entry point. Nzx=)r parseresolve)valparsedrrrrs ztest._resolve_as_epN)r$r,r-__doc__ description user_optionsr;r?r.rBrArK contextlibcontextmanagerrI staticmethodrYrrr~r|propertyrwrrrrrr3Ks.     r3)r_rzrFrrprdistutils.errorsrr distutilsrr pkg_resourcesrrrr r r r r setuptoolsrZ setuptools.extern.more_itertoolsrrr.r3rrrrs  ( ( PKH]kf  Npython3.10/site-packages/setuptools/command/__pycache__/rotate.cpython-310.pycnu[o XaiP@sTddlmZddlmZddlmZddlZddlZddlm Z Gddde Z dS)) convert_path)log)DistutilsOptionErrorN)Commandc@s8eZdZdZdZgdZgZddZddZdd Z d S) rotatezDelete older distributionsz2delete older distributions, keeping N newest files))zmatch=mzpatterns to match (required))z dist-dir=dz%directory where the distributions are)zkeep=kz(number of matching distributions to keepcCsd|_d|_d|_dS)N)matchdist_dirkeep)selfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/rotate.pyinitialize_optionss zrotate.initialize_optionsc Cs|jdur td|jdurtdzt|j|_Wnty+}ztd|d}~wwt|jtr>dd|jdD|_|dddS) NzQMust specify one or more (comma-separated) match patterns (e.g. '.zip' or '.egg')z$Must specify number of files to keepz--keep must be an integercSsg|]}t|qSr)rstrip).0prrr (s z+rotate.finalize_options..,bdist)r r ) r rr int ValueError isinstancestrsplitset_undefined_options)r errrfinalize_optionss"     zrotate.finalize_optionscCs|dddlm}|jD]U}|jd|}|tj|j|}dd|D}| | t dt ||||jd}|D]\}}t d||jsbtj|r]t|qDt|qDqdS) Negg_infor)glob*cSsg|] }tj||fqSr)ospathgetmtime)rfrrrr4szrotate.run..z%d file(s) matching %sz Deleting %s) run_commandr r distributionget_namer"r#joinr sortreverserinfolenr dry_runisdirshutilrmtreeunlink)r r patternfilestr%rrrrun-s&        z rotate.runN) __name__ __module__ __qualname____doc__ description user_optionsboolean_optionsrrr6rrrrr s r) distutils.utilr distutilsrdistutils.errorsrr"r0 setuptoolsrrrrrrs   PKH]nOpython3.10/site-packages/setuptools/command/__pycache__/install.cpython-310.pycnu[o Xai*@s|ddlmZddlZddlZddlZddlZddlmmZ ddl Z e jZ Gddde jZdde jj Dej e_ dS))DistutilsArgErrorNc@seZdZdZejjddgZejjddgZdddfd d dfgZe eZ d d Z d dZ ddZ ddZeddZddZdS)installz7Use easy_install to install the package, w/dependencies)old-and-unmanageableNzTry not to use this!)!single-version-externally-managedNz5used by system package builders to create 'flat' eggsrrinstall_egg_infocCdSNTselfr r /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/install.pyzinstall.install_scriptscCrrr r r r r r rcCs*tdtjtj|d|_d|_dS)NzRsetup.py install is deprecated. Use build and pip and other standards-based tools.) warningswarn setuptoolsZSetuptoolsDeprecationWarningorigrinitialize_optionsold_and_unmanageable!single_version_externally_managedr r r r r s  zinstall.initialize_optionscCsBtj||jrd|_dS|jr|js|jstddSdSdS)NTzAYou must specify --record or --root when building system packages)rrfinalize_optionsrootrrecordrr r r r r,s   zinstall.finalize_optionscCs(|js|jr tj|Sd|_d|_dS)N)rrrrhandle_extra_path path_file extra_dirsr r r r r7s   zinstall.handle_extra_pathcCsB|js|jr tj|S|tstj|dS|dS)N) rrrrrun_called_from_setupinspect currentframedo_egg_installr r r r rAs   z install.runcCsz|durd}t|tdkrd}t|dSt|d}|dd\}t|}|jdd }|d ko<|j d kS) a Attempt to detect whether run() was called from setup() or by another command. If called by setup(), the parent caller will be the 'run_command' method in 'distutils.dist', and *its* caller will be the 'run_commands' method. If called any other way, the immediate caller *might* be 'run_command', but it won't have been called by 'run_commands'. Return True in that case or if a call stack is unavailable. Return False otherwise. Nz4Call stack not available. bdist_* commands may fail. IronPythonz6For best results, pass -X:Frames to enable call stack.T__name__rzdistutils.dist run_commands) rrplatformpython_implementationr getouterframes getframeinfo f_globalsgetfunction)Z run_framemsgresZcallerinfoZ caller_moduler r r rLs     zinstall._called_from_setupcCs|jd}||jd|j|jd}|d|_|jtd| d|j dj g}t j r8|dt j ||_|jdd dt _ dS) N easy_installx)argsrr.z*.eggZ bdist_eggrF)Zshow_deprecation) distributionget_command_classrrensure_finalizedZalways_copy_fromZ package_indexscanglob run_commandget_command_objZ egg_outputrZbootstrap_install_frominsertr4r)r r2cmdr4r r r r"gs    zinstall.do_egg_installN)r& __module__ __qualname____doc__rr user_optionsboolean_options new_commandsdict_ncrrrr staticmethodrr"r r r r rs(       rcCsg|] }|dtjvr|qS)r)rrF).0r>r r r srI)distutils.errorsrr r:rr(distutils.command.installcommandrrr_install sub_commandsrDr r r r s sPKH]>畴 Xpython3.10/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-310.pycnu[o Xai@s\ddlmZmZddlZddlmZddlmZddlmZddl Z Gdddej eZ dS))logdir_utilN)Command) namespaces)unpack_archivec@sBeZdZdZdZdgZddZddZddZd d Z d d Z d S)install_egg_infoz.Install an .egg-info directory for the package)z install-dir=dzdirectory to install tocCs d|_dSN) install_dirselfr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/install_egg_info.pyinitialize_optionss z#install_egg_info.initialize_optionscCsV|dd|d}tdd|j|jd}|j|_tj |j ||_ g|_ dS)N install_lib)r r egg_infoz .egg-info)set_undefined_optionsget_finalized_command pkg_resources Distributionegg_nameZ egg_versionrsourceospathjoinr targetoutputs)r Zei_cmdbasenamer r rfinalize_optionss   z!install_egg_info.finalize_optionscCs|dtj|jrtj|jstj|j|jdntj |jr1| tj |jfd|j|js:t |j| |jdd|j|jf|dS)Nr)dry_runz Removing r Copying %s to %s) run_commandrrisdirrislinkr remove_treerexistsexecuteunlinkrensure_directorycopytreerZinstall_namespacesr r r rrun!s   zinstall_egg_info.runcCs|jSr )rr r r r get_outputs.szinstall_egg_info.get_outputscs fdd}tjj|dS)NcsDdD]}||sd||vrdSqj|td|||S)N)z.svn/zCVS//r ) startswithrappendrdebug)srcdstskipr r rskimmer3s z*install_egg_info.copytree..skimmer)rrr)r r3r r rr)1s  zinstall_egg_info.copytreeN) __name__ __module__ __qualname____doc__ description user_optionsrrr*r+r)r r r rr s  r) distutilsrrr setuptoolsrrZsetuptools.archive_utilrrZ Installerrr r r rs   PKH].8NPpython3.10/site-packages/setuptools/command/__pycache__/saveopts.cpython-310.pycnu[o Xai@s$ddlmZmZGdddeZdS)) edit_config option_basec@seZdZdZdZddZdS)saveoptsz#Save command-line options to a filez7save supplied options to setup.cfg or other config filecCsh|j}i}|jD]!}|dkrq||D]\}\}}|dkr(|||i|<qqt|j||jdS)Nrz command line) distributioncommand_optionsget_option_dictitems setdefaultrfilenamedry_run)selfdistsettingscmdoptsrcvalr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/saveopts.pyrun s z saveopts.runN)__name__ __module__ __qualname____doc__ descriptionrrrrrrs rN)Zsetuptools.command.setoptrrrrrrrsPKH]>v Rpython3.10/site-packages/setuptools/command/__pycache__/build_clib.cpython-310.pycnu[o Xai?@sLddlmmZddlmZddlmZddlm Z GdddejZdS)N)DistutilsSetupError)log)newer_pairwise_groupc@seZdZdZddZdS) build_clibav Override the default build_clib behaviour to do the following: 1. Implement a rudimentary timestamp-based dependency system so 'compile()' doesn't run every time. 2. Add more keys to the 'build_info' dictionary: * obj_deps - specify dependencies for each object compiled. this should be a dictionary mapping a key with the source filename to a list of dependencies. Use an empty string for global dependencies. * cflags - specify a list of additional flags to pass to the compiler. c Csn|D]\}}|d}|dust|ttfstd|t|}td||dt}t|ts8td|g}|dt}t|ttfsNtd||D](}|g} | |||t} t| ttfsntd|| | | | qP|j j ||j d} t || ggfkr|d} |d } |d }|j j||j | | ||jd |j j| ||j|jd qdS) Nsourceszfin 'libraries' option (library '%s'), 'sources' must be present and must be a list of source filenameszbuilding '%s' libraryobj_depsz\in 'libraries' option (library '%s'), 'obj_deps' must be a dictionary of type 'source: list') output_dirmacros include_dirscflags)r r r Zextra_postargsdebug)r r )get isinstancelisttuplerrinfodictextendappendcompilerZobject_filenamesZ build_temprcompiler Zcreate_static_libr)self librariesZlib_nameZ build_inforr dependenciesZ global_depssourceZsrc_depsZ extra_depsZexpected_objectsr r r r/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/build_clib.pybuild_librariess|           zbuild_clib.build_librariesN)__name__ __module__ __qualname____doc__rrrrrrs r) Zdistutils.command.build_clibcommandrorigdistutils.errorsr distutilsrZsetuptools.dep_utilrrrrrs    PKH]f3f3Qpython3.10/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-310.pycnu[o Xai@@s"dZddlmZmZddlmZddlmZddlZddl Z ddl Z ddl Z ddl Z ddl mZmZmZddlmZddlmZdd lmZmZd d Zd d ZddZddZGdddeZedZ ddZ!ddZ"ddZ#dddZ$ddZ%d d!Z&d"d#Z'gd$Z( % &d)d'd(Z)dS)*z6setuptools.command.bdist_egg Build .egg distributions) remove_treemkpath)log)CodeTypeN)get_build_platform Distributionensure_directory)Library)Command)get_pathget_python_versioncCstdS)Npurelib)r rr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/bdist_egg.py _get_purelibrcCs2d|vr tj|d}|dr|dd}|S)N.rmodulei)ospathsplitextendswith)filenamerrr strip_modules   rccs8t|D]\}}}|||||fVqdS)zbDo os.walk in a reproducible way, independent of indeterministic filesystem readdir order N)rwalksort)dirbasedirsfilesrrr sorted_walk!s r cCsLtd}t|d}|||WddS1swYdS)Na def __bootstrap__(): global __bootstrap__, __loader__, __file__ import sys, pkg_resources, importlib.util __file__ = pkg_resources.resource_filename(__name__, %r) __loader__ = None; del __bootstrap__, __loader__ spec = importlib.util.spec_from_file_location(__name__,__file__) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) __bootstrap__() w)textwrapdedentlstripopenwrite)resourcepyfileZ_stub_templatefrrr write_stub+s   "r*c@seZdZdZddddefdddd gZgd Zd d Zd dZddZ ddZ ddZ ddZ ddZ ddZddZddZdd Zd!S)" bdist_eggzcreate an "egg" distribution)z bdist-dir=bz1temporary directory for creating the distributionz plat-name=pz;platform name to embed in generated filenames (default: %s))exclude-source-filesNz+remove all .py files from the generated egg) keep-tempkzPkeep the pseudo-installation tree around after creating the distribution archive)z dist-dir=dz-directory to put final built distributions in) skip-buildNz2skip rebuilding everything (for testing/debugging))r/r2r.cCs.d|_d|_d|_d|_d|_d|_d|_dS)Nr) bdist_dir plat_name keep_tempdist_dir skip_build egg_outputexclude_source_filesselfrrrinitialize_optionsRs zbdist_egg.initialize_optionscCs|d}|_|j|_|jdur|dj}tj|d|_|jdur(t |_| dd|j durTt dd|j |jt|joC|j }tj|j|d|_ dSdS)Negg_infobdistegg)r6r6z.egg)get_finalized_commandei_cmdr=r3 bdist_baserrjoinr4rset_undefined_optionsr8regg_nameZ egg_versionr distributionhas_ext_modulesr6)r;rArBbasenamerrrfinalize_options[s$      zbdist_egg.finalize_optionscCs|j|d_tjtjt}|jj g}|j_ |D]D}t |t rZt |dkrZtj |drZtj|d}tj|}||ksL||tjrZ|t |dd|df}|jj |qztd|j|jddddW||j_ dS||j_ w)Ninstallrzinstalling package data to %s install_data)forceroot)r3r@ install_librrnormcaserealpathrrF data_files isinstancetuplelenisabs startswithsepappendrinfo call_command)r; site_packagesolditemrR normalizedrrrdo_install_datass"  zbdist_egg.do_install_datacCs|jgS)N)r8r:rrr get_outputsrzbdist_egg.get_outputscKsTtD] }|||jq|d|j|d|j|j|fi|}|||S)z8Invoke reinitialized command `cmdname` with keyword argsr7dry_run)INSTALL_DIRECTORY_ATTRS setdefaultr3r7rcreinitialize_command run_command)r;Zcmdnamekwdirnamecmdrrrr\s zbdist_egg.call_commandcCs|dtd|j|d}|j}d|_|jr$|js$|d|j ddd}||_| \}}g|_ g}t |D]>\}}t j|\} } t j|jt| d} |j | td ||jsmtt j|| || |t jd ||<q=|r|||jjr||j} t j| d } || |jjrt j| d }td ||j d|dd|| t j| d}|rtd||jst|t|d}| d|| d|!nt j"|rtd||jst #|t$t j| d |%t j&t j|j'drt(d|j)r|*t+|j,| |j-|j|.d|j/s9t0|j|jdt1|jdgdt2|j,fdS)Nr=zinstalling library code to %srJ build_clibrPr)warn_dir.pyzcreating stub loader for %s/EGG-INFOscriptszinstalling scripts to %sinstall_scriptsrL) install_dirZno_epznative_libs.txtz writing %swt z removing %sz depends.txtzxWARNING: 'depends.txt' will not be used by setuptools 0.6! Use the install_requires/extras_require setup() args instead.)verbosercmoderc dist_filesr+)3rgrr[r3r@rOrFhas_c_librariesr7r\get_ext_outputsstubs enumeraterrrrCrrZrcr*rHreplacerY byte_compilerSrarrpcopy_metadata_torr%r&closeisfileunlinkwrite_safety_flagzip_safeexistsr=warnr9 zap_pyfiles make_zipfiler8ru gen_headerr5rgetattrr )r;ZinstcmdZold_rootrj all_outputs ext_outputsZ to_compiler-Zext_namerextr(Z archive_rootr=Z script_dirZ native_libsZ libs_filerrrruns                    z bdist_egg.runc Cstdt|jD]^\}}}|D]V}tj||}|dr*td|t ||drg|}d}t ||}tj|tj | dd} td|| fzt| Wn ty`Ynwt|| qq dS) Nz+Removing .py files from temporary directoryrmz Deleting %s __pycache__z#(?P.+)\.(?P[^.]+)\.pycname.pyczRenaming file from [%s] to [%s])rr[walk_eggr3rrrCrdebugrrematchpardirgroupremoveOSErrorrename) r;rrrrrZpath_oldpatternmZpath_newrrrrs8        zbdist_egg.zap_pyfilescCs2t|jdd}|dur |Stdt|j|jS)Nrz4zip_safe flag not set; analyzing archive contents...)rrFrr analyze_eggr3r{)r;saferrrrs  zbdist_egg.zip_safecCsdS)Nr!rr:rrrr szbdist_egg.gen_headercCshtj|j}tj|d}|jjjD]}||r1tj||t |d}t || ||qdS)z*Copy metadata (egg info) to the target_dirN) rrnormpathr=rCrAfilelistrrXrVr copy_file)r; target_dirZ norm_egg_infoprefixrtargetrrrrs  zbdist_egg.copy_metadata_toc Csg}g}|jdi}t|jD]3\}}}|D]}tj|dtvr,||||q|D]}|||d|tj||<q/q|j r}| d}|j D]-} t | trWqO|| j} || }tj|ds|tjtj|j|r|||qO||fS)zAGet a list of relative paths to C extensions in the output distrorrLrn build_extzdl-)r3r rrrlowerNATIVE_EXTENSIONSrZrCrFrGr@ extensionsrTr Zget_ext_fullnamerZget_ext_filenamerHrXr) r;rrpathsrrrrZ build_cmdrfullnamerrrrzs6        zbdist_egg.get_ext_outputsN)__name__ __module__ __qualname__ descriptionr user_optionsboolean_optionsr<rIrarbr\rrrrrrzrrrrr+;s.  Q r+z.dll .so .dylib .pydccsJt|}t|\}}}d|vr|d|||fV|D]}|VqdS)z@Walk an unpacked egg's contents, skipping the metadata directoryroN)r nextr)egg_dirwalkerrrrZbdfrrrr:s  rc CstD]\}}tjtj|d|r|SqtsdSd}t|D](\}}}|D] }|ds7|dr8q+|dsB|drKt ||||oJ|}q+q$|S)NroFTrmz.pywrz.pyo) safety_flagsitemsrrrrCcan_scanrr scan_module) rr{flagfnrrrrrrrrrEs rcCstD]9\}}tj||}tj|r%|dust||kr$t|q|dur=t||kr=t|d}| d| qdS)Nrsrt) rrrrrCrboolrr%r&r)rrrrr)rrrrWs    rzzip-safez not-zip-safe)TFc Cstj||}|dd|vrdS|t|ddtjd}||r%dp&dtj|d}tjdkr8d }nd }t |d }| |t |} | d} tt| } d D]} | | vrgtd || d} qXd| vr~dD]} | | vr}td|| d} qn| S)z;Check whether module possibly uses unsafe-for-zipfile stuffNTrLrrr) rb)__file____path__z%s: module references %sFinspect) getsource getabsfile getsourcefileZgetfilegetsourcelines findsource getcomments getframeinfogetinnerframesgetouterframesstacktracez"%s: module MAY be using inspect.%s)rrrCrVr}rYrsys version_infor%readmarshalloadrdictfromkeys iter_symbolsrr) rrrr{rpkgrskipr)codersymbolsbadrrrrjs4     rccsT|jD]}|Vq|jD]}t|tr|Vq t|tr't|D]}|Vq!q dS)zBYield names and strings used by `code` and its nested code objectsN)co_names co_constsrTstrrr)rrconstrrrrs     rcCs2tjds tjdkr dStdtddS)NjavacliTz1Unable to analyze compiled code on this platform.zfPlease ask the author to include a 'zip_safe' setting (either True or False) in the package's setup.py)rplatformrXrrrrrrrs r)rPrrrM install_baseTr!c sddl}ttj|dtd|fdd}|r!|jn|j}sD|j |||d} t D] \} } } || | | q2| |St D] \} } } |d| | qH|S)aqCreate a zip file from all the files under 'base_dir'. The output zip file will be named 'base_dir' + ".zip". Uses either the "zipfile" Python module (if available) or the InfoZIP "zip" utility (if installed and found on the default search path). If neither tool is available, raises DistutilsExecError. Returns the name of the output zip file. rNrwz#creating '%s' and adding '%s' to itcs`|D]+}tjtj||}tj|r-|tdd}s'|||td|qdS)NrLz adding '%s') rrrrCrrVr&rr)zrinamesrrr-base_dirrcrrvisits   zmake_zipfile..visit) compression) zipfilerrrrirr[ ZIP_DEFLATED ZIP_STOREDZipFiler r) zip_filenamerrurccompressrvrrrrrirrrrrrs r)rrTr!)*__doc__distutils.dir_utilrr distutilsrtypesrrrrr"r pkg_resourcesrrrZsetuptools.extensionr setuptoolsr sysconfigr r rrr r*r+rrsplitrrrrrrrrrdrrrrrsB     } "  PKH]abPpython3.10/site-packages/setuptools/command/__pycache__/register.cpython-310.pycnu[o Xai@s@ddlmZddlmmZddlmZGdddejZdS))logN)RemovedCommandErrorc@seZdZdZddZdS)registerz+Formerly used to register packages on PyPI.cCsd}|d|tjt|)Nz]The register command has been removed, use twine to upload instead (https://pypi.org/p/twine)zERROR: )announcerERRORr)selfmsgr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/register.pyrun sz register.runN)__name__ __module__ __qualname____doc__r r r r r rs r) distutilsrZdistutils.command.registercommandrorigZsetuptools.errorsrr r r r s  PKH]ܿRpython3.10/site-packages/setuptools/command/__pycache__/py36compat.cpython-310.pycnu[o XaiR@s\ddlZddlmZddlmZddlmZGdddZeejdr,GdddZdSdS) N)glob) convert_path)sdistc@s\eZdZdZddZeddZddZdd Zd d Z d d Z ddZ ddZ ddZ dS)sdist_add_defaultsz Mix-in providing forward-compatibility for functionality as found in distutils on Python 3.7. Do not edit the code in this class except to update functionality as implemented in distutils. Instead, override in the subclass. cCs<|||||||dS)a9Add all the default files to self.filelist: - README or README.txt - setup.py - test/test*.py - all pure Python modules mentioned in setup script - all files pointed by package_data (build_py) - all files defined in data_files. - all files defined as scripts. - all C sources listed as part of extensions or C libraries in the setup script (doesn't catch C headers!) Warns if (README or README.txt) or setup.py are missing; everything else is optional. N)_add_defaults_standards_add_defaults_optional_add_defaults_python_add_defaults_data_files_add_defaults_ext_add_defaults_c_libs_add_defaults_scripts)selfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/py36compat.py add_defaultss zsdist_add_defaults.add_defaultscCs:tj|sdStj|}tj|\}}|t|vS)z Case-sensitive path existence check >>> sdist_add_defaults._cs_path_exists(__file__) True >>> sdist_add_defaults._cs_path_exists(__file__.upper()) False F)ospathexistsabspathsplitlistdir)fspathr directoryfilenamerrr_cs_path_exists&s  z"sdist_add_defaults._cs_path_existscCs|j|jjg}|D]?}t|tr5|}d}|D]}||r'd}|j|nq|s4|dd |q ||rA|j|q |d|q dS)NFTz,standard file not found: should have one of z, zstandard file '%s' not found) ZREADMES distribution script_name isinstancetuplerfilelistappendwarnjoin)r Z standardsfnZaltsZgot_itrrrr7s(    z*sdist_add_defaults._add_defaults_standardscCs4ddg}|D]}ttjjt|}|j|qdS)Nz test/test*.pyz setup.cfg)filterrrisfilerrextend)r optionalpatternfilesrrrrLs z)sdist_add_defaults._add_defaults_optionalcCs\|d}|jr|j||jD]\}}}}|D] }|jtj ||qqdS)Nbuild_py) get_finalized_commandrhas_pure_modulesrr&get_source_files data_filesr rrr")r r*pkgsrc_dir build_dir filenamesrrrrrRs  z'sdist_add_defaults._add_defaults_pythoncCs~|jr;|jjD]3}t|tr!t|}tj|r |j |q |\}}|D]}t|}tj|r9|j |q'q dSdS)N) rhas_data_filesr.rstrrrrr%rr )r itemdirnamer2frrrr bs       z+sdist_add_defaults._add_defaults_data_filescC,|jr|d}|j|dSdS)N build_ext)rhas_ext_modulesr+rr&r-)r r9rrrr s  z$sdist_add_defaults._add_defaults_extcCr8)N build_clib)rhas_c_librariesr+rr&r-)r r<rrrr xr;z'sdist_add_defaults._add_defaults_c_libscCr8)N build_scripts)r has_scriptsr+rr&r-)r r>rrrr }r;z(sdist_add_defaults._add_defaults_scriptsN)__name__ __module__ __qualname____doc__r staticmethodrrrrr r r r rrrrrs  rrc@s eZdZdS)rN)r@rArBrrrrrs)rrdistutils.utilrdistutils.commandrrhasattrrrrrs    |PKH]Qpython3.10/site-packages/setuptools/command/__pycache__/dist_info.cpython-310.pycnu[o Xai@s8dZddlZddlmZddlmZGdddeZdS)zD Create a dist_info directory As defined in the wheel specification N)Command)logc@s.eZdZdZdgZddZddZddZd S) dist_infozcreate a .dist-info directory)z egg-base=ezLdirectory containing .egg-info directories (default: top of the source tree)cCs d|_dSN)egg_baseselfr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/command/dist_info.pyinitialize_optionss zdist_info.initialize_optionscCsdSrr rr r r finalize_optionsszdist_info.finalize_optionscCsn|d}|j|_|||jdtd d}tdt j ||d}| |j|dS)Negg_infoz .egg-infoz .dist-infoz creating '{}' bdist_wheel) get_finalized_commandrr runrlenrinfoformatospathabspathZegg2dist)r r dist_info_dirrr r r rs  z dist_info.runN)__name__ __module__ __qualname__ description user_optionsr r rr r r r r s r)__doc__rdistutils.corer distutilsrrr r r r s   PKH]3RR9python3.10/site-packages/setuptools/command/py36compat.pynu[import os from glob import glob from distutils.util import convert_path from distutils.command import sdist class sdist_add_defaults: """ Mix-in providing forward-compatibility for functionality as found in distutils on Python 3.7. Do not edit the code in this class except to update functionality as implemented in distutils. Instead, override in the subclass. """ def add_defaults(self): """Add all the default files to self.filelist: - README or README.txt - setup.py - test/test*.py - all pure Python modules mentioned in setup script - all files pointed by package_data (build_py) - all files defined in data_files. - all files defined as scripts. - all C sources listed as part of extensions or C libraries in the setup script (doesn't catch C headers!) Warns if (README or README.txt) or setup.py are missing; everything else is optional. """ self._add_defaults_standards() self._add_defaults_optional() self._add_defaults_python() self._add_defaults_data_files() self._add_defaults_ext() self._add_defaults_c_libs() self._add_defaults_scripts() @staticmethod def _cs_path_exists(fspath): """ Case-sensitive path existence check >>> sdist_add_defaults._cs_path_exists(__file__) True >>> sdist_add_defaults._cs_path_exists(__file__.upper()) False """ if not os.path.exists(fspath): return False # make absolute so we always have a directory abspath = os.path.abspath(fspath) directory, filename = os.path.split(abspath) return filename in os.listdir(directory) def _add_defaults_standards(self): standards = [self.READMES, self.distribution.script_name] for fn in standards: if isinstance(fn, tuple): alts = fn got_it = False for fn in alts: if self._cs_path_exists(fn): got_it = True self.filelist.append(fn) break if not got_it: self.warn("standard file not found: should have one of " + ', '.join(alts)) else: if self._cs_path_exists(fn): self.filelist.append(fn) else: self.warn("standard file '%s' not found" % fn) def _add_defaults_optional(self): optional = ['test/test*.py', 'setup.cfg'] for pattern in optional: files = filter(os.path.isfile, glob(pattern)) self.filelist.extend(files) def _add_defaults_python(self): # build_py is used to get: # - python modules # - files defined in package_data build_py = self.get_finalized_command('build_py') # getting python files if self.distribution.has_pure_modules(): self.filelist.extend(build_py.get_source_files()) # getting package_data files # (computed in build_py.data_files by build_py.finalize_options) for pkg, src_dir, build_dir, filenames in build_py.data_files: for filename in filenames: self.filelist.append(os.path.join(src_dir, filename)) def _add_defaults_data_files(self): # getting distribution.data_files if self.distribution.has_data_files(): for item in self.distribution.data_files: if isinstance(item, str): # plain file item = convert_path(item) if os.path.isfile(item): self.filelist.append(item) else: # a (dirname, filenames) tuple dirname, filenames = item for f in filenames: f = convert_path(f) if os.path.isfile(f): self.filelist.append(f) def _add_defaults_ext(self): if self.distribution.has_ext_modules(): build_ext = self.get_finalized_command('build_ext') self.filelist.extend(build_ext.get_source_files()) def _add_defaults_c_libs(self): if self.distribution.has_c_libraries(): build_clib = self.get_finalized_command('build_clib') self.filelist.extend(build_clib.get_source_files()) def _add_defaults_scripts(self): if self.distribution.has_scripts(): build_scripts = self.get_finalized_command('build_scripts') self.filelist.extend(build_scripts.get_source_files()) if hasattr(sdist.sdist, '_add_defaults_standards'): # disable the functionality already available upstream class sdist_add_defaults: # noqa pass PKH]}! ! >python3.10/site-packages/setuptools/command/install_scripts.pynu[from distutils import log import distutils.command.install_scripts as orig from distutils.errors import DistutilsModuleError import os import sys from pkg_resources import Distribution, PathMetadata, ensure_directory class install_scripts(orig.install_scripts): """Do normal script install, plus any egg_info wrapper scripts""" def initialize_options(self): orig.install_scripts.initialize_options(self) self.no_ep = False def run(self): import setuptools.command.easy_install as ei self.run_command("egg_info") if self.distribution.scripts: orig.install_scripts.run(self) # run first to set up self.outfiles else: self.outfiles = [] if self.no_ep: # don't install entry point scripts into .egg file! return ei_cmd = self.get_finalized_command("egg_info") dist = Distribution( ei_cmd.egg_base, PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info), ei_cmd.egg_name, ei_cmd.egg_version, ) bs_cmd = self.get_finalized_command('build_scripts') exec_param = getattr(bs_cmd, 'executable', None) try: bw_cmd = self.get_finalized_command("bdist_wininst") is_wininst = getattr(bw_cmd, '_is_running', False) except (ImportError, DistutilsModuleError): is_wininst = False writer = ei.ScriptWriter if is_wininst: exec_param = "python.exe" writer = ei.WindowsScriptWriter if exec_param == sys.executable: # In case the path to the Python executable contains a space, wrap # it so it's not split up. exec_param = [exec_param] # resolve the writer to the environment writer = writer.best() cmd = writer.command_spec_class.best().from_param(exec_param) for args in writer.get_args(dist, cmd.as_header()): self.write_script(*args) def write_script(self, script_name, contents, mode="t", *ignored): """Write an executable file to the scripts directory""" from setuptools.command.easy_install import chmod, current_umask log.info("Installing %s script to %s", script_name, self.install_dir) target = os.path.join(self.install_dir, script_name) self.outfiles.append(target) mask = current_umask() if not self.dry_run: ensure_directory(target) f = open(target, "w" + mode) f.write(contents) f.close() chmod(target, 0o777 - mask) PKH]!PP5python3.10/site-packages/setuptools/command/rotate.pynu[from distutils.util import convert_path from distutils import log from distutils.errors import DistutilsOptionError import os import shutil from setuptools import Command class rotate(Command): """Delete older distributions""" description = "delete older distributions, keeping N newest files" user_options = [ ('match=', 'm', "patterns to match (required)"), ('dist-dir=', 'd', "directory where the distributions are"), ('keep=', 'k', "number of matching distributions to keep"), ] boolean_options = [] def initialize_options(self): self.match = None self.dist_dir = None self.keep = None def finalize_options(self): if self.match is None: raise DistutilsOptionError( "Must specify one or more (comma-separated) match patterns " "(e.g. '.zip' or '.egg')" ) if self.keep is None: raise DistutilsOptionError("Must specify number of files to keep") try: self.keep = int(self.keep) except ValueError as e: raise DistutilsOptionError("--keep must be an integer") from e if isinstance(self.match, str): self.match = [ convert_path(p.strip()) for p in self.match.split(',') ] self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) def run(self): self.run_command("egg_info") from glob import glob for pattern in self.match: pattern = self.distribution.get_name() + '*' + pattern files = glob(os.path.join(self.dist_dir, pattern)) files = [(os.path.getmtime(f), f) for f in files] files.sort() files.reverse() log.info("%d file(s) matching %s", len(files), pattern) files = files[self.keep:] for (t, f) in files: log.info("Deleting %s", f) if not self.dry_run: if os.path.isdir(f): shutil.rmtree(f) else: os.unlink(f) PKH]&dd6python3.10/site-packages/setuptools/command/develop.pynu[from distutils.util import convert_path from distutils import log from distutils.errors import DistutilsError, DistutilsOptionError import os import glob import io import pkg_resources from setuptools.command.easy_install import easy_install from setuptools import namespaces import setuptools class develop(namespaces.DevelopInstaller, easy_install): """Set up package for development""" description = "install package in 'development mode'" user_options = easy_install.user_options + [ ("uninstall", "u", "Uninstall this source package"), ("egg-path=", None, "Set the path to be used in the .egg-link file"), ] boolean_options = easy_install.boolean_options + ['uninstall'] command_consumes_arguments = False # override base def run(self): if self.uninstall: self.multi_version = True self.uninstall_link() self.uninstall_namespaces() else: self.install_for_development() self.warn_deprecated_options() def initialize_options(self): self.uninstall = None self.egg_path = None easy_install.initialize_options(self) self.setup_path = None self.always_copy_from = '.' # always copy eggs installed in curdir def finalize_options(self): ei = self.get_finalized_command("egg_info") if ei.broken_egg_info: template = "Please rename %r to %r before using 'develop'" args = ei.egg_info, ei.broken_egg_info raise DistutilsError(template % args) self.args = [ei.egg_name] easy_install.finalize_options(self) self.expand_basedirs() self.expand_dirs() # pick up setup-dir .egg files only: no .egg-info self.package_index.scan(glob.glob('*.egg')) egg_link_fn = ei.egg_name + '.egg-link' self.egg_link = os.path.join(self.install_dir, egg_link_fn) self.egg_base = ei.egg_base if self.egg_path is None: self.egg_path = os.path.abspath(ei.egg_base) target = pkg_resources.normalize_path(self.egg_base) egg_path = pkg_resources.normalize_path( os.path.join(self.install_dir, self.egg_path) ) if egg_path != target: raise DistutilsOptionError( "--egg-path must be a relative path from the install" " directory to " + target ) # Make a distribution for the package's source self.dist = pkg_resources.Distribution( target, pkg_resources.PathMetadata(target, os.path.abspath(ei.egg_info)), project_name=ei.egg_name, ) self.setup_path = self._resolve_setup_path( self.egg_base, self.install_dir, self.egg_path, ) @staticmethod def _resolve_setup_path(egg_base, install_dir, egg_path): """ Generate a path from egg_base back to '.' where the setup script resides and ensure that path points to the setup path from $install_dir/$egg_path. """ path_to_setup = egg_base.replace(os.sep, '/').rstrip('/') if path_to_setup != os.curdir: path_to_setup = '../' * (path_to_setup.count('/') + 1) resolved = pkg_resources.normalize_path( os.path.join(install_dir, egg_path, path_to_setup) ) if resolved != pkg_resources.normalize_path(os.curdir): raise DistutilsOptionError( "Can't get a consistent path to setup script from" " installation directory", resolved, pkg_resources.normalize_path(os.curdir), ) return path_to_setup def install_for_development(self): self.run_command('egg_info') # Build extensions in-place self.reinitialize_command('build_ext', inplace=1) self.run_command('build_ext') if setuptools.bootstrap_install_from: self.easy_install(setuptools.bootstrap_install_from) setuptools.bootstrap_install_from = None self.install_namespaces() # create an .egg-link in the installation dir, pointing to our egg log.info("Creating %s (link to %s)", self.egg_link, self.egg_base) if not self.dry_run: with open(self.egg_link, "w") as f: f.write(self.egg_path + "\n" + self.setup_path) # postprocess the installed distro, fixing up .pth, installing scripts, # and handling requirements self.process_distribution(None, self.dist, not self.no_deps) def uninstall_link(self): if os.path.exists(self.egg_link): log.info("Removing %s (link to %s)", self.egg_link, self.egg_base) egg_link_file = open(self.egg_link) contents = [line.rstrip() for line in egg_link_file] egg_link_file.close() if contents not in ([self.egg_path], [self.egg_path, self.setup_path]): log.warn("Link points to %s: uninstall aborted", contents) return if not self.dry_run: os.unlink(self.egg_link) if not self.dry_run: self.update_pth(self.dist) # remove any .pth link to us if self.distribution.scripts: # XXX should also check for entry point scripts! log.warn("Note: you must uninstall or replace scripts manually!") def install_egg_scripts(self, dist): if dist is not self.dist: # Installing a dependency, so fall back to normal behavior return easy_install.install_egg_scripts(self, dist) # create wrapper scripts in the script dir, pointing to dist.scripts # new-style... self.install_wrapper_scripts(dist) # ...and old-style for script_name in self.distribution.scripts or []: script_path = os.path.abspath(convert_path(script_name)) script_name = os.path.basename(script_path) with io.open(script_path) as strm: script_text = strm.read() self.install_script(dist, script_name, script_text, script_path) def install_wrapper_scripts(self, dist): dist = VersionlessRequirement(dist) return easy_install.install_wrapper_scripts(self, dist) class VersionlessRequirement: """ Adapt a pkg_resources.Distribution to simply return the project name as the 'requirement' so that scripts will work across multiple versions. >>> from pkg_resources import Distribution >>> dist = Distribution(project_name='foo', version='1.0') >>> str(dist.as_requirement()) 'foo==1.0' >>> adapted_dist = VersionlessRequirement(dist) >>> str(adapted_dist.as_requirement()) 'foo' """ def __init__(self, dist): self.__dist = dist def __getattr__(self, name): return getattr(self.__dist, name) def as_requirement(self): return self.project_name PKH]EwNN;python3.10/site-packages/setuptools/command/easy_install.pynu[""" Easy Install ------------ A tool for doing automatic download/extract/build of distutils-based Python packages. For detailed documentation, see the accompanying EasyInstall.txt file, or visit the `EasyInstall home page`__. __ https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html """ from glob import glob from distutils.util import get_platform from distutils.util import convert_path, subst_vars from distutils.errors import ( DistutilsArgError, DistutilsOptionError, DistutilsError, DistutilsPlatformError, ) from distutils.command.install import INSTALL_SCHEMES, SCHEME_KEYS from distutils import log, dir_util from distutils.command.build_scripts import first_line_re from distutils.spawn import find_executable import sys import os import zipimport import shutil import tempfile import zipfile import re import stat import random import textwrap import warnings import site import struct import contextlib import subprocess import shlex import io import configparser from sysconfig import get_config_vars, get_path from setuptools import SetuptoolsDeprecationWarning from setuptools import Command from setuptools.sandbox import run_setup from setuptools.command import setopt from setuptools.archive_util import unpack_archive from setuptools.package_index import ( PackageIndex, parse_requirement_arg, URL_SCHEME, ) from setuptools.command import bdist_egg, egg_info from setuptools.wheel import Wheel from pkg_resources import ( yield_lines, normalize_path, resource_string, ensure_directory, get_distribution, find_distributions, Environment, Requirement, Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound, VersionConflict, DEVELOP_DIST, ) import pkg_resources # Turn on PEP440Warnings warnings.filterwarnings("default", category=pkg_resources.PEP440Warning) __all__ = [ 'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg', 'get_exe_prefixes', ] def is_64bit(): return struct.calcsize("P") == 8 def samefile(p1, p2): """ Determine if two paths reference the same file. Augments os.path.samefile to work on Windows and suppresses errors if the path doesn't exist. """ both_exist = os.path.exists(p1) and os.path.exists(p2) use_samefile = hasattr(os.path, 'samefile') and both_exist if use_samefile: return os.path.samefile(p1, p2) norm_p1 = os.path.normpath(os.path.normcase(p1)) norm_p2 = os.path.normpath(os.path.normcase(p2)) return norm_p1 == norm_p2 def _to_bytes(s): return s.encode('utf8') def isascii(s): try: s.encode('ascii') return True except UnicodeError: return False def _one_liner(text): return textwrap.dedent(text).strip().replace('\n', '; ') class easy_install(Command): """Manage a download/build/install process""" description = "Find/get/install Python packages" command_consumes_arguments = True user_options = [ ('prefix=', None, "installation prefix"), ("zip-ok", "z", "install package as a zipfile"), ("multi-version", "m", "make apps have to require() a version"), ("upgrade", "U", "force upgrade (searches PyPI for latest versions)"), ("install-dir=", "d", "install package to DIR"), ("script-dir=", "s", "install scripts to DIR"), ("exclude-scripts", "x", "Don't install scripts"), ("always-copy", "a", "Copy all needed packages to install dir"), ("index-url=", "i", "base URL of Python Package Index"), ("find-links=", "f", "additional URL(s) to search for packages"), ("build-directory=", "b", "download/extract/build in DIR; keep the results"), ('optimize=', 'O', "also compile with optimization: -O1 for \"python -O\", " "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), ('record=', None, "filename in which to record list of installed files"), ('always-unzip', 'Z', "don't install as a zipfile, no matter what"), ('site-dirs=', 'S', "list of directories where .pth files work"), ('editable', 'e', "Install specified packages in editable form"), ('no-deps', 'N', "don't install dependencies"), ('allow-hosts=', 'H', "pattern(s) that hostnames must match"), ('local-snapshots-ok', 'l', "allow building eggs from local checkouts"), ('version', None, "print version information and exit"), ('no-find-links', None, "Don't load find-links defined in packages being installed"), ('user', None, "install in user site-package '%s'" % site.USER_SITE) ] boolean_options = [ 'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy', 'editable', 'no-deps', 'local-snapshots-ok', 'version', 'user' ] negative_opt = {'always-unzip': 'zip-ok'} create_index = PackageIndex def initialize_options(self): warnings.warn( "easy_install command is deprecated. " "Use build and pip and other standards-based tools.", EasyInstallDeprecationWarning, ) # the --user option seems to be an opt-in one, # so the default should be False. self.user = 0 self.zip_ok = self.local_snapshots_ok = None self.install_dir = self.script_dir = self.exclude_scripts = None self.index_url = None self.find_links = None self.build_directory = None self.args = None self.optimize = self.record = None self.upgrade = self.always_copy = self.multi_version = None self.editable = self.no_deps = self.allow_hosts = None self.root = self.prefix = self.no_report = None self.version = None self.install_purelib = None # for pure module distributions self.install_platlib = None # non-pure (dists w/ extensions) self.install_headers = None # for C/C++ headers self.install_lib = None # set to either purelib or platlib self.install_scripts = None self.install_data = None self.install_base = None self.install_platbase = None if site.ENABLE_USER_SITE: self.install_userbase = site.USER_BASE self.install_usersite = site.USER_SITE else: self.install_userbase = None self.install_usersite = None self.no_find_links = None # Options not specifiable via command line self.package_index = None self.pth_file = self.always_copy_from = None self.site_dirs = None self.installed_projects = {} # Always read easy_install options, even if we are subclassed, or have # an independent instance created. This ensures that defaults will # always come from the standard configuration file(s)' "easy_install" # section, even if this is a "develop" or "install" command, or some # other embedding. self._dry_run = None self.verbose = self.distribution.verbose self.distribution._set_command_options( self, self.distribution.get_option_dict('easy_install') ) def delete_blockers(self, blockers): extant_blockers = ( filename for filename in blockers if os.path.exists(filename) or os.path.islink(filename) ) list(map(self._delete_path, extant_blockers)) def _delete_path(self, path): log.info("Deleting %s", path) if self.dry_run: return is_tree = os.path.isdir(path) and not os.path.islink(path) remover = rmtree if is_tree else os.unlink remover(path) @staticmethod def _render_version(): """ Render the Setuptools version and installation details, then exit. """ ver = '{}.{}'.format(*sys.version_info) dist = get_distribution('setuptools') tmpl = 'setuptools {dist.version} from {dist.location} (Python {ver})' print(tmpl.format(**locals())) raise SystemExit() def finalize_options(self): # noqa: C901 # is too complex (25) # FIXME self.version and self._render_version() py_version = sys.version.split()[0] prefix, exec_prefix = get_config_vars('prefix', 'exec_prefix') self.config_vars = { 'dist_name': self.distribution.get_name(), 'dist_version': self.distribution.get_version(), 'dist_fullname': self.distribution.get_fullname(), 'py_version': py_version, 'py_version_short': py_version[0:3], 'py_version_nodot': py_version[0] + py_version[2], 'sys_prefix': prefix, 'prefix': prefix, 'sys_exec_prefix': exec_prefix, 'exec_prefix': exec_prefix, # Only python 3.2+ has abiflags 'abiflags': getattr(sys, 'abiflags', ''), } if site.ENABLE_USER_SITE: self.config_vars['userbase'] = self.install_userbase self.config_vars['usersite'] = self.install_usersite elif self.user: log.warn("WARNING: The user site-packages directory is disabled.") self._fix_install_dir_for_user_site() self.expand_basedirs() self.expand_dirs() self._expand( 'install_dir', 'script_dir', 'build_directory', 'site_dirs', ) # If a non-default installation directory was specified, default the # script directory to match it. if self.script_dir is None: self.script_dir = self.install_dir if self.no_find_links is None: self.no_find_links = False # Let install_dir get set by install_lib command, which in turn # gets its info from the install command, and takes into account # --prefix and --home and all that other crud. self.set_undefined_options( 'install_lib', ('install_dir', 'install_dir') ) # Likewise, set default script_dir from 'install_scripts.install_dir' self.set_undefined_options( 'install_scripts', ('install_dir', 'script_dir') ) if self.user and self.install_purelib: self.install_dir = self.install_purelib self.script_dir = self.install_scripts # default --record from the install command self.set_undefined_options('install', ('record', 'record')) # Should this be moved to the if statement below? It's not used # elsewhere normpath = map(normalize_path, sys.path) self.all_site_dirs = get_site_dirs() if self.site_dirs is not None: site_dirs = [ os.path.expanduser(s.strip()) for s in self.site_dirs.split(',') ] for d in site_dirs: if not os.path.isdir(d): log.warn("%s (in --site-dirs) does not exist", d) elif normalize_path(d) not in normpath: raise DistutilsOptionError( d + " (in --site-dirs) is not on sys.path" ) else: self.all_site_dirs.append(normalize_path(d)) if not self.editable: self.check_site_dir() self.index_url = self.index_url or "https://pypi.org/simple/" self.shadow_path = self.all_site_dirs[:] for path_item in self.install_dir, normalize_path(self.script_dir): if path_item not in self.shadow_path: self.shadow_path.insert(0, path_item) if self.allow_hosts is not None: hosts = [s.strip() for s in self.allow_hosts.split(',')] else: hosts = ['*'] if self.package_index is None: self.package_index = self.create_index( self.index_url, search_path=self.shadow_path, hosts=hosts, ) self.local_index = Environment(self.shadow_path + sys.path) if self.find_links is not None: if isinstance(self.find_links, str): self.find_links = self.find_links.split() else: self.find_links = [] if self.local_snapshots_ok: self.package_index.scan_egg_links(self.shadow_path + sys.path) if not self.no_find_links: self.package_index.add_find_links(self.find_links) self.set_undefined_options('install_lib', ('optimize', 'optimize')) if not isinstance(self.optimize, int): try: self.optimize = int(self.optimize) if not (0 <= self.optimize <= 2): raise ValueError except ValueError as e: raise DistutilsOptionError( "--optimize must be 0, 1, or 2" ) from e if self.editable and not self.build_directory: raise DistutilsArgError( "Must specify a build directory (-b) when using --editable" ) if not self.args: raise DistutilsArgError( "No urls, filenames, or requirements specified (see --help)") self.outputs = [] def _fix_install_dir_for_user_site(self): """ Fix the install_dir if "--user" was used. """ if not self.user or not site.ENABLE_USER_SITE: return self.create_home_path() if self.install_userbase is None: msg = "User base directory is not specified" raise DistutilsPlatformError(msg) self.install_base = self.install_platbase = self.install_userbase scheme_name = os.name.replace('posix', 'unix') + '_user' self.select_scheme(scheme_name) def _expand_attrs(self, attrs): for attr in attrs: val = getattr(self, attr) if val is not None: if os.name == 'posix' or os.name == 'nt': val = os.path.expanduser(val) val = subst_vars(val, self.config_vars) setattr(self, attr, val) def expand_basedirs(self): """Calls `os.path.expanduser` on install_base, install_platbase and root.""" self._expand_attrs(['install_base', 'install_platbase', 'root']) def expand_dirs(self): """Calls `os.path.expanduser` on install dirs.""" dirs = [ 'install_purelib', 'install_platlib', 'install_lib', 'install_headers', 'install_scripts', 'install_data', ] self._expand_attrs(dirs) def run(self, show_deprecation=True): if show_deprecation: self.announce( "WARNING: The easy_install command is deprecated " "and will be removed in a future version.", log.WARN, ) if self.verbose != self.distribution.verbose: log.set_verbosity(self.verbose) try: for spec in self.args: self.easy_install(spec, not self.no_deps) if self.record: outputs = self.outputs if self.root: # strip any package prefix root_len = len(self.root) for counter in range(len(outputs)): outputs[counter] = outputs[counter][root_len:] from distutils import file_util self.execute( file_util.write_file, (self.record, outputs), "writing list of installed files to '%s'" % self.record ) self.warn_deprecated_options() finally: log.set_verbosity(self.distribution.verbose) def pseudo_tempname(self): """Return a pseudo-tempname base in the install directory. This code is intentionally naive; if a malicious party can write to the target directory you're already in deep doodoo. """ try: pid = os.getpid() except Exception: pid = random.randint(0, sys.maxsize) return os.path.join(self.install_dir, "test-easy-install-%s" % pid) def warn_deprecated_options(self): pass def check_site_dir(self): # noqa: C901 # is too complex (12) # FIXME """Verify that self.install_dir is .pth-capable dir, if needed""" instdir = normalize_path(self.install_dir) pth_file = os.path.join(instdir, 'easy-install.pth') if not os.path.exists(instdir): try: os.makedirs(instdir) except (OSError, IOError): self.cant_write_to_target() # Is it a configured, PYTHONPATH, implicit, or explicit site dir? is_site_dir = instdir in self.all_site_dirs if not is_site_dir and not self.multi_version: # No? Then directly test whether it does .pth file processing is_site_dir = self.check_pth_processing() else: # make sure we can write to target dir testfile = self.pseudo_tempname() + '.write-test' test_exists = os.path.exists(testfile) try: if test_exists: os.unlink(testfile) open(testfile, 'w').close() os.unlink(testfile) except (OSError, IOError): self.cant_write_to_target() if not is_site_dir and not self.multi_version: # Can't install non-multi to non-site dir with easy_install pythonpath = os.environ.get('PYTHONPATH', '') log.warn(self.__no_default_msg, self.install_dir, pythonpath) if is_site_dir: if self.pth_file is None: self.pth_file = PthDistributions(pth_file, self.all_site_dirs) else: self.pth_file = None if self.multi_version and not os.path.exists(pth_file): self.pth_file = None # don't create a .pth file self.install_dir = instdir __cant_write_msg = textwrap.dedent(""" can't create or remove files in install directory The following error occurred while trying to add or remove files in the installation directory: %s The installation directory you specified (via --install-dir, --prefix, or the distutils default setting) was: %s """).lstrip() # noqa __not_exists_id = textwrap.dedent(""" This directory does not currently exist. Please create it and try again, or choose a different installation directory (using the -d or --install-dir option). """).lstrip() # noqa __access_msg = textwrap.dedent(""" Perhaps your account does not have write access to this directory? If the installation directory is a system-owned directory, you may need to sign in as the administrator or "root" account. If you do not have administrative access to this machine, you may wish to choose a different installation directory, preferably one that is listed in your PYTHONPATH environment variable. For information on other options, you may wish to consult the documentation at: https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html Please make the appropriate changes for your system and try again. """).lstrip() # noqa def cant_write_to_target(self): msg = self.__cant_write_msg % (sys.exc_info()[1], self.install_dir,) if not os.path.exists(self.install_dir): msg += '\n' + self.__not_exists_id else: msg += '\n' + self.__access_msg raise DistutilsError(msg) def check_pth_processing(self): """Empirically verify whether .pth files are supported in inst. dir""" instdir = self.install_dir log.info("Checking .pth file support in %s", instdir) pth_file = self.pseudo_tempname() + ".pth" ok_file = pth_file + '.ok' ok_exists = os.path.exists(ok_file) tmpl = _one_liner(""" import os f = open({ok_file!r}, 'w') f.write('OK') f.close() """) + '\n' try: if ok_exists: os.unlink(ok_file) dirname = os.path.dirname(ok_file) os.makedirs(dirname, exist_ok=True) f = open(pth_file, 'w') except (OSError, IOError): self.cant_write_to_target() else: try: f.write(tmpl.format(**locals())) f.close() f = None executable = sys.executable if os.name == 'nt': dirname, basename = os.path.split(executable) alt = os.path.join(dirname, 'pythonw.exe') use_alt = ( basename.lower() == 'python.exe' and os.path.exists(alt) ) if use_alt: # use pythonw.exe to avoid opening a console window executable = alt from distutils.spawn import spawn spawn([executable, '-E', '-c', 'pass'], 0) if os.path.exists(ok_file): log.info( "TEST PASSED: %s appears to support .pth files", instdir ) return True finally: if f: f.close() if os.path.exists(ok_file): os.unlink(ok_file) if os.path.exists(pth_file): os.unlink(pth_file) if not self.multi_version: log.warn("TEST FAILED: %s does NOT support .pth files", instdir) return False def install_egg_scripts(self, dist): """Write all the scripts for `dist`, unless scripts are excluded""" if not self.exclude_scripts and dist.metadata_isdir('scripts'): for script_name in dist.metadata_listdir('scripts'): if dist.metadata_isdir('scripts/' + script_name): # The "script" is a directory, likely a Python 3 # __pycache__ directory, so skip it. continue self.install_script( dist, script_name, dist.get_metadata('scripts/' + script_name) ) self.install_wrapper_scripts(dist) def add_output(self, path): if os.path.isdir(path): for base, dirs, files in os.walk(path): for filename in files: self.outputs.append(os.path.join(base, filename)) else: self.outputs.append(path) def not_editable(self, spec): if self.editable: raise DistutilsArgError( "Invalid argument %r: you can't use filenames or URLs " "with --editable (except via the --find-links option)." % (spec,) ) def check_editable(self, spec): if not self.editable: return if os.path.exists(os.path.join(self.build_directory, spec.key)): raise DistutilsArgError( "%r already exists in %s; can't do a checkout there" % (spec.key, self.build_directory) ) @contextlib.contextmanager def _tmpdir(self): tmpdir = tempfile.mkdtemp(prefix=u"easy_install-") try: # cast to str as workaround for #709 and #710 and #712 yield str(tmpdir) finally: os.path.exists(tmpdir) and rmtree(tmpdir) def easy_install(self, spec, deps=False): with self._tmpdir() as tmpdir: if not isinstance(spec, Requirement): if URL_SCHEME(spec): # It's a url, download it to tmpdir and process self.not_editable(spec) dl = self.package_index.download(spec, tmpdir) return self.install_item(None, dl, tmpdir, deps, True) elif os.path.exists(spec): # Existing file or directory, just process it directly self.not_editable(spec) return self.install_item(None, spec, tmpdir, deps, True) else: spec = parse_requirement_arg(spec) self.check_editable(spec) dist = self.package_index.fetch_distribution( spec, tmpdir, self.upgrade, self.editable, not self.always_copy, self.local_index ) if dist is None: msg = "Could not find suitable distribution for %r" % spec if self.always_copy: msg += " (--always-copy skips system and development eggs)" raise DistutilsError(msg) elif dist.precedence == DEVELOP_DIST: # .egg-info dists don't need installing, just process deps self.process_distribution(spec, dist, deps, "Using") return dist else: return self.install_item(spec, dist.location, tmpdir, deps) def install_item(self, spec, download, tmpdir, deps, install_needed=False): # Installation is also needed if file in tmpdir or is not an egg install_needed = install_needed or self.always_copy install_needed = install_needed or os.path.dirname(download) == tmpdir install_needed = install_needed or not download.endswith('.egg') install_needed = install_needed or ( self.always_copy_from is not None and os.path.dirname(normalize_path(download)) == normalize_path(self.always_copy_from) ) if spec and not install_needed: # at this point, we know it's a local .egg, we just don't know if # it's already installed. for dist in self.local_index[spec.project_name]: if dist.location == download: break else: install_needed = True # it's not in the local index log.info("Processing %s", os.path.basename(download)) if install_needed: dists = self.install_eggs(spec, download, tmpdir) for dist in dists: self.process_distribution(spec, dist, deps) else: dists = [self.egg_distribution(download)] self.process_distribution(spec, dists[0], deps, "Using") if spec is not None: for dist in dists: if dist in spec: return dist def select_scheme(self, name): """Sets the install directories by applying the install schemes.""" # it's the caller's problem if they supply a bad name! scheme = INSTALL_SCHEMES[name] for key in SCHEME_KEYS: attrname = 'install_' + key if getattr(self, attrname) is None: setattr(self, attrname, scheme[key]) # FIXME: 'easy_install.process_distribution' is too complex (12) def process_distribution( # noqa: C901 self, requirement, dist, deps=True, *info, ): self.update_pth(dist) self.package_index.add(dist) if dist in self.local_index[dist.key]: self.local_index.remove(dist) self.local_index.add(dist) self.install_egg_scripts(dist) self.installed_projects[dist.key] = dist log.info(self.installation_report(requirement, dist, *info)) if (dist.has_metadata('dependency_links.txt') and not self.no_find_links): self.package_index.add_find_links( dist.get_metadata_lines('dependency_links.txt') ) if not deps and not self.always_copy: return elif requirement is not None and dist.key != requirement.key: log.warn("Skipping dependencies for %s", dist) return # XXX this is not the distribution we were looking for elif requirement is None or dist not in requirement: # if we wound up with a different version, resolve what we've got distreq = dist.as_requirement() requirement = Requirement(str(distreq)) log.info("Processing dependencies for %s", requirement) try: distros = WorkingSet([]).resolve( [requirement], self.local_index, self.easy_install ) except DistributionNotFound as e: raise DistutilsError(str(e)) from e except VersionConflict as e: raise DistutilsError(e.report()) from e if self.always_copy or self.always_copy_from: # Force all the relevant distros to be copied or activated for dist in distros: if dist.key not in self.installed_projects: self.easy_install(dist.as_requirement()) log.info("Finished processing dependencies for %s", requirement) def should_unzip(self, dist): if self.zip_ok is not None: return not self.zip_ok if dist.has_metadata('not-zip-safe'): return True if not dist.has_metadata('zip-safe'): return True return False def maybe_move(self, spec, dist_filename, setup_base): dst = os.path.join(self.build_directory, spec.key) if os.path.exists(dst): msg = ( "%r already exists in %s; build directory %s will not be kept" ) log.warn(msg, spec.key, self.build_directory, setup_base) return setup_base if os.path.isdir(dist_filename): setup_base = dist_filename else: if os.path.dirname(dist_filename) == setup_base: os.unlink(dist_filename) # get it out of the tmp dir contents = os.listdir(setup_base) if len(contents) == 1: dist_filename = os.path.join(setup_base, contents[0]) if os.path.isdir(dist_filename): # if the only thing there is a directory, move it instead setup_base = dist_filename ensure_directory(dst) shutil.move(setup_base, dst) return dst def install_wrapper_scripts(self, dist): if self.exclude_scripts: return for args in ScriptWriter.best().get_args(dist): self.write_script(*args) def install_script(self, dist, script_name, script_text, dev_path=None): """Generate a legacy script wrapper and install it""" spec = str(dist.as_requirement()) is_script = is_python_script(script_text, script_name) if is_script: body = self._load_template(dev_path) % locals() script_text = ScriptWriter.get_header(script_text) + body self.write_script(script_name, _to_bytes(script_text), 'b') @staticmethod def _load_template(dev_path): """ There are a couple of template scripts in the package. This function loads one of them and prepares it for use. """ # See https://github.com/pypa/setuptools/issues/134 for info # on script file naming and downstream issues with SVR4 name = 'script.tmpl' if dev_path: name = name.replace('.tmpl', ' (dev).tmpl') raw_bytes = resource_string('setuptools', name) return raw_bytes.decode('utf-8') def write_script(self, script_name, contents, mode="t", blockers=()): """Write an executable file to the scripts directory""" self.delete_blockers( # clean up old .py/.pyw w/o a script [os.path.join(self.script_dir, x) for x in blockers] ) log.info("Installing %s script to %s", script_name, self.script_dir) target = os.path.join(self.script_dir, script_name) self.add_output(target) if self.dry_run: return mask = current_umask() ensure_directory(target) if os.path.exists(target): os.unlink(target) with open(target, "w" + mode) as f: f.write(contents) chmod(target, 0o777 - mask) def install_eggs(self, spec, dist_filename, tmpdir): # .egg dirs or files are already built, so just return them installer_map = { '.egg': self.install_egg, '.exe': self.install_exe, '.whl': self.install_wheel, } try: install_dist = installer_map[ dist_filename.lower()[-4:] ] except KeyError: pass else: return [install_dist(dist_filename, tmpdir)] # Anything else, try to extract and build setup_base = tmpdir if os.path.isfile(dist_filename) and not dist_filename.endswith('.py'): unpack_archive(dist_filename, tmpdir, self.unpack_progress) elif os.path.isdir(dist_filename): setup_base = os.path.abspath(dist_filename) if (setup_base.startswith(tmpdir) # something we downloaded and self.build_directory and spec is not None): setup_base = self.maybe_move(spec, dist_filename, setup_base) # Find the setup.py file setup_script = os.path.join(setup_base, 'setup.py') if not os.path.exists(setup_script): setups = glob(os.path.join(setup_base, '*', 'setup.py')) if not setups: raise DistutilsError( "Couldn't find a setup script in %s" % os.path.abspath(dist_filename) ) if len(setups) > 1: raise DistutilsError( "Multiple setup scripts in %s" % os.path.abspath(dist_filename) ) setup_script = setups[0] # Now run it, and return the result if self.editable: log.info(self.report_editable(spec, setup_script)) return [] else: return self.build_and_install(setup_script, setup_base) def egg_distribution(self, egg_path): if os.path.isdir(egg_path): metadata = PathMetadata(egg_path, os.path.join(egg_path, 'EGG-INFO')) else: metadata = EggMetadata(zipimport.zipimporter(egg_path)) return Distribution.from_filename(egg_path, metadata=metadata) # FIXME: 'easy_install.install_egg' is too complex (11) def install_egg(self, egg_path, tmpdir): # noqa: C901 destination = os.path.join( self.install_dir, os.path.basename(egg_path), ) destination = os.path.abspath(destination) if not self.dry_run: ensure_directory(destination) dist = self.egg_distribution(egg_path) if not samefile(egg_path, destination): if os.path.isdir(destination) and not os.path.islink(destination): dir_util.remove_tree(destination, dry_run=self.dry_run) elif os.path.exists(destination): self.execute( os.unlink, (destination,), "Removing " + destination, ) try: new_dist_is_zipped = False if os.path.isdir(egg_path): if egg_path.startswith(tmpdir): f, m = shutil.move, "Moving" else: f, m = shutil.copytree, "Copying" elif self.should_unzip(dist): self.mkpath(destination) f, m = self.unpack_and_compile, "Extracting" else: new_dist_is_zipped = True if egg_path.startswith(tmpdir): f, m = shutil.move, "Moving" else: f, m = shutil.copy2, "Copying" self.execute( f, (egg_path, destination), (m + " %s to %s") % ( os.path.basename(egg_path), os.path.dirname(destination) ), ) update_dist_caches( destination, fix_zipimporter_caches=new_dist_is_zipped, ) except Exception: update_dist_caches(destination, fix_zipimporter_caches=False) raise self.add_output(destination) return self.egg_distribution(destination) def install_exe(self, dist_filename, tmpdir): # See if it's valid, get data cfg = extract_wininst_cfg(dist_filename) if cfg is None: raise DistutilsError( "%s is not a valid distutils Windows .exe" % dist_filename ) # Create a dummy distribution object until we build the real distro dist = Distribution( None, project_name=cfg.get('metadata', 'name'), version=cfg.get('metadata', 'version'), platform=get_platform(), ) # Convert the .exe to an unpacked egg egg_path = os.path.join(tmpdir, dist.egg_name() + '.egg') dist.location = egg_path egg_tmp = egg_path + '.tmp' _egg_info = os.path.join(egg_tmp, 'EGG-INFO') pkg_inf = os.path.join(_egg_info, 'PKG-INFO') ensure_directory(pkg_inf) # make sure EGG-INFO dir exists dist._provider = PathMetadata(egg_tmp, _egg_info) # XXX self.exe_to_egg(dist_filename, egg_tmp) # Write EGG-INFO/PKG-INFO if not os.path.exists(pkg_inf): f = open(pkg_inf, 'w') f.write('Metadata-Version: 1.0\n') for k, v in cfg.items('metadata'): if k != 'target_version': f.write('%s: %s\n' % (k.replace('_', '-').title(), v)) f.close() script_dir = os.path.join(_egg_info, 'scripts') # delete entry-point scripts to avoid duping self.delete_blockers([ os.path.join(script_dir, args[0]) for args in ScriptWriter.get_args(dist) ]) # Build .egg file from tmpdir bdist_egg.make_zipfile( egg_path, egg_tmp, verbose=self.verbose, dry_run=self.dry_run, ) # install the .egg return self.install_egg(egg_path, tmpdir) # FIXME: 'easy_install.exe_to_egg' is too complex (12) def exe_to_egg(self, dist_filename, egg_tmp): # noqa: C901 """Extract a bdist_wininst to the directories an egg would use""" # Check for .pth file and set up prefix translations prefixes = get_exe_prefixes(dist_filename) to_compile = [] native_libs = [] top_level = {} def process(src, dst): s = src.lower() for old, new in prefixes: if s.startswith(old): src = new + src[len(old):] parts = src.split('/') dst = os.path.join(egg_tmp, *parts) dl = dst.lower() if dl.endswith('.pyd') or dl.endswith('.dll'): parts[-1] = bdist_egg.strip_module(parts[-1]) top_level[os.path.splitext(parts[0])[0]] = 1 native_libs.append(src) elif dl.endswith('.py') and old != 'SCRIPTS/': top_level[os.path.splitext(parts[0])[0]] = 1 to_compile.append(dst) return dst if not src.endswith('.pth'): log.warn("WARNING: can't process %s", src) return None # extract, tracking .pyd/.dll->native_libs and .py -> to_compile unpack_archive(dist_filename, egg_tmp, process) stubs = [] for res in native_libs: if res.lower().endswith('.pyd'): # create stubs for .pyd's parts = res.split('/') resource = parts[-1] parts[-1] = bdist_egg.strip_module(parts[-1]) + '.py' pyfile = os.path.join(egg_tmp, *parts) to_compile.append(pyfile) stubs.append(pyfile) bdist_egg.write_stub(resource, pyfile) self.byte_compile(to_compile) # compile .py's bdist_egg.write_safety_flag( os.path.join(egg_tmp, 'EGG-INFO'), bdist_egg.analyze_egg(egg_tmp, stubs)) # write zip-safety flag for name in 'top_level', 'native_libs': if locals()[name]: txt = os.path.join(egg_tmp, 'EGG-INFO', name + '.txt') if not os.path.exists(txt): f = open(txt, 'w') f.write('\n'.join(locals()[name]) + '\n') f.close() def install_wheel(self, wheel_path, tmpdir): wheel = Wheel(wheel_path) assert wheel.is_compatible() destination = os.path.join(self.install_dir, wheel.egg_name()) destination = os.path.abspath(destination) if not self.dry_run: ensure_directory(destination) if os.path.isdir(destination) and not os.path.islink(destination): dir_util.remove_tree(destination, dry_run=self.dry_run) elif os.path.exists(destination): self.execute( os.unlink, (destination,), "Removing " + destination, ) try: self.execute( wheel.install_as_egg, (destination,), ("Installing %s to %s") % ( os.path.basename(wheel_path), os.path.dirname(destination) ), ) finally: update_dist_caches(destination, fix_zipimporter_caches=False) self.add_output(destination) return self.egg_distribution(destination) __mv_warning = textwrap.dedent(""" Because this distribution was installed --multi-version, before you can import modules from this package in an application, you will need to 'import pkg_resources' and then use a 'require()' call similar to one of these examples, in order to select the desired version: pkg_resources.require("%(name)s") # latest installed version pkg_resources.require("%(name)s==%(version)s") # this exact version pkg_resources.require("%(name)s>=%(version)s") # this version or higher """).lstrip() # noqa __id_warning = textwrap.dedent(""" Note also that the installation directory must be on sys.path at runtime for this to work. (e.g. by being the application's script directory, by being on PYTHONPATH, or by being added to sys.path by your code.) """) # noqa def installation_report(self, req, dist, what="Installed"): """Helpful installation message for display to package users""" msg = "\n%(what)s %(eggloc)s%(extras)s" if self.multi_version and not self.no_report: msg += '\n' + self.__mv_warning if self.install_dir not in map(normalize_path, sys.path): msg += '\n' + self.__id_warning eggloc = dist.location name = dist.project_name version = dist.version extras = '' # TODO: self.report_extras(req, dist) return msg % locals() __editable_msg = textwrap.dedent(""" Extracted editable version of %(spec)s to %(dirname)s If it uses setuptools in its setup script, you can activate it in "development" mode by going to that directory and running:: %(python)s setup.py develop See the setuptools documentation for the "develop" command for more info. """).lstrip() # noqa def report_editable(self, spec, setup_script): dirname = os.path.dirname(setup_script) python = sys.executable return '\n' + self.__editable_msg % locals() def run_setup(self, setup_script, setup_base, args): sys.modules.setdefault('distutils.command.bdist_egg', bdist_egg) sys.modules.setdefault('distutils.command.egg_info', egg_info) args = list(args) if self.verbose > 2: v = 'v' * (self.verbose - 1) args.insert(0, '-' + v) elif self.verbose < 2: args.insert(0, '-q') if self.dry_run: args.insert(0, '-n') log.info( "Running %s %s", setup_script[len(setup_base) + 1:], ' '.join(args) ) try: run_setup(setup_script, args) except SystemExit as v: raise DistutilsError( "Setup script exited with %s" % (v.args[0],) ) from v def build_and_install(self, setup_script, setup_base): args = ['bdist_egg', '--dist-dir'] dist_dir = tempfile.mkdtemp( prefix='egg-dist-tmp-', dir=os.path.dirname(setup_script) ) try: self._set_fetcher_options(os.path.dirname(setup_script)) args.append(dist_dir) self.run_setup(setup_script, setup_base, args) all_eggs = Environment([dist_dir]) eggs = [] for key in all_eggs: for dist in all_eggs[key]: eggs.append(self.install_egg(dist.location, setup_base)) if not eggs and not self.dry_run: log.warn("No eggs found in %s (setup script problem?)", dist_dir) return eggs finally: rmtree(dist_dir) log.set_verbosity(self.verbose) # restore our log verbosity def _set_fetcher_options(self, base): """ When easy_install is about to run bdist_egg on a source dist, that source dist might have 'setup_requires' directives, requiring additional fetching. Ensure the fetcher options given to easy_install are available to that command as well. """ # find the fetch options from easy_install and write them out # to the setup.cfg file. ei_opts = self.distribution.get_option_dict('easy_install').copy() fetch_directives = ( 'find_links', 'site_dirs', 'index_url', 'optimize', 'allow_hosts', ) fetch_options = {} for key, val in ei_opts.items(): if key not in fetch_directives: continue fetch_options[key] = val[1] # create a settings dictionary suitable for `edit_config` settings = dict(easy_install=fetch_options) cfg_filename = os.path.join(base, 'setup.cfg') setopt.edit_config(cfg_filename, settings) def update_pth(self, dist): # noqa: C901 # is too complex (11) # FIXME if self.pth_file is None: return for d in self.pth_file[dist.key]: # drop old entries if not self.multi_version and d.location == dist.location: continue log.info("Removing %s from easy-install.pth file", d) self.pth_file.remove(d) if d.location in self.shadow_path: self.shadow_path.remove(d.location) if not self.multi_version: if dist.location in self.pth_file.paths: log.info( "%s is already the active version in easy-install.pth", dist, ) else: log.info("Adding %s to easy-install.pth file", dist) self.pth_file.add(dist) # add new entry if dist.location not in self.shadow_path: self.shadow_path.append(dist.location) if self.dry_run: return self.pth_file.save() if dist.key != 'setuptools': return # Ensure that setuptools itself never becomes unavailable! # XXX should this check for latest version? filename = os.path.join(self.install_dir, 'setuptools.pth') if os.path.islink(filename): os.unlink(filename) with open(filename, 'wt') as f: f.write(self.pth_file.make_relative(dist.location) + '\n') def unpack_progress(self, src, dst): # Progress filter for unpacking log.debug("Unpacking %s to %s", src, dst) return dst # only unpack-and-compile skips files for dry run def unpack_and_compile(self, egg_path, destination): to_compile = [] to_chmod = [] def pf(src, dst): if dst.endswith('.py') and not src.startswith('EGG-INFO/'): to_compile.append(dst) elif dst.endswith('.dll') or dst.endswith('.so'): to_chmod.append(dst) self.unpack_progress(src, dst) return not self.dry_run and dst or None unpack_archive(egg_path, destination, pf) self.byte_compile(to_compile) if not self.dry_run: for f in to_chmod: mode = ((os.stat(f)[stat.ST_MODE]) | 0o555) & 0o7755 chmod(f, mode) def byte_compile(self, to_compile): if sys.dont_write_bytecode: return from distutils.util import byte_compile try: # try to make the byte compile messages quieter log.set_verbosity(self.verbose - 1) byte_compile(to_compile, optimize=0, force=1, dry_run=self.dry_run) if self.optimize: byte_compile( to_compile, optimize=self.optimize, force=1, dry_run=self.dry_run, ) finally: log.set_verbosity(self.verbose) # restore original verbosity __no_default_msg = textwrap.dedent(""" bad install directory or PYTHONPATH You are attempting to install a package to a directory that is not on PYTHONPATH and which Python does not read ".pth" files from. The installation directory you specified (via --install-dir, --prefix, or the distutils default setting) was: %s and your PYTHONPATH environment variable currently contains: %r Here are some of your options for correcting the problem: * You can choose a different installation directory, i.e., one that is on PYTHONPATH or supports .pth files * You can add the installation directory to the PYTHONPATH environment variable. (It must then also be on PYTHONPATH whenever you run Python and want to use the package(s) you are installing.) * You can set up the installation directory to support ".pth" files by using one of the approaches described here: https://setuptools.readthedocs.io/en/latest/deprecated/easy_install.html#custom-installation-locations Please make the appropriate changes for your system and try again. """).strip() def create_home_path(self): """Create directories under ~.""" if not self.user: return home = convert_path(os.path.expanduser("~")) for name, path in self.config_vars.items(): if path.startswith(home) and not os.path.isdir(path): self.debug_print("os.makedirs('%s', 0o700)" % path) os.makedirs(path, 0o700) INSTALL_SCHEMES = dict( posix=dict( install_dir='$base/lib/python$py_version_short/site-packages', script_dir='$base/bin', ), ) DEFAULT_SCHEME = dict( install_dir='$base/Lib/site-packages', script_dir='$base/Scripts', ) def _expand(self, *attrs): config_vars = self.get_finalized_command('install').config_vars if self.prefix: # Set default install_dir/scripts from --prefix config_vars = config_vars.copy() config_vars['base'] = self.prefix scheme = self.INSTALL_SCHEMES.get(os.name, self.DEFAULT_SCHEME) for attr, val in scheme.items(): if getattr(self, attr, None) is None: setattr(self, attr, val) from distutils.util import subst_vars for attr in attrs: val = getattr(self, attr) if val is not None: val = subst_vars(val, config_vars) if os.name == 'posix': val = os.path.expanduser(val) setattr(self, attr, val) def _pythonpath(): items = os.environ.get('PYTHONPATH', '').split(os.pathsep) return filter(None, items) def get_site_dirs(): """ Return a list of 'site' dirs """ sitedirs = [] # start with PYTHONPATH sitedirs.extend(_pythonpath()) prefixes = [sys.prefix] if sys.exec_prefix != sys.prefix: prefixes.append(sys.exec_prefix) for prefix in prefixes: if not prefix: continue if sys.platform in ('os2emx', 'riscos'): sitedirs.append(os.path.join(prefix, "Lib", "site-packages")) elif os.sep == '/': sitedirs.extend([ os.path.join( prefix, "lib", "python{}.{}".format(*sys.version_info), "site-packages", ), os.path.join(prefix, "lib", "site-python"), ]) else: sitedirs.extend([ prefix, os.path.join(prefix, "lib", "site-packages"), ]) if sys.platform != 'darwin': continue # for framework builds *only* we add the standard Apple # locations. Currently only per-user, but /Library and # /Network/Library could be added too if 'Python.framework' not in prefix: continue home = os.environ.get('HOME') if not home: continue home_sp = os.path.join( home, 'Library', 'Python', '{}.{}'.format(*sys.version_info), 'site-packages', ) sitedirs.append(home_sp) lib_paths = get_path('purelib'), get_path('platlib') sitedirs.extend(s for s in lib_paths if s not in sitedirs) if site.ENABLE_USER_SITE: sitedirs.append(site.USER_SITE) with contextlib.suppress(AttributeError): sitedirs.extend(site.getsitepackages()) sitedirs = list(map(normalize_path, sitedirs)) return sitedirs def expand_paths(inputs): # noqa: C901 # is too complex (11) # FIXME """Yield sys.path directories that might contain "old-style" packages""" seen = {} for dirname in inputs: dirname = normalize_path(dirname) if dirname in seen: continue seen[dirname] = 1 if not os.path.isdir(dirname): continue files = os.listdir(dirname) yield dirname, files for name in files: if not name.endswith('.pth'): # We only care about the .pth files continue if name in ('easy-install.pth', 'setuptools.pth'): # Ignore .pth files that we control continue # Read the .pth file f = open(os.path.join(dirname, name)) lines = list(yield_lines(f)) f.close() # Yield existing non-dupe, non-import directory lines from it for line in lines: if line.startswith("import"): continue line = normalize_path(line.rstrip()) if line in seen: continue seen[line] = 1 if not os.path.isdir(line): continue yield line, os.listdir(line) def extract_wininst_cfg(dist_filename): """Extract configuration data from a bdist_wininst .exe Returns a configparser.RawConfigParser, or None """ f = open(dist_filename, 'rb') try: endrec = zipfile._EndRecData(f) if endrec is None: return None prepended = (endrec[9] - endrec[5]) - endrec[6] if prepended < 12: # no wininst data here return None f.seek(prepended - 12) tag, cfglen, bmlen = struct.unpack("egg path translations for a given .exe file""" prefixes = [ ('PURELIB/', ''), ('PLATLIB/pywin32_system32', ''), ('PLATLIB/', ''), ('SCRIPTS/', 'EGG-INFO/scripts/'), ('DATA/lib/site-packages', ''), ] z = zipfile.ZipFile(exe_filename) try: for info in z.infolist(): name = info.filename parts = name.split('/') if len(parts) == 3 and parts[2] == 'PKG-INFO': if parts[1].endswith('.egg-info'): prefixes.insert(0, ('/'.join(parts[:2]), 'EGG-INFO/')) break if len(parts) != 2 or not name.endswith('.pth'): continue if name.endswith('-nspkg.pth'): continue if parts[0].upper() in ('PURELIB', 'PLATLIB'): contents = z.read(name).decode() for pth in yield_lines(contents): pth = pth.strip().replace('\\', '/') if not pth.startswith('import'): prefixes.append((('%s/%s/' % (parts[0], pth)), '')) finally: z.close() prefixes = [(x.lower(), y) for x, y in prefixes] prefixes.sort() prefixes.reverse() return prefixes class PthDistributions(Environment): """A .pth file with Distribution paths in it""" dirty = False def __init__(self, filename, sitedirs=()): self.filename = filename self.sitedirs = list(map(normalize_path, sitedirs)) self.basedir = normalize_path(os.path.dirname(self.filename)) self._load() Environment.__init__(self, [], None, None) for path in yield_lines(self.paths): list(map(self.add, find_distributions(path, True))) def _load(self): self.paths = [] saw_import = False seen = dict.fromkeys(self.sitedirs) if os.path.isfile(self.filename): f = open(self.filename, 'rt') for line in f: if line.startswith('import'): saw_import = True continue path = line.rstrip() self.paths.append(path) if not path.strip() or path.strip().startswith('#'): continue # skip non-existent paths, in case somebody deleted a package # manually, and duplicate paths as well path = self.paths[-1] = normalize_path( os.path.join(self.basedir, path) ) if not os.path.exists(path) or path in seen: self.paths.pop() # skip it self.dirty = True # we cleaned up, so we're dirty now :) continue seen[path] = 1 f.close() if self.paths and not saw_import: self.dirty = True # ensure anything we touch has import wrappers while self.paths and not self.paths[-1].strip(): self.paths.pop() def save(self): """Write changed .pth file back to disk""" if not self.dirty: return rel_paths = list(map(self.make_relative, self.paths)) if rel_paths: log.debug("Saving %s", self.filename) lines = self._wrap_lines(rel_paths) data = '\n'.join(lines) + '\n' if os.path.islink(self.filename): os.unlink(self.filename) with open(self.filename, 'wt') as f: f.write(data) elif os.path.exists(self.filename): log.debug("Deleting empty %s", self.filename) os.unlink(self.filename) self.dirty = False @staticmethod def _wrap_lines(lines): return lines def add(self, dist): """Add `dist` to the distribution map""" new_path = ( dist.location not in self.paths and ( dist.location not in self.sitedirs or # account for '.' being in PYTHONPATH dist.location == os.getcwd() ) ) if new_path: self.paths.append(dist.location) self.dirty = True Environment.add(self, dist) def remove(self, dist): """Remove `dist` from the distribution map""" while dist.location in self.paths: self.paths.remove(dist.location) self.dirty = True Environment.remove(self, dist) def make_relative(self, path): npath, last = os.path.split(normalize_path(path)) baselen = len(self.basedir) parts = [last] sep = os.altsep == '/' and '/' or os.sep while len(npath) >= baselen: if npath == self.basedir: parts.append(os.curdir) parts.reverse() return sep.join(parts) npath, last = os.path.split(npath) parts.append(last) else: return path class RewritePthDistributions(PthDistributions): @classmethod def _wrap_lines(cls, lines): yield cls.prelude for line in lines: yield line yield cls.postlude prelude = _one_liner(""" import sys sys.__plen = len(sys.path) """) postlude = _one_liner(""" import sys new = sys.path[sys.__plen:] del sys.path[sys.__plen:] p = getattr(sys, '__egginsert', 0) sys.path[p:p] = new sys.__egginsert = p + len(new) """) if os.environ.get('SETUPTOOLS_SYS_PATH_TECHNIQUE', 'raw') == 'rewrite': PthDistributions = RewritePthDistributions def _first_line_re(): """ Return a regular expression based on first_line_re suitable for matching strings. """ if isinstance(first_line_re.pattern, str): return first_line_re # first_line_re in Python >=3.1.4 and >=3.2.1 is a bytes pattern. return re.compile(first_line_re.pattern.decode()) def auto_chmod(func, arg, exc): if func in [os.unlink, os.remove] and os.name == 'nt': chmod(arg, stat.S_IWRITE) return func(arg) et, ev, _ = sys.exc_info() # TODO: This code doesn't make sense. What is it trying to do? raise (ev[0], ev[1] + (" %s %s" % (func, arg))) def update_dist_caches(dist_path, fix_zipimporter_caches): """ Fix any globally cached `dist_path` related data `dist_path` should be a path of a newly installed egg distribution (zipped or unzipped). sys.path_importer_cache contains finder objects that have been cached when importing data from the original distribution. Any such finders need to be cleared since the replacement distribution might be packaged differently, e.g. a zipped egg distribution might get replaced with an unzipped egg folder or vice versa. Having the old finders cached may then cause Python to attempt loading modules from the replacement distribution using an incorrect loader. zipimport.zipimporter objects are Python loaders charged with importing data packaged inside zip archives. If stale loaders referencing the original distribution, are left behind, they can fail to load modules from the replacement distribution. E.g. if an old zipimport.zipimporter instance is used to load data from a new zipped egg archive, it may cause the operation to attempt to locate the requested data in the wrong location - one indicated by the original distribution's zip archive directory information. Such an operation may then fail outright, e.g. report having read a 'bad local file header', or even worse, it may fail silently & return invalid data. zipimport._zip_directory_cache contains cached zip archive directory information for all existing zipimport.zipimporter instances and all such instances connected to the same archive share the same cached directory information. If asked, and the underlying Python implementation allows it, we can fix all existing zipimport.zipimporter instances instead of having to track them down and remove them one by one, by updating their shared cached zip archive directory information. This, of course, assumes that the replacement distribution is packaged as a zipped egg. If not asked to fix existing zipimport.zipimporter instances, we still do our best to clear any remaining zipimport.zipimporter related cached data that might somehow later get used when attempting to load data from the new distribution and thus cause such load operations to fail. Note that when tracking down such remaining stale data, we can not catch every conceivable usage from here, and we clear only those that we know of and have found to cause problems if left alive. Any remaining caches should be updated by whomever is in charge of maintaining them, i.e. they should be ready to handle us replacing their zip archives with new distributions at runtime. """ # There are several other known sources of stale zipimport.zipimporter # instances that we do not clear here, but might if ever given a reason to # do so: # * Global setuptools pkg_resources.working_set (a.k.a. 'master working # set') may contain distributions which may in turn contain their # zipimport.zipimporter loaders. # * Several zipimport.zipimporter loaders held by local variables further # up the function call stack when running the setuptools installation. # * Already loaded modules may have their __loader__ attribute set to the # exact loader instance used when importing them. Python 3.4 docs state # that this information is intended mostly for introspection and so is # not expected to cause us problems. normalized_path = normalize_path(dist_path) _uncache(normalized_path, sys.path_importer_cache) if fix_zipimporter_caches: _replace_zip_directory_cache_data(normalized_path) else: # Here, even though we do not want to fix existing and now stale # zipimporter cache information, we still want to remove it. Related to # Python's zip archive directory information cache, we clear each of # its stale entries in two phases: # 1. Clear the entry so attempting to access zip archive information # via any existing stale zipimport.zipimporter instances fails. # 2. Remove the entry from the cache so any newly constructed # zipimport.zipimporter instances do not end up using old stale # zip archive directory information. # This whole stale data removal step does not seem strictly necessary, # but has been left in because it was done before we started replacing # the zip archive directory information cache content if possible, and # there are no relevant unit tests that we can depend on to tell us if # this is really needed. _remove_and_clear_zip_directory_cache_data(normalized_path) def _collect_zipimporter_cache_entries(normalized_path, cache): """ Return zipimporter cache entry keys related to a given normalized path. Alternative path spellings (e.g. those using different character case or those using alternative path separators) related to the same path are included. Any sub-path entries are included as well, i.e. those corresponding to zip archives embedded in other zip archives. """ result = [] prefix_len = len(normalized_path) for p in cache: np = normalize_path(p) if (np.startswith(normalized_path) and np[prefix_len:prefix_len + 1] in (os.sep, '')): result.append(p) return result def _update_zipimporter_cache(normalized_path, cache, updater=None): """ Update zipimporter cache data for a given normalized path. Any sub-path entries are processed as well, i.e. those corresponding to zip archives embedded in other zip archives. Given updater is a callable taking a cache entry key and the original entry (after already removing the entry from the cache), and expected to update the entry and possibly return a new one to be inserted in its place. Returning None indicates that the entry should not be replaced with a new one. If no updater is given, the cache entries are simply removed without any additional processing, the same as if the updater simply returned None. """ for p in _collect_zipimporter_cache_entries(normalized_path, cache): # N.B. pypy's custom zipimport._zip_directory_cache implementation does # not support the complete dict interface: # * Does not support item assignment, thus not allowing this function # to be used only for removing existing cache entries. # * Does not support the dict.pop() method, forcing us to use the # get/del patterns instead. For more detailed information see the # following links: # https://github.com/pypa/setuptools/issues/202#issuecomment-202913420 # http://bit.ly/2h9itJX old_entry = cache[p] del cache[p] new_entry = updater and updater(p, old_entry) if new_entry is not None: cache[p] = new_entry def _uncache(normalized_path, cache): _update_zipimporter_cache(normalized_path, cache) def _remove_and_clear_zip_directory_cache_data(normalized_path): def clear_and_remove_cached_zip_archive_directory_data(path, old_entry): old_entry.clear() _update_zipimporter_cache( normalized_path, zipimport._zip_directory_cache, updater=clear_and_remove_cached_zip_archive_directory_data) # PyPy Python implementation does not allow directly writing to the # zipimport._zip_directory_cache and so prevents us from attempting to correct # its content. The best we can do there is clear the problematic cache content # and have PyPy repopulate it as needed. The downside is that if there are any # stale zipimport.zipimporter instances laying around, attempting to use them # will fail due to not having its zip archive directory information available # instead of being automatically corrected to use the new correct zip archive # directory information. if '__pypy__' in sys.builtin_module_names: _replace_zip_directory_cache_data = \ _remove_and_clear_zip_directory_cache_data else: def _replace_zip_directory_cache_data(normalized_path): def replace_cached_zip_archive_directory_data(path, old_entry): # N.B. In theory, we could load the zip directory information just # once for all updated path spellings, and then copy it locally and # update its contained path strings to contain the correct # spelling, but that seems like a way too invasive move (this cache # structure is not officially documented anywhere and could in # theory change with new Python releases) for no significant # benefit. old_entry.clear() zipimport.zipimporter(path) old_entry.update(zipimport._zip_directory_cache[path]) return old_entry _update_zipimporter_cache( normalized_path, zipimport._zip_directory_cache, updater=replace_cached_zip_archive_directory_data) def is_python(text, filename=''): "Is this string a valid Python script?" try: compile(text, filename, 'exec') except (SyntaxError, TypeError): return False else: return True def is_sh(executable): """Determine if the specified executable is a .sh (contains a #! line)""" try: with io.open(executable, encoding='latin-1') as fp: magic = fp.read(2) except (OSError, IOError): return executable return magic == '#!' def nt_quote_arg(arg): """Quote a command line argument according to Windows parsing rules""" return subprocess.list2cmdline([arg]) def is_python_script(script_text, filename): """Is this text, as a whole, a Python script? (as opposed to shell/bat/etc. """ if filename.endswith('.py') or filename.endswith('.pyw'): return True # extension says it's Python if is_python(script_text, filename): return True # it's syntactically valid Python if script_text.startswith('#!'): # It begins with a '#!' line, so check if 'python' is in it somewhere return 'python' in script_text.splitlines()[0].lower() return False # Not any Python I can recognize try: from os import chmod as _chmod except ImportError: # Jython compatibility def _chmod(*args): pass def chmod(path, mode): log.debug("changing mode of %s to %o", path, mode) try: _chmod(path, mode) except os.error as e: log.debug("chmod failed: %s", e) class CommandSpec(list): """ A command spec for a #! header, specified as a list of arguments akin to those passed to Popen. """ options = [] split_args = dict() @classmethod def best(cls): """ Choose the best CommandSpec class based on environmental conditions. """ return cls @classmethod def _sys_executable(cls): _default = os.path.normpath(sys.executable) return os.environ.get('__PYVENV_LAUNCHER__', _default) @classmethod def from_param(cls, param): """ Construct a CommandSpec from a parameter to build_scripts, which may be None. """ if isinstance(param, cls): return param if isinstance(param, list): return cls(param) if param is None: return cls.from_environment() # otherwise, assume it's a string. return cls.from_string(param) @classmethod def from_environment(cls): return cls([cls._sys_executable()]) @classmethod def from_string(cls, string): """ Construct a command spec from a simple string representing a command line parseable by shlex.split. """ items = shlex.split(string, **cls.split_args) return cls(items) def install_options(self, script_text): self.options = shlex.split(self._extract_options(script_text)) cmdline = subprocess.list2cmdline(self) if not isascii(cmdline): self.options[:0] = ['-x'] @staticmethod def _extract_options(orig_script): """ Extract any options from the first line of the script. """ first = (orig_script + '\n').splitlines()[0] match = _first_line_re().match(first) options = match.group(1) or '' if match else '' return options.strip() def as_header(self): return self._render(self + list(self.options)) @staticmethod def _strip_quotes(item): _QUOTES = '"\'' for q in _QUOTES: if item.startswith(q) and item.endswith(q): return item[1:-1] return item @staticmethod def _render(items): cmdline = subprocess.list2cmdline( CommandSpec._strip_quotes(item.strip()) for item in items) return '#!' + cmdline + '\n' # For pbr compat; will be removed in a future version. sys_executable = CommandSpec._sys_executable() class WindowsCommandSpec(CommandSpec): split_args = dict(posix=False) class ScriptWriter: """ Encapsulates behavior around writing entry point scripts for console and gui apps. """ template = textwrap.dedent(r""" # EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r import re import sys # for compatibility with easy_install; see #2198 __requires__ = %(spec)r try: from importlib.metadata import distribution except ImportError: try: from importlib_metadata import distribution except ImportError: from pkg_resources import load_entry_point def importlib_load_entry_point(spec, group, name): dist_name, _, _ = spec.partition('==') matches = ( entry_point for entry_point in distribution(dist_name).entry_points if entry_point.group == group and entry_point.name == name ) return next(matches).load() globals().setdefault('load_entry_point', importlib_load_entry_point) if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) sys.exit(load_entry_point(%(spec)r, %(group)r, %(name)r)()) """).lstrip() command_spec_class = CommandSpec @classmethod def get_script_args(cls, dist, executable=None, wininst=False): # for backward compatibility warnings.warn("Use get_args", EasyInstallDeprecationWarning) writer = (WindowsScriptWriter if wininst else ScriptWriter).best() header = cls.get_script_header("", executable, wininst) return writer.get_args(dist, header) @classmethod def get_script_header(cls, script_text, executable=None, wininst=False): # for backward compatibility warnings.warn( "Use get_header", EasyInstallDeprecationWarning, stacklevel=2) if wininst: executable = "python.exe" return cls.get_header(script_text, executable) @classmethod def get_args(cls, dist, header=None): """ Yield write_script() argument tuples for a distribution's console_scripts and gui_scripts entry points. """ if header is None: header = cls.get_header() spec = str(dist.as_requirement()) for type_ in 'console', 'gui': group = type_ + '_scripts' for name, ep in dist.get_entry_map(group).items(): cls._ensure_safe_name(name) script_text = cls.template % locals() args = cls._get_script_args(type_, name, header, script_text) for res in args: yield res @staticmethod def _ensure_safe_name(name): """ Prevent paths in *_scripts entry point names. """ has_path_sep = re.search(r'[\\/]', name) if has_path_sep: raise ValueError("Path separators not allowed in script names") @classmethod def get_writer(cls, force_windows): # for backward compatibility warnings.warn("Use best", EasyInstallDeprecationWarning) return WindowsScriptWriter.best() if force_windows else cls.best() @classmethod def best(cls): """ Select the best ScriptWriter for this environment. """ if sys.platform == 'win32' or (os.name == 'java' and os._name == 'nt'): return WindowsScriptWriter.best() else: return cls @classmethod def _get_script_args(cls, type_, name, header, script_text): # Simply write the stub with no extension. yield (name, header + script_text) @classmethod def get_header(cls, script_text="", executable=None): """Create a #! line, getting options (if any) from script_text""" cmd = cls.command_spec_class.best().from_param(executable) cmd.install_options(script_text) return cmd.as_header() class WindowsScriptWriter(ScriptWriter): command_spec_class = WindowsCommandSpec @classmethod def get_writer(cls): # for backward compatibility warnings.warn("Use best", EasyInstallDeprecationWarning) return cls.best() @classmethod def best(cls): """ Select the best ScriptWriter suitable for Windows """ writer_lookup = dict( executable=WindowsExecutableLauncherWriter, natural=cls, ) # for compatibility, use the executable launcher by default launcher = os.environ.get('SETUPTOOLS_LAUNCHER', 'executable') return writer_lookup[launcher] @classmethod def _get_script_args(cls, type_, name, header, script_text): "For Windows, add a .py extension" ext = dict(console='.pya', gui='.pyw')[type_] if ext not in os.environ['PATHEXT'].lower().split(';'): msg = ( "{ext} not listed in PATHEXT; scripts will not be " "recognized as executables." ).format(**locals()) warnings.warn(msg, UserWarning) old = ['.pya', '.py', '-script.py', '.pyc', '.pyo', '.pyw', '.exe'] old.remove(ext) header = cls._adjust_header(type_, header) blockers = [name + x for x in old] yield name + ext, header + script_text, 't', blockers @classmethod def _adjust_header(cls, type_, orig_header): """ Make sure 'pythonw' is used for gui and 'python' is used for console (regardless of what sys.executable is). """ pattern = 'pythonw.exe' repl = 'python.exe' if type_ == 'gui': pattern, repl = repl, pattern pattern_ob = re.compile(re.escape(pattern), re.IGNORECASE) new_header = pattern_ob.sub(string=orig_header, repl=repl) return new_header if cls._use_header(new_header) else orig_header @staticmethod def _use_header(new_header): """ Should _adjust_header use the replaced header? On non-windows systems, always use. On Windows systems, only use the replaced header if it resolves to an executable on the system. """ clean_header = new_header[2:-1].strip('"') return sys.platform != 'win32' or find_executable(clean_header) class WindowsExecutableLauncherWriter(WindowsScriptWriter): @classmethod def _get_script_args(cls, type_, name, header, script_text): """ For Windows, add a .py extension and an .exe launcher """ if type_ == 'gui': launcher_type = 'gui' ext = '-script.pyw' old = ['.pyw'] else: launcher_type = 'cli' ext = '-script.py' old = ['.py', '.pyc', '.pyo'] hdr = cls._adjust_header(type_, header) blockers = [name + x for x in old] yield (name + ext, hdr + script_text, 't', blockers) yield ( name + '.exe', get_win_launcher(launcher_type), 'b' # write in binary mode ) if not is_64bit(): # install a manifest for the launcher to prevent Windows # from detecting it as an installer (which it will for # launchers like easy_install.exe). Consider only # adding a manifest for launchers detected as installers. # See Distribute #143 for details. m_name = name + '.exe.manifest' yield (m_name, load_launcher_manifest(name), 't') # for backward-compatibility get_script_args = ScriptWriter.get_script_args get_script_header = ScriptWriter.get_script_header def get_win_launcher(type): """ Load the Windows launcher (executable) suitable for launching a script. `type` should be either 'cli' or 'gui' Returns the executable as a byte string. """ launcher_fn = '%s.exe' % type if is_64bit(): if get_platform() == "win-arm64": launcher_fn = launcher_fn.replace(".", "-arm64.") else: launcher_fn = launcher_fn.replace(".", "-64.") else: launcher_fn = launcher_fn.replace(".", "-32.") return resource_string('setuptools', launcher_fn) def load_launcher_manifest(name): manifest = pkg_resources.resource_string(__name__, 'launcher manifest.xml') return manifest.decode('utf-8') % vars() def rmtree(path, ignore_errors=False, onerror=auto_chmod): return shutil.rmtree(path, ignore_errors, onerror) def current_umask(): tmp = os.umask(0o022) os.umask(tmp) return tmp class EasyInstallDeprecationWarning(SetuptoolsDeprecationWarning): """ Warning for EasyInstall deprecations, bypassing suppression. """ PKH]\Ҩ?python3.10/site-packages/setuptools/command/install_egg_info.pynu[from distutils import log, dir_util import os from setuptools import Command from setuptools import namespaces from setuptools.archive_util import unpack_archive import pkg_resources class install_egg_info(namespaces.Installer, Command): """Install an .egg-info directory for the package""" description = "Install an .egg-info directory for the package" user_options = [ ('install-dir=', 'd', "directory to install to"), ] def initialize_options(self): self.install_dir = None def finalize_options(self): self.set_undefined_options('install_lib', ('install_dir', 'install_dir')) ei_cmd = self.get_finalized_command("egg_info") basename = pkg_resources.Distribution( None, None, ei_cmd.egg_name, ei_cmd.egg_version ).egg_name() + '.egg-info' self.source = ei_cmd.egg_info self.target = os.path.join(self.install_dir, basename) self.outputs = [] def run(self): self.run_command('egg_info') if os.path.isdir(self.target) and not os.path.islink(self.target): dir_util.remove_tree(self.target, dry_run=self.dry_run) elif os.path.exists(self.target): self.execute(os.unlink, (self.target,), "Removing " + self.target) if not self.dry_run: pkg_resources.ensure_directory(self.target) self.execute( self.copytree, (), "Copying %s to %s" % (self.source, self.target) ) self.install_namespaces() def get_outputs(self): return self.outputs def copytree(self): # Copy the .egg-info tree to site-packages def skimmer(src, dst): # filter out source-control directories; note that 'src' is always # a '/'-separated path, regardless of platform. 'dst' is a # platform-specific path. for skip in '.svn/', 'CVS/': if src.startswith(skip) or '/' + skip in src: return None self.outputs.append(dst) log.debug("Copying %s to %s", src, dst) return dst unpack_archive(self.source, self.target, skimmer) PKH]I338python3.10/site-packages/setuptools/command/build_ext.pynu[import os import sys import itertools from importlib.machinery import EXTENSION_SUFFIXES from distutils.command.build_ext import build_ext as _du_build_ext from distutils.file_util import copy_file from distutils.ccompiler import new_compiler from distutils.sysconfig import customize_compiler, get_config_var from distutils.errors import DistutilsError from distutils import log from setuptools.extension import Library try: # Attempt to use Cython for building extensions, if available from Cython.Distutils.build_ext import build_ext as _build_ext # Additionally, assert that the compiler module will load # also. Ref #1229. __import__('Cython.Compiler.Main') except ImportError: _build_ext = _du_build_ext # make sure _config_vars is initialized get_config_var("LDSHARED") from distutils.sysconfig import _config_vars as _CONFIG_VARS # noqa def _customize_compiler_for_shlib(compiler): if sys.platform == "darwin": # building .dylib requires additional compiler flags on OSX; here we # temporarily substitute the pyconfig.h variables so that distutils' # 'customize_compiler' uses them before we build the shared libraries. tmp = _CONFIG_VARS.copy() try: # XXX Help! I don't have any idea whether these are right... _CONFIG_VARS['LDSHARED'] = ( "gcc -Wl,-x -dynamiclib -undefined dynamic_lookup") _CONFIG_VARS['CCSHARED'] = " -dynamiclib" _CONFIG_VARS['SO'] = ".dylib" customize_compiler(compiler) finally: _CONFIG_VARS.clear() _CONFIG_VARS.update(tmp) else: customize_compiler(compiler) have_rtld = False use_stubs = False libtype = 'shared' if sys.platform == "darwin": use_stubs = True elif os.name != 'nt': try: import dl use_stubs = have_rtld = hasattr(dl, 'RTLD_NOW') except ImportError: pass def if_dl(s): return s if have_rtld else '' def get_abi3_suffix(): """Return the file extension for an abi3-compliant Extension()""" for suffix in EXTENSION_SUFFIXES: if '.abi3' in suffix: # Unix return suffix elif suffix == '.pyd': # Windows return suffix class build_ext(_build_ext): def run(self): """Build extensions in build directory, then copy if --inplace""" old_inplace, self.inplace = self.inplace, 0 _build_ext.run(self) self.inplace = old_inplace if old_inplace: self.copy_extensions_to_source() def copy_extensions_to_source(self): build_py = self.get_finalized_command('build_py') for ext in self.extensions: fullname = self.get_ext_fullname(ext.name) filename = self.get_ext_filename(fullname) modpath = fullname.split('.') package = '.'.join(modpath[:-1]) package_dir = build_py.get_package_dir(package) dest_filename = os.path.join(package_dir, os.path.basename(filename)) src_filename = os.path.join(self.build_lib, filename) # Always copy, even if source is older than destination, to ensure # that the right extensions for the current Python/platform are # used. copy_file( src_filename, dest_filename, verbose=self.verbose, dry_run=self.dry_run ) if ext._needs_stub: self.write_stub(package_dir or os.curdir, ext, True) def get_ext_filename(self, fullname): so_ext = os.getenv('SETUPTOOLS_EXT_SUFFIX') if so_ext: filename = os.path.join(*fullname.split('.')) + so_ext else: filename = _build_ext.get_ext_filename(self, fullname) so_ext = get_config_var('EXT_SUFFIX') if fullname in self.ext_map: ext = self.ext_map[fullname] use_abi3 = getattr(ext, 'py_limited_api') and get_abi3_suffix() if use_abi3: filename = filename[:-len(so_ext)] so_ext = get_abi3_suffix() filename = filename + so_ext if isinstance(ext, Library): fn, ext = os.path.splitext(filename) return self.shlib_compiler.library_filename(fn, libtype) elif use_stubs and ext._links_to_dynamic: d, fn = os.path.split(filename) return os.path.join(d, 'dl-' + fn) return filename def initialize_options(self): _build_ext.initialize_options(self) self.shlib_compiler = None self.shlibs = [] self.ext_map = {} def finalize_options(self): _build_ext.finalize_options(self) self.extensions = self.extensions or [] self.check_extensions_list(self.extensions) self.shlibs = [ext for ext in self.extensions if isinstance(ext, Library)] if self.shlibs: self.setup_shlib_compiler() for ext in self.extensions: ext._full_name = self.get_ext_fullname(ext.name) for ext in self.extensions: fullname = ext._full_name self.ext_map[fullname] = ext # distutils 3.1 will also ask for module names # XXX what to do with conflicts? self.ext_map[fullname.split('.')[-1]] = ext ltd = self.shlibs and self.links_to_dynamic(ext) or False ns = ltd and use_stubs and not isinstance(ext, Library) ext._links_to_dynamic = ltd ext._needs_stub = ns filename = ext._file_name = self.get_ext_filename(fullname) libdir = os.path.dirname(os.path.join(self.build_lib, filename)) if ltd and libdir not in ext.library_dirs: ext.library_dirs.append(libdir) if ltd and use_stubs and os.curdir not in ext.runtime_library_dirs: ext.runtime_library_dirs.append(os.curdir) def setup_shlib_compiler(self): compiler = self.shlib_compiler = new_compiler( compiler=self.compiler, dry_run=self.dry_run, force=self.force ) _customize_compiler_for_shlib(compiler) if self.include_dirs is not None: compiler.set_include_dirs(self.include_dirs) if self.define is not None: # 'define' option is a list of (name,value) tuples for (name, value) in self.define: compiler.define_macro(name, value) if self.undef is not None: for macro in self.undef: compiler.undefine_macro(macro) if self.libraries is not None: compiler.set_libraries(self.libraries) if self.library_dirs is not None: compiler.set_library_dirs(self.library_dirs) if self.rpath is not None: compiler.set_runtime_library_dirs(self.rpath) if self.link_objects is not None: compiler.set_link_objects(self.link_objects) # hack so distutils' build_extension() builds a library instead compiler.link_shared_object = link_shared_object.__get__(compiler) def get_export_symbols(self, ext): if isinstance(ext, Library): return ext.export_symbols return _build_ext.get_export_symbols(self, ext) def build_extension(self, ext): ext._convert_pyx_sources_to_lang() _compiler = self.compiler try: if isinstance(ext, Library): self.compiler = self.shlib_compiler _build_ext.build_extension(self, ext) if ext._needs_stub: cmd = self.get_finalized_command('build_py').build_lib self.write_stub(cmd, ext) finally: self.compiler = _compiler def links_to_dynamic(self, ext): """Return true if 'ext' links to a dynamic lib in the same package""" # XXX this should check to ensure the lib is actually being built # XXX as dynamic, and not just using a locally-found version or a # XXX static-compiled version libnames = dict.fromkeys([lib._full_name for lib in self.shlibs]) pkg = '.'.join(ext._full_name.split('.')[:-1] + ['']) return any(pkg + libname in libnames for libname in ext.libraries) def get_outputs(self): return _build_ext.get_outputs(self) + self.__get_stubs_outputs() def __get_stubs_outputs(self): # assemble the base name for each extension that needs a stub ns_ext_bases = ( os.path.join(self.build_lib, *ext._full_name.split('.')) for ext in self.extensions if ext._needs_stub ) # pair each base with the extension pairs = itertools.product(ns_ext_bases, self.__get_output_extensions()) return list(base + fnext for base, fnext in pairs) def __get_output_extensions(self): yield '.py' yield '.pyc' if self.get_finalized_command('build_py').optimize: yield '.pyo' def write_stub(self, output_dir, ext, compile=False): log.info("writing stub loader for %s to %s", ext._full_name, output_dir) stub_file = (os.path.join(output_dir, *ext._full_name.split('.')) + '.py') if compile and os.path.exists(stub_file): raise DistutilsError(stub_file + " already exists! Please delete.") if not self.dry_run: f = open(stub_file, 'w') f.write( '\n'.join([ "def __bootstrap__():", " global __bootstrap__, __file__, __loader__", " import sys, os, pkg_resources, importlib.util" + if_dl(", dl"), " __file__ = pkg_resources.resource_filename" "(__name__,%r)" % os.path.basename(ext._file_name), " del __bootstrap__", " if '__loader__' in globals():", " del __loader__", if_dl(" old_flags = sys.getdlopenflags()"), " old_dir = os.getcwd()", " try:", " os.chdir(os.path.dirname(__file__))", if_dl(" sys.setdlopenflags(dl.RTLD_NOW)"), " spec = importlib.util.spec_from_file_location(", " __name__, __file__)", " mod = importlib.util.module_from_spec(spec)", " spec.loader.exec_module(mod)", " finally:", if_dl(" sys.setdlopenflags(old_flags)"), " os.chdir(old_dir)", "__bootstrap__()", "" # terminal \n ]) ) f.close() if compile: from distutils.util import byte_compile byte_compile([stub_file], optimize=0, force=True, dry_run=self.dry_run) optimize = self.get_finalized_command('install_lib').optimize if optimize > 0: byte_compile([stub_file], optimize=optimize, force=True, dry_run=self.dry_run) if os.path.exists(stub_file) and not self.dry_run: os.unlink(stub_file) if use_stubs or os.name == 'nt': # Build shared libraries # def link_shared_object( self, objects, output_libname, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): self.link( self.SHARED_LIBRARY, objects, output_libname, output_dir, libraries, library_dirs, runtime_library_dirs, export_symbols, debug, extra_preargs, extra_postargs, build_temp, target_lang ) else: # Build static libraries everywhere else libtype = 'static' def link_shared_object( self, objects, output_libname, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): # XXX we need to either disallow these attrs on Library instances, # or warn/abort here if set, or something... # libraries=None, library_dirs=None, runtime_library_dirs=None, # export_symbols=None, extra_preargs=None, extra_postargs=None, # build_temp=None assert output_dir is None # distutils build_ext doesn't pass this output_dir, filename = os.path.split(output_libname) basename, ext = os.path.splitext(filename) if self.library_filename("x").startswith('lib'): # strip 'lib' prefix; this is kludgy if some platform uses # a different prefix basename = basename[3:] self.create_static_lib( objects, basename, output_dir, debug, target_lang ) PKH]])BttApython3.10/site-packages/setuptools/command/launcher manifest.xmlnu[ PKH],##:python3.10/site-packages/setuptools/command/install_lib.pynu[import os import sys from itertools import product, starmap import distutils.command.install_lib as orig class install_lib(orig.install_lib): """Don't add compiled flags to filenames of non-Python files""" def run(self): self.build() outfiles = self.install() if outfiles is not None: # always compile, in case we have any extension stubs to deal with self.byte_compile(outfiles) def get_exclusions(self): """ Return a collections.Sized collections.Container of paths to be excluded for single_version_externally_managed installations. """ all_packages = ( pkg for ns_pkg in self._get_SVEM_NSPs() for pkg in self._all_packages(ns_pkg) ) excl_specs = product(all_packages, self._gen_exclusion_paths()) return set(starmap(self._exclude_pkg_path, excl_specs)) def _exclude_pkg_path(self, pkg, exclusion_path): """ Given a package name and exclusion path within that package, compute the full exclusion path. """ parts = pkg.split('.') + [exclusion_path] return os.path.join(self.install_dir, *parts) @staticmethod def _all_packages(pkg_name): """ >>> list(install_lib._all_packages('foo.bar.baz')) ['foo.bar.baz', 'foo.bar', 'foo'] """ while pkg_name: yield pkg_name pkg_name, sep, child = pkg_name.rpartition('.') def _get_SVEM_NSPs(self): """ Get namespace packages (list) but only for single_version_externally_managed installations and empty otherwise. """ # TODO: is it necessary to short-circuit here? i.e. what's the cost # if get_finalized_command is called even when namespace_packages is # False? if not self.distribution.namespace_packages: return [] install_cmd = self.get_finalized_command('install') svem = install_cmd.single_version_externally_managed return self.distribution.namespace_packages if svem else [] @staticmethod def _gen_exclusion_paths(): """ Generate file paths to be excluded for namespace packages (bytecode cache files). """ # always exclude the package module itself yield '__init__.py' yield '__init__.pyc' yield '__init__.pyo' if not hasattr(sys, 'implementation'): return base = os.path.join( '__pycache__', '__init__.' + sys.implementation.cache_tag) yield base + '.pyc' yield base + '.pyo' yield base + '.opt-1.pyc' yield base + '.opt-2.pyc' def copy_tree( self, infile, outfile, preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1 ): assert preserve_mode and preserve_times and not preserve_symlinks exclude = self.get_exclusions() if not exclude: return orig.install_lib.copy_tree(self, infile, outfile) # Exclude namespace package __init__.py* files from the output from setuptools.archive_util import unpack_directory from distutils import log outfiles = [] def pf(src, dst): if dst in exclude: log.warn("Skipping installation of %s (namespace package)", dst) return False log.info("copying %s -> %s", src, os.path.dirname(dst)) outfiles.append(dst) return dst unpack_directory(infile, outfile, pf) return outfiles def get_outputs(self): outputs = orig.install_lib.get_outputs(self) exclude = self.get_exclusions() if exclude: return [f for f in outputs if f not in exclude] return outputs PKH]8python3.10/site-packages/setuptools/command/dist_info.pynu[""" Create a dist_info directory As defined in the wheel specification """ import os from distutils.core import Command from distutils import log class dist_info(Command): description = 'create a .dist-info directory' user_options = [ ('egg-base=', 'e', "directory containing .egg-info directories" " (default: top of the source tree)"), ] def initialize_options(self): self.egg_base = None def finalize_options(self): pass def run(self): egg_info = self.get_finalized_command('egg_info') egg_info.egg_base = self.egg_base egg_info.finalize_options() egg_info.run() dist_info_dir = egg_info.egg_info[:-len('.egg-info')] + '.dist-info' log.info("creating '{}'".format(os.path.abspath(dist_info_dir))) bdist_wheel = self.get_finalized_command('bdist_wheel') bdist_wheel.egg2dist(egg_info.egg_info, dist_info_dir) PKH]v7python3.10/site-packages/setuptools/command/register.pynu[from distutils import log import distutils.command.register as orig from setuptools.errors import RemovedCommandError class register(orig.register): """Formerly used to register packages on PyPI.""" def run(self): msg = ( "The register command has been removed, use twine to upload " + "instead (https://pypi.org/p/twine)" ) self.announce("ERROR: " + msg, log.ERROR) raise RemovedCommandError(msg) PKH]"]K5python3.10/site-packages/setuptools/command/upload.pynu[from distutils import log from distutils.command import upload as orig from setuptools.errors import RemovedCommandError class upload(orig.upload): """Formerly used to upload packages to PyPI.""" def run(self): msg = ( "The upload command has been removed, use twine to upload " + "instead (https://pypi.org/p/twine)" ) self.announce("ERROR: " + msg, log.ERROR) raise RemovedCommandError(msg) PKH]2-T T 7python3.10/site-packages/setuptools/command/build_py.pynu[from glob import glob from distutils.util import convert_path import distutils.command.build_py as orig import os import fnmatch import textwrap import io import distutils.errors import itertools import stat from setuptools.extern.more_itertools import unique_everseen def make_writable(target): os.chmod(target, os.stat(target).st_mode | stat.S_IWRITE) class build_py(orig.build_py): """Enhanced 'build_py' command that includes data files with packages The data files are specified via a 'package_data' argument to 'setup()'. See 'setuptools.dist.Distribution' for more details. Also, this version of the 'build_py' command allows you to specify both 'py_modules' and 'packages' in the same setup operation. """ def finalize_options(self): orig.build_py.finalize_options(self) self.package_data = self.distribution.package_data self.exclude_package_data = self.distribution.exclude_package_data or {} if 'data_files' in self.__dict__: del self.__dict__['data_files'] self.__updated_files = [] def run(self): """Build modules, packages, and copy data files to build directory""" if not self.py_modules and not self.packages: return if self.py_modules: self.build_modules() if self.packages: self.build_packages() self.build_package_data() # Only compile actual .py files, using our base class' idea of what our # output files are. self.byte_compile(orig.build_py.get_outputs(self, include_bytecode=0)) def __getattr__(self, attr): "lazily compute data files" if attr == 'data_files': self.data_files = self._get_data_files() return self.data_files return orig.build_py.__getattr__(self, attr) def build_module(self, module, module_file, package): outfile, copied = orig.build_py.build_module(self, module, module_file, package) if copied: self.__updated_files.append(outfile) return outfile, copied def _get_data_files(self): """Generate list of '(package,src_dir,build_dir,filenames)' tuples""" self.analyze_manifest() return list(map(self._get_pkg_data_files, self.packages or ())) def _get_pkg_data_files(self, package): # Locate package source directory src_dir = self.get_package_dir(package) # Compute package build directory build_dir = os.path.join(*([self.build_lib] + package.split('.'))) # Strip directory from globbed filenames filenames = [ os.path.relpath(file, src_dir) for file in self.find_data_files(package, src_dir) ] return package, src_dir, build_dir, filenames def find_data_files(self, package, src_dir): """Return filenames for package's data files in 'src_dir'""" patterns = self._get_platform_patterns( self.package_data, package, src_dir, ) globs_expanded = map(glob, patterns) # flatten the expanded globs into an iterable of matches globs_matches = itertools.chain.from_iterable(globs_expanded) glob_files = filter(os.path.isfile, globs_matches) files = itertools.chain( self.manifest_files.get(package, []), glob_files, ) return self.exclude_data_files(package, src_dir, files) def build_package_data(self): """Copy data files into build directory""" for package, src_dir, build_dir, filenames in self.data_files: for filename in filenames: target = os.path.join(build_dir, filename) self.mkpath(os.path.dirname(target)) srcfile = os.path.join(src_dir, filename) outf, copied = self.copy_file(srcfile, target) make_writable(target) srcfile = os.path.abspath(srcfile) def analyze_manifest(self): self.manifest_files = mf = {} if not self.distribution.include_package_data: return src_dirs = {} for package in self.packages or (): # Locate package source directory src_dirs[assert_relative(self.get_package_dir(package))] = package self.run_command('egg_info') ei_cmd = self.get_finalized_command('egg_info') for path in ei_cmd.filelist.files: d, f = os.path.split(assert_relative(path)) prev = None oldf = f while d and d != prev and d not in src_dirs: prev = d d, df = os.path.split(d) f = os.path.join(df, f) if d in src_dirs: if path.endswith('.py') and f == oldf: continue # it's a module, not data mf.setdefault(src_dirs[d], []).append(path) def get_data_files(self): pass # Lazily compute data files in _get_data_files() function. def check_package(self, package, package_dir): """Check namespace packages' __init__ for declare_namespace""" try: return self.packages_checked[package] except KeyError: pass init_py = orig.build_py.check_package(self, package, package_dir) self.packages_checked[package] = init_py if not init_py or not self.distribution.namespace_packages: return init_py for pkg in self.distribution.namespace_packages: if pkg == package or pkg.startswith(package + '.'): break else: return init_py with io.open(init_py, 'rb') as f: contents = f.read() if b'declare_namespace' not in contents: raise distutils.errors.DistutilsError( "Namespace package problem: %s is a namespace package, but " "its\n__init__.py does not call declare_namespace()! Please " 'fix it.\n(See the setuptools manual under ' '"Namespace Packages" for details.)\n"' % (package,) ) return init_py def initialize_options(self): self.packages_checked = {} orig.build_py.initialize_options(self) def get_package_dir(self, package): res = orig.build_py.get_package_dir(self, package) if self.distribution.src_root is not None: return os.path.join(self.distribution.src_root, res) return res def exclude_data_files(self, package, src_dir, files): """Filter filenames for package's data files in 'src_dir'""" files = list(files) patterns = self._get_platform_patterns( self.exclude_package_data, package, src_dir, ) match_groups = (fnmatch.filter(files, pattern) for pattern in patterns) # flatten the groups of matches into an iterable of matches matches = itertools.chain.from_iterable(match_groups) bad = set(matches) keepers = (fn for fn in files if fn not in bad) # ditch dupes return list(unique_everseen(keepers)) @staticmethod def _get_platform_patterns(spec, package, src_dir): """ yield platform-specific path patterns (suitable for glob or fn_match) from a glob-based spec (such as self.package_data or self.exclude_package_data) matching package in src_dir. """ raw_patterns = itertools.chain( spec.get('', []), spec.get(package, []), ) return ( # Each pattern has to be converted to a platform-specific path os.path.join(src_dir, convert_path(pattern)) for pattern in raw_patterns ) def assert_relative(path): if not os.path.isabs(path): return path from distutils.errors import DistutilsSetupError msg = ( textwrap.dedent( """ Error: setup script specifies an absolute path: %s setup() arguments must *always* be /-separated paths relative to the setup.py directory, *never* absolute paths. """ ).lstrip() % path ) raise DistutilsSetupError(msg) PKH]$3python3.10/site-packages/setuptools/command/test.pynu[import os import operator import sys import contextlib import itertools import unittest from distutils.errors import DistutilsError, DistutilsOptionError from distutils import log from unittest import TestLoader from pkg_resources import ( resource_listdir, resource_exists, normalize_path, working_set, evaluate_marker, add_activation_listener, require, EntryPoint, ) from setuptools import Command from setuptools.extern.more_itertools import unique_everseen class ScanningLoader(TestLoader): def __init__(self): TestLoader.__init__(self) self._visited = set() def loadTestsFromModule(self, module, pattern=None): """Return a suite of all tests cases contained in the given module If the module is a package, load tests from all the modules in it. If the module has an ``additional_tests`` function, call it and add the return value to the tests. """ if module in self._visited: return None self._visited.add(module) tests = [] tests.append(TestLoader.loadTestsFromModule(self, module)) if hasattr(module, "additional_tests"): tests.append(module.additional_tests()) if hasattr(module, '__path__'): for file in resource_listdir(module.__name__, ''): if file.endswith('.py') and file != '__init__.py': submodule = module.__name__ + '.' + file[:-3] else: if resource_exists(module.__name__, file + '/__init__.py'): submodule = module.__name__ + '.' + file else: continue tests.append(self.loadTestsFromName(submodule)) if len(tests) != 1: return self.suiteClass(tests) else: return tests[0] # don't create a nested suite for only one return # adapted from jaraco.classes.properties:NonDataProperty class NonDataProperty: def __init__(self, fget): self.fget = fget def __get__(self, obj, objtype=None): if obj is None: return self return self.fget(obj) class test(Command): """Command to run unit tests after in-place build""" description = "run unit tests after in-place build (deprecated)" user_options = [ ('test-module=', 'm', "Run 'test_suite' in specified module"), ( 'test-suite=', 's', "Run single test, case or suite (e.g. 'module.test_suite')", ), ('test-runner=', 'r', "Test runner to use"), ] def initialize_options(self): self.test_suite = None self.test_module = None self.test_loader = None self.test_runner = None def finalize_options(self): if self.test_suite and self.test_module: msg = "You may specify a module or a suite, but not both" raise DistutilsOptionError(msg) if self.test_suite is None: if self.test_module is None: self.test_suite = self.distribution.test_suite else: self.test_suite = self.test_module + ".test_suite" if self.test_loader is None: self.test_loader = getattr(self.distribution, 'test_loader', None) if self.test_loader is None: self.test_loader = "setuptools.command.test:ScanningLoader" if self.test_runner is None: self.test_runner = getattr(self.distribution, 'test_runner', None) @NonDataProperty def test_args(self): return list(self._test_args()) def _test_args(self): if not self.test_suite and sys.version_info >= (2, 7): yield 'discover' if self.verbose: yield '--verbose' if self.test_suite: yield self.test_suite def with_project_on_sys_path(self, func): """ Backward compatibility for project_on_sys_path context. """ with self.project_on_sys_path(): func() @contextlib.contextmanager def project_on_sys_path(self, include_dists=[]): self.run_command('egg_info') # Build extensions in-place self.reinitialize_command('build_ext', inplace=1) self.run_command('build_ext') ei_cmd = self.get_finalized_command("egg_info") old_path = sys.path[:] old_modules = sys.modules.copy() try: project_path = normalize_path(ei_cmd.egg_base) sys.path.insert(0, project_path) working_set.__init__() add_activation_listener(lambda dist: dist.activate()) require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version)) with self.paths_on_pythonpath([project_path]): yield finally: sys.path[:] = old_path sys.modules.clear() sys.modules.update(old_modules) working_set.__init__() @staticmethod @contextlib.contextmanager def paths_on_pythonpath(paths): """ Add the indicated paths to the head of the PYTHONPATH environment variable so that subprocesses will also see the packages at these paths. Do this in a context that restores the value on exit. """ nothing = object() orig_pythonpath = os.environ.get('PYTHONPATH', nothing) current_pythonpath = os.environ.get('PYTHONPATH', '') try: prefix = os.pathsep.join(unique_everseen(paths)) to_join = filter(None, [prefix, current_pythonpath]) new_path = os.pathsep.join(to_join) if new_path: os.environ['PYTHONPATH'] = new_path yield finally: if orig_pythonpath is nothing: os.environ.pop('PYTHONPATH', None) else: os.environ['PYTHONPATH'] = orig_pythonpath @staticmethod def install_dists(dist): """ Install the requirements indicated by self.distribution and return an iterable of the dists that were built. """ ir_d = dist.fetch_build_eggs(dist.install_requires) tr_d = dist.fetch_build_eggs(dist.tests_require or []) er_d = dist.fetch_build_eggs( v for k, v in dist.extras_require.items() if k.startswith(':') and evaluate_marker(k[1:]) ) return itertools.chain(ir_d, tr_d, er_d) def run(self): self.announce( "WARNING: Testing via this command is deprecated and will be " "removed in a future version. Users looking for a generic test " "entry point independent of test runner are encouraged to use " "tox.", log.WARN, ) installed_dists = self.install_dists(self.distribution) cmd = ' '.join(self._argv) if self.dry_run: self.announce('skipping "%s" (dry run)' % cmd) return self.announce('running "%s"' % cmd) paths = map(operator.attrgetter('location'), installed_dists) with self.paths_on_pythonpath(paths): with self.project_on_sys_path(): self.run_tests() def run_tests(self): test = unittest.main( None, None, self._argv, testLoader=self._resolve_as_ep(self.test_loader), testRunner=self._resolve_as_ep(self.test_runner), exit=False, ) if not test.result.wasSuccessful(): msg = 'Test failed: %s' % test.result self.announce(msg, log.ERROR) raise DistutilsError(msg) @property def _argv(self): return ['unittest'] + self.test_args @staticmethod def _resolve_as_ep(val): """ Load the indicated attribute value, called, as a as if it were specified as an entry point. """ if val is None: return parsed = EntryPoint.parse("x=" + val) return parsed.resolve()() PKH]vQ1**6python3.10/site-packages/setuptools/command/install.pynu[from distutils.errors import DistutilsArgError import inspect import glob import warnings import platform import distutils.command.install as orig import setuptools # Prior to numpy 1.9, NumPy relies on the '_install' name, so provide it for # now. See https://github.com/pypa/setuptools/issues/199/ _install = orig.install class install(orig.install): """Use easy_install to install the package, w/dependencies""" user_options = orig.install.user_options + [ ('old-and-unmanageable', None, "Try not to use this!"), ('single-version-externally-managed', None, "used by system package builders to create 'flat' eggs"), ] boolean_options = orig.install.boolean_options + [ 'old-and-unmanageable', 'single-version-externally-managed', ] new_commands = [ ('install_egg_info', lambda self: True), ('install_scripts', lambda self: True), ] _nc = dict(new_commands) def initialize_options(self): warnings.warn( "setup.py install is deprecated. " "Use build and pip and other standards-based tools.", setuptools.SetuptoolsDeprecationWarning, ) orig.install.initialize_options(self) self.old_and_unmanageable = None self.single_version_externally_managed = None def finalize_options(self): orig.install.finalize_options(self) if self.root: self.single_version_externally_managed = True elif self.single_version_externally_managed: if not self.root and not self.record: raise DistutilsArgError( "You must specify --record or --root when building system" " packages" ) def handle_extra_path(self): if self.root or self.single_version_externally_managed: # explicit backward-compatibility mode, allow extra_path to work return orig.install.handle_extra_path(self) # Ignore extra_path when installing an egg (or being run by another # command without --root or --single-version-externally-managed self.path_file = None self.extra_dirs = '' def run(self): # Explicit request for old-style install? Just do it if self.old_and_unmanageable or self.single_version_externally_managed: return orig.install.run(self) if not self._called_from_setup(inspect.currentframe()): # Run in backward-compatibility mode to support bdist_* commands. orig.install.run(self) else: self.do_egg_install() @staticmethod def _called_from_setup(run_frame): """ Attempt to detect whether run() was called from setup() or by another command. If called by setup(), the parent caller will be the 'run_command' method in 'distutils.dist', and *its* caller will be the 'run_commands' method. If called any other way, the immediate caller *might* be 'run_command', but it won't have been called by 'run_commands'. Return True in that case or if a call stack is unavailable. Return False otherwise. """ if run_frame is None: msg = "Call stack not available. bdist_* commands may fail." warnings.warn(msg) if platform.python_implementation() == 'IronPython': msg = "For best results, pass -X:Frames to enable call stack." warnings.warn(msg) return True res = inspect.getouterframes(run_frame)[2] caller, = res[:1] info = inspect.getframeinfo(caller) caller_module = caller.f_globals.get('__name__', '') return ( caller_module == 'distutils.dist' and info.function == 'run_commands' ) def do_egg_install(self): easy_install = self.distribution.get_command_class('easy_install') cmd = easy_install( self.distribution, args="x", root=self.root, record=self.record, ) cmd.ensure_finalized() # finalize before bdist_egg munges install cmd cmd.always_copy_from = '.' # make sure local-dir eggs get installed # pick up setup-dir .egg files only: no .egg-info cmd.package_index.scan(glob.glob('*.egg')) self.run_command('bdist_egg') args = [self.distribution.get_command_obj('bdist_egg').egg_output] if setuptools.bootstrap_install_from: # Bootstrap self-installation of setuptools args.insert(0, setuptools.bootstrap_install_from) cmd.args = args cmd.run(show_deprecation=False) setuptools.bootstrap_install_from = None # XXX Python 3.1 doesn't see _nc if this is inside the class install.sub_commands = ( [cmd for cmd in orig.install.sub_commands if cmd[0] not in install._nc] + install.new_commands ) PKH]ȹ8python3.10/site-packages/setuptools/command/bdist_rpm.pynu[import distutils.command.bdist_rpm as orig import warnings from setuptools import SetuptoolsDeprecationWarning class bdist_rpm(orig.bdist_rpm): """ Override the default bdist_rpm behavior to do the following: 1. Run egg_info to ensure the name and version are properly calculated. 2. Always run 'install' using --single-version-externally-managed to disable eggs in RPM distributions. """ def run(self): warnings.warn( "bdist_rpm is deprecated and will be removed in a future " "version. Use bdist_wheel (wheel packages) instead.", SetuptoolsDeprecationWarning, ) # ensure distro name is up-to-date self.run_command('egg_info') orig.bdist_rpm.run(self) def _make_spec_file(self): spec = orig.bdist_rpm._make_spec_file(self) spec = [ line.replace( "setup.py install ", "setup.py install --single-version-externally-managed " ).replace( "%setup", "%setup -n %{name}-%{unmangled_version}" ) for line in spec ] return spec PKH]=M M 4python3.10/site-packages/setuptools/command/alias.pynu[from distutils.errors import DistutilsOptionError from setuptools.command.setopt import edit_config, option_base, config_file def shquote(arg): """Quote an argument for later parsing by shlex.split()""" for c in '"', "'", "\\", "#": if c in arg: return repr(arg) if arg.split() != [arg]: return repr(arg) return arg class alias(option_base): """Define a shortcut that invokes one or more commands""" description = "define a shortcut to invoke one or more commands" command_consumes_arguments = True user_options = [ ('remove', 'r', 'remove (unset) the alias'), ] + option_base.user_options boolean_options = option_base.boolean_options + ['remove'] def initialize_options(self): option_base.initialize_options(self) self.args = None self.remove = None def finalize_options(self): option_base.finalize_options(self) if self.remove and len(self.args) != 1: raise DistutilsOptionError( "Must specify exactly one argument (the alias name) when " "using --remove" ) def run(self): aliases = self.distribution.get_option_dict('aliases') if not self.args: print("Command Aliases") print("---------------") for alias in aliases: print("setup.py alias", format_alias(alias, aliases)) return elif len(self.args) == 1: alias, = self.args if self.remove: command = None elif alias in aliases: print("setup.py alias", format_alias(alias, aliases)) return else: print("No alias definition found for %r" % alias) return else: alias = self.args[0] command = ' '.join(map(shquote, self.args[1:])) edit_config(self.filename, {'aliases': {alias: command}}, self.dry_run) def format_alias(name, aliases): source, command = aliases[name] if source == config_file('global'): source = '--global-config ' elif source == config_file('user'): source = '--user-config ' elif source == config_file('local'): source = '' else: source = '--filename=%r' % source return source + name + ' ' + command PKH]. n5python3.10/site-packages/setuptools/command/setopt.pynu[from distutils.util import convert_path from distutils import log from distutils.errors import DistutilsOptionError import distutils import os import configparser from setuptools import Command __all__ = ['config_file', 'edit_config', 'option_base', 'setopt'] def config_file(kind="local"): """Get the filename of the distutils, local, global, or per-user config `kind` must be one of "local", "global", or "user" """ if kind == 'local': return 'setup.cfg' if kind == 'global': return os.path.join( os.path.dirname(distutils.__file__), 'distutils.cfg' ) if kind == 'user': dot = os.name == 'posix' and '.' or '' return os.path.expanduser(convert_path("~/%spydistutils.cfg" % dot)) raise ValueError( "config_file() type must be 'local', 'global', or 'user'", kind ) def edit_config(filename, settings, dry_run=False): """Edit a configuration file to include `settings` `settings` is a dictionary of dictionaries or ``None`` values, keyed by command/section name. A ``None`` value means to delete the entire section, while a dictionary lists settings to be changed or deleted in that section. A setting of ``None`` means to delete that setting. """ log.debug("Reading configuration from %s", filename) opts = configparser.RawConfigParser() opts.optionxform = lambda x: x opts.read([filename]) for section, options in settings.items(): if options is None: log.info("Deleting section [%s] from %s", section, filename) opts.remove_section(section) else: if not opts.has_section(section): log.debug("Adding new section [%s] to %s", section, filename) opts.add_section(section) for option, value in options.items(): if value is None: log.debug( "Deleting %s.%s from %s", section, option, filename ) opts.remove_option(section, option) if not opts.options(section): log.info("Deleting empty [%s] section from %s", section, filename) opts.remove_section(section) else: log.debug( "Setting %s.%s to %r in %s", section, option, value, filename ) opts.set(section, option, value) log.info("Writing %s", filename) if not dry_run: with open(filename, 'w') as f: opts.write(f) class option_base(Command): """Abstract base class for commands that mess with config files""" user_options = [ ('global-config', 'g', "save options to the site-wide distutils.cfg file"), ('user-config', 'u', "save options to the current user's pydistutils.cfg file"), ('filename=', 'f', "configuration file to use (default=setup.cfg)"), ] boolean_options = [ 'global-config', 'user-config', ] def initialize_options(self): self.global_config = None self.user_config = None self.filename = None def finalize_options(self): filenames = [] if self.global_config: filenames.append(config_file('global')) if self.user_config: filenames.append(config_file('user')) if self.filename is not None: filenames.append(self.filename) if not filenames: filenames.append(config_file('local')) if len(filenames) > 1: raise DistutilsOptionError( "Must specify only one configuration file option", filenames ) self.filename, = filenames class setopt(option_base): """Save command-line options to a file""" description = "set an option in setup.cfg or another config file" user_options = [ ('command=', 'c', 'command to set an option for'), ('option=', 'o', 'option to set'), ('set-value=', 's', 'value of the option'), ('remove', 'r', 'remove (unset) the value'), ] + option_base.user_options boolean_options = option_base.boolean_options + ['remove'] def initialize_options(self): option_base.initialize_options(self) self.command = None self.option = None self.set_value = None self.remove = None def finalize_options(self): option_base.finalize_options(self) if self.command is None or self.option is None: raise DistutilsOptionError("Must specify --command *and* --option") if self.set_value is None and not self.remove: raise DistutilsOptionError("Must specify --set-value or --remove") def run(self): edit_config( self.filename, { self.command: {self.option.replace('-', '_'): self.set_value} }, self.dry_run ) PKH]m22:python3.10/site-packages/setuptools/command/upload_docs.pynu[# -*- coding: utf-8 -*- """upload_docs Implements a Distutils 'upload_docs' subcommand (upload documentation to sites other than PyPi such as devpi). """ from base64 import standard_b64encode from distutils import log from distutils.errors import DistutilsOptionError import os import socket import zipfile import tempfile import shutil import itertools import functools import http.client import urllib.parse from pkg_resources import iter_entry_points from .upload import upload def _encode(s): return s.encode('utf-8', 'surrogateescape') class upload_docs(upload): # override the default repository as upload_docs isn't # supported by Warehouse (and won't be). DEFAULT_REPOSITORY = 'https://pypi.python.org/pypi/' description = 'Upload documentation to sites other than PyPi such as devpi' user_options = [ ('repository=', 'r', "url of repository [default: %s]" % upload.DEFAULT_REPOSITORY), ('show-response', None, 'display full response text from server'), ('upload-dir=', None, 'directory to upload'), ] boolean_options = upload.boolean_options def has_sphinx(self): if self.upload_dir is None: for ep in iter_entry_points('distutils.commands', 'build_sphinx'): return True sub_commands = [('build_sphinx', has_sphinx)] def initialize_options(self): upload.initialize_options(self) self.upload_dir = None self.target_dir = None def finalize_options(self): upload.finalize_options(self) if self.upload_dir is None: if self.has_sphinx(): build_sphinx = self.get_finalized_command('build_sphinx') self.target_dir = dict(build_sphinx.builder_target_dirs)['html'] else: build = self.get_finalized_command('build') self.target_dir = os.path.join(build.build_base, 'docs') else: self.ensure_dirname('upload_dir') self.target_dir = self.upload_dir if 'pypi.python.org' in self.repository: log.warn("Upload_docs command is deprecated for PyPi. Use RTD instead.") self.announce('Using upload directory %s' % self.target_dir) def create_zipfile(self, filename): zip_file = zipfile.ZipFile(filename, "w") try: self.mkpath(self.target_dir) # just in case for root, dirs, files in os.walk(self.target_dir): if root == self.target_dir and not files: tmpl = "no files found in upload directory '%s'" raise DistutilsOptionError(tmpl % self.target_dir) for name in files: full = os.path.join(root, name) relative = root[len(self.target_dir):].lstrip(os.path.sep) dest = os.path.join(relative, name) zip_file.write(full, dest) finally: zip_file.close() def run(self): # Run sub commands for cmd_name in self.get_sub_commands(): self.run_command(cmd_name) tmp_dir = tempfile.mkdtemp() name = self.distribution.metadata.get_name() zip_file = os.path.join(tmp_dir, "%s.zip" % name) try: self.create_zipfile(zip_file) self.upload_file(zip_file) finally: shutil.rmtree(tmp_dir) @staticmethod def _build_part(item, sep_boundary): key, values = item title = '\nContent-Disposition: form-data; name="%s"' % key # handle multiple entries for the same name if not isinstance(values, list): values = [values] for value in values: if isinstance(value, tuple): title += '; filename="%s"' % value[0] value = value[1] else: value = _encode(value) yield sep_boundary yield _encode(title) yield b"\n\n" yield value if value and value[-1:] == b'\r': yield b'\n' # write an extra newline (lurve Macs) @classmethod def _build_multipart(cls, data): """ Build up the MIME payload for the POST data """ boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = b'\n--' + boundary.encode('ascii') end_boundary = sep_boundary + b'--' end_items = end_boundary, b"\n", builder = functools.partial( cls._build_part, sep_boundary=sep_boundary, ) part_groups = map(builder, data.items()) parts = itertools.chain.from_iterable(part_groups) body_items = itertools.chain(parts, end_items) content_type = 'multipart/form-data; boundary=%s' % boundary return b''.join(body_items), content_type def upload_file(self, filename): with open(filename, 'rb') as f: content = f.read() meta = self.distribution.metadata data = { ':action': 'doc_upload', 'name': meta.get_name(), 'content': (os.path.basename(filename), content), } # set up the authentication credentials = _encode(self.username + ':' + self.password) credentials = standard_b64encode(credentials).decode('ascii') auth = "Basic " + credentials body, ct = self._build_multipart(data) msg = "Submitting documentation to %s" % (self.repository) self.announce(msg, log.INFO) # build the Request # We can't use urllib2 since we need to send the Basic # auth right with the first request schema, netloc, url, params, query, fragments = \ urllib.parse.urlparse(self.repository) assert not params and not query and not fragments if schema == 'http': conn = http.client.HTTPConnection(netloc) elif schema == 'https': conn = http.client.HTTPSConnection(netloc) else: raise AssertionError("unsupported schema " + schema) data = '' try: conn.connect() conn.putrequest("POST", url) content_type = ct conn.putheader('Content-type', content_type) conn.putheader('Content-length', str(len(body))) conn.putheader('Authorization', auth) conn.endheaders() conn.send(body) except socket.error as e: self.announce(str(e), log.ERROR) return r = conn.getresponse() if r.status == 200: msg = 'Server response (%s): %s' % (r.status, r.reason) self.announce(msg, log.INFO) elif r.status == 301: location = r.getheader('Location') if location is None: location = 'https://pythonhosted.org/%s/' % meta.get_name() msg = 'Upload successful. Visit %s' % location self.announce(msg, log.INFO) else: msg = 'Upload failed (%s): %s' % (r.status, r.reason) self.announce(msg, log.ERROR) if self.show_response: print('-' * 75, r.read(), '-' * 75) PKH]47python3.10/site-packages/setuptools/command/saveopts.pynu[from setuptools.command.setopt import edit_config, option_base class saveopts(option_base): """Save command-line options to a file""" description = "save supplied options to setup.cfg or other config file" def run(self): dist = self.distribution settings = {} for cmd in dist.command_options: if cmd == 'saveopts': continue # don't save our own options! for opt, (src, val) in dist.get_option_dict(cmd).items(): if src == "command line": settings.setdefault(cmd, {})[opt] = val edit_config(self.filename, settings, self.dry_run) PKH]R/7python3.10/site-packages/setuptools/command/__init__.pynu[from distutils.command.bdist import bdist import sys if 'egg' not in bdist.format_commands: bdist.format_command['egg'] = ('bdist_egg', "Python .egg file") bdist.format_commands.append('egg') del bdist, sys PKH]vbb7python3.10/site-packages/setuptools/command/egg_info.pynu["""setuptools.command.egg_info Create a distribution's .egg-info directory and contents""" from distutils.filelist import FileList as _FileList from distutils.errors import DistutilsInternalError from distutils.util import convert_path from distutils import log import distutils.errors import distutils.filelist import functools import os import re import sys import io import warnings import time import collections from setuptools import Command from setuptools.command.sdist import sdist from setuptools.command.sdist import walk_revctrl from setuptools.command.setopt import edit_config from setuptools.command import bdist_egg from pkg_resources import ( parse_requirements, safe_name, parse_version, safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename) import setuptools.unicode_utils as unicode_utils from setuptools.glob import glob from setuptools.extern import packaging from setuptools import SetuptoolsDeprecationWarning def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME """ Translate a file path glob like '*.txt' in to a regular expression. This differs from fnmatch.translate which allows wildcards to match directory separators. It also knows about '**/' which matches any number of directories. """ pat = '' # This will split on '/' within [character classes]. This is deliberate. chunks = glob.split(os.path.sep) sep = re.escape(os.sep) valid_char = '[^%s]' % (sep,) for c, chunk in enumerate(chunks): last_chunk = c == len(chunks) - 1 # Chunks that are a literal ** are globstars. They match anything. if chunk == '**': if last_chunk: # Match anything if this is the last component pat += '.*' else: # Match '(name/)*' pat += '(?:%s+%s)*' % (valid_char, sep) continue # Break here as the whole path component has been handled # Find any special characters in the remainder i = 0 chunk_len = len(chunk) while i < chunk_len: char = chunk[i] if char == '*': # Match any number of name characters pat += valid_char + '*' elif char == '?': # Match a name character pat += valid_char elif char == '[': # Character class inner_i = i + 1 # Skip initial !/] chars if inner_i < chunk_len and chunk[inner_i] == '!': inner_i = inner_i + 1 if inner_i < chunk_len and chunk[inner_i] == ']': inner_i = inner_i + 1 # Loop till the closing ] is found while inner_i < chunk_len and chunk[inner_i] != ']': inner_i = inner_i + 1 if inner_i >= chunk_len: # Got to the end of the string without finding a closing ] # Do not treat this as a matching group, but as a literal [ pat += re.escape(char) else: # Grab the insides of the [brackets] inner = chunk[i + 1:inner_i] char_class = '' # Class negation if inner[0] == '!': char_class = '^' inner = inner[1:] char_class += re.escape(inner) pat += '[%s]' % (char_class,) # Skip to the end ] i = inner_i else: pat += re.escape(char) i += 1 # Join each chunk with the dir separator if not last_chunk: pat += sep pat += r'\Z' return re.compile(pat, flags=re.MULTILINE | re.DOTALL) class InfoCommon: tag_build = None tag_date = None @property def name(self): return safe_name(self.distribution.get_name()) def tagged_version(self): return safe_version(self._maybe_tag(self.distribution.get_version())) def _maybe_tag(self, version): """ egg_info may be called more than once for a distribution, in which case the version string already contains all tags. """ return ( version if self.vtags and version.endswith(self.vtags) else version + self.vtags ) def tags(self): version = '' if self.tag_build: version += self.tag_build if self.tag_date: version += time.strftime("-%Y%m%d") return version vtags = property(tags) class egg_info(InfoCommon, Command): description = "create a distribution's .egg-info directory" user_options = [ ('egg-base=', 'e', "directory containing .egg-info directories" " (default: top of the source tree)"), ('tag-date', 'd', "Add date stamp (e.g. 20050528) to version number"), ('tag-build=', 'b', "Specify explicit tag to add to version number"), ('no-date', 'D', "Don't include date stamp [default]"), ] boolean_options = ['tag-date'] negative_opt = { 'no-date': 'tag-date', } def initialize_options(self): self.egg_base = None self.egg_name = None self.egg_info = None self.egg_version = None self.broken_egg_info = False #################################### # allow the 'tag_svn_revision' to be detected and # set, supporting sdists built on older Setuptools. @property def tag_svn_revision(self): pass @tag_svn_revision.setter def tag_svn_revision(self, value): pass #################################### def save_version_info(self, filename): """ Materialize the value of date into the build tag. Install build keys in a deterministic order to avoid arbitrary reordering on subsequent builds. """ egg_info = collections.OrderedDict() # follow the order these keys would have been added # when PYTHONHASHSEED=0 egg_info['tag_build'] = self.tags() egg_info['tag_date'] = 0 edit_config(filename, dict(egg_info=egg_info)) def finalize_options(self): # Note: we need to capture the current value returned # by `self.tagged_version()`, so we can later update # `self.distribution.metadata.version` without # repercussions. self.egg_name = self.name self.egg_version = self.tagged_version() parsed_version = parse_version(self.egg_version) try: is_version = isinstance(parsed_version, packaging.version.Version) spec = ( "%s==%s" if is_version else "%s===%s" ) list( parse_requirements(spec % (self.egg_name, self.egg_version)) ) except ValueError as e: raise distutils.errors.DistutilsOptionError( "Invalid distribution name or version syntax: %s-%s" % (self.egg_name, self.egg_version) ) from e if self.egg_base is None: dirs = self.distribution.package_dir self.egg_base = (dirs or {}).get('', os.curdir) self.ensure_dirname('egg_base') self.egg_info = to_filename(self.egg_name) + '.egg-info' if self.egg_base != os.curdir: self.egg_info = os.path.join(self.egg_base, self.egg_info) if '-' in self.egg_name: self.check_broken_egg_info() # Set package version for the benefit of dumber commands # (e.g. sdist, bdist_wininst, etc.) # self.distribution.metadata.version = self.egg_version # If we bootstrapped around the lack of a PKG-INFO, as might be the # case in a fresh checkout, make sure that any special tags get added # to the version info # pd = self.distribution._patched_dist if pd is not None and pd.key == self.egg_name.lower(): pd._version = self.egg_version pd._parsed_version = parse_version(self.egg_version) self.distribution._patched_dist = None def write_or_delete_file(self, what, filename, data, force=False): """Write `data` to `filename` or delete if empty If `data` is non-empty, this routine is the same as ``write_file()``. If `data` is empty but not ``None``, this is the same as calling ``delete_file(filename)`. If `data` is ``None``, then this is a no-op unless `filename` exists, in which case a warning is issued about the orphaned file (if `force` is false), or deleted (if `force` is true). """ if data: self.write_file(what, filename, data) elif os.path.exists(filename): if data is None and not force: log.warn( "%s not set in setup(), but %s exists", what, filename ) return else: self.delete_file(filename) def write_file(self, what, filename, data): """Write `data` to `filename` (if not a dry run) after announcing it `what` is used in a log message to identify what is being written to the file. """ log.info("writing %s to %s", what, filename) data = data.encode("utf-8") if not self.dry_run: f = open(filename, 'wb') f.write(data) f.close() def delete_file(self, filename): """Delete `filename` (if not a dry run) after announcing it""" log.info("deleting %s", filename) if not self.dry_run: os.unlink(filename) def run(self): self.mkpath(self.egg_info) os.utime(self.egg_info, None) installer = self.distribution.fetch_build_egg for ep in iter_entry_points('egg_info.writers'): ep.require(installer=installer) writer = ep.resolve() writer(self, ep.name, os.path.join(self.egg_info, ep.name)) # Get rid of native_libs.txt if it was put there by older bdist_egg nl = os.path.join(self.egg_info, "native_libs.txt") if os.path.exists(nl): self.delete_file(nl) self.find_sources() def find_sources(self): """Generate SOURCES.txt manifest file""" manifest_filename = os.path.join(self.egg_info, "SOURCES.txt") mm = manifest_maker(self.distribution) mm.manifest = manifest_filename mm.run() self.filelist = mm.filelist def check_broken_egg_info(self): bei = self.egg_name + '.egg-info' if self.egg_base != os.curdir: bei = os.path.join(self.egg_base, bei) if os.path.exists(bei): log.warn( "-" * 78 + '\n' "Note: Your current .egg-info directory has a '-' in its name;" '\nthis will not work correctly with "setup.py develop".\n\n' 'Please rename %s to %s to correct this problem.\n' + '-' * 78, bei, self.egg_info ) self.broken_egg_info = self.egg_info self.egg_info = bei # make it work for now class FileList(_FileList): # Implementations of the various MANIFEST.in commands def process_template_line(self, line): # Parse the line: split it up, make sure the right number of words # is there, and return the relevant words. 'action' is always # defined: it's the first word of the line. Which of the other # three are defined depends on the action; it'll be either # patterns, (dir and patterns), or (dir_pattern). (action, patterns, dir, dir_pattern) = self._parse_template_line(line) action_map = { 'include': self.include, 'exclude': self.exclude, 'global-include': self.global_include, 'global-exclude': self.global_exclude, 'recursive-include': functools.partial( self.recursive_include, dir, ), 'recursive-exclude': functools.partial( self.recursive_exclude, dir, ), 'graft': self.graft, 'prune': self.prune, } log_map = { 'include': "warning: no files found matching '%s'", 'exclude': ( "warning: no previously-included files found " "matching '%s'" ), 'global-include': ( "warning: no files found matching '%s' " "anywhere in distribution" ), 'global-exclude': ( "warning: no previously-included files matching " "'%s' found anywhere in distribution" ), 'recursive-include': ( "warning: no files found matching '%s' " "under directory '%s'" ), 'recursive-exclude': ( "warning: no previously-included files matching " "'%s' found under directory '%s'" ), 'graft': "warning: no directories found matching '%s'", 'prune': "no previously-included directories found matching '%s'", } try: process_action = action_map[action] except KeyError: raise DistutilsInternalError( "this cannot happen: invalid action '{action!s}'". format(action=action), ) # OK, now we know that the action is valid and we have the # right number of words on the line for that action -- so we # can proceed with minimal error-checking. action_is_recursive = action.startswith('recursive-') if action in {'graft', 'prune'}: patterns = [dir_pattern] extra_log_args = (dir, ) if action_is_recursive else () log_tmpl = log_map[action] self.debug_print( ' '.join( [action] + ([dir] if action_is_recursive else []) + patterns, ) ) for pattern in patterns: if not process_action(pattern): log.warn(log_tmpl, pattern, *extra_log_args) def _remove_files(self, predicate): """ Remove all files from the file list that match the predicate. Return True if any matching files were removed """ found = False for i in range(len(self.files) - 1, -1, -1): if predicate(self.files[i]): self.debug_print(" removing " + self.files[i]) del self.files[i] found = True return found def include(self, pattern): """Include files that match 'pattern'.""" found = [f for f in glob(pattern) if not os.path.isdir(f)] self.extend(found) return bool(found) def exclude(self, pattern): """Exclude files that match 'pattern'.""" match = translate_pattern(pattern) return self._remove_files(match.match) def recursive_include(self, dir, pattern): """ Include all files anywhere in 'dir/' that match the pattern. """ full_pattern = os.path.join(dir, '**', pattern) found = [f for f in glob(full_pattern, recursive=True) if not os.path.isdir(f)] self.extend(found) return bool(found) def recursive_exclude(self, dir, pattern): """ Exclude any file anywhere in 'dir/' that match the pattern. """ match = translate_pattern(os.path.join(dir, '**', pattern)) return self._remove_files(match.match) def graft(self, dir): """Include all files from 'dir/'.""" found = [ item for match_dir in glob(dir) for item in distutils.filelist.findall(match_dir) ] self.extend(found) return bool(found) def prune(self, dir): """Filter out files from 'dir/'.""" match = translate_pattern(os.path.join(dir, '**')) return self._remove_files(match.match) def global_include(self, pattern): """ Include all files anywhere in the current directory that match the pattern. This is very inefficient on large file trees. """ if self.allfiles is None: self.findall() match = translate_pattern(os.path.join('**', pattern)) found = [f for f in self.allfiles if match.match(f)] self.extend(found) return bool(found) def global_exclude(self, pattern): """ Exclude all files anywhere that match the pattern. """ match = translate_pattern(os.path.join('**', pattern)) return self._remove_files(match.match) def append(self, item): if item.endswith('\r'): # Fix older sdists built on Windows item = item[:-1] path = convert_path(item) if self._safe_path(path): self.files.append(path) def extend(self, paths): self.files.extend(filter(self._safe_path, paths)) def _repair(self): """ Replace self.files with only safe paths Because some owners of FileList manipulate the underlying ``files`` attribute directly, this method must be called to repair those paths. """ self.files = list(filter(self._safe_path, self.files)) def _safe_path(self, path): enc_warn = "'%s' not %s encodable -- skipping" # To avoid accidental trans-codings errors, first to unicode u_path = unicode_utils.filesys_decode(path) if u_path is None: log.warn("'%s' in unexpected encoding -- skipping" % path) return False # Must ensure utf-8 encodability utf8_path = unicode_utils.try_encode(u_path, "utf-8") if utf8_path is None: log.warn(enc_warn, path, 'utf-8') return False try: # accept is either way checks out if os.path.exists(u_path) or os.path.exists(utf8_path): return True # this will catch any encode errors decoding u_path except UnicodeEncodeError: log.warn(enc_warn, path, sys.getfilesystemencoding()) class manifest_maker(sdist): template = "MANIFEST.in" def initialize_options(self): self.use_defaults = 1 self.prune = 1 self.manifest_only = 1 self.force_manifest = 1 def finalize_options(self): pass def run(self): self.filelist = FileList() if not os.path.exists(self.manifest): self.write_manifest() # it must exist so it'll get in the list self.add_defaults() if os.path.exists(self.template): self.read_template() self.add_license_files() self.prune_file_list() self.filelist.sort() self.filelist.remove_duplicates() self.write_manifest() def _manifest_normalize(self, path): path = unicode_utils.filesys_decode(path) return path.replace(os.sep, '/') def write_manifest(self): """ Write the file list in 'self.filelist' to the manifest file named by 'self.manifest'. """ self.filelist._repair() # Now _repairs should encodability, but not unicode files = [self._manifest_normalize(f) for f in self.filelist.files] msg = "writing manifest file '%s'" % self.manifest self.execute(write_file, (self.manifest, files), msg) def warn(self, msg): if not self._should_suppress_warning(msg): sdist.warn(self, msg) @staticmethod def _should_suppress_warning(msg): """ suppress missing-file warnings from sdist """ return re.match(r"standard file .*not found", msg) def add_defaults(self): sdist.add_defaults(self) self.filelist.append(self.template) self.filelist.append(self.manifest) rcfiles = list(walk_revctrl()) if rcfiles: self.filelist.extend(rcfiles) elif os.path.exists(self.manifest): self.read_manifest() if os.path.exists("setup.py"): # setup.py should be included by default, even if it's not # the script called to create the sdist self.filelist.append("setup.py") ei_cmd = self.get_finalized_command('egg_info') self.filelist.graft(ei_cmd.egg_info) def add_license_files(self): license_files = self.distribution.metadata.license_files or [] for lf in license_files: log.info("adding license file '%s'", lf) pass self.filelist.extend(license_files) def prune_file_list(self): build = self.get_finalized_command('build') base_dir = self.distribution.get_fullname() self.filelist.prune(build.build_base) self.filelist.prune(base_dir) sep = re.escape(os.sep) self.filelist.exclude_pattern(r'(^|' + sep + r')(RCS|CVS|\.svn)' + sep, is_regex=1) def write_file(filename, contents): """Create a file with the specified name and write 'contents' (a sequence of strings without line terminators) to it. """ contents = "\n".join(contents) # assuming the contents has been vetted for utf-8 encoding contents = contents.encode("utf-8") with open(filename, "wb") as f: # always write POSIX-style manifest f.write(contents) def write_pkg_info(cmd, basename, filename): log.info("writing %s", filename) if not cmd.dry_run: metadata = cmd.distribution.metadata metadata.version, oldver = cmd.egg_version, metadata.version metadata.name, oldname = cmd.egg_name, metadata.name try: # write unescaped data to PKG-INFO, so older pkg_resources # can still parse it metadata.write_pkg_info(cmd.egg_info) finally: metadata.name, metadata.version = oldname, oldver safe = getattr(cmd.distribution, 'zip_safe', None) bdist_egg.write_safety_flag(cmd.egg_info, safe) def warn_depends_obsolete(cmd, basename, filename): if os.path.exists(filename): log.warn( "WARNING: 'depends.txt' is not used by setuptools 0.6!\n" "Use the install_requires/extras_require setup() args instead." ) def _write_requirements(stream, reqs): lines = yield_lines(reqs or ()) def append_cr(line): return line + '\n' lines = map(append_cr, lines) stream.writelines(lines) def write_requirements(cmd, basename, filename): dist = cmd.distribution data = io.StringIO() _write_requirements(data, dist.install_requires) extras_require = dist.extras_require or {} for extra in sorted(extras_require): data.write('\n[{extra}]\n'.format(**vars())) _write_requirements(data, extras_require[extra]) cmd.write_or_delete_file("requirements", filename, data.getvalue()) def write_setup_requirements(cmd, basename, filename): data = io.StringIO() _write_requirements(data, cmd.distribution.setup_requires) cmd.write_or_delete_file("setup-requirements", filename, data.getvalue()) def write_toplevel_names(cmd, basename, filename): pkgs = dict.fromkeys( [ k.split('.', 1)[0] for k in cmd.distribution.iter_distribution_names() ] ) cmd.write_file("top-level names", filename, '\n'.join(sorted(pkgs)) + '\n') def overwrite_arg(cmd, basename, filename): write_arg(cmd, basename, filename, True) def write_arg(cmd, basename, filename, force=False): argname = os.path.splitext(basename)[0] value = getattr(cmd.distribution, argname, None) if value is not None: value = '\n'.join(value) + '\n' cmd.write_or_delete_file(argname, filename, value, force) def write_entries(cmd, basename, filename): ep = cmd.distribution.entry_points if isinstance(ep, str) or ep is None: data = ep elif ep is not None: data = [] for section, contents in sorted(ep.items()): if not isinstance(contents, str): contents = EntryPoint.parse_group(section, contents) contents = '\n'.join(sorted(map(str, contents.values()))) data.append('[%s]\n%s\n\n' % (section, contents)) data = ''.join(data) cmd.write_or_delete_file('entry points', filename, data, True) def get_pkg_info_revision(): """ Get a -r### off of PKG-INFO Version in case this is an sdist of a subversion revision. """ warnings.warn( "get_pkg_info_revision is deprecated.", EggInfoDeprecationWarning) if os.path.exists('PKG-INFO'): with io.open('PKG-INFO') as f: for line in f: match = re.match(r"Version:.*-r(\d+)\s*$", line) if match: return int(match.group(1)) return 0 class EggInfoDeprecationWarning(SetuptoolsDeprecationWarning): """Deprecated behavior warning for EggInfo, bypassing suppression.""" PKH]!1??9python3.10/site-packages/setuptools/command/build_clib.pynu[import distutils.command.build_clib as orig from distutils.errors import DistutilsSetupError from distutils import log from setuptools.dep_util import newer_pairwise_group class build_clib(orig.build_clib): """ Override the default build_clib behaviour to do the following: 1. Implement a rudimentary timestamp-based dependency system so 'compile()' doesn't run every time. 2. Add more keys to the 'build_info' dictionary: * obj_deps - specify dependencies for each object compiled. this should be a dictionary mapping a key with the source filename to a list of dependencies. Use an empty string for global dependencies. * cflags - specify a list of additional flags to pass to the compiler. """ def build_libraries(self, libraries): for (lib_name, build_info) in libraries: sources = build_info.get('sources') if sources is None or not isinstance(sources, (list, tuple)): raise DistutilsSetupError( "in 'libraries' option (library '%s'), " "'sources' must be present and must be " "a list of source filenames" % lib_name) sources = list(sources) log.info("building '%s' library", lib_name) # Make sure everything is the correct type. # obj_deps should be a dictionary of keys as sources # and a list/tuple of files that are its dependencies. obj_deps = build_info.get('obj_deps', dict()) if not isinstance(obj_deps, dict): raise DistutilsSetupError( "in 'libraries' option (library '%s'), " "'obj_deps' must be a dictionary of " "type 'source: list'" % lib_name) dependencies = [] # Get the global dependencies that are specified by the '' key. # These will go into every source's dependency list. global_deps = obj_deps.get('', list()) if not isinstance(global_deps, (list, tuple)): raise DistutilsSetupError( "in 'libraries' option (library '%s'), " "'obj_deps' must be a dictionary of " "type 'source: list'" % lib_name) # Build the list to be used by newer_pairwise_group # each source will be auto-added to its dependencies. for source in sources: src_deps = [source] src_deps.extend(global_deps) extra_deps = obj_deps.get(source, list()) if not isinstance(extra_deps, (list, tuple)): raise DistutilsSetupError( "in 'libraries' option (library '%s'), " "'obj_deps' must be a dictionary of " "type 'source: list'" % lib_name) src_deps.extend(extra_deps) dependencies.append(src_deps) expected_objects = self.compiler.object_filenames( sources, output_dir=self.build_temp, ) if ( newer_pairwise_group(dependencies, expected_objects) != ([], []) ): # First, compile the source code to object files in the library # directory. (This should probably change to putting object # files in a temporary build directory.) macros = build_info.get('macros') include_dirs = build_info.get('include_dirs') cflags = build_info.get('cflags') self.compiler.compile( sources, output_dir=self.build_temp, macros=macros, include_dirs=include_dirs, extra_postargs=cflags, debug=self.debug ) # Now "link" the object files together into a static library. # (On Unix at least, this isn't really linking -- it just # builds an archive. Whatever.) self.compiler.create_static_lib( expected_objects, lib_name, output_dir=self.build_clib, debug=self.debug ) PKH]f;bb.python3.10/site-packages/setuptools/depends.pynu[import sys import marshal import contextlib import dis from distutils.version import StrictVersion from ._imp import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE from . import _imp __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' ] class Require: """A prerequisite to building or installing a distribution""" def __init__( self, name, requested_version, module, homepage='', attribute=None, format=None): if format is None and requested_version is not None: format = StrictVersion if format is not None: requested_version = format(requested_version) if attribute is None: attribute = '__version__' self.__dict__.update(locals()) del self.self def full_name(self): """Return full package/distribution name, w/version""" if self.requested_version is not None: return '%s-%s' % (self.name, self.requested_version) return self.name def version_ok(self, version): """Is 'version' sufficiently up-to-date?""" return self.attribute is None or self.format is None or \ str(version) != "unknown" and version >= self.requested_version def get_version(self, paths=None, default="unknown"): """Get version number of installed module, 'None', or 'default' Search 'paths' for module. If not found, return 'None'. If found, return the extracted version attribute, or 'default' if no version attribute was specified, or the value cannot be determined without importing the module. The version is formatted according to the requirement's version format (if any), unless it is 'None' or the supplied 'default'. """ if self.attribute is None: try: f, p, i = find_module(self.module, paths) if f: f.close() return default except ImportError: return None v = get_module_constant(self.module, self.attribute, default, paths) if v is not None and v is not default and self.format is not None: return self.format(v) return v def is_present(self, paths=None): """Return true if dependency is present on 'paths'""" return self.get_version(paths) is not None def is_current(self, paths=None): """Return true if dependency is present and up-to-date on 'paths'""" version = self.get_version(paths) if version is None: return False return self.version_ok(version) def maybe_close(f): @contextlib.contextmanager def empty(): yield return if not f: return empty() return contextlib.closing(f) def get_module_constant(module, symbol, default=-1, paths=None): """Find 'module' by searching 'paths', and extract 'symbol' Return 'None' if 'module' does not exist on 'paths', or it does not define 'symbol'. If the module defines 'symbol' as a constant, return the constant. Otherwise, return 'default'.""" try: f, path, (suffix, mode, kind) = info = find_module(module, paths) except ImportError: # Module doesn't exist return None with maybe_close(f): if kind == PY_COMPILED: f.read(8) # skip magic & date code = marshal.load(f) elif kind == PY_FROZEN: code = _imp.get_frozen_object(module, paths) elif kind == PY_SOURCE: code = compile(f.read(), path, 'exec') else: # Not something we can parse; we'll have to import it. :( imported = _imp.get_module(module, paths, info) return getattr(imported, symbol, None) return extract_constant(code, symbol, default) def extract_constant(code, symbol, default=-1): """Extract the constant value of 'symbol' from 'code' If the name 'symbol' is bound to a constant value by the Python code object 'code', return that value. If 'symbol' is bound to an expression, return 'default'. Otherwise, return 'None'. Return value is based on the first assignment to 'symbol'. 'symbol' must be a global, or at least a non-"fast" local in the code block. That is, only 'STORE_NAME' and 'STORE_GLOBAL' opcodes are checked, and 'symbol' must be present in 'code.co_names'. """ if symbol not in code.co_names: # name's not there, can't possibly be an assignment return None name_idx = list(code.co_names).index(symbol) STORE_NAME = 90 STORE_GLOBAL = 97 LOAD_CONST = 100 const = default for byte_code in dis.Bytecode(code): op = byte_code.opcode arg = byte_code.arg if op == LOAD_CONST: const = code.co_consts[arg] elif arg == name_idx and (op == STORE_NAME or op == STORE_GLOBAL): return const else: const = default def _update_globals(): """ Patch the globals to remove the objects not available on some platforms. XXX it'd be better to test assertions about bytecode instead. """ if not sys.platform.startswith('java') and sys.platform != 'cli': return incompatible = 'extract_constant', 'get_module_constant' for name in incompatible: del globals()[name] __all__.remove(name) _update_globals() PKH]5python3.10/site-packages/setuptools/script (dev).tmplnu[# EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r __requires__ = %(spec)r __import__('pkg_resources').require(%(spec)r) __file__ = %(dev_path)r with open(__file__) as f: exec(compile(f.read(), __file__, 'exec')) PKH]޷Y  +python3.10/site-packages/setuptools/glob.pynu[""" Filename globbing utility. Mostly a copy of `glob` from Python 3.5. Changes include: * `yield from` and PEP3102 `*` removed. * Hidden files are not ignored. """ import os import re import fnmatch __all__ = ["glob", "iglob", "escape"] def glob(pathname, recursive=False): """Return a list of paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la fnmatch. However, unlike fnmatch, filenames starting with a dot are special cases that are not matched by '*' and '?' patterns. If recursive is true, the pattern '**' will match any files and zero or more directories and subdirectories. """ return list(iglob(pathname, recursive=recursive)) def iglob(pathname, recursive=False): """Return an iterator which yields the paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la fnmatch. However, unlike fnmatch, filenames starting with a dot are special cases that are not matched by '*' and '?' patterns. If recursive is true, the pattern '**' will match any files and zero or more directories and subdirectories. """ it = _iglob(pathname, recursive) if recursive and _isrecursive(pathname): s = next(it) # skip empty string assert not s return it def _iglob(pathname, recursive): dirname, basename = os.path.split(pathname) glob_in_dir = glob2 if recursive and _isrecursive(basename) else glob1 if not has_magic(pathname): if basename: if os.path.lexists(pathname): yield pathname else: # Patterns ending with a slash should match only directories if os.path.isdir(dirname): yield pathname return if not dirname: yield from glob_in_dir(dirname, basename) return # `os.path.split()` returns the argument itself as a dirname if it is a # drive or UNC path. Prevent an infinite recursion if a drive or UNC path # contains magic characters (i.e. r'\\?\C:'). if dirname != pathname and has_magic(dirname): dirs = _iglob(dirname, recursive) else: dirs = [dirname] if not has_magic(basename): glob_in_dir = glob0 for dirname in dirs: for name in glob_in_dir(dirname, basename): yield os.path.join(dirname, name) # These 2 helper functions non-recursively glob inside a literal directory. # They return a list of basenames. `glob1` accepts a pattern while `glob0` # takes a literal basename (so it only has to check for its existence). def glob1(dirname, pattern): if not dirname: if isinstance(pattern, bytes): dirname = os.curdir.encode('ASCII') else: dirname = os.curdir try: names = os.listdir(dirname) except OSError: return [] return fnmatch.filter(names, pattern) def glob0(dirname, basename): if not basename: # `os.path.split()` returns an empty basename for paths ending with a # directory separator. 'q*x/' should match only directories. if os.path.isdir(dirname): return [basename] else: if os.path.lexists(os.path.join(dirname, basename)): return [basename] return [] # This helper function recursively yields relative pathnames inside a literal # directory. def glob2(dirname, pattern): assert _isrecursive(pattern) yield pattern[:0] for x in _rlistdir(dirname): yield x # Recursively yields relative pathnames inside a literal directory. def _rlistdir(dirname): if not dirname: if isinstance(dirname, bytes): dirname = os.curdir.encode('ASCII') else: dirname = os.curdir try: names = os.listdir(dirname) except os.error: return for x in names: yield x path = os.path.join(dirname, x) if dirname else x for y in _rlistdir(path): yield os.path.join(x, y) magic_check = re.compile('([*?[])') magic_check_bytes = re.compile(b'([*?[])') def has_magic(s): if isinstance(s, bytes): match = magic_check_bytes.search(s) else: match = magic_check.search(s) return match is not None def _isrecursive(pattern): if isinstance(pattern, bytes): return pattern == b'**' else: return pattern == '**' def escape(pathname): """Escape all special characters. """ # Escaping is done by wrapping any of "*?[" between square brackets. # Metacharacters do not work in the drive part and shouldn't be escaped. drive, pathname = os.path.splitdrive(pathname) if isinstance(pathname, bytes): pathname = magic_check_bytes.sub(br'[\1]', pathname) else: pathname = magic_check.sub(r'[\1]', pathname) return drive + pathname PKH] X X +python3.10/site-packages/setuptools/_imp.pynu[""" Re-implementation of find_module and get_frozen_object from the deprecated imp module. """ import os import importlib.util import importlib.machinery from .py34compat import module_from_spec PY_SOURCE = 1 PY_COMPILED = 2 C_EXTENSION = 3 C_BUILTIN = 6 PY_FROZEN = 7 def find_spec(module, paths): finder = ( importlib.machinery.PathFinder().find_spec if isinstance(paths, list) else importlib.util.find_spec ) return finder(module, paths) def find_module(module, paths=None): """Just like 'imp.find_module()', but with package support""" spec = find_spec(module, paths) if spec is None: raise ImportError("Can't find %s" % module) if not spec.has_location and hasattr(spec, 'submodule_search_locations'): spec = importlib.util.spec_from_loader('__init__.py', spec.loader) kind = -1 file = None static = isinstance(spec.loader, type) if spec.origin == 'frozen' or static and issubclass( spec.loader, importlib.machinery.FrozenImporter): kind = PY_FROZEN path = None # imp compabilty suffix = mode = '' # imp compatibility elif spec.origin == 'built-in' or static and issubclass( spec.loader, importlib.machinery.BuiltinImporter): kind = C_BUILTIN path = None # imp compabilty suffix = mode = '' # imp compatibility elif spec.has_location: path = spec.origin suffix = os.path.splitext(path)[1] mode = 'r' if suffix in importlib.machinery.SOURCE_SUFFIXES else 'rb' if suffix in importlib.machinery.SOURCE_SUFFIXES: kind = PY_SOURCE elif suffix in importlib.machinery.BYTECODE_SUFFIXES: kind = PY_COMPILED elif suffix in importlib.machinery.EXTENSION_SUFFIXES: kind = C_EXTENSION if kind in {PY_SOURCE, PY_COMPILED}: file = open(path, mode) else: path = None suffix = mode = '' return file, path, (suffix, mode, kind) def get_frozen_object(module, paths=None): spec = find_spec(module, paths) if not spec: raise ImportError("Can't find %s" % module) return spec.loader.get_code(module) def get_module(module, paths, info): spec = find_spec(module, paths) if not spec: raise ImportError("Can't find %s" % module) return module_from_spec(spec) PKH] 4` ` ,python3.10/site-packages/setuptools/wheel.pynu["""Wheels support.""" from distutils.util import get_platform from distutils import log import email import itertools import os import posixpath import re import zipfile import pkg_resources import setuptools from pkg_resources import parse_version from setuptools.extern.packaging.tags import sys_tags from setuptools.extern.packaging.utils import canonicalize_name from setuptools.command.egg_info import write_requirements WHEEL_NAME = re.compile( r"""^(?P.+?)-(?P\d.*?) ((-(?P\d.*?))?-(?P.+?)-(?P.+?)-(?P.+?) )\.whl$""", re.VERBOSE).match NAMESPACE_PACKAGE_INIT = \ "__import__('pkg_resources').declare_namespace(__name__)\n" def unpack(src_dir, dst_dir): '''Move everything under `src_dir` to `dst_dir`, and delete the former.''' for dirpath, dirnames, filenames in os.walk(src_dir): subdir = os.path.relpath(dirpath, src_dir) for f in filenames: src = os.path.join(dirpath, f) dst = os.path.join(dst_dir, subdir, f) os.renames(src, dst) for n, d in reversed(list(enumerate(dirnames))): src = os.path.join(dirpath, d) dst = os.path.join(dst_dir, subdir, d) if not os.path.exists(dst): # Directory does not exist in destination, # rename it and prune it from os.walk list. os.renames(src, dst) del dirnames[n] # Cleanup. for dirpath, dirnames, filenames in os.walk(src_dir, topdown=True): assert not filenames os.rmdir(dirpath) class Wheel: def __init__(self, filename): match = WHEEL_NAME(os.path.basename(filename)) if match is None: raise ValueError('invalid wheel name: %r' % filename) self.filename = filename for k, v in match.groupdict().items(): setattr(self, k, v) def tags(self): '''List tags (py_version, abi, platform) supported by this wheel.''' return itertools.product( self.py_version.split('.'), self.abi.split('.'), self.platform.split('.'), ) def is_compatible(self): '''Is the wheel is compatible with the current platform?''' supported_tags = set( (t.interpreter, t.abi, t.platform) for t in sys_tags()) return next((True for t in self.tags() if t in supported_tags), False) def egg_name(self): return pkg_resources.Distribution( project_name=self.project_name, version=self.version, platform=(None if self.platform == 'any' else get_platform()), ).egg_name() + '.egg' def get_dist_info(self, zf): # find the correct name of the .dist-info dir in the wheel file for member in zf.namelist(): dirname = posixpath.dirname(member) if (dirname.endswith('.dist-info') and canonicalize_name(dirname).startswith( canonicalize_name(self.project_name))): return dirname raise ValueError("unsupported wheel format. .dist-info not found") def install_as_egg(self, destination_eggdir): '''Install wheel as an egg directory.''' with zipfile.ZipFile(self.filename) as zf: self._install_as_egg(destination_eggdir, zf) def _install_as_egg(self, destination_eggdir, zf): dist_basename = '%s-%s' % (self.project_name, self.version) dist_info = self.get_dist_info(zf) dist_data = '%s.data' % dist_basename egg_info = os.path.join(destination_eggdir, 'EGG-INFO') self._convert_metadata(zf, destination_eggdir, dist_info, egg_info) self._move_data_entries(destination_eggdir, dist_data) self._fix_namespace_packages(egg_info, destination_eggdir) @staticmethod def _convert_metadata(zf, destination_eggdir, dist_info, egg_info): def get_metadata(name): with zf.open(posixpath.join(dist_info, name)) as fp: value = fp.read().decode('utf-8') return email.parser.Parser().parsestr(value) wheel_metadata = get_metadata('WHEEL') # Check wheel format version is supported. wheel_version = parse_version(wheel_metadata.get('Wheel-Version')) wheel_v1 = ( parse_version('1.0') <= wheel_version < parse_version('2.0dev0') ) if not wheel_v1: raise ValueError( 'unsupported wheel format version: %s' % wheel_version) # Extract to target directory. os.mkdir(destination_eggdir) zf.extractall(destination_eggdir) # Convert metadata. dist_info = os.path.join(destination_eggdir, dist_info) dist = pkg_resources.Distribution.from_location( destination_eggdir, dist_info, metadata=pkg_resources.PathMetadata(destination_eggdir, dist_info), ) # Note: Evaluate and strip markers now, # as it's difficult to convert back from the syntax: # foobar; "linux" in sys_platform and extra == 'test' def raw_req(req): req.marker = None return str(req) install_requires = list(sorted(map(raw_req, dist.requires()))) extras_require = { extra: sorted( req for req in map(raw_req, dist.requires((extra,))) if req not in install_requires ) for extra in dist.extras } os.rename(dist_info, egg_info) os.rename( os.path.join(egg_info, 'METADATA'), os.path.join(egg_info, 'PKG-INFO'), ) setup_dist = setuptools.Distribution( attrs=dict( install_requires=install_requires, extras_require=extras_require, ), ) # Temporarily disable info traces. log_threshold = log._global_log.threshold log.set_threshold(log.WARN) try: write_requirements( setup_dist.get_command_obj('egg_info'), None, os.path.join(egg_info, 'requires.txt'), ) finally: log.set_threshold(log_threshold) @staticmethod def _move_data_entries(destination_eggdir, dist_data): """Move data entries to their correct location.""" dist_data = os.path.join(destination_eggdir, dist_data) dist_data_scripts = os.path.join(dist_data, 'scripts') if os.path.exists(dist_data_scripts): egg_info_scripts = os.path.join( destination_eggdir, 'EGG-INFO', 'scripts') os.mkdir(egg_info_scripts) for entry in os.listdir(dist_data_scripts): # Remove bytecode, as it's not properly handled # during easy_install scripts install phase. if entry.endswith('.pyc'): os.unlink(os.path.join(dist_data_scripts, entry)) else: os.rename( os.path.join(dist_data_scripts, entry), os.path.join(egg_info_scripts, entry), ) os.rmdir(dist_data_scripts) for subdir in filter(os.path.exists, ( os.path.join(dist_data, d) for d in ('data', 'headers', 'purelib', 'platlib') )): unpack(subdir, destination_eggdir) if os.path.exists(dist_data): os.rmdir(dist_data) @staticmethod def _fix_namespace_packages(egg_info, destination_eggdir): namespace_packages = os.path.join( egg_info, 'namespace_packages.txt') if os.path.exists(namespace_packages): with open(namespace_packages) as fp: namespace_packages = fp.read().split() for mod in namespace_packages: mod_dir = os.path.join(destination_eggdir, *mod.split('.')) mod_init = os.path.join(mod_dir, '__init__.py') if not os.path.exists(mod_dir): os.mkdir(mod_dir) if not os.path.exists(mod_init): with open(mod_init, 'w') as fp: fp.write(NAMESPACE_PACKAGE_INIT) PKH] SB+python3.10/site-packages/setuptools/msvc.pynu[""" Improved support for Microsoft Visual C++ compilers. Known supported compilers: -------------------------- Microsoft Visual C++ 9.0: Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64) Microsoft Windows SDK 6.1 (x86, x64, ia64) Microsoft Windows SDK 7.0 (x86, x64, ia64) Microsoft Visual C++ 10.0: Microsoft Windows SDK 7.1 (x86, x64, ia64) Microsoft Visual C++ 14.X: Microsoft Visual C++ Build Tools 2015 (x86, x64, arm) Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64) Microsoft Visual Studio Build Tools 2019 (x86, x64, arm, arm64) This may also support compilers shipped with compatible Visual Studio versions. """ import json from io import open from os import listdir, pathsep from os.path import join, isfile, isdir, dirname import sys import contextlib import platform import itertools import subprocess import distutils.errors from setuptools.extern.packaging.version import LegacyVersion from setuptools.extern.more_itertools import unique_everseen from .monkey import get_unpatched if platform.system() == 'Windows': import winreg from os import environ else: # Mock winreg and environ so the module can be imported on this platform. class winreg: HKEY_USERS = None HKEY_CURRENT_USER = None HKEY_LOCAL_MACHINE = None HKEY_CLASSES_ROOT = None environ = dict() _msvc9_suppress_errors = ( # msvc9compiler isn't available on some platforms ImportError, # msvc9compiler raises DistutilsPlatformError in some # environments. See #1118. distutils.errors.DistutilsPlatformError, ) try: from distutils.msvc9compiler import Reg except _msvc9_suppress_errors: pass def msvc9_find_vcvarsall(version): """ Patched "distutils.msvc9compiler.find_vcvarsall" to use the standalone compiler build for Python (VCForPython / Microsoft Visual C++ Compiler for Python 2.7). Fall back to original behavior when the standalone compiler is not available. Redirect the path of "vcvarsall.bat". Parameters ---------- version: float Required Microsoft Visual C++ version. Return ------ str vcvarsall.bat path """ vc_base = r'Software\%sMicrosoft\DevDiv\VCForPython\%0.1f' key = vc_base % ('', version) try: # Per-user installs register the compiler path here productdir = Reg.get_value(key, "installdir") except KeyError: try: # All-user installs on a 64-bit system register here key = vc_base % ('Wow6432Node\\', version) productdir = Reg.get_value(key, "installdir") except KeyError: productdir = None if productdir: vcvarsall = join(productdir, "vcvarsall.bat") if isfile(vcvarsall): return vcvarsall return get_unpatched(msvc9_find_vcvarsall)(version) def msvc9_query_vcvarsall(ver, arch='x86', *args, **kwargs): """ Patched "distutils.msvc9compiler.query_vcvarsall" for support extra Microsoft Visual C++ 9.0 and 10.0 compilers. Set environment without use of "vcvarsall.bat". Parameters ---------- ver: float Required Microsoft Visual C++ version. arch: str Target architecture. Return ------ dict environment """ # Try to get environment from vcvarsall.bat (Classical way) try: orig = get_unpatched(msvc9_query_vcvarsall) return orig(ver, arch, *args, **kwargs) except distutils.errors.DistutilsPlatformError: # Pass error if Vcvarsall.bat is missing pass except ValueError: # Pass error if environment not set after executing vcvarsall.bat pass # If error, try to set environment directly try: return EnvironmentInfo(arch, ver).return_env() except distutils.errors.DistutilsPlatformError as exc: _augment_exception(exc, ver, arch) raise def _msvc14_find_vc2015(): """Python 3.8 "distutils/_msvccompiler.py" backport""" try: key = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, r"Software\Microsoft\VisualStudio\SxS\VC7", 0, winreg.KEY_READ | winreg.KEY_WOW64_32KEY ) except OSError: return None, None best_version = 0 best_dir = None with key: for i in itertools.count(): try: v, vc_dir, vt = winreg.EnumValue(key, i) except OSError: break if v and vt == winreg.REG_SZ and isdir(vc_dir): try: version = int(float(v)) except (ValueError, TypeError): continue if version >= 14 and version > best_version: best_version, best_dir = version, vc_dir return best_version, best_dir def _msvc14_find_vc2017(): """Python 3.8 "distutils/_msvccompiler.py" backport Returns "15, path" based on the result of invoking vswhere.exe If no install is found, returns "None, None" The version is returned to avoid unnecessarily changing the function result. It may be ignored when the path is not None. If vswhere.exe is not available, by definition, VS 2017 is not installed. """ root = environ.get("ProgramFiles(x86)") or environ.get("ProgramFiles") if not root: return None, None try: path = subprocess.check_output([ join(root, "Microsoft Visual Studio", "Installer", "vswhere.exe"), "-latest", "-prerelease", "-requiresAny", "-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", "-requires", "Microsoft.VisualStudio.Workload.WDExpress", "-property", "installationPath", "-products", "*", ]).decode(encoding="mbcs", errors="strict").strip() except (subprocess.CalledProcessError, OSError, UnicodeDecodeError): return None, None path = join(path, "VC", "Auxiliary", "Build") if isdir(path): return 15, path return None, None PLAT_SPEC_TO_RUNTIME = { 'x86': 'x86', 'x86_amd64': 'x64', 'x86_arm': 'arm', 'x86_arm64': 'arm64' } def _msvc14_find_vcvarsall(plat_spec): """Python 3.8 "distutils/_msvccompiler.py" backport""" _, best_dir = _msvc14_find_vc2017() vcruntime = None if plat_spec in PLAT_SPEC_TO_RUNTIME: vcruntime_plat = PLAT_SPEC_TO_RUNTIME[plat_spec] else: vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86' if best_dir: vcredist = join(best_dir, "..", "..", "redist", "MSVC", "**", vcruntime_plat, "Microsoft.VC14*.CRT", "vcruntime140.dll") try: import glob vcruntime = glob.glob(vcredist, recursive=True)[-1] except (ImportError, OSError, LookupError): vcruntime = None if not best_dir: best_version, best_dir = _msvc14_find_vc2015() if best_version: vcruntime = join(best_dir, 'redist', vcruntime_plat, "Microsoft.VC140.CRT", "vcruntime140.dll") if not best_dir: return None, None vcvarsall = join(best_dir, "vcvarsall.bat") if not isfile(vcvarsall): return None, None if not vcruntime or not isfile(vcruntime): vcruntime = None return vcvarsall, vcruntime def _msvc14_get_vc_env(plat_spec): """Python 3.8 "distutils/_msvccompiler.py" backport""" if "DISTUTILS_USE_SDK" in environ: return { key.lower(): value for key, value in environ.items() } vcvarsall, vcruntime = _msvc14_find_vcvarsall(plat_spec) if not vcvarsall: raise distutils.errors.DistutilsPlatformError( "Unable to find vcvarsall.bat" ) try: out = subprocess.check_output( 'cmd /u /c "{}" {} && set'.format(vcvarsall, plat_spec), stderr=subprocess.STDOUT, ).decode('utf-16le', errors='replace') except subprocess.CalledProcessError as exc: raise distutils.errors.DistutilsPlatformError( "Error executing {}".format(exc.cmd) ) from exc env = { key.lower(): value for key, _, value in (line.partition('=') for line in out.splitlines()) if key and value } if vcruntime: env['py_vcruntime_redist'] = vcruntime return env def msvc14_get_vc_env(plat_spec): """ Patched "distutils._msvccompiler._get_vc_env" for support extra Microsoft Visual C++ 14.X compilers. Set environment without use of "vcvarsall.bat". Parameters ---------- plat_spec: str Target architecture. Return ------ dict environment """ # Always use backport from CPython 3.8 try: return _msvc14_get_vc_env(plat_spec) except distutils.errors.DistutilsPlatformError as exc: _augment_exception(exc, 14.0) raise def msvc14_gen_lib_options(*args, **kwargs): """ Patched "distutils._msvccompiler.gen_lib_options" for fix compatibility between "numpy.distutils" and "distutils._msvccompiler" (for Numpy < 1.11.2) """ if "numpy.distutils" in sys.modules: import numpy as np if LegacyVersion(np.__version__) < LegacyVersion('1.11.2'): return np.distutils.ccompiler.gen_lib_options(*args, **kwargs) return get_unpatched(msvc14_gen_lib_options)(*args, **kwargs) def _augment_exception(exc, version, arch=''): """ Add details to the exception message to help guide the user as to what action will resolve it. """ # Error if MSVC++ directory not found or environment not set message = exc.args[0] if "vcvarsall" in message.lower() or "visual c" in message.lower(): # Special error message if MSVC++ not installed tmpl = 'Microsoft Visual C++ {version:0.1f} or greater is required.' message = tmpl.format(**locals()) msdownload = 'www.microsoft.com/download/details.aspx?id=%d' if version == 9.0: if arch.lower().find('ia64') > -1: # For VC++ 9.0, if IA64 support is needed, redirect user # to Windows SDK 7.0. # Note: No download link available from Microsoft. message += ' Get it with "Microsoft Windows SDK 7.0"' else: # For VC++ 9.0 redirect user to Vc++ for Python 2.7 : # This redirection link is maintained by Microsoft. # Contact vspython@microsoft.com if it needs updating. message += ' Get it from http://aka.ms/vcpython27' elif version == 10.0: # For VC++ 10.0 Redirect user to Windows SDK 7.1 message += ' Get it with "Microsoft Windows SDK 7.1": ' message += msdownload % 8279 elif version >= 14.0: # For VC++ 14.X Redirect user to latest Visual C++ Build Tools message += (' Get it with "Microsoft C++ Build Tools": ' r'https://visualstudio.microsoft.com' r'/visual-cpp-build-tools/') exc.args = (message, ) class PlatformInfo: """ Current and Target Architectures information. Parameters ---------- arch: str Target architecture. """ current_cpu = environ.get('processor_architecture', '').lower() def __init__(self, arch): self.arch = arch.lower().replace('x64', 'amd64') @property def target_cpu(self): """ Return Target CPU architecture. Return ------ str Target CPU """ return self.arch[self.arch.find('_') + 1:] def target_is_x86(self): """ Return True if target CPU is x86 32 bits.. Return ------ bool CPU is x86 32 bits """ return self.target_cpu == 'x86' def current_is_x86(self): """ Return True if current CPU is x86 32 bits.. Return ------ bool CPU is x86 32 bits """ return self.current_cpu == 'x86' def current_dir(self, hidex86=False, x64=False): """ Current platform specific subfolder. Parameters ---------- hidex86: bool return '' and not '\x86' if architecture is x86. x64: bool return '\x64' and not '\amd64' if architecture is amd64. Return ------ str subfolder: '\target', or '' (see hidex86 parameter) """ return ( '' if (self.current_cpu == 'x86' and hidex86) else r'\x64' if (self.current_cpu == 'amd64' and x64) else r'\%s' % self.current_cpu ) def target_dir(self, hidex86=False, x64=False): r""" Target platform specific subfolder. Parameters ---------- hidex86: bool return '' and not '\x86' if architecture is x86. x64: bool return '\x64' and not '\amd64' if architecture is amd64. Return ------ str subfolder: '\current', or '' (see hidex86 parameter) """ return ( '' if (self.target_cpu == 'x86' and hidex86) else r'\x64' if (self.target_cpu == 'amd64' and x64) else r'\%s' % self.target_cpu ) def cross_dir(self, forcex86=False): r""" Cross platform specific subfolder. Parameters ---------- forcex86: bool Use 'x86' as current architecture even if current architecture is not x86. Return ------ str subfolder: '' if target architecture is current architecture, '\current_target' if not. """ current = 'x86' if forcex86 else self.current_cpu return ( '' if self.target_cpu == current else self.target_dir().replace('\\', '\\%s_' % current) ) class RegistryInfo: """ Microsoft Visual Studio related registry information. Parameters ---------- platform_info: PlatformInfo "PlatformInfo" instance. """ HKEYS = (winreg.HKEY_USERS, winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CLASSES_ROOT) def __init__(self, platform_info): self.pi = platform_info @property def visualstudio(self): """ Microsoft Visual Studio root registry key. Return ------ str Registry key """ return 'VisualStudio' @property def sxs(self): """ Microsoft Visual Studio SxS registry key. Return ------ str Registry key """ return join(self.visualstudio, 'SxS') @property def vc(self): """ Microsoft Visual C++ VC7 registry key. Return ------ str Registry key """ return join(self.sxs, 'VC7') @property def vs(self): """ Microsoft Visual Studio VS7 registry key. Return ------ str Registry key """ return join(self.sxs, 'VS7') @property def vc_for_python(self): """ Microsoft Visual C++ for Python registry key. Return ------ str Registry key """ return r'DevDiv\VCForPython' @property def microsoft_sdk(self): """ Microsoft SDK registry key. Return ------ str Registry key """ return 'Microsoft SDKs' @property def windows_sdk(self): """ Microsoft Windows/Platform SDK registry key. Return ------ str Registry key """ return join(self.microsoft_sdk, 'Windows') @property def netfx_sdk(self): """ Microsoft .NET Framework SDK registry key. Return ------ str Registry key """ return join(self.microsoft_sdk, 'NETFXSDK') @property def windows_kits_roots(self): """ Microsoft Windows Kits Roots registry key. Return ------ str Registry key """ return r'Windows Kits\Installed Roots' def microsoft(self, key, x86=False): """ Return key in Microsoft software registry. Parameters ---------- key: str Registry key path where look. x86: str Force x86 software registry. Return ------ str Registry key """ node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node' return join('Software', node64, 'Microsoft', key) def lookup(self, key, name): """ Look for values in registry in Microsoft software registry. Parameters ---------- key: str Registry key path where look. name: str Value name to find. Return ------ str value """ key_read = winreg.KEY_READ openkey = winreg.OpenKey closekey = winreg.CloseKey ms = self.microsoft for hkey in self.HKEYS: bkey = None try: bkey = openkey(hkey, ms(key), 0, key_read) except (OSError, IOError): if not self.pi.current_is_x86(): try: bkey = openkey(hkey, ms(key, True), 0, key_read) except (OSError, IOError): continue else: continue try: return winreg.QueryValueEx(bkey, name)[0] except (OSError, IOError): pass finally: if bkey: closekey(bkey) class SystemInfo: """ Microsoft Windows and Visual Studio related system information. Parameters ---------- registry_info: RegistryInfo "RegistryInfo" instance. vc_ver: float Required Microsoft Visual C++ version. """ # Variables and properties in this class use originals CamelCase variables # names from Microsoft source files for more easy comparison. WinDir = environ.get('WinDir', '') ProgramFiles = environ.get('ProgramFiles', '') ProgramFilesx86 = environ.get('ProgramFiles(x86)', ProgramFiles) def __init__(self, registry_info, vc_ver=None): self.ri = registry_info self.pi = self.ri.pi self.known_vs_paths = self.find_programdata_vs_vers() # Except for VS15+, VC version is aligned with VS version self.vs_ver = self.vc_ver = ( vc_ver or self._find_latest_available_vs_ver()) def _find_latest_available_vs_ver(self): """ Find the latest VC version Return ------ float version """ reg_vc_vers = self.find_reg_vs_vers() if not (reg_vc_vers or self.known_vs_paths): raise distutils.errors.DistutilsPlatformError( 'No Microsoft Visual C++ version found') vc_vers = set(reg_vc_vers) vc_vers.update(self.known_vs_paths) return sorted(vc_vers)[-1] def find_reg_vs_vers(self): """ Find Microsoft Visual Studio versions available in registry. Return ------ list of float Versions """ ms = self.ri.microsoft vckeys = (self.ri.vc, self.ri.vc_for_python, self.ri.vs) vs_vers = [] for hkey, key in itertools.product(self.ri.HKEYS, vckeys): try: bkey = winreg.OpenKey(hkey, ms(key), 0, winreg.KEY_READ) except (OSError, IOError): continue with bkey: subkeys, values, _ = winreg.QueryInfoKey(bkey) for i in range(values): with contextlib.suppress(ValueError): ver = float(winreg.EnumValue(bkey, i)[0]) if ver not in vs_vers: vs_vers.append(ver) for i in range(subkeys): with contextlib.suppress(ValueError): ver = float(winreg.EnumKey(bkey, i)) if ver not in vs_vers: vs_vers.append(ver) return sorted(vs_vers) def find_programdata_vs_vers(self): r""" Find Visual studio 2017+ versions from information in "C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances". Return ------ dict float version as key, path as value. """ vs_versions = {} instances_dir = \ r'C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances' try: hashed_names = listdir(instances_dir) except (OSError, IOError): # Directory not exists with all Visual Studio versions return vs_versions for name in hashed_names: try: # Get VS installation path from "state.json" file state_path = join(instances_dir, name, 'state.json') with open(state_path, 'rt', encoding='utf-8') as state_file: state = json.load(state_file) vs_path = state['installationPath'] # Raises OSError if this VS installation does not contain VC listdir(join(vs_path, r'VC\Tools\MSVC')) # Store version and path vs_versions[self._as_float_version( state['installationVersion'])] = vs_path except (OSError, IOError, KeyError): # Skip if "state.json" file is missing or bad format continue return vs_versions @staticmethod def _as_float_version(version): """ Return a string version as a simplified float version (major.minor) Parameters ---------- version: str Version. Return ------ float version """ return float('.'.join(version.split('.')[:2])) @property def VSInstallDir(self): """ Microsoft Visual Studio directory. Return ------ str path """ # Default path default = join(self.ProgramFilesx86, 'Microsoft Visual Studio %0.1f' % self.vs_ver) # Try to get path from registry, if fail use default path return self.ri.lookup(self.ri.vs, '%0.1f' % self.vs_ver) or default @property def VCInstallDir(self): """ Microsoft Visual C++ directory. Return ------ str path """ path = self._guess_vc() or self._guess_vc_legacy() if not isdir(path): msg = 'Microsoft Visual C++ directory not found' raise distutils.errors.DistutilsPlatformError(msg) return path def _guess_vc(self): """ Locate Visual C++ for VS2017+. Return ------ str path """ if self.vs_ver <= 14.0: return '' try: # First search in known VS paths vs_dir = self.known_vs_paths[self.vs_ver] except KeyError: # Else, search with path from registry vs_dir = self.VSInstallDir guess_vc = join(vs_dir, r'VC\Tools\MSVC') # Subdir with VC exact version as name try: # Update the VC version with real one instead of VS version vc_ver = listdir(guess_vc)[-1] self.vc_ver = self._as_float_version(vc_ver) return join(guess_vc, vc_ver) except (OSError, IOError, IndexError): return '' def _guess_vc_legacy(self): """ Locate Visual C++ for versions prior to 2017. Return ------ str path """ default = join(self.ProgramFilesx86, r'Microsoft Visual Studio %0.1f\VC' % self.vs_ver) # Try to get "VC++ for Python" path from registry as default path reg_path = join(self.ri.vc_for_python, '%0.1f' % self.vs_ver) python_vc = self.ri.lookup(reg_path, 'installdir') default_vc = join(python_vc, 'VC') if python_vc else default # Try to get path from registry, if fail use default path return self.ri.lookup(self.ri.vc, '%0.1f' % self.vs_ver) or default_vc @property def WindowsSdkVersion(self): """ Microsoft Windows SDK versions for specified MSVC++ version. Return ------ tuple of str versions """ if self.vs_ver <= 9.0: return '7.0', '6.1', '6.0a' elif self.vs_ver == 10.0: return '7.1', '7.0a' elif self.vs_ver == 11.0: return '8.0', '8.0a' elif self.vs_ver == 12.0: return '8.1', '8.1a' elif self.vs_ver >= 14.0: return '10.0', '8.1' @property def WindowsSdkLastVersion(self): """ Microsoft Windows SDK last version. Return ------ str version """ return self._use_last_dir_name(join(self.WindowsSdkDir, 'lib')) @property # noqa: C901 def WindowsSdkDir(self): # noqa: C901 # is too complex (12) # FIXME """ Microsoft Windows SDK directory. Return ------ str path """ sdkdir = '' for ver in self.WindowsSdkVersion: # Try to get it from registry loc = join(self.ri.windows_sdk, 'v%s' % ver) sdkdir = self.ri.lookup(loc, 'installationfolder') if sdkdir: break if not sdkdir or not isdir(sdkdir): # Try to get "VC++ for Python" version from registry path = join(self.ri.vc_for_python, '%0.1f' % self.vc_ver) install_base = self.ri.lookup(path, 'installdir') if install_base: sdkdir = join(install_base, 'WinSDK') if not sdkdir or not isdir(sdkdir): # If fail, use default new path for ver in self.WindowsSdkVersion: intver = ver[:ver.rfind('.')] path = r'Microsoft SDKs\Windows Kits\%s' % intver d = join(self.ProgramFiles, path) if isdir(d): sdkdir = d if not sdkdir or not isdir(sdkdir): # If fail, use default old path for ver in self.WindowsSdkVersion: path = r'Microsoft SDKs\Windows\v%s' % ver d = join(self.ProgramFiles, path) if isdir(d): sdkdir = d if not sdkdir: # If fail, use Platform SDK sdkdir = join(self.VCInstallDir, 'PlatformSDK') return sdkdir @property def WindowsSDKExecutablePath(self): """ Microsoft Windows SDK executable directory. Return ------ str path """ # Find WinSDK NetFx Tools registry dir name if self.vs_ver <= 11.0: netfxver = 35 arch = '' else: netfxver = 40 hidex86 = True if self.vs_ver <= 12.0 else False arch = self.pi.current_dir(x64=True, hidex86=hidex86) fx = 'WinSDK-NetFx%dTools%s' % (netfxver, arch.replace('\\', '-')) # list all possibles registry paths regpaths = [] if self.vs_ver >= 14.0: for ver in self.NetFxSdkVersion: regpaths += [join(self.ri.netfx_sdk, ver, fx)] for ver in self.WindowsSdkVersion: regpaths += [join(self.ri.windows_sdk, 'v%sA' % ver, fx)] # Return installation folder from the more recent path for path in regpaths: execpath = self.ri.lookup(path, 'installationfolder') if execpath: return execpath @property def FSharpInstallDir(self): """ Microsoft Visual F# directory. Return ------ str path """ path = join(self.ri.visualstudio, r'%0.1f\Setup\F#' % self.vs_ver) return self.ri.lookup(path, 'productdir') or '' @property def UniversalCRTSdkDir(self): """ Microsoft Universal CRT SDK directory. Return ------ str path """ # Set Kit Roots versions for specified MSVC++ version vers = ('10', '81') if self.vs_ver >= 14.0 else () # Find path of the more recent Kit for ver in vers: sdkdir = self.ri.lookup(self.ri.windows_kits_roots, 'kitsroot%s' % ver) if sdkdir: return sdkdir or '' @property def UniversalCRTSdkLastVersion(self): """ Microsoft Universal C Runtime SDK last version. Return ------ str version """ return self._use_last_dir_name(join(self.UniversalCRTSdkDir, 'lib')) @property def NetFxSdkVersion(self): """ Microsoft .NET Framework SDK versions. Return ------ tuple of str versions """ # Set FxSdk versions for specified VS version return (('4.7.2', '4.7.1', '4.7', '4.6.2', '4.6.1', '4.6', '4.5.2', '4.5.1', '4.5') if self.vs_ver >= 14.0 else ()) @property def NetFxSdkDir(self): """ Microsoft .NET Framework SDK directory. Return ------ str path """ sdkdir = '' for ver in self.NetFxSdkVersion: loc = join(self.ri.netfx_sdk, ver) sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder') if sdkdir: break return sdkdir @property def FrameworkDir32(self): """ Microsoft .NET Framework 32bit directory. Return ------ str path """ # Default path guess_fw = join(self.WinDir, r'Microsoft.NET\Framework') # Try to get path from registry, if fail use default path return self.ri.lookup(self.ri.vc, 'frameworkdir32') or guess_fw @property def FrameworkDir64(self): """ Microsoft .NET Framework 64bit directory. Return ------ str path """ # Default path guess_fw = join(self.WinDir, r'Microsoft.NET\Framework64') # Try to get path from registry, if fail use default path return self.ri.lookup(self.ri.vc, 'frameworkdir64') or guess_fw @property def FrameworkVersion32(self): """ Microsoft .NET Framework 32bit versions. Return ------ tuple of str versions """ return self._find_dot_net_versions(32) @property def FrameworkVersion64(self): """ Microsoft .NET Framework 64bit versions. Return ------ tuple of str versions """ return self._find_dot_net_versions(64) def _find_dot_net_versions(self, bits): """ Find Microsoft .NET Framework versions. Parameters ---------- bits: int Platform number of bits: 32 or 64. Return ------ tuple of str versions """ # Find actual .NET version in registry reg_ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits) dot_net_dir = getattr(self, 'FrameworkDir%d' % bits) ver = reg_ver or self._use_last_dir_name(dot_net_dir, 'v') or '' # Set .NET versions for specified MSVC++ version if self.vs_ver >= 12.0: return ver, 'v4.0' elif self.vs_ver >= 10.0: return 'v4.0.30319' if ver.lower()[:2] != 'v4' else ver, 'v3.5' elif self.vs_ver == 9.0: return 'v3.5', 'v2.0.50727' elif self.vs_ver == 8.0: return 'v3.0', 'v2.0.50727' @staticmethod def _use_last_dir_name(path, prefix=''): """ Return name of the last dir in path or '' if no dir found. Parameters ---------- path: str Use dirs in this path prefix: str Use only dirs starting by this prefix Return ------ str name """ matching_dirs = ( dir_name for dir_name in reversed(listdir(path)) if isdir(join(path, dir_name)) and dir_name.startswith(prefix) ) return next(matching_dirs, None) or '' class EnvironmentInfo: """ Return environment variables for specified Microsoft Visual C++ version and platform : Lib, Include, Path and libpath. This function is compatible with Microsoft Visual C++ 9.0 to 14.X. Script created by analysing Microsoft environment configuration files like "vcvars[...].bat", "SetEnv.Cmd", "vcbuildtools.bat", ... Parameters ---------- arch: str Target architecture. vc_ver: float Required Microsoft Visual C++ version. If not set, autodetect the last version. vc_min_ver: float Minimum Microsoft Visual C++ version. """ # Variables and properties in this class use originals CamelCase variables # names from Microsoft source files for more easy comparison. def __init__(self, arch, vc_ver=None, vc_min_ver=0): self.pi = PlatformInfo(arch) self.ri = RegistryInfo(self.pi) self.si = SystemInfo(self.ri, vc_ver) if self.vc_ver < vc_min_ver: err = 'No suitable Microsoft Visual C++ version found' raise distutils.errors.DistutilsPlatformError(err) @property def vs_ver(self): """ Microsoft Visual Studio. Return ------ float version """ return self.si.vs_ver @property def vc_ver(self): """ Microsoft Visual C++ version. Return ------ float version """ return self.si.vc_ver @property def VSTools(self): """ Microsoft Visual Studio Tools. Return ------ list of str paths """ paths = [r'Common7\IDE', r'Common7\Tools'] if self.vs_ver >= 14.0: arch_subdir = self.pi.current_dir(hidex86=True, x64=True) paths += [r'Common7\IDE\CommonExtensions\Microsoft\TestWindow'] paths += [r'Team Tools\Performance Tools'] paths += [r'Team Tools\Performance Tools%s' % arch_subdir] return [join(self.si.VSInstallDir, path) for path in paths] @property def VCIncludes(self): """ Microsoft Visual C++ & Microsoft Foundation Class Includes. Return ------ list of str paths """ return [join(self.si.VCInstallDir, 'Include'), join(self.si.VCInstallDir, r'ATLMFC\Include')] @property def VCLibraries(self): """ Microsoft Visual C++ & Microsoft Foundation Class Libraries. Return ------ list of str paths """ if self.vs_ver >= 15.0: arch_subdir = self.pi.target_dir(x64=True) else: arch_subdir = self.pi.target_dir(hidex86=True) paths = ['Lib%s' % arch_subdir, r'ATLMFC\Lib%s' % arch_subdir] if self.vs_ver >= 14.0: paths += [r'Lib\store%s' % arch_subdir] return [join(self.si.VCInstallDir, path) for path in paths] @property def VCStoreRefs(self): """ Microsoft Visual C++ store references Libraries. Return ------ list of str paths """ if self.vs_ver < 14.0: return [] return [join(self.si.VCInstallDir, r'Lib\store\references')] @property def VCTools(self): """ Microsoft Visual C++ Tools. Return ------ list of str paths """ si = self.si tools = [join(si.VCInstallDir, 'VCPackages')] forcex86 = True if self.vs_ver <= 10.0 else False arch_subdir = self.pi.cross_dir(forcex86) if arch_subdir: tools += [join(si.VCInstallDir, 'Bin%s' % arch_subdir)] if self.vs_ver == 14.0: path = 'Bin%s' % self.pi.current_dir(hidex86=True) tools += [join(si.VCInstallDir, path)] elif self.vs_ver >= 15.0: host_dir = (r'bin\HostX86%s' if self.pi.current_is_x86() else r'bin\HostX64%s') tools += [join( si.VCInstallDir, host_dir % self.pi.target_dir(x64=True))] if self.pi.current_cpu != self.pi.target_cpu: tools += [join( si.VCInstallDir, host_dir % self.pi.current_dir(x64=True))] else: tools += [join(si.VCInstallDir, 'Bin')] return tools @property def OSLibraries(self): """ Microsoft Windows SDK Libraries. Return ------ list of str paths """ if self.vs_ver <= 10.0: arch_subdir = self.pi.target_dir(hidex86=True, x64=True) return [join(self.si.WindowsSdkDir, 'Lib%s' % arch_subdir)] else: arch_subdir = self.pi.target_dir(x64=True) lib = join(self.si.WindowsSdkDir, 'lib') libver = self._sdk_subdir return [join(lib, '%sum%s' % (libver, arch_subdir))] @property def OSIncludes(self): """ Microsoft Windows SDK Include. Return ------ list of str paths """ include = join(self.si.WindowsSdkDir, 'include') if self.vs_ver <= 10.0: return [include, join(include, 'gl')] else: if self.vs_ver >= 14.0: sdkver = self._sdk_subdir else: sdkver = '' return [join(include, '%sshared' % sdkver), join(include, '%sum' % sdkver), join(include, '%swinrt' % sdkver)] @property def OSLibpath(self): """ Microsoft Windows SDK Libraries Paths. Return ------ list of str paths """ ref = join(self.si.WindowsSdkDir, 'References') libpath = [] if self.vs_ver <= 9.0: libpath += self.OSLibraries if self.vs_ver >= 11.0: libpath += [join(ref, r'CommonConfiguration\Neutral')] if self.vs_ver >= 14.0: libpath += [ ref, join(self.si.WindowsSdkDir, 'UnionMetadata'), join( ref, 'Windows.Foundation.UniversalApiContract', '1.0.0.0'), join(ref, 'Windows.Foundation.FoundationContract', '1.0.0.0'), join( ref, 'Windows.Networking.Connectivity.WwanContract', '1.0.0.0'), join( self.si.WindowsSdkDir, 'ExtensionSDKs', 'Microsoft.VCLibs', '%0.1f' % self.vs_ver, 'References', 'CommonConfiguration', 'neutral'), ] return libpath @property def SdkTools(self): """ Microsoft Windows SDK Tools. Return ------ list of str paths """ return list(self._sdk_tools()) def _sdk_tools(self): """ Microsoft Windows SDK Tools paths generator. Return ------ generator of str paths """ if self.vs_ver < 15.0: bin_dir = 'Bin' if self.vs_ver <= 11.0 else r'Bin\x86' yield join(self.si.WindowsSdkDir, bin_dir) if not self.pi.current_is_x86(): arch_subdir = self.pi.current_dir(x64=True) path = 'Bin%s' % arch_subdir yield join(self.si.WindowsSdkDir, path) if self.vs_ver in (10.0, 11.0): if self.pi.target_is_x86(): arch_subdir = '' else: arch_subdir = self.pi.current_dir(hidex86=True, x64=True) path = r'Bin\NETFX 4.0 Tools%s' % arch_subdir yield join(self.si.WindowsSdkDir, path) elif self.vs_ver >= 15.0: path = join(self.si.WindowsSdkDir, 'Bin') arch_subdir = self.pi.current_dir(x64=True) sdkver = self.si.WindowsSdkLastVersion yield join(path, '%s%s' % (sdkver, arch_subdir)) if self.si.WindowsSDKExecutablePath: yield self.si.WindowsSDKExecutablePath @property def _sdk_subdir(self): """ Microsoft Windows SDK version subdir. Return ------ str subdir """ ucrtver = self.si.WindowsSdkLastVersion return ('%s\\' % ucrtver) if ucrtver else '' @property def SdkSetup(self): """ Microsoft Windows SDK Setup. Return ------ list of str paths """ if self.vs_ver > 9.0: return [] return [join(self.si.WindowsSdkDir, 'Setup')] @property def FxTools(self): """ Microsoft .NET Framework Tools. Return ------ list of str paths """ pi = self.pi si = self.si if self.vs_ver <= 10.0: include32 = True include64 = not pi.target_is_x86() and not pi.current_is_x86() else: include32 = pi.target_is_x86() or pi.current_is_x86() include64 = pi.current_cpu == 'amd64' or pi.target_cpu == 'amd64' tools = [] if include32: tools += [join(si.FrameworkDir32, ver) for ver in si.FrameworkVersion32] if include64: tools += [join(si.FrameworkDir64, ver) for ver in si.FrameworkVersion64] return tools @property def NetFxSDKLibraries(self): """ Microsoft .Net Framework SDK Libraries. Return ------ list of str paths """ if self.vs_ver < 14.0 or not self.si.NetFxSdkDir: return [] arch_subdir = self.pi.target_dir(x64=True) return [join(self.si.NetFxSdkDir, r'lib\um%s' % arch_subdir)] @property def NetFxSDKIncludes(self): """ Microsoft .Net Framework SDK Includes. Return ------ list of str paths """ if self.vs_ver < 14.0 or not self.si.NetFxSdkDir: return [] return [join(self.si.NetFxSdkDir, r'include\um')] @property def VsTDb(self): """ Microsoft Visual Studio Team System Database. Return ------ list of str paths """ return [join(self.si.VSInstallDir, r'VSTSDB\Deploy')] @property def MSBuild(self): """ Microsoft Build Engine. Return ------ list of str paths """ if self.vs_ver < 12.0: return [] elif self.vs_ver < 15.0: base_path = self.si.ProgramFilesx86 arch_subdir = self.pi.current_dir(hidex86=True) else: base_path = self.si.VSInstallDir arch_subdir = '' path = r'MSBuild\%0.1f\bin%s' % (self.vs_ver, arch_subdir) build = [join(base_path, path)] if self.vs_ver >= 15.0: # Add Roslyn C# & Visual Basic Compiler build += [join(base_path, path, 'Roslyn')] return build @property def HTMLHelpWorkshop(self): """ Microsoft HTML Help Workshop. Return ------ list of str paths """ if self.vs_ver < 11.0: return [] return [join(self.si.ProgramFilesx86, 'HTML Help Workshop')] @property def UCRTLibraries(self): """ Microsoft Universal C Runtime SDK Libraries. Return ------ list of str paths """ if self.vs_ver < 14.0: return [] arch_subdir = self.pi.target_dir(x64=True) lib = join(self.si.UniversalCRTSdkDir, 'lib') ucrtver = self._ucrt_subdir return [join(lib, '%sucrt%s' % (ucrtver, arch_subdir))] @property def UCRTIncludes(self): """ Microsoft Universal C Runtime SDK Include. Return ------ list of str paths """ if self.vs_ver < 14.0: return [] include = join(self.si.UniversalCRTSdkDir, 'include') return [join(include, '%sucrt' % self._ucrt_subdir)] @property def _ucrt_subdir(self): """ Microsoft Universal C Runtime SDK version subdir. Return ------ str subdir """ ucrtver = self.si.UniversalCRTSdkLastVersion return ('%s\\' % ucrtver) if ucrtver else '' @property def FSharp(self): """ Microsoft Visual F#. Return ------ list of str paths """ if 11.0 > self.vs_ver > 12.0: return [] return [self.si.FSharpInstallDir] @property def VCRuntimeRedist(self): """ Microsoft Visual C++ runtime redistributable dll. Return ------ str path """ vcruntime = 'vcruntime%d0.dll' % self.vc_ver arch_subdir = self.pi.target_dir(x64=True).strip('\\') # Installation prefixes candidates prefixes = [] tools_path = self.si.VCInstallDir redist_path = dirname(tools_path.replace(r'\Tools', r'\Redist')) if isdir(redist_path): # Redist version may not be exactly the same as tools redist_path = join(redist_path, listdir(redist_path)[-1]) prefixes += [redist_path, join(redist_path, 'onecore')] prefixes += [join(tools_path, 'redist')] # VS14 legacy path # CRT directory crt_dirs = ('Microsoft.VC%d.CRT' % (self.vc_ver * 10), # Sometime store in directory with VS version instead of VC 'Microsoft.VC%d.CRT' % (int(self.vs_ver) * 10)) # vcruntime path for prefix, crt_dir in itertools.product(prefixes, crt_dirs): path = join(prefix, arch_subdir, crt_dir, vcruntime) if isfile(path): return path def return_env(self, exists=True): """ Return environment dict. Parameters ---------- exists: bool It True, only return existing paths. Return ------ dict environment """ env = dict( include=self._build_paths('include', [self.VCIncludes, self.OSIncludes, self.UCRTIncludes, self.NetFxSDKIncludes], exists), lib=self._build_paths('lib', [self.VCLibraries, self.OSLibraries, self.FxTools, self.UCRTLibraries, self.NetFxSDKLibraries], exists), libpath=self._build_paths('libpath', [self.VCLibraries, self.FxTools, self.VCStoreRefs, self.OSLibpath], exists), path=self._build_paths('path', [self.VCTools, self.VSTools, self.VsTDb, self.SdkTools, self.SdkSetup, self.FxTools, self.MSBuild, self.HTMLHelpWorkshop, self.FSharp], exists), ) if self.vs_ver >= 14 and isfile(self.VCRuntimeRedist): env['py_vcruntime_redist'] = self.VCRuntimeRedist return env def _build_paths(self, name, spec_path_lists, exists): """ Given an environment variable name and specified paths, return a pathsep-separated string of paths containing unique, extant, directories from those paths and from the environment variable. Raise an error if no paths are resolved. Parameters ---------- name: str Environment variable name spec_path_lists: list of str Paths exists: bool It True, only return existing paths. Return ------ str Pathsep-separated paths """ # flatten spec_path_lists spec_paths = itertools.chain.from_iterable(spec_path_lists) env_paths = environ.get(name, '').split(pathsep) paths = itertools.chain(spec_paths, env_paths) extant_paths = list(filter(isdir, paths)) if exists else paths if not extant_paths: msg = "%s environment variable is empty" % name.upper() raise distutils.errors.DistutilsPlatformError(msg) unique_paths = unique_everseen(extant_paths) return pathsep.join(unique_paths) PKH]HLb.python3.10/site-packages/setuptools/version.pynu[import pkg_resources try: __version__ = pkg_resources.get_distribution('setuptools').version except Exception: __version__ = 'unknown' PKH]pm!  1python3.10/site-packages/setuptools/namespaces.pynu[import os from distutils import log import itertools flatten = itertools.chain.from_iterable class Installer: nspkg_ext = '-nspkg.pth' def install_namespaces(self): nsp = self._get_all_ns_packages() if not nsp: return filename, ext = os.path.splitext(self._get_target()) filename += self.nspkg_ext self.outputs.append(filename) log.info("Installing %s", filename) lines = map(self._gen_nspkg_line, nsp) if self.dry_run: # always generate the lines, even in dry run list(lines) return with open(filename, 'wt') as f: f.writelines(lines) def uninstall_namespaces(self): filename, ext = os.path.splitext(self._get_target()) filename += self.nspkg_ext if not os.path.exists(filename): return log.info("Removing %s", filename) os.remove(filename) def _get_target(self): return self.target _nspkg_tmpl = ( "import sys, types, os", "has_mfs = sys.version_info > (3, 5)", "p = os.path.join(%(root)s, *%(pth)r)", "importlib = has_mfs and __import__('importlib.util')", "has_mfs and __import__('importlib.machinery')", ( "m = has_mfs and " "sys.modules.setdefault(%(pkg)r, " "importlib.util.module_from_spec(" "importlib.machinery.PathFinder.find_spec(%(pkg)r, " "[os.path.dirname(p)])))" ), ( "m = m or " "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))" ), "mp = (m or []) and m.__dict__.setdefault('__path__',[])", "(p not in mp) and mp.append(p)", ) "lines for the namespace installer" _nspkg_tmpl_multi = ( 'm and setattr(sys.modules[%(parent)r], %(child)r, m)', ) "additional line(s) when a parent package is indicated" def _get_root(self): return "sys._getframe(1).f_locals['sitedir']" def _gen_nspkg_line(self, pkg): pth = tuple(pkg.split('.')) root = self._get_root() tmpl_lines = self._nspkg_tmpl parent, sep, child = pkg.rpartition('.') if parent: tmpl_lines += self._nspkg_tmpl_multi return ';'.join(tmpl_lines) % locals() + '\n' def _get_all_ns_packages(self): """Return sorted list of all package namespaces""" pkgs = self.distribution.namespace_packages or [] return sorted(flatten(map(self._pkg_names, pkgs))) @staticmethod def _pkg_names(pkg): """ Given a namespace package, yield the components of that package. >>> names = Installer._pkg_names('a.b.c') >>> set(names) == set(['a', 'a.b', 'a.b.c']) True """ parts = pkg.split('.') while parts: yield '.'.join(parts) parts.pop() class DevelopInstaller(Installer): def _get_root(self): return repr(str(self.egg_path)) def _get_target(self): return self.egg_link PKH]3/python3.10/site-packages/setuptools/script.tmplnu[# EASY-INSTALL-SCRIPT: %(spec)r,%(script_name)r __requires__ = %(spec)r __import__('pkg_resources').run_script(%(spec)r, %(script_name)r) PKH]n 8python3.10/site-packages/setuptools/_distutils/errors.pynu["""distutils.errors Provides exceptions used by the Distutils modules. Note that Distutils modules may raise standard exceptions; in particular, SystemExit is usually raised for errors that are obviously the end-user's fault (eg. bad command-line arguments). This module is safe to use in "from ... import *" mode; it only exports symbols whose names start with "Distutils" and end with "Error".""" class DistutilsError (Exception): """The root of all Distutils evil.""" pass class DistutilsModuleError (DistutilsError): """Unable to load an expected module, or to find an expected class within some module (in particular, command modules and classes).""" pass class DistutilsClassError (DistutilsError): """Some command class (or possibly distribution class, if anyone feels a need to subclass Distribution) is found not to be holding up its end of the bargain, ie. implementing some part of the "command "interface.""" pass class DistutilsGetoptError (DistutilsError): """The option table provided to 'fancy_getopt()' is bogus.""" pass class DistutilsArgError (DistutilsError): """Raised by fancy_getopt in response to getopt.error -- ie. an error in the command line usage.""" pass class DistutilsFileError (DistutilsError): """Any problems in the filesystem: expected file not found, etc. Typically this is for problems that we detect before OSError could be raised.""" pass class DistutilsOptionError (DistutilsError): """Syntactic/semantic errors in command options, such as use of mutually conflicting options, or inconsistent options, badly-spelled values, etc. No distinction is made between option values originating in the setup script, the command line, config files, or what-have-you -- but if we *know* something originated in the setup script, we'll raise DistutilsSetupError instead.""" pass class DistutilsSetupError (DistutilsError): """For errors that can be definitely blamed on the setup script, such as invalid keyword arguments to 'setup()'.""" pass class DistutilsPlatformError (DistutilsError): """We don't know how to do something on the current platform (but we do know how to do it on some platform) -- eg. trying to compile C files on a platform not supported by a CCompiler subclass.""" pass class DistutilsExecError (DistutilsError): """Any problems executing an external program (such as the C compiler, when compiling C files).""" pass class DistutilsInternalError (DistutilsError): """Internal inconsistencies or impossibilities (obviously, this should never be seen if the code is working!).""" pass class DistutilsTemplateError (DistutilsError): """Syntax error in a file list template.""" class DistutilsByteCompileError(DistutilsError): """Byte compile error.""" # Exception classes used by the CCompiler implementation classes class CCompilerError (Exception): """Some compile/link operation failed.""" class PreprocessError (CCompilerError): """Failure to preprocess one or more C/C++ files.""" class CompileError (CCompilerError): """Failure to compile one or more C/C++ source files.""" class LibError (CCompilerError): """Failure to create a static library from one or more C/C++ object files.""" class LinkError (CCompilerError): """Failure to link one or more C/C++ object files into an executable or shared library file.""" class UnknownFileError (CCompilerError): """Attempt to process an unknown file type.""" PKH]_H%7python3.10/site-packages/setuptools/_distutils/debug.pynu[import os # If DISTUTILS_DEBUG is anything other than the empty string, we run in # debug mode. DEBUG = os.environ.get('DISTUTILS_DEBUG') PKH]. A6python3.10/site-packages/setuptools/_distutils/dist.pynu["""distutils.dist Provides the Distribution class, which represents the module distribution being built/installed/distributed. """ import sys import os import re from email import message_from_file try: import warnings except ImportError: warnings = None from distutils.errors import * from distutils.fancy_getopt import FancyGetopt, translate_longopt from distutils.util import check_environ, strtobool, rfc822_escape from distutils import log from distutils.debug import DEBUG # Regex to define acceptable Distutils command names. This is not *quite* # the same as a Python NAME -- I don't allow leading underscores. The fact # that they're very similar is no coincidence; the default naming scheme is # to look for a Python module named after the command. command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$') def _ensure_list(value, fieldname): if isinstance(value, str): # a string containing comma separated values is okay. It will # be converted to a list by Distribution.finalize_options(). pass elif not isinstance(value, list): # passing a tuple or an iterator perhaps, warn and convert typename = type(value).__name__ msg = "Warning: '{fieldname}' should be a list, got type '{typename}'" msg = msg.format(**locals()) log.log(log.WARN, msg) value = list(value) return value class Distribution: """The core of the Distutils. Most of the work hiding behind 'setup' is really done within a Distribution instance, which farms the work out to the Distutils commands specified on the command line. Setup scripts will almost never instantiate Distribution directly, unless the 'setup()' function is totally inadequate to their needs. However, it is conceivable that a setup script might wish to subclass Distribution for some specialized purpose, and then pass the subclass to 'setup()' as the 'distclass' keyword argument. If so, it is necessary to respect the expectations that 'setup' has of Distribution. See the code for 'setup()', in core.py, for details. """ # 'global_options' describes the command-line options that may be # supplied to the setup script prior to any actual commands. # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of # these global options. This list should be kept to a bare minimum, # since every global option is also valid as a command option -- and we # don't want to pollute the commands with too many options that they # have minimal control over. # The fourth entry for verbose means that it can be repeated. global_options = [ ('verbose', 'v', "run verbosely (default)", 1), ('quiet', 'q', "run quietly (turns verbosity off)"), ('dry-run', 'n', "don't actually do anything"), ('help', 'h', "show detailed help message"), ('no-user-cfg', None, 'ignore pydistutils.cfg in your home directory'), ] # 'common_usage' is a short (2-3 line) string describing the common # usage of the setup script. common_usage = """\ Common commands: (see '--help-commands' for more) setup.py build will build the package underneath 'build/' setup.py install will install the package """ # options that are not propagated to the commands display_options = [ ('help-commands', None, "list all available commands"), ('name', None, "print package name"), ('version', 'V', "print package version"), ('fullname', None, "print -"), ('author', None, "print the author's name"), ('author-email', None, "print the author's email address"), ('maintainer', None, "print the maintainer's name"), ('maintainer-email', None, "print the maintainer's email address"), ('contact', None, "print the maintainer's name if known, else the author's"), ('contact-email', None, "print the maintainer's email address if known, else the author's"), ('url', None, "print the URL for this package"), ('license', None, "print the license of the package"), ('licence', None, "alias for --license"), ('description', None, "print the package description"), ('long-description', None, "print the long package description"), ('platforms', None, "print the list of platforms"), ('classifiers', None, "print the list of classifiers"), ('keywords', None, "print the list of keywords"), ('provides', None, "print the list of packages/modules provided"), ('requires', None, "print the list of packages/modules required"), ('obsoletes', None, "print the list of packages/modules made obsolete") ] display_option_names = [translate_longopt(x[0]) for x in display_options] # negative options are options that exclude other options negative_opt = {'quiet': 'verbose'} # -- Creation/initialization methods ------------------------------- def __init__(self, attrs=None): """Construct a new Distribution instance: initialize all the attributes of a Distribution, and then use 'attrs' (a dictionary mapping attribute names to values) to assign some of those attributes their "real" values. (Any attributes not mentioned in 'attrs' will be assigned to some null value: 0, None, an empty list or dictionary, etc.) Most importantly, initialize the 'command_obj' attribute to the empty dictionary; this will be filled in with real command objects by 'parse_command_line()'. """ # Default values for our command-line options self.verbose = 1 self.dry_run = 0 self.help = 0 for attr in self.display_option_names: setattr(self, attr, 0) # Store the distribution meta-data (name, version, author, and so # forth) in a separate object -- we're getting to have enough # information here (and enough command-line options) that it's # worth it. Also delegate 'get_XXX()' methods to the 'metadata' # object in a sneaky and underhanded (but efficient!) way. self.metadata = DistributionMetadata() for basename in self.metadata._METHOD_BASENAMES: method_name = "get_" + basename setattr(self, method_name, getattr(self.metadata, method_name)) # 'cmdclass' maps command names to class objects, so we # can 1) quickly figure out which class to instantiate when # we need to create a new command object, and 2) have a way # for the setup script to override command classes self.cmdclass = {} # 'command_packages' is a list of packages in which commands # are searched for. The factory for command 'foo' is expected # to be named 'foo' in the module 'foo' in one of the packages # named here. This list is searched from the left; an error # is raised if no named package provides the command being # searched for. (Always access using get_command_packages().) self.command_packages = None # 'script_name' and 'script_args' are usually set to sys.argv[0] # and sys.argv[1:], but they can be overridden when the caller is # not necessarily a setup script run from the command-line. self.script_name = None self.script_args = None # 'command_options' is where we store command options between # parsing them (from config files, the command-line, etc.) and when # they are actually needed -- ie. when the command in question is # instantiated. It is a dictionary of dictionaries of 2-tuples: # command_options = { command_name : { option : (source, value) } } self.command_options = {} # 'dist_files' is the list of (command, pyversion, file) that # have been created by any dist commands run so far. This is # filled regardless of whether the run is dry or not. pyversion # gives sysconfig.get_python_version() if the dist file is # specific to a Python version, 'any' if it is good for all # Python versions on the target platform, and '' for a source # file. pyversion should not be used to specify minimum or # maximum required Python versions; use the metainfo for that # instead. self.dist_files = [] # These options are really the business of various commands, rather # than of the Distribution itself. We provide aliases for them in # Distribution as a convenience to the developer. self.packages = None self.package_data = {} self.package_dir = None self.py_modules = None self.libraries = None self.headers = None self.ext_modules = None self.ext_package = None self.include_dirs = None self.extra_path = None self.scripts = None self.data_files = None self.password = '' # And now initialize bookkeeping stuff that can't be supplied by # the caller at all. 'command_obj' maps command names to # Command instances -- that's how we enforce that every command # class is a singleton. self.command_obj = {} # 'have_run' maps command names to boolean values; it keeps track # of whether we have actually run a particular command, to make it # cheap to "run" a command whenever we think we might need to -- if # it's already been done, no need for expensive filesystem # operations, we just check the 'have_run' dictionary and carry on. # It's only safe to query 'have_run' for a command class that has # been instantiated -- a false value will be inserted when the # command object is created, and replaced with a true value when # the command is successfully run. Thus it's probably best to use # '.get()' rather than a straight lookup. self.have_run = {} # Now we'll use the attrs dictionary (ultimately, keyword args from # the setup script) to possibly override any or all of these # distribution options. if attrs: # Pull out the set of command options and work on them # specifically. Note that this order guarantees that aliased # command options will override any supplied redundantly # through the general options dictionary. options = attrs.get('options') if options is not None: del attrs['options'] for (command, cmd_options) in options.items(): opt_dict = self.get_option_dict(command) for (opt, val) in cmd_options.items(): opt_dict[opt] = ("setup script", val) if 'licence' in attrs: attrs['license'] = attrs['licence'] del attrs['licence'] msg = "'licence' distribution option is deprecated; use 'license'" if warnings is not None: warnings.warn(msg) else: sys.stderr.write(msg + "\n") # Now work on the rest of the attributes. Any attribute that's # not already defined is invalid! for (key, val) in attrs.items(): if hasattr(self.metadata, "set_" + key): getattr(self.metadata, "set_" + key)(val) elif hasattr(self.metadata, key): setattr(self.metadata, key, val) elif hasattr(self, key): setattr(self, key, val) else: msg = "Unknown distribution option: %s" % repr(key) warnings.warn(msg) # no-user-cfg is handled before other command line args # because other args override the config files, and this # one is needed before we can load the config files. # If attrs['script_args'] wasn't passed, assume false. # # This also make sure we just look at the global options self.want_user_cfg = True if self.script_args is not None: for arg in self.script_args: if not arg.startswith('-'): break if arg == '--no-user-cfg': self.want_user_cfg = False break self.finalize_options() def get_option_dict(self, command): """Get the option dictionary for a given command. If that command's option dictionary hasn't been created yet, then create it and return the new dictionary; otherwise, return the existing option dictionary. """ dict = self.command_options.get(command) if dict is None: dict = self.command_options[command] = {} return dict def dump_option_dicts(self, header=None, commands=None, indent=""): from pprint import pformat if commands is None: # dump all command option dicts commands = sorted(self.command_options.keys()) if header is not None: self.announce(indent + header) indent = indent + " " if not commands: self.announce(indent + "no commands known yet") return for cmd_name in commands: opt_dict = self.command_options.get(cmd_name) if opt_dict is None: self.announce(indent + "no option dict for '%s' command" % cmd_name) else: self.announce(indent + "option dict for '%s' command:" % cmd_name) out = pformat(opt_dict) for line in out.split('\n'): self.announce(indent + " " + line) # -- Config file finding/parsing methods --------------------------- def find_config_files(self): """Find as many configuration files as should be processed for this platform, and return a list of filenames in the order in which they should be parsed. The filenames returned are guaranteed to exist (modulo nasty race conditions). There are three possible config files: distutils.cfg in the Distutils installation directory (ie. where the top-level Distutils __inst__.py file lives), a file in the user's home directory named .pydistutils.cfg on Unix and pydistutils.cfg on Windows/Mac; and setup.cfg in the current directory. The file in the user's home directory can be disabled with the --no-user-cfg option. """ files = [] check_environ() # Where to look for the system-wide Distutils config file sys_dir = os.path.dirname(sys.modules['distutils'].__file__) # Look for the system config file sys_file = os.path.join(sys_dir, "distutils.cfg") if os.path.isfile(sys_file): files.append(sys_file) # What to call the per-user config file if os.name == 'posix': user_filename = ".pydistutils.cfg" else: user_filename = "pydistutils.cfg" # And look for the user config file if self.want_user_cfg: user_file = os.path.join(os.path.expanduser('~'), user_filename) if os.path.isfile(user_file): files.append(user_file) # All platforms support local setup.cfg local_file = "setup.cfg" if os.path.isfile(local_file): files.append(local_file) if DEBUG: self.announce("using config files: %s" % ', '.join(files)) return files def parse_config_files(self, filenames=None): from configparser import ConfigParser # Ignore install directory options if we have a venv if sys.prefix != sys.base_prefix: ignore_options = [ 'install-base', 'install-platbase', 'install-lib', 'install-platlib', 'install-purelib', 'install-headers', 'install-scripts', 'install-data', 'prefix', 'exec-prefix', 'home', 'user', 'root'] else: ignore_options = [] ignore_options = frozenset(ignore_options) if filenames is None: filenames = self.find_config_files() if DEBUG: self.announce("Distribution.parse_config_files():") parser = ConfigParser() for filename in filenames: if DEBUG: self.announce(" reading %s" % filename) parser.read(filename) for section in parser.sections(): options = parser.options(section) opt_dict = self.get_option_dict(section) for opt in options: if opt != '__name__' and opt not in ignore_options: val = parser.get(section,opt) opt = opt.replace('-', '_') opt_dict[opt] = (filename, val) # Make the ConfigParser forget everything (so we retain # the original filenames that options come from) parser.__init__() # If there was a "global" section in the config file, use it # to set Distribution options. if 'global' in self.command_options: for (opt, (src, val)) in self.command_options['global'].items(): alias = self.negative_opt.get(opt) try: if alias: setattr(self, alias, not strtobool(val)) elif opt in ('verbose', 'dry_run'): # ugh! setattr(self, opt, strtobool(val)) else: setattr(self, opt, val) except ValueError as msg: raise DistutilsOptionError(msg) # -- Command-line parsing methods ---------------------------------- def parse_command_line(self): """Parse the setup script's command line, taken from the 'script_args' instance attribute (which defaults to 'sys.argv[1:]' -- see 'setup()' in core.py). This list is first processed for "global options" -- options that set attributes of the Distribution instance. Then, it is alternately scanned for Distutils commands and options for that command. Each new command terminates the options for the previous command. The allowed options for a command are determined by the 'user_options' attribute of the command class -- thus, we have to be able to load command classes in order to parse the command line. Any error in that 'options' attribute raises DistutilsGetoptError; any error on the command-line raises DistutilsArgError. If no Distutils commands were found on the command line, raises DistutilsArgError. Return true if command-line was successfully parsed and we should carry on with executing commands; false if no errors but we shouldn't execute commands (currently, this only happens if user asks for help). """ # # We now have enough information to show the Macintosh dialog # that allows the user to interactively specify the "command line". # toplevel_options = self._get_toplevel_options() # We have to parse the command line a bit at a time -- global # options, then the first command, then its options, and so on -- # because each command will be handled by a different class, and # the options that are valid for a particular class aren't known # until we have loaded the command class, which doesn't happen # until we know what the command is. self.commands = [] parser = FancyGetopt(toplevel_options + self.display_options) parser.set_negative_aliases(self.negative_opt) parser.set_aliases({'licence': 'license'}) args = parser.getopt(args=self.script_args, object=self) option_order = parser.get_option_order() log.set_verbosity(self.verbose) # for display options we return immediately if self.handle_display_options(option_order): return while args: args = self._parse_command_opts(parser, args) if args is None: # user asked for help (and got it) return # Handle the cases of --help as a "global" option, ie. # "setup.py --help" and "setup.py --help command ...". For the # former, we show global options (--verbose, --dry-run, etc.) # and display-only options (--name, --version, etc.); for the # latter, we omit the display-only options and show help for # each command listed on the command line. if self.help: self._show_help(parser, display_options=len(self.commands) == 0, commands=self.commands) return # Oops, no commands found -- an end-user error if not self.commands: raise DistutilsArgError("no commands supplied") # All is well: return true return True def _get_toplevel_options(self): """Return the non-display options recognized at the top level. This includes options that are recognized *only* at the top level as well as options recognized for commands. """ return self.global_options + [ ("command-packages=", None, "list of packages that provide distutils commands"), ] def _parse_command_opts(self, parser, args): """Parse the command-line options for a single command. 'parser' must be a FancyGetopt instance; 'args' must be the list of arguments, starting with the current command (whose options we are about to parse). Returns a new version of 'args' with the next command at the front of the list; will be the empty list if there are no more commands on the command line. Returns None if the user asked for help on this command. """ # late import because of mutual dependence between these modules from distutils.cmd import Command # Pull the current command from the head of the command line command = args[0] if not command_re.match(command): raise SystemExit("invalid command name '%s'" % command) self.commands.append(command) # Dig up the command class that implements this command, so we # 1) know that it's a valid command, and 2) know which options # it takes. try: cmd_class = self.get_command_class(command) except DistutilsModuleError as msg: raise DistutilsArgError(msg) # Require that the command class be derived from Command -- want # to be sure that the basic "command" interface is implemented. if not issubclass(cmd_class, Command): raise DistutilsClassError( "command class %s must subclass Command" % cmd_class) # Also make sure that the command object provides a list of its # known options. if not (hasattr(cmd_class, 'user_options') and isinstance(cmd_class.user_options, list)): msg = ("command class %s must provide " "'user_options' attribute (a list of tuples)") raise DistutilsClassError(msg % cmd_class) # If the command class has a list of negative alias options, # merge it in with the global negative aliases. negative_opt = self.negative_opt if hasattr(cmd_class, 'negative_opt'): negative_opt = negative_opt.copy() negative_opt.update(cmd_class.negative_opt) # Check for help_options in command class. They have a different # format (tuple of four) so we need to preprocess them here. if (hasattr(cmd_class, 'help_options') and isinstance(cmd_class.help_options, list)): help_options = fix_help_options(cmd_class.help_options) else: help_options = [] # All commands support the global options too, just by adding # in 'global_options'. parser.set_option_table(self.global_options + cmd_class.user_options + help_options) parser.set_negative_aliases(negative_opt) (args, opts) = parser.getopt(args[1:]) if hasattr(opts, 'help') and opts.help: self._show_help(parser, display_options=0, commands=[cmd_class]) return if (hasattr(cmd_class, 'help_options') and isinstance(cmd_class.help_options, list)): help_option_found=0 for (help_option, short, desc, func) in cmd_class.help_options: if hasattr(opts, parser.get_attr_name(help_option)): help_option_found=1 if callable(func): func() else: raise DistutilsClassError( "invalid help function %r for help option '%s': " "must be a callable object (function, etc.)" % (func, help_option)) if help_option_found: return # Put the options from the command-line into their official # holding pen, the 'command_options' dictionary. opt_dict = self.get_option_dict(command) for (name, value) in vars(opts).items(): opt_dict[name] = ("command line", value) return args def finalize_options(self): """Set final values for all the options on the Distribution instance, analogous to the .finalize_options() method of Command objects. """ for attr in ('keywords', 'platforms'): value = getattr(self.metadata, attr) if value is None: continue if isinstance(value, str): value = [elm.strip() for elm in value.split(',')] setattr(self.metadata, attr, value) def _show_help(self, parser, global_options=1, display_options=1, commands=[]): """Show help for the setup script command-line in the form of several lists of command-line options. 'parser' should be a FancyGetopt instance; do not expect it to be returned in the same state, as its option table will be reset to make it generate the correct help text. If 'global_options' is true, lists the global options: --verbose, --dry-run, etc. If 'display_options' is true, lists the "display-only" options: --name, --version, etc. Finally, lists per-command help for every command name or command class in 'commands'. """ # late import because of mutual dependence between these modules from distutils.core import gen_usage from distutils.cmd import Command if global_options: if display_options: options = self._get_toplevel_options() else: options = self.global_options parser.set_option_table(options) parser.print_help(self.common_usage + "\nGlobal options:") print('') if display_options: parser.set_option_table(self.display_options) parser.print_help( "Information display options (just display " + "information, ignore any commands)") print('') for command in self.commands: if isinstance(command, type) and issubclass(command, Command): klass = command else: klass = self.get_command_class(command) if (hasattr(klass, 'help_options') and isinstance(klass.help_options, list)): parser.set_option_table(klass.user_options + fix_help_options(klass.help_options)) else: parser.set_option_table(klass.user_options) parser.print_help("Options for '%s' command:" % klass.__name__) print('') print(gen_usage(self.script_name)) def handle_display_options(self, option_order): """If there were any non-global "display-only" options (--help-commands or the metadata display options) on the command line, display the requested info and return true; else return false. """ from distutils.core import gen_usage # User just wants a list of commands -- we'll print it out and stop # processing now (ie. if they ran "setup --help-commands foo bar", # we ignore "foo bar"). if self.help_commands: self.print_commands() print('') print(gen_usage(self.script_name)) return 1 # If user supplied any of the "display metadata" options, then # display that metadata in the order in which the user supplied the # metadata options. any_display_options = 0 is_display_option = {} for option in self.display_options: is_display_option[option[0]] = 1 for (opt, val) in option_order: if val and is_display_option.get(opt): opt = translate_longopt(opt) value = getattr(self.metadata, "get_"+opt)() if opt in ['keywords', 'platforms']: print(','.join(value)) elif opt in ('classifiers', 'provides', 'requires', 'obsoletes'): print('\n'.join(value)) else: print(value) any_display_options = 1 return any_display_options def print_command_list(self, commands, header, max_length): """Print a subset of the list of all commands -- used by 'print_commands()'. """ print(header + ":") for cmd in commands: klass = self.cmdclass.get(cmd) if not klass: klass = self.get_command_class(cmd) try: description = klass.description except AttributeError: description = "(no description available)" print(" %-*s %s" % (max_length, cmd, description)) def print_commands(self): """Print out a help message listing all available commands with a description of each. The list is divided into "standard commands" (listed in distutils.command.__all__) and "extra commands" (mentioned in self.cmdclass, but not a standard command). The descriptions come from the command class attribute 'description'. """ import distutils.command std_commands = distutils.command.__all__ is_std = {} for cmd in std_commands: is_std[cmd] = 1 extra_commands = [] for cmd in self.cmdclass.keys(): if not is_std.get(cmd): extra_commands.append(cmd) max_length = 0 for cmd in (std_commands + extra_commands): if len(cmd) > max_length: max_length = len(cmd) self.print_command_list(std_commands, "Standard commands", max_length) if extra_commands: print() self.print_command_list(extra_commands, "Extra commands", max_length) def get_command_list(self): """Get a list of (command, description) tuples. The list is divided into "standard commands" (listed in distutils.command.__all__) and "extra commands" (mentioned in self.cmdclass, but not a standard command). The descriptions come from the command class attribute 'description'. """ # Currently this is only used on Mac OS, for the Mac-only GUI # Distutils interface (by Jack Jansen) import distutils.command std_commands = distutils.command.__all__ is_std = {} for cmd in std_commands: is_std[cmd] = 1 extra_commands = [] for cmd in self.cmdclass.keys(): if not is_std.get(cmd): extra_commands.append(cmd) rv = [] for cmd in (std_commands + extra_commands): klass = self.cmdclass.get(cmd) if not klass: klass = self.get_command_class(cmd) try: description = klass.description except AttributeError: description = "(no description available)" rv.append((cmd, description)) return rv # -- Command class/object methods ---------------------------------- def get_command_packages(self): """Return a list of packages from which commands are loaded.""" pkgs = self.command_packages if not isinstance(pkgs, list): if pkgs is None: pkgs = '' pkgs = [pkg.strip() for pkg in pkgs.split(',') if pkg != ''] if "distutils.command" not in pkgs: pkgs.insert(0, "distutils.command") self.command_packages = pkgs return pkgs def get_command_class(self, command): """Return the class that implements the Distutils command named by 'command'. First we check the 'cmdclass' dictionary; if the command is mentioned there, we fetch the class object from the dictionary and return it. Otherwise we load the command module ("distutils.command." + command) and fetch the command class from the module. The loaded class is also stored in 'cmdclass' to speed future calls to 'get_command_class()'. Raises DistutilsModuleError if the expected module could not be found, or if that module does not define the expected class. """ klass = self.cmdclass.get(command) if klass: return klass for pkgname in self.get_command_packages(): module_name = "%s.%s" % (pkgname, command) klass_name = command try: __import__(module_name) module = sys.modules[module_name] except ImportError: continue try: klass = getattr(module, klass_name) except AttributeError: raise DistutilsModuleError( "invalid command '%s' (no class '%s' in module '%s')" % (command, klass_name, module_name)) self.cmdclass[command] = klass return klass raise DistutilsModuleError("invalid command '%s'" % command) def get_command_obj(self, command, create=1): """Return the command object for 'command'. Normally this object is cached on a previous call to 'get_command_obj()'; if no command object for 'command' is in the cache, then we either create and return it (if 'create' is true) or return None. """ cmd_obj = self.command_obj.get(command) if not cmd_obj and create: if DEBUG: self.announce("Distribution.get_command_obj(): " "creating '%s' command object" % command) klass = self.get_command_class(command) cmd_obj = self.command_obj[command] = klass(self) self.have_run[command] = 0 # Set any options that were supplied in config files # or on the command line. (NB. support for error # reporting is lame here: any errors aren't reported # until 'finalize_options()' is called, which means # we won't report the source of the error.) options = self.command_options.get(command) if options: self._set_command_options(cmd_obj, options) return cmd_obj def _set_command_options(self, command_obj, option_dict=None): """Set the options for 'command_obj' from 'option_dict'. Basically this means copying elements of a dictionary ('option_dict') to attributes of an instance ('command'). 'command_obj' must be a Command instance. If 'option_dict' is not supplied, uses the standard option dictionary for this command (from 'self.command_options'). """ command_name = command_obj.get_command_name() if option_dict is None: option_dict = self.get_option_dict(command_name) if DEBUG: self.announce(" setting options for '%s' command:" % command_name) for (option, (source, value)) in option_dict.items(): if DEBUG: self.announce(" %s = %s (from %s)" % (option, value, source)) try: bool_opts = [translate_longopt(o) for o in command_obj.boolean_options] except AttributeError: bool_opts = [] try: neg_opt = command_obj.negative_opt except AttributeError: neg_opt = {} try: is_string = isinstance(value, str) if option in neg_opt and is_string: setattr(command_obj, neg_opt[option], not strtobool(value)) elif option in bool_opts and is_string: setattr(command_obj, option, strtobool(value)) elif hasattr(command_obj, option): setattr(command_obj, option, value) else: raise DistutilsOptionError( "error in %s: command '%s' has no such option '%s'" % (source, command_name, option)) except ValueError as msg: raise DistutilsOptionError(msg) def reinitialize_command(self, command, reinit_subcommands=0): """Reinitializes a command to the state it was in when first returned by 'get_command_obj()': ie., initialized but not yet finalized. This provides the opportunity to sneak option values in programmatically, overriding or supplementing user-supplied values from the config files and command line. You'll have to re-finalize the command object (by calling 'finalize_options()' or 'ensure_finalized()') before using it for real. 'command' should be a command name (string) or command object. If 'reinit_subcommands' is true, also reinitializes the command's sub-commands, as declared by the 'sub_commands' class attribute (if it has one). See the "install" command for an example. Only reinitializes the sub-commands that actually matter, ie. those whose test predicates return true. Returns the reinitialized command object. """ from distutils.cmd import Command if not isinstance(command, Command): command_name = command command = self.get_command_obj(command_name) else: command_name = command.get_command_name() if not command.finalized: return command command.initialize_options() command.finalized = 0 self.have_run[command_name] = 0 self._set_command_options(command) if reinit_subcommands: for sub in command.get_sub_commands(): self.reinitialize_command(sub, reinit_subcommands) return command # -- Methods that operate on the Distribution ---------------------- def announce(self, msg, level=log.INFO): log.log(level, msg) def run_commands(self): """Run each command that was seen on the setup script command line. Uses the list of commands found and cache of command objects created by 'get_command_obj()'. """ for cmd in self.commands: self.run_command(cmd) # -- Methods that operate on its Commands -------------------------- def run_command(self, command): """Do whatever it takes to run a command (including nothing at all, if the command has already been run). Specifically: if we have already created and run the command named by 'command', return silently without doing anything. If the command named by 'command' doesn't even have a command object yet, create one. Then invoke 'run()' on that command object (or an existing one). """ # Already been here, done that? then return silently. if self.have_run.get(command): return log.info("running %s", command) cmd_obj = self.get_command_obj(command) cmd_obj.ensure_finalized() cmd_obj.run() self.have_run[command] = 1 # -- Distribution query methods ------------------------------------ def has_pure_modules(self): return len(self.packages or self.py_modules or []) > 0 def has_ext_modules(self): return self.ext_modules and len(self.ext_modules) > 0 def has_c_libraries(self): return self.libraries and len(self.libraries) > 0 def has_modules(self): return self.has_pure_modules() or self.has_ext_modules() def has_headers(self): return self.headers and len(self.headers) > 0 def has_scripts(self): return self.scripts and len(self.scripts) > 0 def has_data_files(self): return self.data_files and len(self.data_files) > 0 def is_pure(self): return (self.has_pure_modules() and not self.has_ext_modules() and not self.has_c_libraries()) # -- Metadata query methods ---------------------------------------- # If you're looking for 'get_name()', 'get_version()', and so forth, # they are defined in a sneaky way: the constructor binds self.get_XXX # to self.metadata.get_XXX. The actual code is in the # DistributionMetadata class, below. class DistributionMetadata: """Dummy class to hold the distribution meta-data: name, version, author, and so forth. """ _METHOD_BASENAMES = ("name", "version", "author", "author_email", "maintainer", "maintainer_email", "url", "license", "description", "long_description", "keywords", "platforms", "fullname", "contact", "contact_email", "classifiers", "download_url", # PEP 314 "provides", "requires", "obsoletes", ) def __init__(self, path=None): if path is not None: self.read_pkg_file(open(path)) else: self.name = None self.version = None self.author = None self.author_email = None self.maintainer = None self.maintainer_email = None self.url = None self.license = None self.description = None self.long_description = None self.keywords = None self.platforms = None self.classifiers = None self.download_url = None # PEP 314 self.provides = None self.requires = None self.obsoletes = None def read_pkg_file(self, file): """Reads the metadata values from a file object.""" msg = message_from_file(file) def _read_field(name): value = msg[name] if value == 'UNKNOWN': return None return value def _read_list(name): values = msg.get_all(name, None) if values == []: return None return values metadata_version = msg['metadata-version'] self.name = _read_field('name') self.version = _read_field('version') self.description = _read_field('summary') # we are filling author only. self.author = _read_field('author') self.maintainer = None self.author_email = _read_field('author-email') self.maintainer_email = None self.url = _read_field('home-page') self.license = _read_field('license') if 'download-url' in msg: self.download_url = _read_field('download-url') else: self.download_url = None self.long_description = _read_field('description') self.description = _read_field('summary') if 'keywords' in msg: self.keywords = _read_field('keywords').split(',') self.platforms = _read_list('platform') self.classifiers = _read_list('classifier') # PEP 314 - these fields only exist in 1.1 if metadata_version == '1.1': self.requires = _read_list('requires') self.provides = _read_list('provides') self.obsoletes = _read_list('obsoletes') else: self.requires = None self.provides = None self.obsoletes = None def write_pkg_info(self, base_dir): """Write the PKG-INFO file into the release tree. """ with open(os.path.join(base_dir, 'PKG-INFO'), 'w', encoding='UTF-8') as pkg_info: self.write_pkg_file(pkg_info) def write_pkg_file(self, file): """Write the PKG-INFO format data to a file object. """ version = '1.0' if (self.provides or self.requires or self.obsoletes or self.classifiers or self.download_url): version = '1.1' file.write('Metadata-Version: %s\n' % version) file.write('Name: %s\n' % self.get_name()) file.write('Version: %s\n' % self.get_version()) file.write('Summary: %s\n' % self.get_description()) file.write('Home-page: %s\n' % self.get_url()) file.write('Author: %s\n' % self.get_contact()) file.write('Author-email: %s\n' % self.get_contact_email()) file.write('License: %s\n' % self.get_license()) if self.download_url: file.write('Download-URL: %s\n' % self.download_url) long_desc = rfc822_escape(self.get_long_description()) file.write('Description: %s\n' % long_desc) keywords = ','.join(self.get_keywords()) if keywords: file.write('Keywords: %s\n' % keywords) self._write_list(file, 'Platform', self.get_platforms()) self._write_list(file, 'Classifier', self.get_classifiers()) # PEP 314 self._write_list(file, 'Requires', self.get_requires()) self._write_list(file, 'Provides', self.get_provides()) self._write_list(file, 'Obsoletes', self.get_obsoletes()) def _write_list(self, file, name, values): for value in values: file.write('%s: %s\n' % (name, value)) # -- Metadata query methods ---------------------------------------- def get_name(self): return self.name or "UNKNOWN" def get_version(self): return self.version or "0.0.0" def get_fullname(self): return "%s-%s" % (self.get_name(), self.get_version()) def get_author(self): return self.author or "UNKNOWN" def get_author_email(self): return self.author_email or "UNKNOWN" def get_maintainer(self): return self.maintainer or "UNKNOWN" def get_maintainer_email(self): return self.maintainer_email or "UNKNOWN" def get_contact(self): return self.maintainer or self.author or "UNKNOWN" def get_contact_email(self): return self.maintainer_email or self.author_email or "UNKNOWN" def get_url(self): return self.url or "UNKNOWN" def get_license(self): return self.license or "UNKNOWN" get_licence = get_license def get_description(self): return self.description or "UNKNOWN" def get_long_description(self): return self.long_description or "UNKNOWN" def get_keywords(self): return self.keywords or [] def set_keywords(self, value): self.keywords = _ensure_list(value, 'keywords') def get_platforms(self): return self.platforms or ["UNKNOWN"] def set_platforms(self, value): self.platforms = _ensure_list(value, 'platforms') def get_classifiers(self): return self.classifiers or [] def set_classifiers(self, value): self.classifiers = _ensure_list(value, 'classifiers') def get_download_url(self): return self.download_url or "UNKNOWN" # PEP 314 def get_requires(self): return self.requires or [] def set_requires(self, value): import distutils.versionpredicate for v in value: distutils.versionpredicate.VersionPredicate(v) self.requires = list(value) def get_provides(self): return self.provides or [] def set_provides(self, value): value = [v.strip() for v in value] for v in value: import distutils.versionpredicate distutils.versionpredicate.split_provision(v) self.provides = value def get_obsoletes(self): return self.obsoletes or [] def set_obsoletes(self, value): import distutils.versionpredicate for v in value: distutils.versionpredicate.VersionPredicate(v) self.obsoletes = list(value) def fix_help_options(options): """Convert a 4-tuple 'help_options' list as found in various command classes to the 3-tuple form required by FancyGetopt. """ new_options = [] for help_tuple in options: new_options.append(help_tuple[0:3]) return new_options PKH] ~T~T;python3.10/site-packages/setuptools/_distutils/sysconfig.pynu["""Provide access to Python's configuration information. The specific configuration variables available depend heavily on the platform and configuration. The values may be retrieved using get_config_var(name), and the list of variables is available via get_config_vars().keys(). Additional convenience functions are also available. Written by: Fred L. Drake, Jr. Email: """ import _imp import os import re import sys from .errors import DistutilsPlatformError IS_PYPY = '__pypy__' in sys.builtin_module_names # These are needed in a couple of spots, so just compute them once. PREFIX = os.path.normpath(sys.prefix) EXEC_PREFIX = os.path.normpath(sys.exec_prefix) BASE_PREFIX = os.path.normpath(sys.base_prefix) BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) # Path to the base directory of the project. On Windows the binary may # live in project/PCbuild/win32 or project/PCbuild/amd64. # set for cross builds if "_PYTHON_PROJECT_BASE" in os.environ: project_base = os.path.abspath(os.environ["_PYTHON_PROJECT_BASE"]) else: if sys.executable: project_base = os.path.dirname(os.path.abspath(sys.executable)) else: # sys.executable can be empty if argv[0] has been changed and Python is # unable to retrieve the real program name project_base = os.getcwd() # python_build: (Boolean) if true, we're either building Python or # building an extension with an un-installed Python, so we use # different (hard-wired) directories. def _is_python_source_dir(d): for fn in ("Setup", "Setup.local"): if os.path.isfile(os.path.join(d, "Modules", fn)): return True return False _sys_home = getattr(sys, '_home', None) if os.name == 'nt': def _fix_pcbuild(d): if d and os.path.normcase(d).startswith( os.path.normcase(os.path.join(PREFIX, "PCbuild"))): return PREFIX return d project_base = _fix_pcbuild(project_base) _sys_home = _fix_pcbuild(_sys_home) def _python_build(): if _sys_home: return _is_python_source_dir(_sys_home) return _is_python_source_dir(project_base) python_build = _python_build() # Calculate the build qualifier flags if they are defined. Adding the flags # to the include and lib directories only makes sense for an installation, not # an in-source build. build_flags = '' try: if not python_build: build_flags = sys.abiflags except AttributeError: # It's not a configure-based build, so the sys module doesn't have # this attribute, which is fine. pass def get_python_version(): """Return a string containing the major and minor Python version, leaving off the patchlevel. Sample return values could be '1.5' or '2.2'. """ return '%d.%d' % sys.version_info[:2] def get_python_inc(plat_specific=0, prefix=None): """Return the directory containing installed Python header files. If 'plat_specific' is false (the default), this is the path to the non-platform-specific header files, i.e. Python.h and so on; otherwise, this is the path to platform-specific header files (namely pyconfig.h). If 'prefix' is supplied, use it instead of sys.base_prefix or sys.base_exec_prefix -- i.e., ignore 'plat_specific'. """ if prefix is None: prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX if os.name == "posix": if IS_PYPY and sys.version_info < (3, 8): return os.path.join(prefix, 'include') if python_build: # Assume the executable is in the build directory. The # pyconfig.h file should be in the same directory. Since # the build directory may not be the source directory, we # must use "srcdir" from the makefile to find the "Include" # directory. if plat_specific: return _sys_home or project_base else: incdir = os.path.join(get_config_var('srcdir'), 'Include') return os.path.normpath(incdir) implementation = 'pypy' if IS_PYPY else 'python' python_dir = implementation + get_python_version() + build_flags return os.path.join(prefix, "include", python_dir) elif os.name == "nt": if python_build: # Include both the include and PC dir to ensure we can find # pyconfig.h return (os.path.join(prefix, "include") + os.path.pathsep + os.path.join(prefix, "PC")) return os.path.join(prefix, "include") else: raise DistutilsPlatformError( "I don't know where Python installs its C header files " "on platform '%s'" % os.name) def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): """Return the directory containing the Python library (standard or site additions). If 'plat_specific' is true, return the directory containing platform-specific modules, i.e. any module from a non-pure-Python module distribution; otherwise, return the platform-shared library directory. If 'standard_lib' is true, return the directory containing standard Python library modules; otherwise, return the directory for site-specific modules. If 'prefix' is supplied, use it instead of sys.base_prefix or sys.base_exec_prefix -- i.e., ignore 'plat_specific'. """ if IS_PYPY and sys.version_info < (3, 8): # PyPy-specific schema if prefix is None: prefix = PREFIX if standard_lib: return os.path.join(prefix, "lib-python", sys.version[0]) return os.path.join(prefix, 'site-packages') if prefix is None: if standard_lib: prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX else: prefix = plat_specific and EXEC_PREFIX or PREFIX if os.name == "posix": if plat_specific or standard_lib: # Platform-specific modules (any module from a non-pure-Python # module distribution) or standard Python library modules. libdir = getattr(sys, "platlibdir", "lib") else: # Pure Python libdir = "lib" implementation = 'pypy' if IS_PYPY else 'python' libpython = os.path.join(prefix, libdir, implementation + get_python_version()) if standard_lib: return libpython else: return os.path.join(libpython, "site-packages") elif os.name == "nt": if standard_lib: return os.path.join(prefix, "Lib") else: return os.path.join(prefix, "Lib", "site-packages") else: raise DistutilsPlatformError( "I don't know where Python installs its library " "on platform '%s'" % os.name) def customize_compiler(compiler): """Do any platform-specific customization of a CCompiler instance. Mainly needed on Unix, so we can plug in the information that varies across Unices and is stored in Python's Makefile. """ if compiler.compiler_type == "unix": if sys.platform == "darwin": # Perform first-time customization of compiler-related # config vars on OS X now that we know we need a compiler. # This is primarily to support Pythons from binary # installers. The kind and paths to build tools on # the user system may vary significantly from the system # that Python itself was built on. Also the user OS # version and build tools may not support the same set # of CPU architectures for universal builds. global _config_vars # Use get_config_var() to ensure _config_vars is initialized. if not get_config_var('CUSTOMIZED_OSX_COMPILER'): import _osx_support _osx_support.customize_compiler(_config_vars) _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True' (cc, cxx, cflags, ccshared, ldshared, shlib_suffix, ar, ar_flags) = \ get_config_vars('CC', 'CXX', 'CFLAGS', 'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS') if 'CC' in os.environ: newcc = os.environ['CC'] if('LDSHARED' not in os.environ and ldshared.startswith(cc)): # If CC is overridden, use that as the default # command for LDSHARED as well ldshared = newcc + ldshared[len(cc):] cc = newcc if 'CXX' in os.environ: cxx = os.environ['CXX'] if 'LDSHARED' in os.environ: ldshared = os.environ['LDSHARED'] if 'CPP' in os.environ: cpp = os.environ['CPP'] else: cpp = cc + " -E" # not always if 'LDFLAGS' in os.environ: ldshared = ldshared + ' ' + os.environ['LDFLAGS'] if 'CFLAGS' in os.environ: cflags = cflags + ' ' + os.environ['CFLAGS'] ldshared = ldshared + ' ' + os.environ['CFLAGS'] if 'CPPFLAGS' in os.environ: cpp = cpp + ' ' + os.environ['CPPFLAGS'] cflags = cflags + ' ' + os.environ['CPPFLAGS'] ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] if 'AR' in os.environ: ar = os.environ['AR'] if 'ARFLAGS' in os.environ: archiver = ar + ' ' + os.environ['ARFLAGS'] else: archiver = ar + ' ' + ar_flags cc_cmd = cc + ' ' + cflags compiler.set_executables( preprocessor=cpp, compiler=cc_cmd, compiler_so=cc_cmd + ' ' + ccshared, compiler_cxx=cxx, linker_so=ldshared, linker_exe=cc, archiver=archiver) if 'RANLIB' in os.environ and compiler.executables.get('ranlib', None): compiler.set_executables(ranlib=os.environ['RANLIB']) compiler.shared_lib_extension = shlib_suffix def get_config_h_filename(): """Return full pathname of installed pyconfig.h file.""" if python_build: if os.name == "nt": inc_dir = os.path.join(_sys_home or project_base, "PC") else: inc_dir = _sys_home or project_base else: inc_dir = get_python_inc(plat_specific=1) return os.path.join(inc_dir, 'pyconfig.h') def get_makefile_filename(): """Return full pathname of installed Makefile from the Python build.""" if python_build: return os.path.join(_sys_home or project_base, "Makefile") lib_dir = get_python_lib(plat_specific=0, standard_lib=1) config_file = 'config-{}{}'.format(get_python_version(), build_flags) if hasattr(sys.implementation, '_multiarch'): config_file += '-%s' % sys.implementation._multiarch return os.path.join(lib_dir, config_file, 'Makefile') def parse_config_h(fp, g=None): """Parse a config.h-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. """ if g is None: g = {} define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") # while True: line = fp.readline() if not line: break m = define_rx.match(line) if m: n, v = m.group(1, 2) try: v = int(v) except ValueError: pass g[n] = v else: m = undef_rx.match(line) if m: g[m.group(1)] = 0 return g # Regexes needed for parsing Makefile (and similar syntaxes, # like old-style Setup files). _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") def parse_makefile(fn, g=None): """Parse a Makefile-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. """ from distutils.text_file import TextFile fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1, errors="surrogateescape") if g is None: g = {} done = {} notdone = {} while True: line = fp.readline() if line is None: # eof break m = _variable_rx.match(line) if m: n, v = m.group(1, 2) v = v.strip() # `$$' is a literal `$' in make tmpv = v.replace('$$', '') if "$" in tmpv: notdone[n] = v else: try: v = int(v) except ValueError: # insert literal `$' done[n] = v.replace('$$', '$') else: done[n] = v # Variables with a 'PY_' prefix in the makefile. These need to # be made available without that prefix through sysconfig. # Special care is needed to ensure that variable expansion works, even # if the expansion uses the name without a prefix. renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') # do variable interpolation here while notdone: for name in list(notdone): value = notdone[name] m = _findvar1_rx.search(value) or _findvar2_rx.search(value) if m: n = m.group(1) found = True if n in done: item = str(done[n]) elif n in notdone: # get it on a subsequent round found = False elif n in os.environ: # do it like make: fall back to environment item = os.environ[n] elif n in renamed_variables: if name.startswith('PY_') and name[3:] in renamed_variables: item = "" elif 'PY_' + n in notdone: found = False else: item = str(done['PY_' + n]) else: done[n] = item = "" if found: after = value[m.end():] value = value[:m.start()] + item + after if "$" in after: notdone[name] = value else: try: value = int(value) except ValueError: done[name] = value.strip() else: done[name] = value del notdone[name] if name.startswith('PY_') \ and name[3:] in renamed_variables: name = name[3:] if name not in done: done[name] = value else: # bogus variable reference; just drop it since we can't deal del notdone[name] fp.close() # strip spurious spaces for k, v in done.items(): if isinstance(v, str): done[k] = v.strip() # save the results in the global dictionary g.update(done) return g def expand_makefile_vars(s, vars): """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in 'string' according to 'vars' (a dictionary mapping variable names to values). Variables not present in 'vars' are silently expanded to the empty string. The variable values in 'vars' should not contain further variable expansions; if 'vars' is the output of 'parse_makefile()', you're fine. Returns a variable-expanded version of 's'. """ # This algorithm does multiple expansion, so if vars['foo'] contains # "${bar}", it will expand ${foo} to ${bar}, and then expand # ${bar}... and so forth. This is fine as long as 'vars' comes from # 'parse_makefile()', which takes care of such expansions eagerly, # according to make's variable expansion semantics. while True: m = _findvar1_rx.search(s) or _findvar2_rx.search(s) if m: (beg, end) = m.span() s = s[0:beg] + vars.get(m.group(1)) + s[end:] else: break return s _config_vars = None def _init_posix(): """Initialize the module as appropriate for POSIX systems.""" # _sysconfigdata is generated at build time, see the sysconfig module name = os.environ.get('_PYTHON_SYSCONFIGDATA_NAME', '_sysconfigdata_{abi}_{platform}_{multiarch}'.format( abi=sys.abiflags, platform=sys.platform, multiarch=getattr(sys.implementation, '_multiarch', ''), )) try: _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) except ImportError: # Python 3.5 and pypy 7.3.1 _temp = __import__( '_sysconfigdata', globals(), locals(), ['build_time_vars'], 0) build_time_vars = _temp.build_time_vars global _config_vars _config_vars = {} _config_vars.update(build_time_vars) def _init_nt(): """Initialize the module as appropriate for NT""" g = {} # set basic install directories g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) # XXX hmmm.. a normal install puts include files here g['INCLUDEPY'] = get_python_inc(plat_specific=0) g['EXT_SUFFIX'] = _imp.extension_suffixes()[0] g['EXE'] = ".exe" g['VERSION'] = get_python_version().replace(".", "") g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable)) global _config_vars _config_vars = g def get_config_vars(*args): """With no arguments, return a dictionary of all configuration variables relevant for the current platform. Generally this includes everything needed to build extensions and install both pure modules and extensions. On Unix, this means every variable defined in Python's installed Makefile; on Windows it's a much smaller set. With arguments, return a list of values that result from looking up each argument in the configuration variable dictionary. """ global _config_vars if _config_vars is None: func = globals().get("_init_" + os.name) if func: func() else: _config_vars = {} # Normalized versions of prefix and exec_prefix are handy to have; # in fact, these are the standard versions used most places in the # Distutils. _config_vars['prefix'] = PREFIX _config_vars['exec_prefix'] = EXEC_PREFIX if not IS_PYPY: # For backward compatibility, see issue19555 SO = _config_vars.get('EXT_SUFFIX') if SO is not None: _config_vars['SO'] = SO # Always convert srcdir to an absolute path srcdir = _config_vars.get('srcdir', project_base) if os.name == 'posix': if python_build: # If srcdir is a relative path (typically '.' or '..') # then it should be interpreted relative to the directory # containing Makefile. base = os.path.dirname(get_makefile_filename()) srcdir = os.path.join(base, srcdir) else: # srcdir is not meaningful since the installation is # spread about the filesystem. We choose the # directory containing the Makefile since we know it # exists. srcdir = os.path.dirname(get_makefile_filename()) _config_vars['srcdir'] = os.path.abspath(os.path.normpath(srcdir)) # Convert srcdir into an absolute path if it appears necessary. # Normally it is relative to the build directory. However, during # testing, for example, we might be running a non-installed python # from a different directory. if python_build and os.name == "posix": base = project_base if (not os.path.isabs(_config_vars['srcdir']) and base != os.getcwd()): # srcdir is relative and we are not in the same directory # as the executable. Assume executable is in the build # directory and make srcdir absolute. srcdir = os.path.join(base, _config_vars['srcdir']) _config_vars['srcdir'] = os.path.normpath(srcdir) # OS X platforms require special customization to handle # multi-architecture, multi-os-version installers if sys.platform == 'darwin': import _osx_support _osx_support.customize_config_vars(_config_vars) if args: vals = [] for name in args: vals.append(_config_vars.get(name)) return vals else: return _config_vars def get_config_var(name): """Return the value of a single variable using the dictionary returned by 'get_config_vars()'. Equivalent to get_config_vars().get(name) """ if name == 'SO': import warnings warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2) return get_config_vars().get(name) PKH]ٱRpython3.10/site-packages/setuptools/_distutils/__pycache__/version.cpython-310.pycnu[o Xai0@s>dZddlZGdddZGdddeZGdddeZdS) aProvides classes to represent module version numbers (one class for each style of version numbering). There are currently two such classes implemented: StrictVersion and LooseVersion. Every version number class implements the following interface: * the 'parse' method takes a string and parses it to some internal representation; if the string is an invalid version number, 'parse' raises a ValueError exception * the class constructor takes an optional string argument which, if supplied, is passed to 'parse' * __str__ reconstructs the string that was passed to 'parse' (or an equivalent string -- ie. one that will generate an equivalent version number instance) * __repr__ generates Python code to recreate the version number instance * _cmp compares the current instance with either another instance of the same class or a string (which will be parsed to an instance of the same class, thus must follow the same rules) Nc@sJeZdZdZdddZddZddZd d Zd d Zd dZ ddZ dS)VersionzAbstract base class for version numbering classes. Just provides constructor (__init__) and reproducer (__repr__), because those seem to be the same for all version numbering classes; and route rich comparisons to _cmp. NcC|r ||dSdSNparseselfvstringr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/version.py__init__&zVersion.__init__cCsd|jjt|fS)Nz %s ('%s')) __class____name__strrr r r __repr__*szVersion.__repr__cCs||}|tur |S|dkSNr_cmpNotImplementedrothercr r r __eq__- zVersion.__eq__cCs||}|tur |S|dkSrrrr r r __lt__3rzVersion.__lt__cCs||}|tur |S|dkSrrrr r r __le__9rzVersion.__le__cCs||}|tur |S|dkSrrrr r r __gt__?rzVersion.__gt__cCs||}|tur |S|dkSrrrr r r __ge__ErzVersion.__ge__r) r __module__ __qualname____doc__r rrrrrrr r r r rs  rc@s<eZdZdZedejejBZddZ ddZ ddZ d S) StrictVersiona?Version numbering for anal retentives and software idealists. Implements the standard interface for version number classes as described above. A version number consists of two or three dot-separated numeric components, with an optional "pre-release" tag on the end. The pre-release tag consists of the letter 'a' or 'b' followed by a number. If the numeric components of two version numbers are equal, then one with a pre-release tag will always be deemed earlier (lesser) than one without. The following are valid version numbers (shown in the order that would be obtained by sorting according to the supplied cmp function): 0.4 0.4.0 (these two are equivalent) 0.4.1 0.5a1 0.5b3 0.5 0.9.6 1.0 1.0.4a3 1.0.4b1 1.0.4 The following are examples of invalid version numbers: 1 2.7.2.2 1.3.a4 1.3pl1 1.3c4 The rationale for this version numbering system will be explained in the distutils documentation. z)^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$cCs|j|}|std||ddddd\}}}}}|r*ttt|||g|_n ttt||gd|_|rC|dt|f|_dSd|_dS) Nzinvalid version number '%s')rr) version_rematch ValueErrorgrouptuplemapintversion prerelease)rr r*majorminorpatchr1Zprerelease_numr r r rs    zStrictVersion.parsecCsb|jddkrdtt|jdd}n dtt|j}|jr/||jdt|jd}|S)Nr%r.r$)r0joinr.rr1rr r r __str__s zStrictVersion.__str__cCst|tr t|}nt|tstS|j|jkr!|j|jkrdSdS|js)|js)dS|jr1|js1dS|js9|jr9dS|jrQ|jrQ|j|jkrGdS|j|jkrOdSdSJd)Nr$rFznever get here) isinstancerr#rr0r1rrr r r rs*           zStrictVersion._cmpN) rr r!r"recompileVERBOSEASCIIr)rr7rr r r r r#]s#  r#c@sHeZdZdZedejZdddZddZ dd Z d d Z d d Z dS) LooseVersionaVersion numbering for anarchists and software realists. Implements the standard interface for version number classes as described above. A version number consists of a series of numbers, separated by either periods or strings of letters. When comparing version numbers, the numeric components will be compared numerically, and the alphabetic components lexically. The following are all valid version numbers, in no particular order: 1.5.1 1.5.2b2 161 3.10a 8.02 3.4j 1996.07.12 3.2.pl0 3.1.1.6 2g6 11g 0.960923 2.2beta29 1.13++ 5.5.kw 2.0b1pl0 In fact, there is no such thing as an invalid version number under this scheme; the rules for comparison are simple and predictable, but may not always give the results you want (for some definition of "want"). z(\d+ | [a-z]+ | \.)NcCrrrrr r r r 0r zLooseVersion.__init__c CsZ||_dd|j|D}t|D]\}}zt|||<Wqty'Yqw||_dS)NcSsg|] }|r |dkr|qS)r5r ).0xr r r :s z&LooseVersion.parse..)r component_resplit enumerater/r+r0)rr componentsiobjr r r r5s  zLooseVersion.parsecCs|jSr)r rr r r r7EszLooseVersion.__str__cCs dt|S)NzLooseVersion ('%s'))rrr r r rIs zLooseVersion.__repr__cCsVt|tr t|}nt|tstS|j|jkrdS|j|jkr!dS|j|jkr)dSdS)Nrr8r$)r9rr?rr0r:r r r rMs      zLooseVersion._cmpr) rr r!r"r;r<r=rCr rr7rrr r r r r? s  r?)r"r;rr#r?r r r r s  >1PKH]cQpython3.10/site-packages/setuptools/_distutils/__pycache__/errors.cpython-310.pycnu[o Xai @s8dZGdddeZGdddeZGdddeZGdddeZGd d d eZGd d d eZGd ddeZGdddeZ GdddeZ GdddeZ GdddeZ GdddeZ GdddeZGdddeZGdddeZGdd d eZGd!d"d"eZGd#d$d$eZGd%d&d&eZd'S)(adistutils.errors Provides exceptions used by the Distutils modules. Note that Distutils modules may raise standard exceptions; in particular, SystemExit is usually raised for errors that are obviously the end-user's fault (eg. bad command-line arguments). This module is safe to use in "from ... import *" mode; it only exports symbols whose names start with "Distutils" and end with "Error".c@eZdZdZdS)DistutilsErrorzThe root of all Distutils evil.N__name__ __module__ __qualname____doc__rr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/errors.pyr rc@r)DistutilsModuleErrorzUnable to load an expected module, or to find an expected class within some module (in particular, command modules and classes).Nrrrrr r r c@r)DistutilsClassErrorzSome command class (or possibly distribution class, if anyone feels a need to subclass Distribution) is found not to be holding up its end of the bargain, ie. implementing some part of the "command "interface.Nrrrrr r sr c@r)DistutilsGetoptErrorz7The option table provided to 'fancy_getopt()' is bogus.Nrrrrr rr rc@r)DistutilsArgErrorzaRaised by fancy_getopt in response to getopt.error -- ie. an error in the command line usage.Nrrrrr rr rc@r)DistutilsFileErrorzAny problems in the filesystem: expected file not found, etc. Typically this is for problems that we detect before OSError could be raised.Nrrrrr r$rc@r)DistutilsOptionErroraSyntactic/semantic errors in command options, such as use of mutually conflicting options, or inconsistent options, badly-spelled values, etc. No distinction is made between option values originating in the setup script, the command line, config files, or what-have-you -- but if we *know* something originated in the setup script, we'll raise DistutilsSetupError instead.Nrrrrr r*src@r)DistutilsSetupErrorzqFor errors that can be definitely blamed on the setup script, such as invalid keyword arguments to 'setup()'.Nrrrrr r3r rc@r)DistutilsPlatformErrorzWe don't know how to do something on the current platform (but we do know how to do it on some platform) -- eg. trying to compile C files on a platform not supported by a CCompiler subclass.Nrrrrr r8rrc@r)DistutilsExecErrorz`Any problems executing an external program (such as the C compiler, when compiling C files).Nrrrrr r>r rc@r)DistutilsInternalErrorzoInternal inconsistencies or impossibilities (obviously, this should never be seen if the code is working!).Nrrrrr rCr rc@r)DistutilsTemplateErrorz%Syntax error in a file list template.Nrrrrr rHrc@r)DistutilsByteCompileErrorzByte compile error.Nrrrrr rKrrc@r)CCompilerErrorz#Some compile/link operation failed.Nrrrrr rOrrc@r)PreprocessErrorz.Failure to preprocess one or more C/C++ files.Nrrrrr rRrrc@r) CompileErrorz2Failure to compile one or more C/C++ source files.Nrrrrr rUrrc@r)LibErrorzKFailure to create a static library from one or more C/C++ object files.Nrrrrr rXrrc@r) LinkErrorz]Failure to link one or more C/C++ object files into an executable or shared library file.Nrrrrr r\rrc@r)UnknownFileErrorz(Attempt to process an unknown file type.Nrrrrr r`rrN)r Exceptionrr r rrrrrrrrrrrrrrrrrrrr s(  PKH]o,^88Opython3.10/site-packages/setuptools/_distutils/__pycache__/dist.cpython-310.pycnu[o Xai@sdZddlZddlZddlZddlmZzddlZWn ey%dZYnwddlTddl m Z m Z ddl m Z mZmZddlmZddlmZed Zd d ZGd d d ZGdddZddZdS)z}distutils.dist Provides the Distribution class, which represents the module distribution being built/installed/distributed. N)message_from_file)*) FancyGetopttranslate_longopt) check_environ strtobool rfc822_escapelog)DEBUGz^[a-zA-Z]([a-zA-Z0-9_]*)$cCsTt|tr |St|ts(t|j}d}|jdit}ttj|t|}|S)Nz>Warning: '{fieldname}' should be a list, got type '{typename}') isinstancestrlisttype__name__formatlocalsr WARN)value fieldnametypenamemsgr r /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/dist.py _ensure_lists  rc@sDeZdZdZgdZdZgdZddeDZddiZdId d Z d d Z dJddZ ddZ dIddZ ddZddZddZddZddgfddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+ZdKd,d-ZdId.d/ZdLd1d2Zejfd3d4Zd5d6Zd7d8Z d9d:Z!d;d<Z"d=d>Z#d?d@Z$dAdBZ%dCdDZ&dEdFZ'dGdHZ(d S)M DistributionaThe core of the Distutils. Most of the work hiding behind 'setup' is really done within a Distribution instance, which farms the work out to the Distutils commands specified on the command line. Setup scripts will almost never instantiate Distribution directly, unless the 'setup()' function is totally inadequate to their needs. However, it is conceivable that a setup script might wish to subclass Distribution for some specialized purpose, and then pass the subclass to 'setup()' as the 'distclass' keyword argument. If so, it is necessary to respect the expectations that 'setup' has of Distribution. See the code for 'setup()', in core.py, for details. ))verbosevzrun verbosely (default))quietqz!run quietly (turns verbosity off))zdry-runnzdon't actually do anything)helphzshow detailed help message)z no-user-cfgNz-ignore pydistutils.cfg in your home directoryzCommon commands: (see '--help-commands' for more) setup.py build will build the package underneath 'build/' setup.py install will install the package ))z help-commandsNzlist all available commands)nameNzprint package name)versionVzprint package version)fullnameNzprint -)authorNzprint the author's name) author-emailNz print the author's email address) maintainerNzprint the maintainer's name)zmaintainer-emailNz$print the maintainer's email address)contactNz7print the maintainer's name if known, else the author's)z contact-emailNz@print the maintainer's email address if known, else the author's)urlNzprint the URL for this package)licenseNz print the license of the package)licenceNzalias for --license) descriptionNzprint the package description)zlong-descriptionNz"print the long package description) platformsNzprint the list of platforms) classifiersNzprint the list of classifiers)keywordsNzprint the list of keywords)providesNz+print the list of packages/modules provided)requiresNz+print the list of packages/modules required) obsoletesNz0print the list of packages/modules made obsoletecCsg|]}t|dqSrr).0xr r r szDistribution.rrNcCsDd|_d|_d|_|jD]}t||dq t|_|jjD]}d|}t||t|j|qi|_ d|_ d|_ d|_ i|_ g|_d|_i|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_i|_i|_|r|d}|dur|d=|D]\}}| |}|D] \} } d| f|| <qqd|vr|d|d <|d=d } t!durt!"| nt#j$%| d |D]<\} } t&|jd | rt|jd | | qt&|j| rt|j| | qt&|| rt|| | qd t'| } t!"| qd|_(|j dur|j D]} | )dsn | dkrd|_(nq|*dS)a0Construct a new Distribution instance: initialize all the attributes of a Distribution, and then use 'attrs' (a dictionary mapping attribute names to values) to assign some of those attributes their "real" values. (Any attributes not mentioned in 'attrs' will be assigned to some null value: 0, None, an empty list or dictionary, etc.) Most importantly, initialize the 'command_obj' attribute to the empty dictionary; this will be filled in with real command objects by 'parse_command_line()'. rrget_Noptionsz setup scriptr.r-z:'licence' distribution option is deprecated; use 'license' set_zUnknown distribution option: %sT-z --no-user-cfgF)+rdry_runr"display_option_namessetattrDistributionMetadatametadata_METHOD_BASENAMESgetattrcmdclasscommand_packages script_name script_argscommand_options dist_filespackages package_data package_dir py_modules librariesheaders ext_modules ext_package include_dirs extra_pathscripts data_filespassword command_objhave_rungetitemsget_option_dictwarningswarnsysstderrwritehasattrrepr want_user_cfg startswithfinalize_options)selfattrsattrbasename method_namer=command cmd_optionsopt_dictoptvalrkeyargr r r__init__s                  zDistribution.__init__cCs&|j|}|duri}|j|<|S)zGet the option dictionary for a given command. If that command's option dictionary hasn't been created yet, then create it and return the new dictionary; otherwise, return the existing option dictionary. N)rLr])rjrodictr r rr_'s zDistribution.get_option_dictr<c Csddlm}|durt|j}|dur ||||d}|s+||ddS|D]4}|j|}|durC||d|q-||d|||}|dD] }||d|qUq-dS)Nr)pformatz zno commands known yetzno option dict for '%s' commandzoption dict for '%s' command:r>)pprintrxsortedrLkeysannouncer]split) rjheadercommandsindentrxcmd_namerqoutliner r rdump_option_dicts2s.  zDistribution.dump_option_dictscCsg}ttjtjdj}tj|d}tj|r!| |tj dkr)d}nd}|j rDtjtj d|}tj|rD| |d}tj|rQ| |t r]|dd ||S) aFind as many configuration files as should be processed for this platform, and return a list of filenames in the order in which they should be parsed. The filenames returned are guaranteed to exist (modulo nasty race conditions). There are three possible config files: distutils.cfg in the Distutils installation directory (ie. where the top-level Distutils __inst__.py file lives), a file in the user's home directory named .pydistutils.cfg on Unix and pydistutils.cfg on Windows/Mac; and setup.cfg in the current directory. The file in the user's home directory can be disabled with the --no-user-cfg option. distutilsz distutils.cfgposixz.pydistutils.cfgzpydistutils.cfg~z setup.cfgzusing config files: %sz, )rospathdirnamerbmodules__file__joinisfileappendr$rg expanduserr r|)rjfilessys_dirsys_file user_filename user_file local_filer r rfind_config_filesNs&       zDistribution.find_config_filesc Cs|ddlm}tjtjkrgd}ng}t|}|dur|}tr&|d|}|D]D}tr6|d|| || D]+}| |}| |}|D]} | dkri| |vri| || } | dd} || f|| <qMq?|q+d |jvr|jd D]?\} \} } |j | } z!| rt|| t|  n| d vrt|| t| nt|| | Wq|ty} zt| d} ~ wwdSdS) Nr) ConfigParser) z install-basezinstall-platbasez install-libzinstall-platlibzinstall-purelibzinstall-headerszinstall-scriptsz install-dataprefixz exec-prefixhomeuserrootz"Distribution.parse_config_files():z reading %srr@_global)rrA) configparserrrbr base_prefix frozensetrr r|readsectionsr=r_r]replacervrLr^ negative_optrCr ValueErrorDistutilsOptionError)rj filenamesrignore_optionsparserfilenamesectionr=rqrrrssrcaliasrr r rparse_config_files~sR               zDistribution.parse_config_filescCs|}g|_t||j}||j|ddi|j|j|d}| }t |j | |r4dS|rD|||}|durBdS|s6|jrW|j|t|jdk|jddS|js^tddS) aParse the setup script's command line, taken from the 'script_args' instance attribute (which defaults to 'sys.argv[1:]' -- see 'setup()' in core.py). This list is first processed for "global options" -- options that set attributes of the Distribution instance. Then, it is alternately scanned for Distutils commands and options for that command. Each new command terminates the options for the previous command. The allowed options for a command are determined by the 'user_options' attribute of the command class -- thus, we have to be able to load command classes in order to parse the command line. Any error in that 'options' attribute raises DistutilsGetoptError; any error on the command-line raises DistutilsArgError. If no Distutils commands were found on the command line, raises DistutilsArgError. Return true if command-line was successfully parsed and we should carry on with executing commands; false if no errors but we shouldn't execute commands (currently, this only happens if user asks for help). r.r-)argsobjectNrdisplay_optionsrzno commands suppliedT)_get_toplevel_optionsrrrset_negative_aliasesr set_aliasesgetoptrKget_option_orderr set_verbosityrhandle_display_options_parse_command_optsr" _show_helplenDistutilsArgError)rjtoplevel_optionsrr option_orderr r rparse_command_lines0       zDistribution.parse_command_linecCs |jdgS)zReturn the non-display options recognized at the top level. This includes options that are recognized *only* at the top level as well as options recognized for commands. )zcommand-packages=Nz0list of packages that provide distutils commands)global_optionsrjr r rrsz"Distribution._get_toplevel_optionsc Csddlm}|d}t|std||j|z||}Wnty2}zt |d}~wwt ||s>t d|t |drIt |jtsQd}t |||j}t |drc|}||jt |d rtt |jtrtt|j}ng}||j|j|||||d d\}} t | d r| jr|j|d|gd dSt |d rt |jtrd} |jD] \} } } }t | || rd } t|r|qt d || fq| rdS||}t| D] \}}d|f||<q|S)aParse the command-line options for a single command. 'parser' must be a FancyGetopt instance; 'args' must be the list of arguments, starting with the current command (whose options we are about to parse). Returns a new version of 'args' with the next command at the front of the list; will be the empty list if there are no more commands on the command line. Returns None if the user asked for help on this command. rCommandzinvalid command name '%s'Nz&command class %s must subclass Command user_optionszIcommand class %s must provide 'user_options' attribute (a list of tuples)r help_optionsrr"rzYinvalid help function %r for help option '%s': must be a callable object (function, etc.)z command line) distutils.cmdr command_rematch SystemExitrrget_command_classDistutilsModuleErrorr issubclassDistutilsClassErrorrer rrrcopyupdaterfix_help_optionsset_option_tablerrrr"r get_attr_namecallabler_varsr^)rjrrrro cmd_classrrroptshelp_option_found help_optionshortdescfuncrqr$rr r rrsx                  z Distribution._parse_command_optscCsPdD]#}t|j|}|durqt|tr%dd|dD}t|j||qdS)zSet final values for all the options on the Distribution instance, analogous to the .finalize_options() method of Command objects. r2r0NcSg|]}|qSr strip)r8elmr r rr:kz1Distribution.finalize_options..,)rGrEr rr}rC)rjrlrr r rrias  zDistribution.finalize_optionsrc Csddlm}ddlm}|r)|r|}n|j}||||jdt d|r:||j |dt d|j D]=}t |t rLt||rL|} n||} t| drht | jtrh|| jt| jn|| j|d| jt dq=t ||jd S) abShow help for the setup script command-line in the form of several lists of command-line options. 'parser' should be a FancyGetopt instance; do not expect it to be returned in the same state, as its option table will be reset to make it generate the correct help text. If 'global_options' is true, lists the global options: --verbose, --dry-run, etc. If 'display_options' is true, lists the "display-only" options: --name, --version, etc. Finally, lists per-command help for every command name or command class in 'commands'. r gen_usagerz Global options:r<zKInformation display options (just display information, ignore any commands)rzOptions for '%s' command:N)distutils.corerrrrrr print_help common_usageprintrrr rrrrerrrrrrJ) rjrrrrrrr=roklassr r rrns:           zDistribution._show_helpc Csddlm}|jr|tdt||jdSd}i}|jD]}d||d<q!|D]6\}}|rb||rbt|}t |j d|}|dvrPtd |n|dvr\td |nt|d}q,|S) zIf there were any non-global "display-only" options (--help-commands or the metadata display options) on the command line, display the requested info and return true; else return false. rrr<rr;rr)r1r3r4r5r>) rr help_commandsprint_commandsrrJrr]rrGrEr) rjrrany_display_optionsis_display_optionoptionrrrsrr r rrs,   z#Distribution.handle_display_optionsc Csht|d|D])}|j|}|s||}z|j}Wn ty'd}Ynwtd|||fqdS)zZPrint a subset of the list of all commands -- used by 'print_commands()'. :(no description available)z %-*s %sN)rrHr]rr/AttributeError)rjrr~ max_lengthcmdrr/r r rprint_command_lists     zDistribution.print_command_listcCsddl}|jj}i}|D]}d||<q g}|jD] }||s&||qd}||D] }t||kr9t|}q-||d||rOt ||d|dSdS)anPrint out a help message listing all available commands with a description of each. The list is divided into "standard commands" (listed in distutils.command.__all__) and "extra commands" (mentioned in self.cmdclass, but not a standard command). The descriptions come from the command class attribute 'description'. rNrzStandard commandszExtra commands) distutils.commandro__all__rHr{r]rrrr)rjr std_commandsis_stdrextra_commandsrr r rrs4     zDistribution.print_commandsc Csddl}|jj}i}|D]}d||<q g}|jD] }||s&||qg}||D]'}|j|}|s<||}z|j}Wn t yLd}Ynw|||fq-|S)a>Get a list of (command, description) tuples. The list is divided into "standard commands" (listed in distutils.command.__all__) and "extra commands" (mentioned in self.cmdclass, but not a standard command). The descriptions come from the command class attribute 'description'. rNrr) rrorrHr{r]rrr/r) rjrrrrrrvrr/r r rget_command_lists,         zDistribution.get_command_listcCsN|j}t|ts%|durd}dd|dD}d|vr"|dd||_|S)z9Return a list of packages from which commands are loaded.Nr<cSsg|] }|dkr|qS)r<r)r8pkgr r rr:"sz5Distribution.get_command_packages..rzdistutils.commandr)rIr rr}insert)rjpkgsr r rget_command_packagess  z!Distribution.get_command_packagesc Cs|j|}|r |S|D]?}d||f}|}z t|tj|}Wn ty,Yqwzt||}WntyDt d|||fw||j|<|St d|)aoReturn the class that implements the Distutils command named by 'command'. First we check the 'cmdclass' dictionary; if the command is mentioned there, we fetch the class object from the dictionary and return it. Otherwise we load the command module ("distutils.command." + command) and fetch the command class from the module. The loaded class is also stored in 'cmdclass' to speed future calls to 'get_command_class()'. Raises DistutilsModuleError if the expected module could not be found, or if that module does not define the expected class. z%s.%sz3invalid command '%s' (no class '%s' in module '%s')zinvalid command '%s') rHr]r __import__rbr ImportErrorrGrr)rjrorpkgname module_name klass_namemoduler r rr(s0       zDistribution.get_command_classcCsl|j|}|s4|r4tr|d|||}||}|j|<d|j|<|j|}|r4||||S)aReturn the command object for 'command'. Normally this object is cached on a previous call to 'get_command_obj()'; if no command object for 'command' is in the cache, then we either create and return it (if 'create' is true) or return None. z.z1error in %s: command '%s' has no such option '%s')get_command_namer_r r|r^boolean_optionsrrr rrCrrerr) rjr[ option_dict command_namersourcer bool_optsneg_opt is_stringrr r rrisR          z!Distribution._set_command_optionsrcCs|ddlm}t||s|}||}n|}|js|S|d|_d|j|<|||r<| D]}| ||q3|S)aReinitializes a command to the state it was in when first returned by 'get_command_obj()': ie., initialized but not yet finalized. This provides the opportunity to sneak option values in programmatically, overriding or supplementing user-supplied values from the config files and command line. You'll have to re-finalize the command object (by calling 'finalize_options()' or 'ensure_finalized()') before using it for real. 'command' should be a command name (string) or command object. If 'reinit_subcommands' is true, also reinitializes the command's sub-commands, as declared by the 'sub_commands' class attribute (if it has one). See the "install" command for an example. Only reinitializes the sub-commands that actually matter, ie. those whose test predicates return true. Returns the reinitialized command object. rr) rrr r r  finalizedinitialize_optionsr\rget_sub_commandsreinitialize_command)rjroreinit_subcommandsrrsubr r rrs      z!Distribution.reinitialize_commandcCst||dSNr )rjrlevelr r rr|zDistribution.announcecCs|jD]}||qdS)zRun each command that was seen on the setup script command line. Uses the list of commands found and cache of command objects created by 'get_command_obj()'. N)r run_command)rjrr r r run_commandss  zDistribution.run_commandscCsD|j|rdStd|||}||d|j|<dS)aDo whatever it takes to run a command (including nothing at all, if the command has already been run). Specifically: if we have already created and run the command named by 'command', return silently without doing anything. If the command named by 'command' doesn't even have a command object yet, create one. Then invoke 'run()' on that command object (or an existing one). Nz running %sr)r\r]r infor ensure_finalizedrun)rjror r r rrs   zDistribution.run_commandcCst|jp|jpgdkSNr)rrNrQrr r rhas_pure_modulesszDistribution.has_pure_modulescC|jo t|jdkSr#)rTrrr r rhas_ext_moduleszDistribution.has_ext_modulescCr%r#)rRrrr r rhas_c_librariesr'zDistribution.has_c_librariescCs|p|Sr)r$r&rr r r has_modulesrzDistribution.has_modulescCr%r#)rSrrr r r has_headersr'zDistribution.has_headerscCr%r#)rXrrr r r has_scriptsr'zDistribution.has_scriptscCr%r#)rYrrr r rhas_data_filesr'zDistribution.has_data_filescCs|o | o | Sr)r$r&r(rr r ris_pures zDistribution.is_purer)NNr<)rr6))r __module__ __qualname____doc__rrrrBrrvr_rrrrrrrirrrrrrrr rrr INFOr|rrr$r&r(r)r*r+r,r-r r r rr-sP ,   0:C [  2(!" &  ,)  rc@seZdZdZdZdBddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZddZd d!Zd"d#ZeZd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Z d:d;Z!dd?Z#d@dAZ$dS)CrDz]Dummy class to hold the distribution meta-data: name, version, author, and so forth. )r$r%r( author_emailr*maintainer_emailr,r-r/long_descriptionr2r0r'r+ contact_emailr1 download_urlr3r4r5NcCs|dur |t|dSd|_d|_d|_d|_d|_d|_d|_d|_ d|_ d|_ d|_ d|_ d|_d|_d|_d|_d|_dSr) read_pkg_fileopenr$r%r(r2r*r3r,r-r/r4r2r0r1r6r3r4r5)rjrr r rrvs& zDistributionMetadata.__init__cst|fdd}fdd}d}|d|_|d|_|d|_|d |_d |_|d |_d |_|d |_|d |_ dvrG|d|_ nd |_ |d|_ |d|_dvr`|d d|_ |d|_|d|_|dkr|d|_|d|_|d|_d Sd |_d |_d |_d S)z-Reads the metadata values from a file object.cs|}|dkr dS|SNUNKNOWNr )r$rrr r _read_field)sz7DistributionMetadata.read_pkg_file.._read_fieldcs|d}|gkr dS|Sr)get_all)r$valuesr;r r _read_list/s z6DistributionMetadata.read_pkg_file.._read_listzmetadata-versionr$r%summaryr(Nr)z home-pager-z download-urlr/r2rplatform classifier1.1r4r3r5)rr$r%r/r(r*r2r3r,r-r6r4r}r2r0r1r4r3r5)rjfiler<r?metadata_versionr r;rr7%s:                 z"DistributionMetadata.read_pkg_filecCsHttj|dddd}||WddS1swYdS)z7Write the PKG-INFO file into the release tree. zPKG-INFOwzUTF-8)encodingN)r8rrrwrite_pkg_file)rjbase_dirpkg_infor r rwrite_pkg_infoYs  "z#DistributionMetadata.write_pkg_infocCs`d}|js|js|js|js|jrd}|d||d||d||d||d| |d| |d | |d | |jrd|d |jt |}|d |d |}|r|d|||d|||d|||d|||d|||d|dS)z9Write the PKG-INFO format data to a file object. z1.0rCzMetadata-Version: %s z Name: %s z Version: %s z Summary: %s zHome-page: %s z Author: %s zAuthor-email: %s z License: %s zDownload-URL: %s zDescription: %s rz Keywords: %s Platform ClassifierRequiresProvides ObsoletesN)r3r4r5r1r6rdget_name get_versionget_descriptionget_url get_contactget_contact_email get_licenserget_long_descriptionr get_keywords _write_list get_platformsget_classifiers get_requires get_provides get_obsoletes)rjrDr% long_descr2r r rrH`s6 z#DistributionMetadata.write_pkg_filecCs |D] }|d||fqdS)Nz%s: %s )rd)rjrDr$r>rr r rrZsz DistributionMetadata._write_listcC |jpdSr9)r$rr r rrQ zDistributionMetadata.get_namecCra)Nz0.0.0)r%rr r rrRrbz DistributionMetadata.get_versioncCsd||fS)Nz%s-%s)rQrRrr r r get_fullnamer'z!DistributionMetadata.get_fullnamecCrar9)r(rr r r get_authorrbzDistributionMetadata.get_authorcCrar9)r2rr r rget_author_emailrbz%DistributionMetadata.get_author_emailcCrar9)r*rr r rget_maintainerrbz#DistributionMetadata.get_maintainercCrar9)r3rr r rget_maintainer_emailrbz)DistributionMetadata.get_maintainer_emailcC|jp|jpdSr9)r*r(rr r rrUrz DistributionMetadata.get_contactcCrhr9)r3r2rr r rrVrz&DistributionMetadata.get_contact_emailcCrar9)r,rr r rrTrbzDistributionMetadata.get_urlcCrar9)r-rr r rrWrbz DistributionMetadata.get_licensecCrar9)r/rr r rrSrbz$DistributionMetadata.get_descriptioncCrar9)r4rr r rrXrbz)DistributionMetadata.get_long_descriptioncC |jpgSr)r2rr r rrYrbz!DistributionMetadata.get_keywordscCt|d|_dS)Nr2)rr2rjrr r r set_keywordsrz!DistributionMetadata.set_keywordscCs |jpdgSr9)r0rr r rr[s z"DistributionMetadata.get_platformscCrj)Nr0)rr0rkr r r set_platformsrz"DistributionMetadata.set_platformscCrir)r1rr r rr\rbz$DistributionMetadata.get_classifierscCrj)Nr1)rr1rkr r rset_classifiersrz$DistributionMetadata.set_classifierscCrar9)r6rr r rget_download_urlrbz%DistributionMetadata.get_download_urlcCrir)r4rr r rr]rbz!DistributionMetadata.get_requirescC,ddl}|D]}|j|qt||_dSr#)distutils.versionpredicateversionpredicateVersionPredicaterr4rjrrrr r r set_requiresz!DistributionMetadata.set_requirescCrir)r3rr r rr^rbz!DistributionMetadata.get_providescCs6dd|D}|D] }ddl}|j|q ||_dS)NcSrr r)r8rr r rr:rz5DistributionMetadata.set_provides..r)rqrrsplit_provisionr3)rjrrrr r r set_providess  z!DistributionMetadata.set_providescCrir)r5rr r rr_rbz"DistributionMetadata.get_obsoletescCrpr#)rqrrrsrr5rtr r r set_obsoletesrvz"DistributionMetadata.set_obsoletesr)%rr.r/r0rFrvr7rKrHrZrQrRrcrdrerfrgrUrVrTrW get_licencerSrXrYrlr[rmr\rnror]rur^rxr_ryr r r rrDsF 4" rDcCs$g}|D] }||ddq|S)zConvert a 4-tuple 'help_options' list as found in various command classes to the 3-tuple form required by FancyGetopt. r)r)r= new_options help_tupler r rrsr)r0rbrreemailrr`rdistutils.errorsdistutils.fancy_getoptrrdistutils.utilrrrrr distutils.debugr compilerrrrDrr r r rs8      Z cPKH]H<<Qpython3.10/site-packages/setuptools/_distutils/__pycache__/config.cpython-310.pycnu[o Xai@s<dZddlZddlmZddlmZdZGdddeZdS)zdistutils.pypirc Provides the PyPIRCCommand class, the base class for the command classes that uses .pypirc in the distutils.command package. N)RawConfigParser)CommandzE[distutils] index-servers = pypi [pypi] username:%s password:%s c@sheZdZdZdZdZdZdZdddefdgZd gZ d d Z d d Z ddZ ddZ ddZddZdS) PyPIRCCommandz;Base command that knows how to handle the .pypirc file zhttps://upload.pypi.org/legacy/pypiNz repository=rzurl of repository [default: %s]) show-responseNz&display full response text from serverrcCstjtjddS)zReturns rc file path.~z.pypirc)ospathjoin expanduserselfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/config.py _get_rc_file&szPyPIRCCommand._get_rc_filecCs^|}tt|tjtjBdd}|t||fWddS1s(wYdS)zCreates a default .pypirc file.iwN)rr fdopenopenO_CREATO_WRONLYwriteDEFAULT_PYPIRC)rusernamepasswordrcfrrr _store_pypirc*s "zPyPIRCCommand._store_pypircc Cs|}tj|r|d||jp|j}t}||| }d|vr| dd}dd| dD}|gkrEd|vrCdg}niS|D]U}d|i}| |d |d <d |jfd |j fd fD]\} } | || rs| || || <q`| || <q`|dkr||jdfvr|j|d <|S|d|ks|d |kr|SqGiSd |vrd }| |d r| |d }n|j}| |d | |d|||j dSiS)zReads the .pypirc file.zUsing PyPI login from %s distutilsz index-serverscSs g|] }|dkr|qS))strip).0serverrrr =s z.PyPIRCCommand._read_pypirc.. rr"r repositoryrealm)rNz server-loginr)rrr%r"r&)rr r existsannouncer%DEFAULT_REPOSITORYrreadsectionsgetsplit DEFAULT_REALM has_option) rrr%configr+ index_servers_serversr"currentkeydefaultrrr _read_pypirc0sb            zPyPIRCCommand._read_pypirccCs8ddl}|dd}||ddd}||S)z%Read and decode a PyPI HTTP response.rNz content-typez text/plaincharsetascii)cgi getheader parse_headerr,r*decode)rresponser: content_typeencodingrrr_read_pypi_responseps z!PyPIRCCommand._read_pypi_responsecCsd|_d|_d|_dS)zInitialize options.Nr)r%r& show_responser rrrinitialize_optionsws z PyPIRCCommand.initialize_optionscCs,|jdur |j|_|jdur|j|_dSdS)zFinalizes options.N)r%r)r&r.r rrrfinalize_options}s   zPyPIRCCommand.finalize_options)__name__ __module__ __qualname____doc__r)r.r%r& user_optionsboolean_optionsrrr6rArCrDrrrrrs(@ r)rHr configparserr distutils.cmdrrrrrrrs    PKH]q$%B6B6Xpython3.10/site-packages/setuptools/_distutils/__pycache__/_msvccompiler.cpython-310.pycnu[o XaiMQ@sdZddlZddlZddlZddlZddlZee ddl Z Wdn1s*wYddl m Z m Z m Z mZmZddlmZmZddlmZddlmZddlmZdd Zd d Zd d dddZddZddZdddZd ddddZGdddeZ dS)adistutils._msvccompiler Contains MSVCCompiler, an implementation of the abstract CCompiler class for Microsoft Visual Studio 2015. The module is compatible with VS 2015 and later. You can find legacy support for older versions in distutils.msvc9compiler and distutils.msvccompiler. N)DistutilsExecErrorDistutilsPlatformError CompileErrorLibError LinkError) CCompilergen_lib_options)log) get_platform)countc Cs ztjtjdtjtjBd}WntytdYdSwd}d}|_tD]F}z t ||\}}}Wn ty@Yn:w|ro|tj krot j |roztt|}Wn ttfyaYq)w|dkro||kro||}}q)Wd||fSWd||fS1swY||fS)Nz'Software\Microsoft\VisualStudio\SxS\VC7)accesszVisual C++ is not registeredNNr)winreg OpenKeyExHKEY_LOCAL_MACHINEZKEY_READZKEY_WOW64_32KEYOSErrorr debugr Z EnumValueREG_SZospathisdirintfloat ValueError TypeError)key best_versionbest_dirivZvc_dirZvtversionr"/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/_msvccompiler.py _find_vc2015 sH           r$c Cstjdp tjd}|sdSztjtj|dddddd d d d d dg ddd}Wntjt t fy:YdSwtj|ddd}tj |rNd|fSdS)aJReturns "15, path" based on the result of invoking vswhere.exe If no install is found, returns "None, None" The version is returned to avoid unnecessarily changing the function result. It may be ignored when the path is not None. If vswhere.exe is not available, by definition, VS 2017 is not installed. zProgramFiles(x86)Z ProgramFilesr zMicrosoft Visual StudioZ Installerz vswhere.exez-latestz -prereleasez -requiresz1Microsoft.VisualStudio.Component.VC.Tools.x86.x64z -propertyZinstallationPathz -products*mbcsstrict)encodingerrorsZVCZ AuxiliaryZBuild) renvironget subprocess check_outputrjoinstripCalledProcessErrorrUnicodeDecodeErrorr)rootrr"r"r# _find_vc2017<s.  r4x86x64armarm64)r5 x86_amd64x86_arm x86_arm64cCs\t\}}|s t\}}|stddStj|d}tj|s*td|dS|dfS)Nz$No suitable Visual C++ version foundr z vcvarsall.batz%s cannot be found)r4r$r rrrr/isfile) plat_spec_rr vcvarsallr"r"r#_find_vcvarsallcs     r@c CstdrddtjDSt|\}}|stdztjd||tj dj ddd }Wntj yI}zt |jtd |jd}~wwd dd d |DD}|S)NZDISTUTILS_USE_SDKcSsi|] \}}||qSr"lower).0rvaluer"r"r# wsz_get_vc_env..zUnable to find vcvarsall.batzcmd /u /c "{}" {} && set)stderrzutf-16lereplace)r)zError executing {}cSs$i|]\}}}|r|r||qSr"rA)rCrr>rDr"r"r#rEscss|]}|dVqdS)=N) partition)rCliner"r"r# sz_get_vc_env..)rgetenvr+itemsr@rr-r.formatSTDOUTdecoder1r erroroutputcmd splitlines)r=r?r>outexcenvr"r"r# _get_vc_envus2     rXcCsN|s tdtj}|D]}tjtj||}tj|r$|Sq |S)atReturn path to an MSVC executable program. Tries to find the program in several places: first, one of the MSVC program search paths from the registry; next, the directories in the PATH environment variable. If any of those work, return an absolute path that is known to exist. If none of them work, just return the original program name, 'exe'. r)rrLsplitpathseprr/abspathr<)Zexepathspfnr"r"r# _find_exes  r_r9r:r;)win32z win-amd64z win-arm32z win-arm64cseZdZdZdZiZdgZgdZdgZdgZ eeee Z dZ dZ d Z d Zd ZZd Zd(ddZd)ddZ d*ddZ d+ddZ  d,ddZ         d-ddZfddZejfddZd d!Zd"d#Zd$d%Zd.d&d'ZZ S)/ MSVCCompilerzwConcrete class that implements an interface to Microsoft Visual C++, as defined by the CCompiler abstract class.Zmsvcz.c)z.ccz.cppz.cxx.rcz.mcz.resz.objz.libz.dllz%s%sz.exercCs t||||d|_d|_dS)NF)r__init__ plat_name initialized)selfverbosedry_runforcer"r"r#rcs zMSVCCompiler.__init__NcCs|jrJd|durt}|tvrtdttt|}t|}|s)td|dd|_|j t j }t d||_ t d||_t d||_t d ||_t d ||_t d ||_|d d t j D] }|rr||t jqe|d d t j D] }|r||t jq}d|_gd|_gd|_gd}gd}g|d|_g|d|_g|ddd|_g|ddd|_g||_g||_t j!df|jt j!df|jt j!df|jt j"df|jt j"df|jt j"df|jt j#df|jt j#df|jt j#df|ji |_$d|_dS)Nzdon't init multiple timesz--plat-name must be one of {}z7Unable to find a compatible Visual Studio installation.rzcl.exezlink.exezlib.exezrc.exezmc.exezmt.exeincludelib)/nologoz/O2/W3z/GLz/DNDEBUGz/MD)rmz/Odz/MDdz/Zirnz/D_DEBUG)rm/INCREMENTAL:NO/LTCG)rmrorpz /DEBUG:FULLz/MANIFEST:EMBED,ID=1z/DLLz/MANIFEST:EMBED,ID=2z/MANIFESTUAC:NOFT)%rer PLAT_TO_VCVARSrrNtuplerXr,_pathsrYrrZr_cclinkerrlrcmcmtZadd_include_dirrstripsepZadd_library_dirZpreprocess_optionscompile_optionscompile_options_debugZ ldflags_exeZldflags_exe_debugZldflags_sharedZldflags_shared_debugZldflags_staticZldflags_static_debugrZ EXECUTABLEZ SHARED_OBJECTZSHARED_LIBRARY_ldflags)rfrdr=Zvc_envr\dirldflagsZ ldflags_debugr"r"r# initializesb                     zMSVCCompiler.initializerjcsXifddjDfddjjDpdfdd}tt||S)Nci|]}|jqSr") obj_extensionrCextrfr"r#rE&z1MSVCCompiler.object_filenames..crr") res_extensionrrr"r#rE'rrjcstj|\}}rtj|}ntj|\}}|tjjtjjfr*|dd}z tj||WSt yDt d |w)NzDon't know how to compile {}) rrsplitextbasename splitdrive startswithrzaltsepr/ LookupErrorrrN)r]baserr>)ext_map output_dir strip_dirr"r# make_out_path,s  z4MSVCCompiler.object_filenames..make_out_path)src_extensions_rc_extensions_mc_extensionslistmap)rfZsource_filenamesrrrr")rrrfrr#object_filenames!szMSVCCompiler.object_filenamesc  CsL|js||||||||} | \}} }} } |pg} | d|r*| |jn| |jd}| D]}z| |\}}Wn tyGYq4w|rPtj |}||j vrZd|}n||j vrfd|}d}n||j vr|}d|}z||jg| ||gWnty}zt|d}~wwq4||jvrtj |}tj |}z.||jd|d||gtj tj |\}}tj ||d }||jd||gWnty}zt|d}~wwq4td |||jg| | }|r|d |||d |||z||Wq4ty#}zt|d}~ww| S) Nz/cFz/Tcz/TpTz/foz-hz-rrbz"Don't know how to compile {} to {}z/EHscz/Fo)rerZ_setup_compileappendextendr|r{KeyErrorrrr[ _c_extensions_cpp_extensionsrspawnrvrrrdirnamerwrrr/rNrt)rfsourcesrZmacros include_dirsr extra_preargsextra_postargsdependsZ compile_infoobjectsZpp_optsbuildZ compile_optsZ add_cpp_optsobjsrcrZ input_optZ output_optmsgZh_dirZrc_dirrr>Zrc_fileargsr"r"r#compileBs              zMSVCCompiler.compilec Cs|js||||\}}|j||d}|||rN|d|g}|r& ztd|jd|| |jg|WdSt yM}zt |d}~wwtd|dS)N)r/OUT:Executing "%s" %s skipping %s (up-to-date)) rer_fix_object_argslibrary_filename _need_linkr rrlr/rrr) rfrZoutput_libnamerr target_langoutput_filenameZlib_argsrr"r"r#create_static_libs$ zMSVCCompiler.create_static_libc Cs|js||||\}}||||}|\}}}|r&|dt|t||||}|dur8tj ||}| ||r|j || f}dd|pKgD}||||d|g}tj |d} |durtj tj|\}}tj | ||}|d|| r| |dd<| r|| tj tj|}||ztd|jd |||jg|WdSty}zt|d}~wwtd |dS) Nz5I don't know what to do with 'runtime_library_dirs': cSsg|]}d|qS)z/EXPORT:r")rCsymr"r"r# rz%MSVCCompiler.link..rrz/IMPLIB:rrr)rerrZ _fix_lib_argswarnstrrrrr/rr}rrrrrrr[mkpathr rrurrr)rfZ target_descrrr libraries library_dirsruntime_library_dirsexport_symbolsrrrZ build_temprZ fixed_argsZlib_optsrZ export_optsZld_argsZdll_nameZdll_extZ implib_filerr"r"r#linksb       zMSVCCompiler.linkcsRttj|jd}|||}tj||dWdS1s!wY|jS)N)PATH)rW)dictrr+rs_fallback_spawnsuperrrD)rfrSrWfallback __class__r"r#rs  zMSVCCompiler.spawnc #stddi}z|VWdSty'}z dt|vrWYd}~nd}~wwtdtjd|t ||_ WddS1sGwYdS)z Discovered in pypa/distutils#15, some tools monkeypatch the compiler, so the 'env' kwarg causes a TypeError. Detect this condition and restore the legacy, unsafe behavior. ZBagr"z!unexpected keyword argument 'env'Nz>Fallback spawn triggered. Please update distutils monkeypatch.z os.environ) typerrwarningsrunittestZmockpatchrrrD)rfrSrWZbagrVrr"r#rs"  "zMSVCCompiler._fallback_spawncCsd|S)Nz /LIBPATH:r"rfr~r"r"r#library_dir_optionszMSVCCompiler.library_dir_optioncCstd)Nz:don't know how to set runtime library search path for MSVC)rrr"r"r#runtime_library_dir_optionsz'MSVCCompiler.runtime_library_dir_optioncCs ||SN)r)rfrlr"r"r#library_option s zMSVCCompiler.library_optioncCs\|r |d|g}n|g}|D]}|D]}tj|||}tj|r*|SqqdS)N_d)rrr/rr<)rfdirsrlrZ try_namesr~nameZlibfiler"r"r#find_library_file#s  zMSVCCompiler.find_library_file)rrrr)rrj)NNNrNNN)NrN) NNNNNrNNNN)r)!__name__ __module__ __qualname____doc__ compiler_typeZ executablesrrrrrrrZstatic_lib_extensionshared_lib_extensionZstatic_lib_formatZshared_lib_formatZ exe_extensionrcrrrrrr contextlibcontextmanagerrrrrr __classcell__r"r"rr#rasb  P " ]  Erar)!rrr-rrZ unittest.mockrsuppress ImportErrorrdistutils.errorsrrrrrZdistutils.ccompilerrr distutilsr distutils.utilr itertoolsr r$r4ZPLAT_SPEC_TO_RUNTIMEr@rXr_rqrar"r"r"r#s<     ! PKH]N Xpython3.10/site-packages/setuptools/_distutils/__pycache__/unixccompiler.cpython-310.pycnu[o Xai8@sdZddlZddlZddlZddlZddlmZddlmZddl m Z m Z m Z ddl mZmZmZmZddlmZejdkrCddlZGd d d e ZdS) a9distutils.unixccompiler Contains the UnixCCompiler class, a subclass of CCompiler that handles the "typical" Unix-style command-line C compiler: * macros defined with -Dname[=value] * macros undefined with -Uname * include search directories specified with -Idir * libraries specified with -lllib * library search directories specified with -Ldir * compile handled by 'cc' (or similar) executable with -c option: compiles .c to .o * link static library handled by 'ar' command (possibly with 'ranlib') * link shared library handled by 'cc -shared' N) sysconfig)newer) CCompilergen_preprocess_optionsgen_lib_options)DistutilsExecError CompileErrorLibError LinkError)logdarwinc @seZdZdZddgdgdgddgdgddgddZejddd kr'd ged <gd Zd Zd Z dZ dZ dZ dZ ZZeZejdkrDdZ  d'ddZddZ d(ddZ    d)ddZddZdd Zd!d"Zd#d$Zd*d%d&ZdS)+ UnixCCompilerunixNccz-sharedarz-cr) preprocessorcompiler compiler_so compiler_cxx linker_so linker_exearchiverranlibr r)z.cz.Cz.ccz.cxxz.cppz.mz.oz.az.soz.dylibz.tbdzlib%s%scygwinz.exec Cs|d||}|\}}}t||} |j| } |r| d|g|r'|| dd<|r.| || ||js?|dus?t||rc|rJ|tj |z| | WdSt yb} zt | d} ~ wwdS)N-or)Z_fix_compile_argsrrextendappendforcermkpathospathdirnamespawnrr) selfsourceZ output_fileZmacros include_dirs extra_preargsextra_postargs fixed_argsignorepp_optsZpp_argsmsgr-/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/unixccompiler.py preprocessUs*      zUnixCCompiler.preprocessc Csd|j}tjdkrt|||}z||||d|g|WdSty1}zt|d}~ww)Nr r)rsysplatform _osx_supportcompiler_fixupr#rr) r$objsrcextZcc_argsr(r+rr,r-r-r._compileos  zUnixCCompiler._compilerc Cs|||\}}|j||d}|||rN|tj|||j|g||j |j rLz ||j |gWdSt yK}zt |d}~wwdSt d|dS)N) output_dirskipping %s (up-to-date))_fix_object_argslibrary_filename _need_linkrr r!r"r#robjectsrrr r debug)r$r=Zoutput_libnamer8r> target_langoutput_filenamer,r-r-r.create_static_libzs*   zUnixCCompiler.create_static_libc Cs|||\}}||||}|\}}}t||||}t|ttdfs(td|dur3tj ||}| ||r||j |d|g}| rMdg|dd<| rU| |dd<| r\| | | tj|zf|tjkrs|jdd}n|jdd}| dkr|jrd}tj|ddkrd}d||vr|d7}d||vstj||d krd}nd}|j||||<tjd krt||}|||WdSty}zt|d}~wwtd |dS) Nz%'output_dir' must be a string or Nonerz-grzc++env=Z ld_so_aixr r9)r:Z _fix_lib_argsr isinstancestrtype TypeErrorr r!joinr<r=rrr"rZ EXECUTABLErrrbasenamer0r1r2r3r#rr r r>)r$Z target_descr=r@r8 libraries library_dirsruntime_library_dirsexport_symbolsr>r'r(Z build_tempr?r)Zlib_optsZld_argsZlinkerioffsetr,r-r-r.links`         zUnixCCompiler.linkcCd|S)N-Lr-)r$dirr-r-r.library_dir_optionz UnixCCompiler.library_dir_optioncCsd|vpd|vS)Ngcczg++r-)r$Z compiler_namer-r-r._is_gccszUnixCCompiler._is_gcccCstjttdd}tjdddkr4ddl m }m }|}|r0||ddgkr0d|Sd |Stjdd d krAd |Stjddd kr[| |rUdd |gSdd |gStddkrfd|Sd|S)NCCrrr )get_macosx_target_ver split_version z -Wl,-rpath,rSZfreebsdz -Wl,-rpath=zhp-uxz-Wl,+sz+sGNULDyesz-Wl,--enable-new-dtags,-Rz-Wl,-R) r r!rJshlexsplitrget_config_varr0r1distutils.utilrZr[rX)r$rTrrZr[Zmacosx_target_verr-r-r.runtime_library_dir_options    z(UnixCCompiler.runtime_library_dir_optioncCrR)Nz-lr-)r$libr-r-r.library_optionrVzUnixCCompiler.library_optioncCs|j|dd}|j|dd}|j|dd}|j|dd}tjdkr8td}td|} | dur3d } n| d } |D]} tj | |} tj | |} tj | |}tj | |}tjdkr| d sl| d r| d stj | | d d|} tj | | d d|} tj | | d d|}tj | | d d|}tj | r| Stj |r|Stj | r| Stj |r|Sq:dS)Nshared)Zlib_typedylib xcode_stubstaticr CFLAGSz-isysroot\s*(\S+)/rCz/System/z/usr/z /usr/local/) r;r0r1rrcresearchgroupr r!rI startswithexists)r$dirsrfr>Zshared_fZdylib_fZ xcode_stub_fZstatic_fcflagsmZsysrootrTrhrirkrjr-r-r.find_library_filesH         zUnixCCompiler.find_library_file)NNNNN)NrN) NNNNNrNNNN)r)__name__ __module__ __qualname__ compiler_typeZ executablesr0r1Zsrc_extensionsZ obj_extensionZstatic_lib_extensionshared_lib_extensionZdylib_lib_extensionZxcode_stub_lib_extensionZstatic_lib_formatZshared_lib_formatZdylib_lib_formatZxcode_stub_lib_formatZ exe_extensionr/r7rArQrUrXrergrvr-r-r-r.r -sN      B'r )__doc__r r0rnra distutilsrdistutils.dep_utilrZdistutils.ccompilerrrrdistutils.errorsrrr r r r1r2r r-r-r-r.s     PKH]NR...Tpython3.10/site-packages/setuptools/_distutils/__pycache__/ccompiler.cpython-310.pycnu[o Xai@sdZddlZddlZddlZddlTddlmZddlmZddl m Z ddl m Z ddl mZmZdd lmZGd d d Zd Zdd dZddddddZddZdddZddZddZdS)zdistutils.ccompiler Contains CCompiler, an abstract base class that defines the interface for the Distutils compiler abstraction model.N)*)spawn) move_file)mkpath) newer_group) split_quotedexecute)logc@sdeZdZdZdZdZdZdZdZdZ dZ dZ ddddddZ gdZ drd d Zd d Zd dZddZddZdsddZddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Z d/d0Z!dsd1d2Z"d3d4Z#d5d6Z$d7d8Z%d9d:Z&  dtd;d<Z'   dud=d>Z(d?d@Z)  dvdAdBZ*dCZ+dDZ,dEZ-          dwdFdGZ.          dwdHdIZ/          dwdJdKZ0        dxdLdMZ1dNdOZ2dPdQZ3dRdSZ4  dydTdUZ5dzdVdWZ6d{dYdZZ7d{d[d\Z8d{d]d^Z9 _ Xd|d`daZ:d}dcddZ;dedfZdkdlZ?dmdnZ@ddpdqZAdS) CCompileraAbstract base class to define the interface that must be implemented by real compiler classes. Also has some utility methods used by several compiler classes. The basic idea behind a compiler abstraction class is that each instance can be used for all the compile/link steps in building a single project. Thus, attributes common to all of those compile and link steps -- include directories, macros to define, libraries to link against, etc. -- are attributes of the compiler instance. To allow for variability in how individual files are treated, most of those attributes may be varied on a per-compilation or per-link basis. Ncc++objc).cz.ccz.cppz.cxxz.m)r r r rcCsb||_||_||_d|_g|_g|_g|_g|_g|_g|_ |j D] }| ||j |q#dSN) dry_runforceverbose output_dirmacros include_dirs libraries library_dirsruntime_library_dirsobjects executableskeysset_executable)selfrrrkeyr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/ccompiler.py__init__UszCCompiler.__init__cKs<|D]}||jvrtd||jjf||||qdS)aDefine the executables (and options for them) that will be run to perform the various stages of compilation. The exact set of executables that may be specified here depends on the compiler class (via the 'executables' class attribute), but most will have: compiler the C/C++ compiler linker_so linker used to create shared objects and libraries linker_exe linker used to create binary executables archiver static library creator On platforms with a command-line (Unix, DOS/Windows), each of these is a string that will be split into executable name and (optional) list of arguments. (Splitting the string is done similarly to how Unix shells operate: words are delimited by spaces, but quotes and backslashes can override this. See 'distutils.util.split_quoted()'.) z$unknown executable '%s' for class %sN)r ValueError __class____name__r)rkwargsrrrr set_executablesys  zCCompiler.set_executablescCs.t|trt||t|dSt|||dSr) isinstancestrsetattrr)rrvaluerrr rs zCCompiler.set_executablecCs0d}|jD]}|d|kr|S|d7}qdS)Nr)r)rnameidefnrrr _find_macros    zCCompiler._find_macrocCs`|D]+}t|tr#t|dvr#t|dts|ddur#t|dts-td|ddqdS)zEnsures that every element of 'definitions' is a valid macro definition, ie. either (name,value) 2-tuple or a (name,) tuple. Do nothing if all definitions are OK, raise TypeError otherwise. )r+r+Nrzinvalid macro definition '%s': z.must be tuple (string,), (string, string), or z(string, None))r'tuplelenr( TypeError)rZ definitionsr.rrr _check_macro_definitionss     z"CCompiler._check_macro_definitionscCs.||}|dur |j|=|j||fdS)a_Define a preprocessor macro for all compilations driven by this compiler object. The optional parameter 'value' should be a string; if it is not supplied, then the macro will be defined without an explicit value and the exact outcome depends on the compiler used (XXX true? does ANSI say anything about this?) Nr/rappend)rr,r*r-rrr define_macros zCCompiler.define_macrocCs0||}|dur |j|=|f}|j|dS)aUndefine a preprocessor macro for all compilations driven by this compiler object. If the same macro is defined by 'define_macro()' and undefined by 'undefine_macro()' the last call takes precedence (including multiple redefinitions or undefinitions). If the macro is redefined/undefined on a per-compilation basis (ie. in the call to 'compile()'), then that takes precedence. Nr5)rr,r-Zundefnrrr undefine_macros zCCompiler.undefine_macrocC|j|dS)zAdd 'dir' to the list of directories that will be searched for header files. The compiler is instructed to search directories in the order in which they are supplied by successive calls to 'add_include_dir()'. N)rr6rdirrrr add_include_dirzCCompiler.add_include_dircC|dd|_dS)aySet the list of directories that will be searched to 'dirs' (a list of strings). Overrides any preceding calls to 'add_include_dir()'; subsequence calls to 'add_include_dir()' add to the list passed to 'set_include_dirs()'. This does not affect any list of standard include directories that the compiler may search by default. Nrrdirsrrr set_include_dirsszCCompiler.set_include_dirscCr9)aAdd 'libname' to the list of libraries that will be included in all links driven by this compiler object. Note that 'libname' should *not* be the name of a file containing a library, but the name of the library itself: the actual filename will be inferred by the linker, the compiler, or the compiler class (depending on the platform). The linker will be instructed to link against libraries in the order they were supplied to 'add_library()' and/or 'set_libraries()'. It is perfectly valid to duplicate library names; the linker will be instructed to link against libraries as many times as they are mentioned. N)rr6)rlibnamerrr add_libraryszCCompiler.add_librarycCr>)zSet the list of libraries to be included in all links driven by this compiler object to 'libnames' (a list of strings). This does not affect any standard system libraries that the linker may include by default. N)r)rZlibnamesrrr set_librarieszCCompiler.set_librariescCr9)a'Add 'dir' to the list of directories that will be searched for libraries specified to 'add_library()' and 'set_libraries()'. The linker will be instructed to search for libraries in the order they are supplied to 'add_library_dir()' and/or 'set_library_dirs()'. N)rr6r:rrr add_library_dirr=zCCompiler.add_library_dircCr>)zSet the list of library search directories to 'dirs' (a list of strings). This does not affect any standard library search path that the linker may search by default. N)rr@rrr set_library_dirs szCCompiler.set_library_dirscCr9)zlAdd 'dir' to the list of directories that will be searched for shared libraries at runtime. N)rr6r:rrr add_runtime_library_dirsz!CCompiler.add_runtime_library_dircCr>)zSet the list of directories to search for shared libraries at runtime to 'dirs' (a list of strings). This does not affect any standard search path that the runtime linker may search by default. N)rr@rrr set_runtime_library_dirsrFz"CCompiler.set_runtime_library_dirscCr9)zAdd 'object' to the list of object files (or analogues, such as explicitly named library files or the output of "resource compilers") to be included in every link driven by this compiler object. N)rr6)robjectrrr add_link_object r=zCCompiler.add_link_objectcCr>)zSet the list of object files (or analogues) to be included in every link to 'objects'. This does not affect any standard object files that the linker may include by default (such as system libraries). N)r)rrrrr set_link_objects(rFzCCompiler.set_link_objectscCs*|dur|j}n t|tstd|dur|j}nt|tr&||jp#g}ntd|dur2|j}nt|ttfrCt||jp@g}ntd|durMg}|j|d|d}t |t |ks_Jt ||}i} t t |D]!} || } || } t j | d} |t j | | | f| | <ql||||| fS)z;Process arguments and decide which source files to compile.N%'output_dir' must be a string or None/'macros' (if supplied) must be a list of tuples6'include_dirs' (if supplied) must be a list of stringsr) strip_dirrr+)rr'r(r3rlistrr1object_filenamesr2gen_preprocess_optionsrangeospathsplitextrdirname)rZoutdirrZincdirssourcesdependsextrarpp_optsbuildr-srcobjextrrr _setup_compile6s>   zCCompiler._setup_compilecCs0|dg}|rdg|dd<|r||dd<|S)Nz-cz-grr)rr]debugbeforecc_argsrrr _get_cc_argsas  zCCompiler._get_cc_argscCs|dur|j}n t|tstd|dur|j}nt|tr&||jp#g}ntd|dur2|j}nt|ttfrCt||jp@g}ntd|||fS)a'Typecheck and fix-up some of the arguments to the 'compile()' method, and return fixed-up values. Specifically: if 'output_dir' is None, replaces it with 'self.output_dir'; ensures that 'macros' is a list, and augments it with 'self.macros'; ensures that 'include_dirs' is a list, and augments it with 'self.include_dirs'. Guarantees that the returned values are of the correct type, i.e. for 'output_dir' either string or None, and for 'macros' and 'include_dirs' either list or None. NrNrOrP)rr'r(r3rrRrr1)rrrrrrr _fix_compile_argsjs"    zCCompiler._fix_compile_argscCs*|j||d}t|t|ksJ|ifS)a,Decide which source files must be recompiled. Determine the list of object files corresponding to 'sources', and figure out which ones really need to be recompiled. Return a list of all object files and a dictionary telling which source files can be skipped. )r)rSr2)rrZrr[rrrr _prep_compiles zCCompiler._prep_compilecCsNt|ttfs tdt|}|dur|j}||fSt|ts#td||fS)zTypecheck and fix up some arguments supplied to various methods. Specifically: ensure that 'objects' is a list; if output_dir is None, replace with self.output_dir. Return fixed versions of 'objects' and 'output_dir'. z,'objects' must be a list or tuple of stringsNrN)r'rRr1r3rr()rrrrrr _fix_object_argss zCCompiler._fix_object_argscCs|dur|j}nt|ttfrt||jpg}ntd|dur%|j}nt|ttfr6t||jp3g}ntd|durB|j}nt|ttfrSt||jpPg}ntd|||fS)a;Typecheck and fix up some of the arguments supplied to the 'link_*' methods. Specifically: ensure that all arguments are lists, and augment them with their permanent versions (eg. 'self.libraries' augments 'libraries'). Return a tuple with fixed versions of all arguments. Nz3'libraries' (if supplied) must be a list of stringsz6'library_dirs' (if supplied) must be a list of stringsz>'runtime_library_dirs' (if supplied) must be a list of strings)rr'rRr1r3rr)rrrrrrr _fix_lib_argss, zCCompiler._fix_lib_argscCs0|jrdS|jrt||dd}|St||}|S)zjReturn true if we need to relink the files listed in 'objects' to recreate 'output_file'. Tnewer)missing)rrr)rr output_filerkrrr _need_links zCCompiler._need_linkc Cszt|ts|g}d}t|j}|D])}tj|\}}|j|}z|j |}||kr0|}|}Wqt y:Yqw|S)z|Detect the language of a given file, or list of files. Uses language_map, and language_order to do the job. N) r'rRr2language_orderrVrWrX language_mapgetindexr") rrZlangrrsourcebaseraZextlangZextindexrrr detect_languages"     zCCompiler.detect_languagecCdS)aPreprocess a single C/C++ source file, named in 'source'. Output will be written to file named 'output_file', or stdout if 'output_file' not supplied. 'macros' is a list of macro definitions as for 'compile()', which will augment the macros set with 'define_macro()' and 'undefine_macro()'. 'include_dirs' is a list of directory names that will be added to the default list. Raises PreprocessError on failure. Nr)rrtrmrr extra_preargsextra_postargsrrr preprocesss zCCompiler.preprocessc  Csr|||||||\}} }} } || ||} | D]} z| | \}}Wn ty+Yqw|| ||| || q| S)aK Compile one or more source files. 'sources' must be a list of filenames, most likely C/C++ files, but in reality anything that can be handled by a particular compiler and compiler class (eg. MSVCCompiler can handle resource files in 'sources'). Return a list of object filenames, one per source filename in 'sources'. Depending on the implementation, not all source files will necessarily be compiled, but all corresponding object filenames will be returned. If 'output_dir' is given, object files will be put under it, while retaining their original path component. That is, "foo/bar.c" normally compiles to "foo/bar.o" (for a Unix implementation); if 'output_dir' is "build", then it would compile to "build/foo/bar.o". 'macros', if given, must be a list of macro definitions. A macro definition is either a (name, value) 2-tuple or a (name,) 1-tuple. The former defines a macro; if the value is None, the macro is defined without an explicit value. The 1-tuple case undefines a macro. Later definitions/redefinitions/ undefinitions take precedence. 'include_dirs', if given, must be a list of strings, the directories to add to the default include file search path for this compilation only. 'debug' is a boolean; if true, the compiler will be instructed to output debug symbols in (or alongside) the object file(s). 'extra_preargs' and 'extra_postargs' are implementation- dependent. On platforms that have the notion of a command-line (e.g. Unix, DOS/Windows), they are most likely lists of strings: extra command-line arguments to prepend/append to the compiler command line. On other platforms, consult the implementation class documentation. In any event, they are intended as an escape hatch for those occasions when the abstract compiler framework doesn't cut the mustard. 'depends', if given, is a list of filenames that all targets depend on. If a source file is older than any file in depends, then the source file will be recompiled. This supports dependency tracking, but only at a coarse granularity. Raises CompileError on failure. )rbrfKeyError_compile)rrZrrrrcrxryr[rr]r^rer`r_rarrr compiles 6  zCCompiler.compilecCrw)zCompile 'src' to product 'obj'.Nr)rr`r_rareryr]rrr r|CzCCompiler._compilecCrw)a&Link a bunch of stuff together to create a static library file. The "bunch of stuff" consists of the list of object files supplied as 'objects', the extra object files supplied to 'add_link_object()' and/or 'set_link_objects()', the libraries supplied to 'add_library()' and/or 'set_libraries()', and the libraries supplied as 'libraries' (if any). 'output_libname' should be a library name, not a filename; the filename will be inferred from the library name. 'output_dir' is the directory where the library file will be put. 'debug' is a boolean; if true, debugging information will be included in the library (note that on most platforms, it is the compile step where this matters: the 'debug' flag is included here just for consistency). 'target_lang' is the target language for which the given objects are being compiled. This allows specific linkage time treatment of certain languages. Raises LibError on failure. Nr)rroutput_libnamerrc target_langrrr create_static_libIszCCompiler.create_static_libZ shared_objectZshared_library executablecCt)auLink a bunch of stuff together to create an executable or shared library file. The "bunch of stuff" consists of the list of object files supplied as 'objects'. 'output_filename' should be a filename. If 'output_dir' is supplied, 'output_filename' is relative to it (i.e. 'output_filename' can provide directory components if needed). 'libraries' is a list of libraries to link against. These are library names, not filenames, since they're translated into filenames in a platform-specific way (eg. "foo" becomes "libfoo.a" on Unix and "foo.lib" on DOS/Windows). However, they can include a directory component, which means the linker will look in that specific directory rather than searching all the normal locations. 'library_dirs', if supplied, should be a list of directories to search for libraries that were specified as bare library names (ie. no directory component). These are on top of the system default and those supplied to 'add_library_dir()' and/or 'set_library_dirs()'. 'runtime_library_dirs' is a list of directories that will be embedded into the shared library and used to search for other shared libraries that *it* depends on at run-time. (This may only be relevant on Unix.) 'export_symbols' is a list of symbols that the shared library will export. (This appears to be relevant only on Windows.) 'debug' is as for 'compile()' and 'create_static_lib()', with the slight distinction that it actually matters on most platforms (as opposed to 'create_static_lib()', which includes a 'debug' flag mostly for form's sake). 'extra_preargs' and 'extra_postargs' are as for 'compile()' (except of course that they supply command-line arguments for the particular linker being used). 'target_lang' is the target language for which the given objects are being compiled. This allows specific linkage time treatment of certain languages. Raises LinkError on failure. NotImplementedError)rZ target_descroutput_filenamerrrrexport_symbolsrcrxry build_temprrrr linkis9zCCompiler.linkc Cs2|tj||j|dd||||||| | | | dS)Nshared)lib_type)rr SHARED_LIBRARYlibrary_filename) rrrrrrrrrcrxryrrrrr link_shared_libs zCCompiler.link_shared_libc Cs(|tj||||||||| | | | dSr)rr SHARED_OBJECT) rrrrrrrrrcrxryrrrrr link_shared_objects zCCompiler.link_shared_objectc Cs.|tj|||||||d||| d| dSr)rr EXECUTABLEexecutable_filename) rrZoutput_prognamerrrrrcrxryrrrr link_executables  zCCompiler.link_executablecCr)zkReturn the compiler option to add 'dir' to the list of directories searched for libraries. rr:rrr library_dir_optionr~zCCompiler.library_dir_optioncCr)zsReturn the compiler option to add 'dir' to the list of directories searched for runtime libraries. rr:rrr runtime_library_dir_optionr~z$CCompiler.runtime_library_dir_optioncCr)zReturn the compiler option to add 'lib' to the list of libraries linked into the shared library or executable. r)rlibrrr library_optionr~zCCompiler.library_optionc Csjddl}|dur g}|durg}|durg}|durg}|jd|dd\}}t|d} z|D] } | d| q/| d|W| n| wz"z |j|g|d } WntyfYWt|d SwWt|nt|wz5z |j | d ||d Wnt t fyYW| D]} t| qd Swtd W| D]} t| qdS| D]} t| qw) zReturn a boolean indicating whether funcname is supported on the current platform. The optional arguments can be used to augment the compilation environment. rNrT)textwz#include "%s" z=int main (int argc, char **argv) { %s(); return 0; } r?Fza.out)rr) tempfilemkstemprVfdopenwritecloser} CompileErrorremover LinkErrorr3) rfuncnameZincludesrrrrfdfnamefZinclrfnrrr has_functionsX        zCCompiler.has_functioncCr)aHSearch the specified list of directories for a static or shared library file 'lib' and return the full path to that file. If 'debug' true, look for a debugging version (if that makes sense on the current platform). Return None if 'lib' wasn't found in any of the specified directories. r)rrArrcrrr find_library_file+szCCompiler.find_library_filecCs|durd}g}|D]>}tj|\}}tj|d}|tj|d}||jvr3td||f|r;tj|}|tj |||j q |S)Nrr+z"unknown file type '%s' (from '%s')) rVrWrX splitdriveisabssrc_extensionsUnknownFileErrorbasenamer6join obj_extension)rZsource_filenamesrQrZ obj_namessrc_namerurarrr rSVs"    zCCompiler.object_filenamescCs0|dusJ|rtj|}tj|||jSr)rVrWrrshared_lib_extensionrrrQrrrr shared_object_filenamegs  z CCompiler.shared_object_filenamecCs4|dusJ|rtj|}tj|||jpdS)Nr)rVrWrr exe_extensionrrrr rms  zCCompiler.executable_filenamestaticc Csl|dusJ|dvrtdt||d}t||d}tj|\}}|||f} |r.d}tj||| S)N)rrZdylibZ xcode_stubz?'lib_type' must be "static", "shared", "dylib", or "xcode_stub"Z _lib_formatZ_lib_extensionr)r"getattrrVrWsplitr) rrCrrQrfmtrar;rufilenamerrr rss  zCCompiler.library_filenamer+cCst|dSr)r rc)rmsglevelrrr announceszCCompiler.announcecCs ddlm}|rt|dSdS)Nr)DEBUG)distutils.debugrprint)rrrrrr debug_prints  zCCompiler.debug_printcCstjd|dS)Nz warning: %s )sysstderrr)rrrrr warnzCCompiler.warncCst||||jdSr)rr)rfuncargsrrrrr rrzCCompiler.executecKst|fd|ji|dS)Nr)rr)rcmdr%rrr rszCCompiler.spawncCst|||jdSN)r)rr)rr_dstrrr rszCCompiler.move_filecCst|||jddSr)rr)rr,moderrr rrzCCompiler.mkpath)rrrr)NNNNN)NNNrNNN)NrN) NNNNNrNNNN)NNNNrNNN)NNNN)r)rr)rrr)r+)Nr+)r)Br$ __module__ __qualname____doc__ compiler_typerrZstatic_lib_extensionrZstatic_lib_formatZshared_lib_formatrrpror!r&rr/r4r7r8r<rBrDrErGrHrIrJrLrMrbrfrgrhrirjrnrvrzr}r|rrrrrrrrrrrrrrSrrrrrrrrrrrrrr r s $   + "    D  A    3 +    r ))zcygwin.*unix)posixr)ntmsvccCsV|durtj}|durtj}tD]\}}t||dus$t||dur(|SqdS)akDetermine the default compiler to use for the given platform. osname should be one of the standard Python OS names (i.e. the ones returned by os.name) and platform the common value returned by sys.platform for the platform in question. The default values are os.name and sys.platform in case the parameters are not given. Nr)rVr,rplatform_default_compilersrematch)osnamerpatterncompilerrrr get_default_compilers  r)Z unixccompilerZ UnixCCompilerzstandard UNIX-style compiler)Z _msvccompilerZ MSVCCompilerzMicrosoft Visual C++)cygwinccompilerZCygwinCCompilerz'Cygwin port of GNU C Compiler for Win32)rZMingw32CCompilerz(Mingw32 port of GNU C Compiler for Win32)Z bcppcompilerZ BCPPCompilerzBorland C++ Compiler)rrcygwinZmingw32ZbcppcCsXddlm}g}tD]}|d|dt|dfq |||}|ddS)zyPrint list of available compilers (used by the "--help-compiler" options to "build", "build_ext", "build_clib"). r) FancyGetoptz compiler=Nr0zList of available compilers:)distutils.fancy_getoptrcompiler_classrr6sort print_help)rZ compilersrZpretty_printerrrr show_compilerss    rc Cs|durtj}z|durt|}t|\}}}Wnty1d|}|dur-|d|}t|wzd|}t|tj|} t | |} Wnt yTt d|tybt d||fw| d||S)a[Generate an instance of some CCompiler subclass for the supplied platform/compiler combination. 'plat' defaults to 'os.name' (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler for that platform. Currently only 'posix' and 'nt' are supported, and the default compilers are "traditional Unix interface" (UnixCCompiler class) and Visual C++ (MSVCCompiler class). Note that it's perfectly possible to ask for a Unix compiler object under Windows, and a Microsoft compiler object under Unix -- if you supply a value for 'compiler', 'plat' is ignored. Nz5don't know how to compile C/C++ code on platform '%s'z with '%s' compilerz distutils.z4can't compile C/C++ code: unable to load module '%s'zBcan't compile C/C++ code: unable to find class '%s' in module '%s') rVr,rrr{DistutilsPlatformError __import__rmodulesvars ImportErrorDistutilsModuleError) platrrrr module_name class_namelong_descriptionrmoduleklassrrr new_compilers>       rcCsg}|D]G}t|trdt|krdksntd|t|dkr.|d|dqt|dkrK|ddurD|d|dq|d|q|D] }|d |qN|S) aGenerate C pre-processor options (-D, -U, -I) as used by at least two types of compilers: the typical Unix compiler and Visual C++. 'macros' is the usual thing, a list of 1- or 2-tuples, where (name,) means undefine (-U) macro 'name', and (name,value) means define (-D) macro 'name' to 'value'. 'include_dirs' is just a list of directory names to be added to the header file search path (-I). Returns a list of command-line options suitable for either Unix compilers or Visual C++. r+r0zPbad macro definition '%s': each element of 'macros' list must be a 1- or 2-tuplez-U%srNz-D%sz-D%s=%sz-I%s)r'r1r2r3r6)rrr]Zmacror;rrr rTs$$   rTc Csg}|D] }|||q|D]}||}t|tr"||}q||q|D]+}tj|\}} |rM||g| } | rE|| q*| d|q*|| |q*|S)acGenerate linker options for searching library directories and linking with specific libraries. 'libraries' and 'library_dirs' are, respectively, lists of library names (not filenames!) and search directories. Returns a list of command-line options suitable for use with some compiler (depending on the two format strings passed in). z6no library file corresponding to '%s' found (skipping)) r6rrr'rRrVrWrrrr) rrrrZlib_optsr;optrlib_dirZlib_nameZlib_filerrr gen_lib_options?s&     r)NN)NNrrr)rrrVrdistutils.errorsdistutils.spawnrdistutils.file_utilrdistutils.dir_utilrdistutils.dep_utilrdistutils.utilrr distutilsr r rrrrrrTrrrrr s:       - -PKH]٨99Opython3.10/site-packages/setuptools/_distutils/__pycache__/core.cpython-310.pycnu[o Xai"@sdZddlZddlZddlmZddlTddlmZddlm Z ddl m Z ddl m Z d Zd d Zdadad Zd ZddZdddZdS)a#distutils.core The only module that needs to be imported to use the Distutils; provides the 'setup' function (which is to be called from the setup script). Also indirectly provides the Distribution and Command classes, although they are really defined in distutils.dist and distutils.cmd. N)DEBUG)*) Distribution)Command) PyPIRCCommand) Extensionzusage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] or: %(script)s --help [cmd1 cmd2 ...] or: %(script)s --help-commands or: %(script)s cmd --help cCstj|}ttS)N)ospathbasenameUSAGEvars) script_namescriptr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/core.py gen_usage s  r) distclassr script_argsoptionsnameversionauthor author_email maintainermaintainer_emailurllicense descriptionlong_descriptionkeywords platforms classifiers download_urlrequiresprovides obsoletes)rsources include_dirs define_macros undef_macros library_dirs librariesruntime_library_dirs extra_objectsextra_compile_argsextra_link_args swig_optsexport_symbolsdependslanguagec Ks|d}|r |d=nt}d|vrtjtjd|d<d|vr)tjdd|d<z||a}Wn tyQ}zd|vrCt d|t d |d|fd}~wwt d krX|S| t rft d |t d krl|Sz|}Wnty}z t t|jd |d}~wwt rt d|t dkr|S|rz|W|Styt dty}zt rtjd|ft d|fd}~wttfy}z t r؂t dt|d}~ww|S)aThe gateway to the Distutils: do everything your setup script needs to do, in a highly flexible and user-driven way. Briefly: create a Distribution instance; find and parse config files; parse the command line; run each Distutils command found there, customized by the options supplied to 'setup()' (as keyword arguments), in config files, and on the command line. The Distribution instance might be an instance of a class supplied via the 'distclass' keyword argument to 'setup'; if no such class is supplied, then the Distribution class (in dist.py) is instantiated. All other arguments to 'setup' (except for 'cmdclass') are used to set attributes of the Distribution instance. The 'cmdclass' argument, if supplied, is a dictionary mapping command names to command classes. Each command encountered on the command line will be turned into a command class, which is in turn instantiated; any class found in 'cmdclass' is used in place of the default, which is (for command 'foo_bar') class 'foo_bar' in module 'distutils.command.foo_bar'. The command class must provide a 'user_options' attribute which is a list of option specifiers for 'distutils.fancy_getopt'. Any command-line options between the current and the next command are used to set attributes of the current command object. When the entire command-line has been successfully parsed, calls the 'run()' method on each command object in turn. This method will be driven entirely by the Distribution object (which each command object has a reference to, thanks to its constructor), and the command-specific options that became attributes of each command object. rr rrNrzerror in setup command: %szerror in %s setup command: %sinitz%options (after parsing config files):configz error: %sz%options (after parsing command line): commandline interruptedz error: %s z error: %szerror: )getrrr r sysargv_setup_distributionDistutilsSetupError SystemExit_setup_stop_afterparse_config_filesrprintdump_option_dictsparse_command_lineDistutilsArgErrorrr run_commandsKeyboardInterruptOSErrorstderrwriteDistutilsErrorCCompilerErrorstr)attrsklassdistmsgokexcrrrsetup9st %      rSruncCs|dvr td|f|atj}d|i}zr< RuntimeError)r r stop_after save_argvgfrrr run_setups4     ra)NrT)__doc__rr:distutils.debugrdistutils.errorsdistutils.distr distutils.cmdrdistutils.configrdistutils.extensionrr rr?r<setup_keywordsextension_keywordsrSrarrrrs"      qPKH]8NbSpython3.10/site-packages/setuptools/_distutils/__pycache__/__init__.cpython-310.pycnu[o Xai@s*dZddlZejdejdZdZdS)zdistutils The main package for the Python Module Distribution Utilities. Normally used from a setup script as from distutils.core import setup setup (...) N T)__doc__sysversionindex __version__localr r /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/__init__.pys PKH]ww8N!N!Tpython3.10/site-packages/setuptools/_distutils/__pycache__/text_file.cpython-310.pycnu[o Xai0@s&dZddlZddlZGdddZdS)ztext_file provides the TextFile class, which gives an interface to text files that (optionally) takes care of stripping comments, ignoring blank lines, and joining lines with backslashes.Nc@steZdZdZddddddddZdddZd d Zd d Zdd dZdddZ dddZ ddZ ddZ ddZ dS)TextFilea Provides a file-like object that takes care of all the things you commonly want to do when processing a text file that has some line-by-line syntax: strip comments (as long as "#" is your comment character), skip blank lines, join adjacent lines by escaping the newline (ie. backslash at end of line), strip leading and/or trailing whitespace. All of these are optional and independently controllable. Provides a 'warn()' method so you can generate warning messages that report physical line number, even if the logical line in question spans multiple physical lines. Also provides 'unreadline()' for implementing line-at-a-time lookahead. Constructor is called as: TextFile (filename=None, file=None, **options) It bombs (RuntimeError) if both 'filename' and 'file' are None; 'filename' should be a string, and 'file' a file object (or something that provides 'readline()' and 'close()' methods). It is recommended that you supply at least 'filename', so that TextFile can include it in warning messages. If 'file' is not supplied, TextFile creates its own using 'io.open()'. The options are all boolean, and affect the value returned by 'readline()': strip_comments [default: true] strip from "#" to end-of-line, as well as any whitespace leading up to the "#" -- unless it is escaped by a backslash lstrip_ws [default: false] strip leading whitespace from each line before returning it rstrip_ws [default: true] strip trailing whitespace (including line terminator!) from each line before returning it skip_blanks [default: true} skip lines that are empty *after* stripping comments and whitespace. (If both lstrip_ws and rstrip_ws are false, then some lines may consist of solely whitespace: these will *not* be skipped, even if 'skip_blanks' is true.) join_lines [default: false] if a backslash is the last non-newline character on a line after stripping comments and whitespace, join the following line to it to form one "logical line"; if N consecutive lines end with a backslash, then N+1 physical lines will be joined to form one logical line. collapse_join [default: false] strip leading whitespace from lines that are joined to their predecessor; only matters if (join_lines and not lstrip_ws) errors [default: 'strict'] error handler used to decode the file content Note that since 'rstrip_ws' can strip the trailing newline, the semantics of 'readline()' must differ from those of the builtin file object's 'readline()' method! In particular, 'readline()' returns None for end-of-file: an empty string might just be a blank line (or an all-whitespace line), if 'rstrip_ws' is true but 'skip_blanks' is not.rstrict)strip_comments skip_blanks lstrip_ws rstrip_ws join_lines collapse_joinerrorsNcKs|dur |dur td|jD]}||vr t||||qt|||j|q|D] }||jvr;td|q.|durF||n ||_||_d|_g|_ dS)zConstruct a new TextFile object. At least one of 'filename' (a string) and 'file' (a file-like object) must be supplied. They keyword argument options are described above and affect the values returned by 'readline()'.Nz7you must supply either or both of 'filename' and 'file'zinvalid TextFile option '%s'r) RuntimeErrordefault_optionskeyssetattrKeyErroropenfilenamefile current_linelinebuf)selfrroptionsoptr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/text_file.py__init__Ns      zTextFile.__init__cCs&||_tj|jd|jd|_d|_dS)zyOpen a new file named 'filename'. This overrides both the 'filename' and 'file' arguments to the constructor.r)r rN)riorr rr)rrrrrros z TextFile.opencCs$|j}d|_d|_d|_|dS)ziClose the current file and forget everything we know about it (filename, current line number).N)rrrclose)rrrrrrvs  zTextFile.closecCsjg}|dur |j}||jdt|ttfr"|dt|n|d||t|d|S)Nz, z lines %d-%d: z line %d: )rappendr isinstancelisttuplestrjoin)rmsglineZoutmsgrrr gen_errors zTextFile.gen_errorcCstd|||)Nzerror: ) ValueErrorr(rr&r'rrrerrorszTextFile.errorcCs tjd|||ddS)aPrint (to stderr) a warning message tied to the current logical line in the current file. If the current logical line in the file spans multiple physical lines, the warning refers to the whole range, eg. "lines 3-5". If 'line' supplied, it overrides the current line number; it may be a list or tuple to indicate a range of physical lines, or an integer for a single physical line.z warning:  N)sysstderrwriter(r*rrrwarns z TextFile.warncCs|jr|jd}|jd=|Sd} |j}|dkrd}|jrW|rW|d}|dkr+n,|dks7||ddkrQ|dd kr?d p@d}|d||}|dkrPqn|d d}|jr|r|durg|d |S|j rn| }||}t |j t r|j dd|j d<n%|j |j dg|_ n|durdSt |j t r|j dd|_ n|j d|_ |jr|jr|}n|jr| }n|jr|}|dks|d kr|jrq|jr|ddkr|dd}q|d dd kr|dd d }q|S)aURead and return a single logical line from the current file (or from an internal buffer if lines have previously been "unread" with 'unreadline()'). If the 'join_lines' option is true, this may involve reading multiple physical lines concatenated into a single string. Updates the current line number, so calling 'warn()' after 'readline()' emits a warning about the physical line(s) just read. Returns None on end-of-file, since the empty string can occur if 'rstrip_ws' is true but 'strip_blanks' is not.rTN#rr\r,z\#z2continuation line immediately precedes end-of-filez\ )rrreadlinerfindstripreplacer r0r lstripr!rr"rrrstripr)rr'Z buildup_lineposeolrrrr5sj                zTextFile.readlinecCs&g} |}|dur |S||q)zWRead and return the list of all logical lines remaining in the current file.TN)r5r )rlinesr'rrr readliness zTextFile.readlinescCs|j|dS)zPush 'line' (a string) onto an internal buffer that will be checked by future 'readline()' calls. Handy for implementing a parser with line-at-a-time lookahead.N)rr )rr'rrr unreadlineszTextFile.unreadline)NN)N)__name__ __module__ __qualname____doc__r rrrr(r+r0r5r>r?rrrrr s&: !  x r)rCr-rrrrrrsPKH]*[Wpython3.10/site-packages/setuptools/_distutils/__pycache__/archive_util.cpython-310.pycnu[o Xai|!@sFdZddlZddlmZddlZzddlZWn ey!dZYnwddlmZddl m Z ddl m Z ddl mZzddlmZWn eyMdZYnwzdd lmZWn eyadZYnwd d Zd d Z  d#ddZd$ddZedgdfedgdfedgdfedgdfedgdfegdfdZdd Z  d%d!d"ZdS)&zodistutils.archive_util Utility functions for creating archive files (tarballs, zip files, that sort of thing).N)warn)DistutilsExecError)spawn)mkpath)log)getpwnam)getgrnamcCLtdus|dur dSzt|}Wn tyd}Ynw|dur$|dSdS)z"Returns a gid, given a group name.N)rKeyErrornameresultr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/archive_util.py_get_gid  rcCr )z"Returns an uid, given a user name.Nr )rr r rrr_get_uid+rrgzipcs2dddddd}dddd d }|d ur||vrtd |d } |dkr-| ||d7} ttj| |ddd l} t dt t fdd} |sp| | d||} z | j || dW| n| w|dkrtdt| ||} tjdkr|| | g}n|d| g}t||d| S| S)a=Create a (possibly compressed) tar file from all the files under 'base_dir'. 'compress' must be "gzip" (the default), "bzip2", "xz", "compress", or None. ("compress" will be deprecated in Python 3.2) 'owner' and 'group' can be used to define an owner and a group for the archive that is being built. If not provided, the current owner and group will be used. The output tar file will be named 'base_dir' + ".tar", possibly plus the appropriate compression extension (".gz", ".bz2", ".xz" or ".Z"). Returns the output filename. gzbz2xz)rbzip2rNcompressz.gzz.bz2z.xzz.Z)rrrrNzKbad value for 'compress': must be None, 'gzip', 'bzip2', 'xz' or 'compress'z.tarrdry_runrzCreating tar archivecs,dur |_|_dur|_|_|S)N)gidgnameuiduname)tarinforgroupownerrrr _set_uid_gidasz"make_tarball.._set_uid_gidzw|%s)filterz'compress' will be deprecated.win32z-f)keys ValueErrorgetrospathdirnametarfilerinforropenaddcloserPendingDeprecationWarningsysplatformr) base_namebase_dirrverboserr$r#tar_compression compress_ext archive_namer.r%tarcompressed_namecmdrr"r make_tarball7sB        r?c Cs|d}ttj||dtdur4|rd}nd}z td|||g|dW|Sty3td|wtd|||sz tj |d tj d }Wnt yZtj |d tj d }Ynw|o|tj krztjtj|d }|||td |t|D]D\}} } | D]} tjtj|| d }|||td |q| D]} tjtj|| }tj|r|||td |qqWd|S1swY|S) avCreate a zip file from all the files under 'base_dir'. The output zip file will be named 'base_name' + ".zip". Uses either the "zipfile" Python module (if available) or the InfoZIP "zip" utility (if installed and found on the default search path). If neither tool is available, raises DistutilsExecError. Returns the name of the output zip file. z.ziprNz-rz-rqzipzkunable to create zip file '%s': could neither import the 'zipfile' module nor find a standalone zip utilityz#creating '%s' and adding '%s' to itw) compressionrz adding '%s')rr+r,r-zipfilerrrr/ZipFile ZIP_DEFLATED RuntimeError ZIP_STOREDcurdirnormpathjoinwritewalkisfile) r6r7r8r zip_filename zipoptionsr@r,dirpathdirnames filenamesr rrr make_zipfilesf  %           rS)rrzgzip'ed tar-file)rrzbzip2'ed tar-file)rrzxz'ed tar-file)rrzcompressed tar file)rNzuncompressed tar filezZIP file)gztarbztarxztarztarr<r@cCs|D] }|tvr |SqdS)zqReturns the first format from the 'format' list that is unknown. If all formats are known, returns None N)ARCHIVE_FORMATS)formatsformatrrrcheck_archive_formatss r[c Cst}|durtd|tj|}|st||dur"tj}d|i} zt|} Wn t y9t d|w| d} | dD]\} } | | | <qB|dkrW|| d<|| d <z| ||fi| }W|durqtd |t||S|durtd |t|ww) aCreate an archive file (eg. zip or tar). 'base_name' is the name of the file to create, minus any format-specific extension; 'format' is the archive format: one of "zip", "tar", "gztar", "bztar", "xztar", or "ztar". 'root_dir' is a directory that will be the root directory of the archive; ie. we typically chdir into 'root_dir' before creating the archive. 'base_dir' is the directory where we start archiving from; ie. 'base_dir' will be the common prefix of all files and directories in the archive. 'root_dir' and 'base_dir' both default to the current directory. Returns the name of the archive file. 'owner' and 'group' are used when creating a tar archive. By default, uses the current owner and group. Nzchanging into '%s'rzunknown archive format '%s'rr@r$r#zchanging back to '%s') r+getcwdrdebugr,abspathchdirrHrXr r))r6rZroot_dirr7r8rr$r#save_cwdkwargs format_infofuncargvalfilenamerrr make_archives<           ri)rrrNN)rr)NNrrNN)__doc__r+warningsrr4rC ImportErrordistutils.errorsrdistutils.spawnrdistutils.dir_utilr distutilsrpwdrgrprrrr?rSrXr[rirrrrsP            H =      PKH];E1E1Tpython3.10/site-packages/setuptools/_distutils/__pycache__/sysconfig.cpython-310.pycnu[o Xai~T@sdZddlZddlZddlZddlZddlmZdejvZej ej Z ej ej Zej ejZej ejZdejvrHej ejdZnejrWej ej ejZneZddZeed dZejd krvd d ZeeZeeZd dZeZdZ zesej!Z Wn e"yYnwddZ#d-ddZ$d.ddZ%ddZ&ddZ'ddZ(d/ddZ)e*dZ+e*dZ,e*d Z-d/d!d"Z.d#d$Z/da0d%d&Z1d'd(Z2d)d*Z3d+d,Z4dS)0aProvide access to Python's configuration information. The specific configuration variables available depend heavily on the platform and configuration. The values may be retrieved using get_config_var(name), and the list of variables is available via get_config_vars().keys(). Additional convenience functions are also available. Written by: Fred L. Drake, Jr. Email: N)DistutilsPlatformErrorZ__pypy__Z_PYTHON_PROJECT_BASEcCs,dD]}tjtj|d|rdSqdS)N)Setupz Setup.localModulesTF)ospathisfilejoin)dfnr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/sysconfig.py_is_python_source_dir,s r_homentcCs0|rtj|tjtjtdrtS|S)NZPCbuild)rrnormcase startswithr PREFIX)r r r r _fix_pcbuild5s rcCstrttSttSN) _sys_homer project_baser r r r _python_build=srcCsdtjddS)zReturn a string containing the major and minor Python version, leaving off the patchlevel. Sample return values could be '1.5' or '2.2'. z%d.%dN)sys version_infor r r r get_python_versionQsrcCs|dur |rtp t}tjdkrItrtjdkrtj|dSt r4|r%t p$t Stjt dd}tj |Str8dnd}|tt}tj|d|Stjd krit rbtj|dtjjtj|d Stj|dStd tj) aReturn the directory containing installed Python header files. If 'plat_specific' is false (the default), this is the path to the non-platform-specific header files, i.e. Python.h and so on; otherwise, this is the path to platform-specific header files (namely pyconfig.h). If 'prefix' is supplied, use it instead of sys.base_prefix or sys.base_exec_prefix -- i.e., ignore 'plat_specific'. NposixincludesrcdirIncludepypypythonrPCzFI don't know where Python installs its C header files on platform '%s')BASE_EXEC_PREFIX BASE_PREFIXrnameIS_PYPYrrrr python_buildrrget_config_varnormpathr build_flagspathsepr) plat_specificprefixincdirimplementation python_dirr r r get_python_incYs0      r6cCstr!tjdkr!|dur t}|rtj|dtjdStj|dS|dur4|r.|r+tp,t }n|r2t p3t}tj dkrb|s=|rDt tdd}nd}trJd nd }tj|||t }|r[|Stj|dStj d krx|rptj|d Stj|d dStd tj )aSReturn the directory containing the Python library (standard or site additions). If 'plat_specific' is true, return the directory containing platform-specific modules, i.e. any module from a non-pure-Python module distribution; otherwise, return the platform-shared library directory. If 'standard_lib' is true, return the directory containing standard Python library modules; otherwise, return the directory for site-specific modules. If 'prefix' is supplied, use it instead of sys.base_prefix or sys.base_exec_prefix -- i.e., ignore 'plat_specific'. rNz lib-pythonrz site-packagesr platlibdirlibr%r&rLibz?I don't know where Python installs its library on platform '%s')r+rrrrrr versionr(r) EXEC_PREFIXr*getattrrr)r1 standard_libr2libdirr4 libpythonr r r get_python_libs<     r@c Cs|jdkrtjdkrtdsddl}|tdtd<tddd d d d d d\}}}}}}}} dtj vrOtj d} d tj vrM| |rM| |t |d}| }dtj vrYtj d}d tj vrctj d }dtj vrntj d} n|d} dtj vr|dtj d}d tj vr|dtj d }|dtj d }dtj vr| dtj d} |dtj d}|dtj d}d tj vrtj d }dtj vr|dtj d} n|d| } |d|} |j | | | d||||| ddtj vr|j ddr|j tj dd||_dSdS)zDo any platform-specific customization of a CCompiler instance. Mainly needed on Unix, so we can plug in the information that varies across Unices and is stored in Python's Makefile. unixdarwinCUSTOMIZED_OSX_COMPILERrNTrueCCCXXCFLAGSCCSHAREDLDSHARED SHLIB_SUFFIXARARFLAGSCPPz -ELDFLAGS CPPFLAGS) preprocessorcompiler compiler_so compiler_cxx linker_so linker_exearchiverZRANLIBranlib)rX) compiler_typerplatformr- _osx_supportcustomize_compiler _config_varsget_config_varsrenvironrlenset_executablesZ executablesgetshared_lib_extension)rRr[cccxxcflagsccsharedldshared shlib_suffixarar_flagsnewcccpprWcc_cmdr r r r\sh                         r\cCsDtrtjdkrtjtp td}n tpt}ntdd}tj|dS)z2Return full pathname of installed pyconfig.h file.rr'rr1z pyconfig.h)r,rr*rr rrr6)inc_dirr r r get_config_h_filenames    rqcCs\tr tjtptdStddd}dtt }t t j dr&|dt j j 7}tj||dS)zAReturn full pathname of installed Makefile from the Python build.Makefilerrr1r=z config-{}{} _multiarchz-%s)r,rrr rrr@formatrr/hasattrrr4rt)lib_dir config_filer r r get_makefile_filenames  rycCs|duri}td}td} |}|s |S||}|r>|dd\}}zt|}Wn ty8Ynw|||<n||}|rLd||d<q)zParse a config.h-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. Nz"#define ([A-Z][A-Za-z0-9_]+) (.*) z&/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/ Trrr)recompilereadlinematchgroupint ValueError)fpg define_rxundef_rxlinemnvr r r parse_config_hs&     rz"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)z\$\(([A-Za-z][A-Za-z0-9_]*)\)z\${([A-Za-z][A-Za-z0-9_]*)}c Csddlm}||ddddd}|duri}i}i} |}|dur#n?t|}|ra|dd\}} | } | d d } d | vrE| ||<nzt| } Wnt y\| d d ||<Ynw| ||<qd } |r1t |D]} || } t | pzt | }|r+|d}d}||vrt||}n>||vrd }n7|tjvrtj|}n,|| vr| dr| dd| vrd }nd||vrd }nt|d|}nd ||<}|r*| |d}| d|||} d |vr| || <qkzt| } Wnt y| || <Ynw| || <|| =| dr*| dd| vr*| dd} | |vr*| || <qk|| =qk|sg||D]\}} t| trI| ||<q9|||S)zParse a Makefile-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. r)TextFilersurrogateescape)strip_comments skip_blanks join_lineserrorsNTrz$$r$)rGrNrPFPY_r )distutils.text_filerr| _variable_rxr}r~stripreplacerrlist _findvar1_rxsearch _findvar2_rxstrrr_rendstartcloseitems isinstanceupdate)r rrrdonenotdonerrrrtmpvrenamed_variablesr*valuefounditemafterkr r r parse_makefileBs                2   rcCsX t|p t|}|r(|\}}|d|||d||d}n |Sq)aExpand Makefile-style variables -- "${foo}" or "$(foo)" -- in 'string' according to 'vars' (a dictionary mapping variable names to values). Variables not present in 'vars' are silently expanded to the empty string. The variable values in 'vars' should not contain further variable expansions; if 'vars' is the output of 'parse_makefile()', you're fine. Returns a variable-expanded version of 's'. TrrN)rrrspanrbr~)svarsrbegrr r r expand_makefile_varss *rc Cstjddjtjtjttjddd}z t |t t dgd}Wnt y5t dt t dgd}Ynw|j }iat|d S) z7Initialize the module as appropriate for POSIX systems._PYTHON_SYSCONFIGDATA_NAMEz+_sysconfigdata_{abi}_{platform}_{multiarch}rtr)abirZ multiarchbuild_time_varsrZ_sysconfigdataN)rr_rbrurabiflagsrZr<r4 __import__globalslocals ImportErrorrr]r)r*_temprr r r _init_posixs"  rcCs~i}tddd|d<tddd|d<tdd|d<td|d<d |d <td d |d <tjtj t j |d<|a dS)z+Initialize the module as appropriate for NTrrrsLIBDEST BINLIBDESTro INCLUDEPY EXT_SUFFIXz.exeEXE.rVERSIONBINDIRN) r@r6_impextension_suffixesrrrrdirnameabspathr executabler])rr r r _init_ntsrcGsLtdurtdtj}|r|niattd<ttd<tstd}|dur,|td<tdt}tjdkrOt rHtj t }tj ||}ntj t }tj tj |td<t rtjdkrt}tj tds|tkrtj |td}tj |td<tjd krd dl}|t|rg}|D] }|t|q|StS) aWith no arguments, return a dictionary of all configuration variables relevant for the current platform. Generally this includes everything needed to build extensions and install both pure modules and extensions. On Unix, this means every variable defined in Python's installed Makefile; on Windows it's a much smaller set. With arguments, return a list of values that result from looking up each argument in the configuration variable dictionary. NZ_init_r2 exec_prefixrSOr#rrBr)r]rrbrr*rr;r+rr,rrryr rr.isabsgetcwdrrZr[customize_config_varsappend)argsfuncrr#baser[valsr*r r r r^sB       r^cCs*|dkrddl}|dtdt|S)zReturn the value of a single variable using the dictionary returned by 'get_config_vars()'. Equivalent to get_config_vars().get(name) rrNz SO is deprecated, use EXT_SUFFIXr)warningswarnDeprecationWarningr^rb)r*rr r r r-:s r-)rN)rrNr)5__doc__rrrzrrrbuiltin_module_namesr+rr.r2rrr; base_prefixr)base_exec_prefixr(r_rrrrrrr<rr*rrr,r/rAttributeErrorrr6r@r\rqryrr{rrrrrr]rrr^r-r r r r sb         +8K    j KPKH]U8DDXpython3.10/site-packages/setuptools/_distutils/__pycache__/msvc9compiler.cpython-310.pycnu[o Xaiv@sLdZddlZddlZddlZddlZddlmZmZmZm Z m Z ddl m Z m Z ddlmZddlmZddlZejZejZejZejZejejejejfZej dkoWej!dkZ"e"rad Z#d Z$d Z%nd Z#d Z$dZ%dddZ&GdddZ'GdddZ(ddZ)ddZ*ddZ+ddZ,d$ddZ-e)Z.e.d kred!e.Gd"d#d#e Z/dS)%a distutils.msvc9compiler Contains MSVCCompiler, an implementation of the abstract CCompiler class for the Microsoft Visual Studio 2008. The module is compatible with VS 2005 and VS 2008. You can find legacy support for older versions of VS in distutils.msvccompiler. N)DistutilsExecErrorDistutilsPlatformError CompileErrorLibError LinkError) CCompilergen_lib_options)log) get_platformwin32lz1Software\Wow6432Node\Microsoft\VisualStudio\%0.1fz5Software\Wow6432Node\Microsoft\Microsoft SDKs\Windowsz,Software\Wow6432Node\Microsoft\.NETFrameworkz%Software\Microsoft\VisualStudio\%0.1fz)Software\Microsoft\Microsoft SDKs\Windowsz Software\Microsoft\.NETFrameworkx86amd64r z win-amd64c@sPeZdZdZddZeeZddZeeZddZeeZdd Ze eZd S) Regz2Helper class to read values from the registry cCs6tD]}|||}|r||vr||Sqt|N)HKEYS read_valuesKeyError)clspathkeybasedr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/msvc9compiler.py get_value?s    z Reg.get_valuecCsfzt||}Wn tyYdSwg}d} zt||}Wn ty(Y|Sw|||d7}q)zReturn list of registry keys.NrT) RegOpenKeyExRegError RegEnumKeyappend)rrrhandleLikrrr read_keysGs"   z Reg.read_keysc Cs~zt||}Wn tyYdSwi}d} z t||\}}}Wn ty+Y|Sw|}|||||<|d7}q)z`Return dict of registry keys and values. All names are converted to lowercase. NrTr)rr RegEnumValuelower convert_mbcs) rrrr!rr#namevaluetyperrrrYs$  zReg.read_valuescCs<t|dd}|durz|d}W|StyY|Sw|S)Ndecodembcs)getattr UnicodeError)sdecrrrr(os   zReg.convert_mbcsN) __name__ __module__ __qualname____doc__r classmethodr%rr( staticmethodrrrrr;s rc@s,eZdZddZddZddZddZd S) MacroExpandercCsi|_t||_||dSr)macrosVS_BASEvsbase load_macros)selfversionrrr__init__{s zMacroExpander.__init__cCst|||jd|<dS)Nz$(%s))rrr9)r=Zmacrorrrrr set_macroszMacroExpander.set_macroc Cs|d|jdd|d|jdd|dtdz|dkr(|d td ntd Wn ty8td w|d krN|d |jd|dtddSd}tD])}zt||}Wn tydYqRwt |d}t |d||f}|d|j d<qRdS)NZ VCInstallDirz \Setup\VC productdirZ VSInstallDirz \Setup\VSZ FrameworkDirZ installroot @ZFrameworkSDKDirzsdkinstallrootv2.0aPython was built with Visual Studio 2008; extensions must be built with a compiler than can generate compatible binaries. Visual Studio 2008 was not found on this system. If you have Cygwin installed, you can try compiling with MingW32, by passing "-c mingw32" to setup.py.g"@ZFrameworkVersionz clr versionZ WindowsSdkDirZcurrentinstallfolderz.Software\Microsoft\NET Framework Setup\Productrz%s\%sr>z$(FrameworkVersion)) r@r;NET_BASErr WINSDK_BASErrrrrrr9)r=r>prhrrrrrr<s:   zMacroExpander.load_macroscCs$|jD] \}}|||}q|Sr)r9itemsreplace)r=r0r$vrrrsubszMacroExpander.subN)r2r3r4r?r@r<rJrrrrr8ys  r8cCsd}tj|}|dkrdS|t|}tj|ddd\}}t|ddd}|dkr3|d7}t|d d d }|dkrCd }|dkrK||SdS) zReturn the version of MSVC that was used to build Python. For Python 2.3 and up, the version number is included in sys.version. For earlier versions, assume the compiler is MSVC 6. zMSC v.N r g$@r)sysr>findlensplitint)prefixr#r0restZ majorVersionZ minorVersionrrrget_build_versions  rYcCs0g}|D]}tj|}||vr||q|S)znReturn a list of normalized paths with duplicates removed. The current order of paths is maintained. )osrnormpathr )pathsZ reduced_pathsrEnprrrnormalize_and_reduce_pathss  r^cCs<|tj}g}|D] }||vr||q tj|}|S)z8Remove duplicate values of an environment variable. )rUrZpathsepr join)variableZoldListZnewListr#Z newVariablerrrremoveDuplicatess   rbcCst|}z td|d}Wntytdd}Ynw|r'tj|sbd|}tj |d}|r[tj|r[tj |tj tj d}tj |}tj|sZtd|dSntd||sktd dStj |d }tj|rz|Std dS) zFind the vcvarsall.bat file At first it tries to find the productdir of VS 2008 in the registry. If that fails it falls back to the VS90COMNTOOLS env var. z %s\Setup\VCrAz%Unable to find productdir in registryNzVS%0.f0COMNTOOLSZVCz%s is not a valid directoryz Env var %s is not set or invalidzNo productdir foundz vcvarsall.batUnable to find vcvarsall.bat)r:rrrr debugrZrisdirenvirongetr`pardirabspathisfile)r>r;rAZtoolskeyZtoolsdir vcvarsallrrrfind_vcvarsalls8        rlc CsFt|}hd}i}|durtdtd||tjd||ftjtjd}z\|\}}|dkr;t| d| d}| d D]2}t |}d |vrQqE| }| d d \} } | } | |vrw| tjrq| dd } t| || <qEW|j|jn |j|jwt|t|krttt||S) zDLaunch vcvarsall.bat and read the settings from its environment >ZlibpathincludelibrNrcz'Calling 'vcvarsall.bat %s' (version=%s)z "%s" %s & set)stdoutstderrrr- =rrK)rlrr rd subprocessPopenPIPE communicatewaitr,rUrr(stripr'endswithrZr_rbrocloserprT ValueErrorstrlistkeys) r>archrk interestingresultpopenrorplinerr*rrrquery_vcvarsallsF         rrBz(VC %0.1f is not supported by this modulec@seZdZdZdZiZdgZgdZdgZdgZ eeee Z dZ dZ d Z d Zd ZZd Zd,ddZd-ddZ d.ddZ d/ddZ  d0ddZ         d1ddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd2d(d)Zd*d+ZdS)3 MSVCCompilerzwConcrete class that implements an interface to Microsoft Visual C++, as defined by the CCompiler abstract class.Zmsvcz.c)z.ccz.cppz.cxx.rcz.mcz.resz.objz.libz.dllz%s%sz.exercCs8t||||t|_d|_g|_d|_d|_d|_dS)NzSoftware\Microsoft\VisualStudioF) rr?VERSION_MSVCCompiler__versionZ_MSVCCompiler__root_MSVCCompiler__paths plat_name_MSVCCompiler__arch initialized)r=verbosedry_runforcerrrr?Hs zMSVCCompiler.__init__NcCs|jrJd|durt}d}||vrtd|fdtjvr:dtjvr:|dr:d|_d|_d|_d |_ d |_ na|tksC|d krHt |}n t td t |}t t |}|d tj|_|dtjd<|dtjd<t|jdkr}td|j|d|_|d|_|d|_|d |_ |d |_ ztjd dD]}|j|qWn tyYnwt|j|_d|jtjd <d|_|jdkrgd|_gd|_n gd|_gd|_gd|_|jdkrgd|_dg|_d|_dS)Nzdon't init multiple timesrz--plat-name must be one of %sZDISTUTILS_USE_SDKZMSSdkzcl.exezlink.exezlib.exezrc.exezmc.exer _rrnrmrzxPython was built with %s, and extensions need to be built with the same version of the compiler, but it isn't installed.;r )/nologo/O2/MD/W3/DNDEBUG)r/Od/MDdr/Z7/D_DEBUG)rrrr/GS-r)rrrrrrr)/DLLrz/INCREMENTAL:NO)rrz/INCREMENTAL:noz/DEBUGrT)rr rrZrffind_execclinkerrnrcmcPLAT_TO_VCVARSrrrUr_rrTZ_MSVCCompiler__productr rr^r`Zpreprocess_optionsrcompile_optionscompile_options_debugldflags_sharedrldflags_shared_debugZldflags_static)r=rZok_platsZ plat_specZvc_envrErrr initializeSsh                   zMSVCCompiler.initializecCs|durd}g}|D]b}tj|\}}tj|d}|tj|d}||jvr1td||r9tj|}||jvrL| tj |||j q ||j vr_| tj |||j q | tj |||j q |S)NrrzDon't know how to compile %s)rZrsplitext splitdriveisabssrc_extensionsrbasename_rc_extensionsr r` res_extension_mc_extensions obj_extension)r=Zsource_filenamesZ strip_dir output_dirZ obj_namessrc_namerextrrrobject_filenamess,         zMSVCCompiler.object_filenamesc  Cs8|js||||||||} | \}} }} } |pg} | d|r*| |jn| |j| D]}z| |\}}Wn tyEYq2w|rNtj |}||j vrXd|}n||j vrbd|}n||j vr|}d|}z||jg| |g|gWnty}zt|d}~wwq2||jvrtj |}tj |}z6||jgd|d|g|gtj tj |\}}tj ||d}||jgd|g|gWnty}zt|d}~wwq2td||fd |}z||jg| | ||g|Wq2ty}zt|d}~ww| S) Nz/cz/Tcz/Tpz/foz-hz-rrz"Don't know how to compile %s to %sz/Fo)rrZ_setup_compiler extendrrrrZrri _c_extensions_cpp_extensionsrspawnrrrrdirnamerrrr`r)r=sourcesrr9 include_dirsrd extra_preargsextra_postargsdependsZ compile_infoobjectsZpp_optsbuildZ compile_optsobjsrcrZ input_optZ output_optmsgZh_dirZrc_dirrrZrc_filerrrcompiles                  zMSVCCompiler.compilec Cs|js||||\}}|j||d}|||rC|d|g}|r& z ||jg|WdStyB}zt|d}~wwt d|dS)N)r/OUT:skipping %s (up-to-date)) rr_fix_object_argslibrary_filename _need_linkrrnrrr rd) r=rZoutput_libnamerrd target_langoutput_filenameZlib_argsrrrrcreate_static_libs" zMSVCCompiler.create_static_libc Cs<|js||||\}}||||}|\}}}|r&|dt|t||||}|dur8tj ||}| ||r|t j krV| rN|j dd}n|jdd}n | r\|j }n|j}g}|pdgD] }|d|qe||||d|g}tj|d} |durtjtj|\}}tj | ||}|d|||| || r| |dd<| r|| |tj|z ||jg|Wnty}zt|d}~ww|||}|dur|\}}d||f}z |dd d ||gWdSty}zt|d}~wwdStd |dS) Nz5I don't know what to do with 'runtime_library_dirs': rz/EXPORT:rrz/IMPLIB:z-outputresource:%s;%szmt.exez-nologoz -manifestr)rrrZ _fix_lib_argswarnr|rrZrr`rr EXECUTABLErrr rrrrmanifest_setup_ldargsrmkpathrrrrmanifest_get_embed_infor rd)r= target_descrrr libraries library_dirsruntime_library_dirsexport_symbolsrdrr build_temprZ fixed_argsZlib_optsZldflagsZ export_optssymld_argsZdll_nameZdll_extZ implib_filerZmfinfoZ mffilenamemfidZout_argrrrlink5s             zMSVCCompiler.linkcCs,tj|tj|d}|d|dS)Nz .manifest/MANIFESTFILE:)rZrr`rr )r=rrr temp_manifestrrrrs z"MSVCCompiler.manifest_setup_ldargscCs^|D]}|dr|ddd}nqdS|tjkrd}nd}||}|dur+dS||fS)Nr:rrP) startswithrUrr_remove_visual_c_ref)r=rrargrrrrrrs   z$MSVCCompiler.manifest_get_embed_infocCszUt|}z |}W|n|wtdtj}t|d|}d}t|d|}tdtj}t||dur>WdSt|d}z |||W|WS|wt y_YdSw)NzU|)rz*\s*zI|)w) openreadrzrerDOTALLrJsearchwriteOSError)r=Z manifest_fileZ manifest_fZ manifest_bufpatternrrrrs4     z!MSVCCompiler._remove_visual_c_refcCsd|S)Nz /LIBPATH:rr=dirrrrlibrary_dir_optionszMSVCCompiler.library_dir_optioncCstd)NzsR  >. #) PKH]- Ppython3.10/site-packages/setuptools/_distutils/__pycache__/spawn.cpython-310.pycnu[o Xai @s\dZddlZddlZddlZddlmZmZddlmZddl m Z d ddZ d d d Z dS) zdistutils.spawn Provides the 'spawn()' function, a front-end to various platform- specific functions for launching another program in a sub-process. Also provides the 'find_executable()' to search the path for a given executable name. N)DistutilsPlatformErrorDistutilsExecError)DEBUG)logc Cst|}tt||rdS|r t|d}|dur ||d<|dur&|nttj}t j dkrAddl m }m }|}|rA|||<ztj||d} | | j} Wntyo} zts_|d}td|| jdf| d} ~ ww| rtsx|d}td|| fdS) aRun another program, specified as a command list 'cmd', in a new process. 'cmd' is just the argument list for the new process, ie. cmd[0] is the program to run and cmd[1:] are the rest of its arguments. There is no way to run a program with a name different from that of its executable. If 'search_path' is true (the default), the system's executable search path will be used to find the program; otherwise, cmd[0] must be the exact path to the executable. If 'dry_run' is true, the command will not actually be run. Raise DistutilsExecError if running the program fails in any way; just return on success. Nrdarwin)MACOSX_VERSION_VARget_macosx_target_ver)envzcommand %r failed: %sz#command %r failed with exit code %s)listrinfo subprocess list2cmdlinefind_executabledictosenvironsysplatformdistutils.utilrr Popenwait returncodeOSErrorrrargs) cmd search_pathverbosedry_runr executablerr Zmacosx_target_verprocexitcodeexcr$/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/spawn.pyspawnsF    r&c Cstj|\}}tjdkr|dkr|d}tj|r|S|durBtjdd}|durBztd}Wnt t fyAtj }Ynw|sFdS| tj }|D]}tj||}tj|ra|SqNdS)zTries to find 'executable' in the directories listed in 'path'. A string listing directories separated by 'os.pathsep'; defaults to os.environ['PATH']. Returns the complete filename or None if not found. win32z.exeNPATHCS_PATH)rpathsplitextrrisfilergetconfstrAttributeError ValueErrordefpathsplitpathsepjoin)r r*_extpathspfr$r$r%rHs,    r)rrrN)N) __doc__rrrdistutils.errorsrrdistutils.debugr distutilsrr&rr$r$r$r%s   6PKH]Y< < Npython3.10/site-packages/setuptools/_distutils/__pycache__/log.cpython-310.pycnu[o Xai@sldZdZdZdZdZdZddlZGdd d ZeZej Z ej Z ej Z ej Z ej Z ejZd d Zd d ZdS)z,A simple log mechanism styled after PEP 282.Nc@sPeZdZefddZddZddZddZd d Zd d Z d dZ ddZ dS)LogcCs ||_dSN) threshold)selfr r /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/log.py__init__s z Log.__init__cCs|tttttfvrtdt|||jkrV|r||}|tttfvr'tj }ntj }z | d|Wnt yO|j }||d|}| d|Ynw|dSdS)Nz%s wrong log levelz%s backslashreplace)DEBUGINFOWARNERRORFATAL ValueErrorstrr sysstderrstdoutwriteUnicodeEncodeErrorencodingencodedecodeflush)r levelmsgargsstreamrr r r _logs"   zLog._logcGs||||dSr)r#)r rr r!r r r log'zLog.logcG|t||dSr)r#rr r r!r r r debug*r%z Log.debugcGr&r)r#rr'r r r info-r%zLog.infocGr&r)r#rr'r r r warn0r%zLog.warncGr&r)r#rr'r r r error3r%z Log.errorcGr&r)r#rr'r r r fatal6r%z Log.fatalN) __name__ __module__ __qualname__rr r#r$r(r)r*r+r,r r r r rs  rcCstj}|t_|Sr) _global_logr )roldr r r set_thresholdAsr2cCs@|dkr ttdS|dkrttdS|dkrttdSdS)Nrrr)r2rrr)vr r r set_verbosityGs   r4)__doc__rrrrrrrr0r$r(r)r*r+r,r2r4r r r r s"+ PKH]P7||[python3.10/site-packages/setuptools/_distutils/__pycache__/versionpredicate.cpython-310.pycnu[o Xai @sdZddlZddlZddlZedejZedZedZ ddZ ej ej ej ejejejdZGd d d Zdad d ZdS) zBModule for parsing and testing package version predicate strings. Nz'(?i)^\s*([a-z_]\w*(?:\.[a-z_]\w*)*)(.*)z^\s*\((.*)\)\s*$z%^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$cCs6t|}|s td||\}}|tj|fS)zVParse a single version comparison. Return (comparison string, StrictVersion) z"bad package restriction syntax: %r)re_splitComparisonmatch ValueErrorgroups distutilsversion StrictVersion)predrescompZverStrr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/versionpredicate.pysplitUps   r)z>=z!=c@s(eZdZdZddZddZddZdS) VersionPredicateaParse and test package version predicates. >>> v = VersionPredicate('pyepat.abc (>1.0, <3333.3a1, !=1555.1b3)') The `name` attribute provides the full dotted name that is given:: >>> v.name 'pyepat.abc' The str() of a `VersionPredicate` provides a normalized human-readable version of the expression:: >>> print(v) pyepat.abc (> 1.0, < 3333.3a1, != 1555.1b3) The `satisfied_by()` method can be used to determine with a given version number is included in the set described by the version restrictions:: >>> v.satisfied_by('1.1') True >>> v.satisfied_by('1.4') True >>> v.satisfied_by('1.0') False >>> v.satisfied_by('4444.4') False >>> v.satisfied_by('1555.1b3') False `VersionPredicate` is flexible in accepting extra whitespace:: >>> v = VersionPredicate(' pat( == 0.1 ) ') >>> v.name 'pat' >>> v.satisfied_by('0.1') True >>> v.satisfied_by('0.2') False If any version numbers passed in do not conform to the restrictions of `StrictVersion`, a `ValueError` is raised:: >>> v = VersionPredicate('p1.p2.p3.p4(>=1.0, <=1.3a1, !=1.2zb3)') Traceback (most recent call last): ... ValueError: invalid version number '1.2zb3' It the module or package name given does not conform to what's allowed as a legal module or package name, `ValueError` is raised:: >>> v = VersionPredicate('foo-bar') Traceback (most recent call last): ... ValueError: expected parenthesized list: '-bar' >>> v = VersionPredicate('foo bar (12.21)') Traceback (most recent call last): ... ValueError: expected parenthesized list: 'bar (12.21)' cCs|}|s tdt|}|std||\|_}|}|rMt|}|s1td||d}dd|dD|_|jsKtd|d Sg|_d S) z*Parse a version predicate string. zempty package restrictionzbad package name in %rzexpected parenthesized list: %rrcSsg|]}t|qSr )r).0ZaPredr r r tsz-VersionPredicate.__init__..,zempty parenthesized list in %rN) striprre_validPackagerrnamere_parensplitr )selfZversionPredicateStrrZparenstrr r r __init__`s(      zVersionPredicate.__init__cCs4|jrdd|jD}|jdd|dS|jS)NcSs g|] \}}|dt|qS) )r)rcondverr r r r}s z,VersionPredicate.__str__..z (z, ))r rjoin)rseqr r r __str__{szVersionPredicate.__str__cCs(|jD]\}}t|||sdSqdS)zTrue if version is compatible with all the predicates in self. The parameter version must be acceptable to the StrictVersion constructor. It may be either a string or StrictVersion. FT)r compmap)rrrrr r r satisfied_bys zVersionPredicate.satisfied_byN)__name__ __module__ __qualname____doc__rr#r%r r r r rs @ rcCsdtdur tdtja|}t|}|std||dp"d}|r+tj |}|d|fS)a9Return the name and optional version number of a provision. The version number, if given, will be returned as a `StrictVersion` instance, otherwise it will be `None`. >>> split_provision('mypkg') ('mypkg', None) >>> split_provision(' mypkg( 1.2 ) ') ('mypkg', StrictVersion ('1.2')) Nz=([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)(?:\s*\(\s*([^)\s]+)\s*\))?$z"illegal provides specification: %r) _provision_rxrecompileASCIIrrrgrouprrr)valuemrr r r split_provisions    r3)r)r-Zdistutils.versionroperatorr.r/rrrrltleeqgtgener$rr,r3r r r r s    n PKH]0YTpython3.10/site-packages/setuptools/_distutils/__pycache__/extension.cpython-310.pycnu[o Xai)@s.dZddlZddlZGdddZddZdS)zmdistutils.extension Provides the Extension class, used to describe C/C++ extension modules in setup scripts.Nc@s>eZdZdZ              dddZddZdS) Extensiona Just a collection of attributes that describes an extension module and everything needed to build it (hopefully in a portable way, but there are hooks that let you be as unportable as you need). Instance attributes: name : string the full name of the extension, including any packages -- ie. *not* a filename or pathname, but Python dotted name sources : [string] list of source filenames, relative to the distribution root (where the setup script lives), in Unix form (slash-separated) for portability. Source files may be C, C++, SWIG (.i), platform-specific resource files, or whatever else is recognized by the "build_ext" command as source for a Python extension. include_dirs : [string] list of directories to search for C/C++ header files (in Unix form for portability) define_macros : [(name : string, value : string|None)] list of macros to define; each macro is defined using a 2-tuple, where 'value' is either the string to define it to or None to define it without a particular value (equivalent of "#define FOO" in source or -DFOO on Unix C compiler command line) undef_macros : [string] list of macros to undefine explicitly library_dirs : [string] list of directories to search for C/C++ libraries at link time libraries : [string] list of library names (not filenames or paths) to link against runtime_library_dirs : [string] list of directories to search for C/C++ libraries at run time (for shared extensions, this is when the extension is loaded) extra_objects : [string] list of extra files to link with (eg. object files not implied by 'sources', static library that must be explicitly specified, binary resource files, etc.) extra_compile_args : [string] any extra platform- and compiler-specific information to use when compiling the source files in 'sources'. For platforms and compilers where "command line" makes sense, this is typically a list of command-line arguments, but for other platforms it could be anything. extra_link_args : [string] any extra platform- and compiler-specific information to use when linking object files together to create the extension (or to create a new static Python interpreter). Similar interpretation as for 'extra_compile_args'. export_symbols : [string] list of symbols to be exported from a shared extension. Not used on all platforms, and not generally necessary for Python extensions, which typically export exactly one symbol: "init" + extension_name. swig_opts : [string] any extra options to pass to SWIG if a source file has the .i extension. depends : [string] list of files that the extension depends on language : string extension language (i.e. "c", "c++", "objc"). Will be detected from the source extensions if not provided. optional : boolean specifies that a build failure in the extension should not abort the build process, but simply not install the failing extension. NcKst|ts tdt|trtdd|Dstd||_||_|p$g|_|p)g|_|p.g|_ |p3g|_ |p8g|_ |p=g|_ | pBg|_ | pGg|_| pLg|_| pQg|_| pVg|_|p[g|_||_||_t|dkrdd|D}dt|}d |}t|dSdS) Nz'name' must be a stringcss|]}t|tVqdS)N) isinstancestr).0vr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/extension.py jsz%Extension.__init__..z#'sources' must be a list of stringsrcSsg|]}t|qSr)repr)roptionrrr sz&Extension.__init__..z, zUnknown Extension options: %s)rrAssertionErrorlistallnamesources include_dirs define_macros undef_macros library_dirs librariesruntime_library_dirs extra_objectsextra_compile_argsextra_link_argsexport_symbols swig_optsdependslanguageoptionallenjoinsortedwarningswarn)selfrrrrrrrrrrrrrrrrkwoptionsmsgrrr__init__Vs8               zExtension.__init__cCsd|jj|jj|jt|fS)Nz<%s.%s(%r) at %#x>) __class__ __module__ __qualname__rid)r%rrr__repr__s zExtension.__repr__)NNNNNNNNNNNNNN)__name__r+r,__doc__r)r.rrrrrs$C /rcCsddlm}m}m}ddlm}ddlm}||}||dddddd}z,g} |} | dur3n| | r9q(| d| d krGd krQnn| d | q(|| |} || } | d} t | g} d} | ddD]}| dury| |d} qkt j|d}|dd }|d d}|d vr| j |qk|dkr| j |qk|dkr|d}|d kr| j |dfqk| j |d|||d dfqk|dkr| j |qk|dkr| j |qk|dkr| j |qk|dkr| j |qk|dkr| j |qk|dkr | j} qk|dkr| j} qk|dkr| j} qk|dkr1| j ||s0| j} qk|dvr=| j |qk| d|qk| | q)W||S|w)z3Reads a Setup file and returns Extension instances.r)parse_makefileexpand_makefile_vars _variable_rx)TextFile) split_quoted)strip_comments skip_blanks join_lines lstrip_ws rstrip_wsTN*z'%s' lines not handled yet)z.cz.ccz.cppz.cxxz.c++z.mz.mmz-Iz-D=z-Uz-Cz-lz-Lz-Rz-rpathz-Xlinkerz -Xcompilerz-u)z.az.soz.slz.oz.dylibzunrecognized argument '%s')distutils.sysconfigr1r2r3distutils.text_filer4distutils.utilr5readlinematchr$rappendospathsplitextrrfindrrrrrrrrclose)filenamer1r2r3r4r5varsfile extensionslinewordsmoduleextappend_next_wordwordsuffixswitchvalueequalsrrrread_setup_files                K rY)r0rFr#rrYrrrrs  zPKH]8[h))Wpython3.10/site-packages/setuptools/_distutils/__pycache__/fancy_getopt.cpython-310.pycnu[o XaixE@sdZddlZddlZddlZddlZddlTdZedeZedeefZ e ddZ Gd d d Z d d Zd dejDZddZddZGdddZedkrndZdD]ZedeedeeeeqXdSdS)a6distutils.fancy_getopt Wrapper around the standard getopt module that provides the following additional features: * short and long options are tied together * options have help strings, so fancy_getopt could potentially create a complete usage summary * options set attributes of a passed-in object N)*z[a-zA-Z](?:[a-zA-Z0-9-]*)z^%s$z ^(%s)=!(%s)$-_c@seZdZdZdddZddZddZd d d Zd d Zd dZ ddZ ddZ ddZ ddZ d ddZddZdddZd ddZdS)! FancyGetoptaWrapper around the standard 'getopt()' module that provides some handy extra functionality: * short and long options are tied together * options have help strings, and help text can be assembled from them * options set attributes of a passed-in object * boolean options can have "negative aliases" -- eg. if --quiet is the "negative alias" of --verbose, then "--quiet" on the command line sets 'verbose' to false NcCsN||_i|_|jr |i|_i|_g|_g|_i|_i|_i|_ g|_ dSN) option_table option_index _build_indexaliasnegative_alias short_opts long_opts short2long attr_name takes_arg option_orderselfrr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/fancy_getopt.py__init__)s  zFancyGetopt.__init__cCs(|j|jD] }||j|d<qdS)Nr)rclearr)roptionrrrr Qs  zFancyGetopt._build_indexcCs||_|dSr)rr rrrrset_option_tableVs zFancyGetopt.set_option_tablecCs:||jvr td||||f}|j|||j|<dS)Nz'option conflict: already an option '%s')rDistutilsGetoptErrorrappend)r long_option short_option help_stringrrrr add_optionZs   zFancyGetopt.add_optioncCs ||jvS)zcReturn true if the option table for this parser has an option with long name 'long_option'.)rrrrrr has_optioncs zFancyGetopt.has_optioncCs |tS)zTranslate long option name 'long_option' to the form it has as an attribute of some object: ie., translate hyphens to underscores. translate longopt_xlater rrr get_attr_nameh zFancyGetopt.get_attr_namecCs\t|tsJ|D] \}}||jvrtd|||f||jvr+td|||fq dS)Nz(invalid %s '%s': option '%s' not definedz0invalid %s '%s': aliased option '%s' not defined) isinstancedictitemsrr)raliaseswhatr optrrr_check_alias_dictns  zFancyGetopt._check_alias_dictcC||d||_dS)z'Set the aliases for this option parser.r N)r-r )rr rrr set_aliasesxs  zFancyGetopt.set_aliasescCr.)zSet the negative aliases for this option parser. 'negative_alias' should be a dictionary mapping option names to option names, both the key and value must already be defined in the option table.znegative aliasN)r-r )rr rrrset_negative_aliases}s  z FancyGetopt.set_negative_aliasescCsg|_g|_|ji|_|jD]}t|dkr!|\}}}d}nt|dkr.|\}}}}ntd|ft|t r@t|dkrFt d||dus[t|t rUt|dks[t d |||j|<|j ||d d kr~|rr|d }|dd }d|j |<n!|j |}|dur|j |rt d ||f||jd <d|j |<|j|}|dur|j ||j |krt d||ft|st d||||j|<|r|j |||j|d<qdS)zPopulate the various data structures that keep tabs on the option table. Called by 'getopt()' before it can do anything worthwhile. rzinvalid option tuple: %rz9invalid long option '%s': must be a string of length >= 2Nz:invalid short option '%s': must a single character or None=:z>invalid negative alias '%s': aliased option '%s' takes a valuezginvalid alias '%s': inconsistent with aliased option '%s' (one of them takes a value, the other doesn'tzEinvalid long option name '%s' (must be letters, numbers, hyphens only)r r rrrepeatrlen ValueErrorr'strrrrr getr longopt_rematchr%r)rrlongshorthelpr8alias_torrr_grok_option_tablest                   zFancyGetopt._grok_option_tablec Cs|dur tjdd}|durt}d}nd}|d|j}z t|||j\}}Wntjy>}zt |d}~ww|D]y\}}t |dkrY|ddkrY|j |d}nt |dkrg|ddd ksiJ|dd}|j |} | ry| }|j|s|d ksJd |j |} | r| }d}nd}|j|} |r|j | durt|| dd}t|| ||j||fqA|r||fS|S) aParse command-line options in args. Store as attributes on object. If 'args' is None or not supplied, uses 'sys.argv[1:]'. If 'object' is None or not supplied, creates a new OptionDummy object, stores option values there, and returns a tuple (args, object). If 'object' is supplied, it is modified in place and 'getopt()' just returns 'args'; in both cases, the returned 'args' is a modified copy of the passed-in 'args' list, which is left untouched. Nr4TF r3rrz--zboolean option can't have value)sysargv OptionDummyrCjoinr getoptr errorDistutilsArgErrorr9rr r<rr rr8getattrsetattrrr) rargsobjectcreated_objectr optsmsgr,valr attrrrrrJsJ          zFancyGetopt.getoptcCs|jdur td|jS)zReturns the list of (option, value) tuples processed by the previous run of 'getopt()'. Raises RuntimeError if 'getopt()' hasn't been called yet. Nz!'getopt()' hasn't been called yet)r RuntimeError)rrrrget_option_orders zFancyGetopt.get_option_ordercCsdd}|jD]&}|d}|d}t|}|ddkr|d}|dur%|d}||kr+|}q|ddd}d}||} d |} |rD|g} nd g} |jD]e}|dd \}}} t| | } |ddkrf|dd}|dur| ry| d ||| dfn&| d ||fnd||f}| r| d ||| dfn| d|| ddD] }| | |qqJ| S)zGenerate help text (a list of strings, one per suggested line of output) from the option table for this FancyGetopt object. rr4r5r6Nr3NrDzOption summary:r1z --%-*s %sz --%-*s z%s (-%s)z --%-*s)rr9 wrap_textr)rheadermax_optrr?r@l opt_width line_width text_width big_indentlinesrAtext opt_namesrrr generate_helpsL        zFancyGetopt.generate_helpcCs0|durtj}||D] }||dq dS)N )rFstdoutrewrite)rr[filelinerrr print_helphs zFancyGetopt.print_helpr)NN)__name__ __module__ __qualname____doc__rr rrr!r%r-r/r0rCrJrWrerkrrrrrs  (    M= OrcCst|}|||||Sr)rr0rJ)options negative_optrPrOparserrrr fancy_getoptos  rscCsi|]}t|dqS)rD)ord).0Z_wscharrrr usrvcCs|durgSt||kr|gS|}|t}td|}dd|D}g}|rg}d}|rZt|d}|||krJ||d|d=||}n|rW|dddkrW|d=n|s/|r|dkru||dd||d|d|d<|dddkr|d=|d||s)|S) zwrap_text(text : string, width : int) -> [string] Split 'text' into multiple lines of no more than 'width' characters each, and return the list of strings that results. Nz( +|-+)cSsg|]}|r|qSrr)ruchrrr szwrap_text..rr5rDrE)r9 expandtabsr#WS_TRANSresplitrrI)rcwidthchunksrbcur_linecur_lenr]rrrrZws>       "rZcCs |tS)zXConvert a long option name to a valid Python identifier by changing "-" to "_". r")r,rrrtranslate_longoptr&rc@seZdZdZgfddZdS)rHz_Dummy class just used as a place to hold command-line option values as instance attributes.cCs|D]}t||dqdS)zkCreate a new OptionDummy instance. The attributes listed in 'options' will be initialized to None.N)rN)rrpr,rrrrszOptionDummy.__init__N)rlrmrnrorrrrrrHsrH__main__zTra-la-la, supercalifragilisticexpialidocious. How *do* you spell that odd word, anyways? (Someone ask Mary -- she'll know [or she'll say, "How should I know?"].)) (z width: %drf)rorFstringr{rJdistutils.errors longopt_patcompiler= neg_alias_rer; maketransr$rrs whitespacerzrZrrHrlrcwprintrIrrrrs0  T6  PKH]D33Ppython3.10/site-packages/setuptools/_distutils/__pycache__/debug.cpython-310.pycnu[o Xai@sddlZejdZdS)NZDISTUTILS_DEBUG)osenvirongetDEBUGrr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/debug.pysPKH]Upython3.10/site-packages/setuptools/_distutils/__pycache__/py35compat.cpython-310.pycnu[o Xai@s(ddlZddlZddZeedeZdS)NcCs*g}tjj}|dkr|dd||S)zgReturn a list of command-line arguments reproducing the current optimization settings in sys.flags.r-O)sysflagsoptimizeappend)argsvaluer /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/py35compat.py#__optim_args_from_interpreter_flagss r "_optim_args_from_interpreter_flags)r subprocessr getattrr r r r r s PKH]/**Spython3.10/site-packages/setuptools/_distutils/__pycache__/filelist.cpython-310.pycnu[o Xai_4@sdZddlZddlZddlZddlZddlmZddlmZm Z ddl m Z GdddZ dd Z Gd d d eZejfd d ZddZdddZdS)zsdistutils.filelist Provides the FileList class, used for poking about the filesystem and building lists of files. N convert_path)DistutilsTemplateErrorDistutilsInternalError)logc@s~eZdZdZdddZddZejfddZd d Z d d Z d dZ ddZ ddZ ddZddZdddZ dddZdS)FileListaA list of files built by on exploring the filesystem and filtered by applying various patterns to what we find there. Instance attributes: dir directory from which files will be taken -- only used if 'allfiles' not supplied to constructor files list of filenames currently being built/filtered/manipulated allfiles complete list of files under consideration (ie. without any filtering applied) NcCsd|_g|_dSN)allfilesfiles)selfwarn debug_printr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/filelist.py__init__ s zFileList.__init__cCs ||_dSr)r )r r rrr set_allfiles&s zFileList.set_allfilescCst||_dSr)findallr )r dirrrrr)szFileList.findallcCs ddlm}|rt|dSdS)z~Print 'msg' to stdout if the global DEBUG (taken from the DISTUTILS_DEBUG environment variable) flag is true. r)DEBUGN)distutils.debugrprint)r msgrrrrr ,s  zFileList.debug_printcC|j|dSr)r append)r itemrrrr6zFileList.appendcCrr)r extend)r itemsrrrr9rzFileList.extendcCs<tttjj|j}g|_|D] }|jtjj|qdSr)sortedmapospathsplitr rjoin)r Zsortable_filesZ sort_tuplerrrsort<s z FileList.sortcCs@tt|jdddD]}|j||j|dkr|j|=q dS)Nr)rangelenr )r irrrremove_duplicatesEs zFileList.remove_duplicatescCs|}|d}d}}}|dvr*t|dkrtd|dd|ddD}n?|dvrLt|d kr:td |t|d}d d|ddD}n|d vrct|dkr\td |t|d}ntd|||||fS)Nr)includeexcludeglobal-includeglobal-excludez&'%s' expects ...cSg|]}t|qSrr.0wrrr Xz1FileList._parse_template_line..r%)recursive-includerecursive-excludez,'%s' expects ...cSr0rrr1rrrr4^r5)graftprunez#'%s' expects a single zunknown action '%s')r"r(rr)r linewordsactionpatternsr dir_patternrrr_parse_template_lineMs0       zFileList._parse_template_linecCs:||\}}}}|dkr+|dd||D]}|j|dds(td|qdS|dkrM|dd||D]}|j|ddsJtd |q;dS|d kro|d d||D]}|j|d dsltd |q]dS|dkr|dd||D]}|j|d dstd|qdS|dkr|d|d|f|D]}|j||dsd}t|||qdS|dkr|d|d|f|D]}|j||dstd||qdS|dkr|d||jd|dstd|dSdS|dkr|d||jd|dstd|dSdStd|)Nr+zinclude  r%)anchorz%warning: no files found matching '%s'r,zexclude z9warning: no previously-included files found matching '%s'r-zglobal-include rz>warning: no files found matching '%s' anywhere in distributionr.zglobal-exclude zRwarning: no previously-included files matching '%s' found anywhere in distributionr6zrecursive-include %s %s)prefixz:warning: no files found matching '%s' under directory '%s'r7zrecursive-exclude %s %szNwarning: no previously-included files matching '%s' found under directory '%s'r9zgraft z+warning: no directories found matching '%s'r:zprune z6no previously-included directories found matching '%s'z'this cannot happen: invalid action '%s')r@r r#include_patternrr exclude_patternr)r r;r=r>rr?patternrrrrprocess_template_lineis   zFileList.process_template_liner%rcCsld}t||||}|d|j|jdur||jD]}||r3|d||j|d}q|S)aSelect strings (presumably filenames) from 'self.files' that match 'pattern', a Unix-style wildcard (glob) pattern. Patterns are not quite the same as implemented by the 'fnmatch' module: '*' and '?' match non-special characters, where "special" is platform- dependent: slash on Unix; colon, slash, and backslash on DOS/Windows; and colon on Mac OS. If 'anchor' is true (the default), then the pattern match is more stringent: "*.py" will match "foo.py" but not "foo/bar.py". If 'anchor' is false, both of these will match. If 'prefix' is supplied, then only filenames starting with 'prefix' (itself a pattern) and ending with 'pattern', with anything in between them, will match. 'anchor' is ignored in this case. If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and 'pattern' is assumed to be either a string containing a regex or a regex object -- no translation is done, the regex is just compiled and used as-is. Selected strings will be added to self.files. Return True if files are found, False otherwise. Fz%include_pattern: applying regex r'%s'Nz adding T)translate_patternr rFr rsearchr r)r rFrBrCis_regex files_found pattern_renamerrrrDs    zFileList.include_patterncCsrd}t||||}|d|jtt|jdddD]}||j|r6|d|j||j|=d}q|S)aRemove strings (presumably filenames) from 'files' that match 'pattern'. Other parameters are the same as for 'include_pattern()', above. The list 'self.files' is modified in place. Return True if files are found, False otherwise. Fz%exclude_pattern: applying regex r'%s'r%r&z removing T)rHr rFr'r(r rI)r rFrBrCrJrKrLr)rrrrEszFileList.exclude_pattern)NNr%Nr)__name__ __module__ __qualname____doc__rrr curdirrr rrr$r*r@rGrDrErrrrrs    M+rcCs0ttj|dd}dd|D}ttjj|S)z% Find all files under 'path' T) followlinkscss.|]\}}}|D] }tj||Vq qdSr)r r!r#)r2basedirsr filerrr s z#_find_all_simple..) _UniqueDirsfilterr walkr!isfile)r!Z all_uniqueresultsrrr_find_all_simples r^c@s$eZdZdZddZeddZdS)rYz Exclude previously-seen dirs from walk results, avoiding infinite recursion. Ref https://bugs.python.org/issue44497. cCsF|\}}}t|}|j|jf}||v}|r|dd=||| S)z Given an item from an os.walk result, determine if the item represents a unique dir for this instance and if not, prevent further traversal. N)r statst_devst_inoadd)r Z walk_itemrUrVr r_ candidatefoundrrr__call__ s     z_UniqueDirs.__call__cCs t||Sr)rZ)clsrrrrrZs z_UniqueDirs.filterN)rOrPrQrRre classmethodrZrrrrrYs rYcCs6t|}|tjkrtjtjj|d}t||}t|S)z Find all files under 'dir' and return the list of full filenames. Unless dir is '.', return full filenames with dir prepended. )start) r^r rS functoolspartialr!relpathrlist)rr Zmake_relrrrrs   rcCs8t|}tj}tjdkrd}d|}td||}|S)zTranslate a shell-like glob pattern to a regular expression; return a string containing the regex. Differs from 'fnmatch.translate()' in that '*' does not match "special characters" (which are platform-specific). \z\\\\z\1[^%s]z((?s  f  PKH]25Tpython3.10/site-packages/setuptools/_distutils/__pycache__/file_util.cpython-310.pycnu[o Xai@sbdZddlZddlmZddlmZddddZdd d Z  dd dZ dddZ ddZ dS)zFdistutils.file_util Utility functions for operating on single files. N)DistutilsFileError)logcopyingz hard linkingzsymbolically linking)Nhardsym@c Csd}d}zzt|d}Wnty!}z td||jfd}~wwtj|rEzt|WntyD}z td||jfd}~wwzt|d}Wntya}z td||jfd}~ww z||}Wnty}z td||jfd}~ww|snz| |Wnty}z td ||jfd}~wwqcW|r| |r| dSdS|r| |r| ww) a5Copy the file 'src' to 'dst'; both must be filenames. Any error opening either file, reading from 'src', or writing to 'dst', raises DistutilsFileError. Data is read/written in chunks of 'buffer_size' bytes (default 16k). No attempt is made to handle anything apart from regular files. Nrbzcould not open '%s': %szcould not delete '%s': %swbzcould not create '%s': %sTzcould not read from '%s': %szcould not write to '%s': %s) openOSErrorrstrerrorospathexistsunlinkreadwriteclose)srcdst buffer_sizefsrcfdstebufr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/file_util.py_copy_file_contentssr        rcCsddlm}ddlm} m} m} m} tj |st d|tj |r2|} tj |tj |}ntj|} |rM|||sM|dkrItd||dfSzt|}Wn ty`td|w|dkrtj |tj |krztd||| ntd||||r|dfS|d krtj|rtj||sz t|||dfWStyYnwn|d krtj|rtj||st|||dfSt|||s|rt|}|rt||| || f|rt|| || |dfS) aCopy a file 'src' to 'dst'. If 'dst' is a directory, then 'src' is copied there with the same name; otherwise, it must be a filename. (If the file exists, it will be ruthlessly clobbered.) If 'preserve_mode' is true (the default), the file's mode (type and permission bits, or whatever is analogous on the current platform) is copied. If 'preserve_times' is true (the default), the last-modified and last-access times are copied as well. If 'update' is true, 'src' will only be copied if 'dst' does not exist, or if 'dst' does exist but is older than 'src'. 'link' allows you to make hard links (os.link) or symbolic links (os.symlink) instead of copying: set it to "hard" or "sym"; if it is None (the default), files are copied. Don't set 'link' on systems that don't support it: 'copy_file()' doesn't check if hard or symbolic linking is available. If hardlink fails, falls back to _copy_file_contents(). Under Mac OS, uses the native file copy function in macostools; on other systems, uses '_copy_file_contents()' to copy file contents. Return a tuple (dest_name, copied): 'dest_name' is the actual name of the output file, and 'copied' is true if the file was copied (or would have been copied, if 'dry_run' true). r)newer)ST_ATIMEST_MTIMEST_MODES_IMODEz4can't copy '%s': doesn't exist or not a regular filerz"not copying %s (output up-to-date)z&invalid value '%s' for 'link' argumentz %s %s -> %srr)distutils.dep_utilrstatr r!r"r#r risfilerisdirjoinbasenamedirnamerdebug _copy_actionKeyError ValueErrorinforsamefilelinkr symlinkrutimechmod)rr preserve_modepreserve_timesupdater1verbosedry_runrr r!r"r#diractionstrrr copy_fileCs\ !              r=c Csddlm}m}m}m}m}ddl} |dkrtd|||r!|S||s+t d|||r9t j |||}n ||rEt d||f|||sSt d||fd } zt ||Wn(ty} z| j\} } | | jkrrd } n t d ||| fWYd} ~ nd} ~ ww| rt|||d zt |W|Sty} z | j\} } zt |Wn tyYnwt d |||| fd} ~ ww|S)a%Move a file 'src' to 'dst'. If 'dst' is a directory, the file will be moved into it with the same name; otherwise, 'src' is just renamed to 'dst'. Return the new full name of the file. Handles cross-device moves on Unix using 'copy_file()'. What about other systems??? r)rr&r'r)r*Nrzmoving %s -> %sz#can't move '%s': not a regular filez0can't move '%s': destination '%s' already existsz2can't move '%s': destination '%s' not a valid pathFTzcouldn't move '%s' to '%s': %s)r8zAcouldn't move '%s' to '%s' by copy/delete: delete '%s' failed: %s)os.pathrr&r'r)r*errnorr/rr rr(renamer argsEXDEVr=r)rrr8r9rr&r'r)r*r?copy_itrnummsgrrr move_filesn             rFcCs<t|d}z|D] }||dqW|dS|w)z{Create a file with the specified name and write 'contents' (a sequence of strings without line terminators) to it. w N)r rr)filenamecontentsflinerrr write_files rM)r)rrrNrr)rr) __doc__r distutils.errorsr distutilsrr,rr=rFrMrrrrs    3 d ?PKH]\Y"Y"Zpython3.10/site-packages/setuptools/_distutils/__pycache__/cygwinccompiler.cpython-310.pycnu[o Xai*B@sdZddlZddlZddlZddlmZmZmZddlZddl m Z ddl m Z ddl mZmZmZmZddlmZddlmZd d ZGd d d e ZGd ddeZdZdZdZddZedZddZddZ ddZ!dS)adistutils.cygwinccompiler Provides the CygwinCCompiler class, a subclass of UnixCCompiler that handles the Cygwin port of the GNU C compiler to Windows. It also contains the Mingw32CCompiler class which handles the mingw32 port of GCC (same as cygwin in no-cygwin mode). N)PopenPIPE check_output) UnixCCompiler) write_file)DistutilsExecErrorCCompilerError CompileErrorUnknownFileError) LooseVersion)find_executablecCstjd}|dkr>tj|d|d}|dkrdgS|dkr#dgS|d kr*d gS|d kr1d gS|d kr8dgStd|dS)zaInclude the appropriate MSVC runtime library if Python was built with MSVC 7.0 or later. zMSC v. Z1300Zmsvcr70Z1310Zmsvcr71Z1400Zmsvcr80Z1500Zmsvcr90Z1600Zmsvcr100zUnknown MS Compiler version %s N)sysversionfind ValueError)Zmsc_posZmsc_verr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/cygwinccompiler.py get_msvcr?s  rc@sZeZdZdZdZdZdZdZdZdZ dZ dd d Z d d Z    dddZ dddZdS)CygwinCCompilerz? Handles the Cygwin port of the GNU C compiler to Windows. cygwinz.o.az.dllzlib%s%sz%s%sz.exercCsFt||||t\}}|d||f|tur!|d|tjdd|_ tjdd|_ d|j vrgt \|_ |_ |_||jd|j |j |jf|j dkrY|j |_nd |_|j d krdd }n d }n|j |_d }|jd |j d|j d |j d|j d|j|fdd|j vr|j dkrdg|_|ddSt|_dS)Nz%Python's GCC status: %s (details: %s)zPython's pyconfig.h doesn't seem to support your compiler. Reason: %s. Compiling may fail because of undefined preprocessor macros.CCgccCXXzg++z: gcc %s, ld %s, dllwrap %s z2.10.90dllwrap2.13-shared -mdll -staticz%s -mcygwin -O -Wallz%s -mcygwin -mdll -O -Wallz %s -mcygwinz%s -mcygwin %scompiler compiler_so compiler_cxx linker_exe linker_so2.91.57msvcrtz,Consider upgrading to a newer version of gcc)r__init__check_config_h debug_print CONFIG_H_OKwarnosenvirongetcccxx get_versions gcc_version ld_versionZdllwrap_version compiler_type linker_dllset_executables dll_librariesr)selfverbosedry_runforcestatusdetails shared_optionrrrr)dsX       zCygwinCCompiler.__init__c Cs|dks|dkr&z |dd|d|gWdSty%}zt|d}~wwz||j||d|g|WdStyH}zt|d}~ww)z:Compiles the source by spawning GCC and windres if needed..rc.resZwindresz-iz-oN)spawnrr r#)r:objsrcextZcc_argsextra_postargsZpp_optsmsgrrr_compiles zCygwinCCompiler._compileNcCsHt| pg} t|p g}t|pg}||j|dur||jks)|jdkrtj|d}tjtj |\}}tj ||d}tj |d|d}dtj |dg}|D]}| |q]| t ||fd ||jd kr| d |g| d |gn| || s| d t||||||||d| | | | | dS)zLink the objects.Nrrz.deflibrz LIBRARY %sZEXPORTSz writing %srz --output-libz--defz-s)copyextendr9Z EXECUTABLEr7r.pathdirnamesplitextbasenamejoinappendexecuterrlink)r:Z target_descZobjectsZoutput_filename output_dir libraries library_dirsruntime_library_dirsexport_symbolsdebugZ extra_preargsrGZ build_tempZ target_langtemp_dirZdll_nameZ dll_extensionZdef_fileZlib_filecontentssymrrrrTsB         zCygwinCCompiler.linkcCs|durd}g}|D]H}tjtj|\}}||jddgvr)td||f|r1tj|}|dvrE|tj||||j q |tj|||j q |S)z#Adds supports for rc and res files.Nr^rArBz"unknown file type '%s' (from '%s'))rBrA) r.rMrOnormcaseZsrc_extensionsr rPrRrQ obj_extension)r:Zsource_filenamesZ strip_dirrUZ obj_namessrc_namebaserFrrrobject_filenamess&    z CygwinCCompiler.object_filenamesrrr) NNNNNrNNNN)rr^)__name__ __module__ __qualname____doc__r6r`Zstatic_lib_extensionshared_lib_extensionZstatic_lib_formatZshared_lib_formatZ exe_extensionr)rIrTrcrrrrrYs" @ Nrc@seZdZdZdZdddZdS)Mingw32CCompilerz@ Handles the Mingw32 port of the GNU C compiler to Windows. Zmingw32rc Cst||||d|jvr|jdkrd}nd}d|jvr$|jdkr$d}nd}t|jr/td|jd |jd |jd |jd |jd |j ||fd g|_ t |_ dS)Nrrr rr'z--entry _DllMain@12r^z1Cygwin gcc cannot be used with --compiler=mingw32z %s -O -Wallz%s -mdll -O -Wallz%sz%s %s %sr!) rr)r1r5r4 is_cygwinccrr8r2r7r9r)r:r;r<r=r@ entry_pointrrrr)s.   zMingw32CCompiler.__init__Nrd)rerfrgrhr6r)rrrrrjsrjokznot okZ uncertainc Csddlm}dtjvrtdfSdtjvrtdfS|}z(t|}zd|vr4td|fW|WSt d |fW|WS|wt y_}zt d ||j ffWYd }~Sd }~ww) awCheck if the current Python installation appears amenable to building extensions with GCC. Returns a tuple (status, details), where 'status' is one of the following constants: - CONFIG_H_OK: all is well, go ahead and compile - CONFIG_H_NOTOK: doesn't look good - CONFIG_H_UNCERTAIN: not sure -- unable to read pyconfig.h 'details' is a human-readable string explaining the situation. Note there are two ways to conclude "OK": either 'sys.version' contains the string "GCC" (implying that this Python was built with GCC), or the installed "pyconfig.h" contains the string "__GNUC__". r) sysconfigZGCCzsys.version mentions 'GCC'ZClangzsys.version mentions 'Clang'Z__GNUC__z'%s' mentions '__GNUC__'z '%s' does not mention '__GNUC__'zcouldn't read '%s': %sN) distutilsrnrrr,get_config_h_filenameopenreadcloseCONFIG_H_NOTOKOSErrorCONFIG_H_UNCERTAINstrerror)rnfnconfig_hexcrrrr*Ms(        r*s(\d+\.\d+(\.\d+)*)cCst|d}t|durdSt|dtdj}z |}W|n|wt|}|dur1dSt | d S)zFind the version of an executable by running `cmd` in the shell. If the command is not found, or the output does not match `RE_VERSION`, returns None. rNT)shellstdout) splitr rrr|rrrs RE_VERSIONsearchr groupdecode)cmd executableout out_stringresultrrr_find_exe_version~s    rcCsgd}tdd|DS)zg Try to find out the versions of gcc, ld and dllwrap. If not possible it returns None for it. )zgcc -dumpversionzld -vzdllwrap --versioncSsg|]}t|qSr)r).0rrrr sz get_versions..)tuple)commandsrrrr3sr3cCst|dg}|dS)zCTry to determine if the compiler that would be used is from cygwin.z -dumpmachinescygwin)rstripendswith)r1rrrrrks rk)"rhr.rrK subprocessrrrreZdistutils.unixccompilerrdistutils.file_utilrdistutils.errorsrrr r Zdistutils.versionr distutils.spawnr rrrjr,rtrvr*compilerrr3rkrrrrs.1    @1 / PKH]J Spython3.10/site-packages/setuptools/_distutils/__pycache__/dep_util.cpython-310.pycnu[o Xai @s6dZddlZddlmZddZddZd d d ZdS) zdistutils.dep_util Utility functions for simple, timestamp-based dependency of files and groups of files; also, function based entirely on such timestamp dependency analysis.N)DistutilsFileErrorcCs`tj|stdtj|tj|sdSddlm}t||}t||}||kS)aReturn true if 'source' exists and is more recently modified than 'target', or if 'source' exists and 'target' doesn't. Return false if both exist and 'target' is the same age or younger than 'source'. Raise DistutilsFileError if 'source' does not exist. zfile '%s' does not existrST_MTIME)ospathexistsrabspathstatr)sourcetargetrmtime1mtime2r/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/dep_util.pynewer s    rcCsht|t|kr tdg}g}tt|D]}t||||r/||||||q||fS)zWalk two filename lists in parallel, testing if each source is newer than its corresponding target. Return a pair of lists (sources, targets) where source is newer than target, according to the semantics of 'newer()'. z+'sources' and 'targets' must be same length)len ValueErrorrangerappend)sourcestargets n_sources n_targetsirrrnewer_pairwise srerrorcCstj|sdSddlm}t||}|D]'}tj|s0|dkr$n |dkr)q|dkr0dSt||}||kr>dSqdS)aReturn true if 'target' is out-of-date with respect to any file listed in 'sources'. In other words, if 'target' exists and is newer than every file in 'sources', return false; otherwise return true. 'missing' controls what we do when a source file is missing; the default ("error") is to blow up with an OSError from inside 'stat()'; if it is "ignore", we silently drop any missing source files; if it is "newer", any missing source files make us assume that 'target' is out-of-date (this is handy in "dry-run" mode: it'll make you pretend to carry out commands that wouldn't work because inputs are missing, but that doesn't matter because you're not actually going to run the commands). rrrrignorer)rrrr r)rr missingr target_mtimer source_mtimerrr newer_group6s"   r!)r)__doc__rdistutils.errorsrrrr!rrrrs  PKH]7B99Wpython3.10/site-packages/setuptools/_distutils/__pycache__/msvccompiler.cpython-310.pycnu[o Xai[ @sdZddlZddlZddlmZmZmZmZmZddl m Z m Z ddl m Z dZzddlZdZeZejZejZejZejZWn2eypzddlZddlZdZeZejZejZejZejZWneyme dYnwYnwer}ejejejej fZ!d d Z"d d Z#d dZ$GdddZ%ddZ&ddZ'ddZ(Gddde Z)e&dkre *de)Z+ddl,m)Z)ddl,m%Z%dSdS)zdistutils.msvccompiler Contains MSVCCompiler, an implementation of the abstract CCompiler class for the Microsoft Visual Studio. N)DistutilsExecErrorDistutilsPlatformError CompileErrorLibError LinkError) CCompilergen_lib_options)logFTzWarning: Can't read registry to find the necessary compiler setting Make sure that Python modules winreg, win32api or win32con are installed.cCsfzt||}Wn tyYdSwg}d} zt||}Wn ty(Y|Sw|||d7}q)zReturn list of registry keys.NrT) RegOpenKeyExRegError RegEnumKeyappend)basekeyhandleLikr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/msvccompiler.py read_keys7s"   rcCszzt||}Wn tyYdSwi}d} z t||\}}}Wn ty+Y|Sw|}t||t|<|d7}q)zXReturn dict of registry keys and values. All names are converted to lowercase. NrTr )r r RegEnumValuelower convert_mbcs)rrrdrnamevaluetyperrr read_valuesHs$  rcCs<t|dd}|durz|d}W|StyY|Sw|S)Ndecodembcs)getattr UnicodeError)sdecrrrr]s   rc@s,eZdZddZddZddZddZd S) MacroExpandercCsi|_||dSN)macros load_macros)selfversionrrr__init__gszMacroExpander.__init__cCs4tD]}t||}|r|||jd|<dSqdS)Nz$(%s))HKEYSrr()r*Zmacropathrrrrrr set_macroks zMacroExpander.set_macroc Csd|}|d|dd|d|ddd}|d|d z|d kr,|d |d n|d |d WntyD}ztdd}~wwd}tD](}zt||}Wn ty[YqIwt|d}t|d||f} | d|jd<qIdS)Nz%Software\Microsoft\VisualStudio\%0.1fZ VCInstallDirz \Setup\VCZ productdirZ VSInstallDirz \Setup\VSz Software\Microsoft\.NETFrameworkZ FrameworkDirZ installrootg@ZFrameworkSDKDirzsdkinstallrootv1.1ZsdkinstallrootaPython was built with Visual Studio 2003; extensions must be built with a compiler than can generate compatible binaries. Visual Studio 2003 was not found on this system. If you have Cygwin installed, you can try compiling with MingW32, by passing "-c mingw32" to setup.py.z.Software\Microsoft\NET Framework Setup\Productrz%s\%sr+z$(FrameworkVersion)) r/KeyErrorrr-r r r rr() r*r+Zvsbasenetexcprhrrrrrr)rs6  zMacroExpander.load_macroscCs$|jD] \}}|||}q|Sr')r(itemsreplace)r*r$rvrrrsubszMacroExpander.subN)__name__ __module__ __qualname__r,r/r)r8rrrrr&fs  r&cCsd}tj|}|dkrdS|t|}tj|ddd\}}t|ddd}|dkr3|d7}t|d d d }|dkrCd }|dkrK||SdS) zReturn the version of MSVC that was used to build Python. For Python 2.3 and up, the version number is included in sys.version. For earlier versions, assume the compiler is MSVC 6. zMSC v.N r g$@r)sysr+findlensplitint)prefixrr$restZ majorVersionZ minorVersionrrrget_build_versions  rJcCs@d}tj|}|dkrdStjd|}tj|t||S)zUReturn the processor architecture. Possible results are "Intel" or "AMD64". z bit (r<Intel))rCr+rDrE)rHrjrrrget_build_architectures  rNcCs0g}|D]}tj|}||vr||q|S)znReturn a list of normalized paths with duplicates removed. The current order of paths is maintained. )osr.normpathr)pathsZ reduced_pathsr3nprrrnormalize_and_reduce_pathss  rSc@seZdZdZdZiZdgZgdZdgZdgZ eeee Z dZ dZ d Z d Zd ZZd Zd+ddZddZ d,ddZ d-ddZ  d.ddZ         d/ddZddZddZd d!Zd0d"d#Zd$d%Zd1d'd(Zd)d*ZdS)2 MSVCCompilerzwConcrete class that implements an interface to Microsoft Visual C++, as defined by the CCompiler abstract class.Zmsvcz.c)z.ccz.cppz.cxx.rcz.mcz.resz.objz.libz.dllz%s%sz.exercCsvt||||t|_t|_|jdkr.|jdkr$d|_t|j|_nd|_d|j|_ nd|jd|_ d|_ dS) NrKzSoftware\Microsoft\VisualStudiozSoftware\Microsoft\DevstudiozVisual Studio version %szMicrosoft SDK compiler %sr=F) rr,rJ_MSVCCompiler__versionrN_MSVCCompiler__arch_MSVCCompiler__rootr&_MSVCCompiler__macros_MSVCCompiler__product initialized)r*verbosedry_runforcerrrr,s   zMSVCCompiler.__init__cCsg|_dtjvr"dtjvr"|dr"d|_d|_d|_d|_d|_n<| d|_t |jd kr6t d |j |d|_|d|_|d|_|d|_|d|_| d | d ztjdd D]}|j|qgWn tyzYnwt|j|_d |jtjd<d|_|jdkrgd|_gd|_n gd|_gd|_gd|_|jdkrgd|_ngd|_dg|_d|_dS)NZDISTUTILS_USE_SDKZMSSdkzcl.exezlink.exezlib.exezrc.exezmc.exer.rzxPython was built with %s, and extensions need to be built with the same version of the compiler, but it isn't installed.libinclude;rK)/nologo/O2/MD/W3/GX/DNDEBUG)rc/Od/MDdrfrg/Z7/D_DEBUG)rcrdrerf/GS-rh)rcrirjrfrmrkrl)/DLLrcz/INCREMENTAL:NOrV)rnrc/INCREMENTAL:no/DEBUG)rnrcroz /pdb:NonerprcT)_MSVCCompiler__pathsrOenvironfind_execclinkerr`rcmcget_msvc_pathsrErr[set_path_env_varrFrr0rSjoinZpreprocess_optionsrXcompile_optionscompile_options_debugldflags_sharedrWldflags_shared_debugZldflags_staticr\)r*r3rrr initializesP                    zMSVCCompiler.initializecCs|durd}g}|D]b}tj|\}}tj|d}|tj|d}||jvr1td||r9tj|}||jvrL| tj |||j q ||j vr_| tj |||j q | tj |||j q |S)Nrr zDon't know how to compile %s)rOr.splitext splitdriveisabssrc_extensionsrbasename_rc_extensionsrrz res_extension_mc_extensions obj_extension)r*Zsource_filenamesZ strip_dir output_dirZ obj_namessrc_namerextrrrobject_filenames8s,         zMSVCCompiler.object_filenamesNc  Cs8|js||||||||} | \}} }} } |pg} | d|r*| |jn| |j| D]}z| |\}}Wn tyEYq2w|rNtj |}||j vrXd|}n||j vrbd|}n||j vr|}d|}z||jg| |g|gWnty}zt|d}~wwq2||jvrtj |}tj |}z6||jgd|d|g|gtj tj |\}}tj ||d}||jgd|g|gWnty}zt|d}~wwq2td||fd |}z||jg| | ||g|Wq2ty}zt|d}~ww| S) Nz/cz/Tcz/Tpz/foz-hz-rrUz"Don't know how to compile %s to %sz/Fo)r\rZ_setup_compilerextendr|r{r0rOr.abspath _c_extensions_cpp_extensionsrspawnrvrrrdirnamerwrrrzrt)r*sourcesrr( include_dirsdebug extra_preargsextra_postargsdependsZ compile_infoobjectsZpp_optsbuildZ compile_optsobjsrcrZ input_optZ output_optmsgZh_dirZrc_dirr_Zrc_filerrrcompileWs                  zMSVCCompiler.compilec Cs|js||||\}}|j||d}|||rC|d|g}|r& z ||jg|WdStyB}zt|d}~wwt d|dS)N)r/OUT:skipping %s (up-to-date)) r\r_fix_object_argslibrary_filename _need_linkrr`rrr r) r*rZoutput_libnamerr target_langoutput_filenameZlib_argsrrrrcreate_static_libs" zMSVCCompiler.create_static_libc Cs|js||||\}}||||}|\}}}|r&|dt|t||||}|dur8tj ||}| ||r|t j krU| rM|j dd}n|jdd}n | r[|j }n|j}g}|pcgD] }|d|qd||||d|g}|durtjtj|\}}tj tj|d||}|d|| r| |dd<| r|| |tj|z ||jg|WdSty}zt|d}~wwtd|dS)Nz5I don't know what to do with 'runtime_library_dirs': r z/EXPORT:rrz/IMPLIB:r)r\rrZ _fix_lib_argswarnstrrrOr.rzrrZ EXECUTABLEr~r}rrrrrrmkpathrrurrr r)r*Z target_descrrr libraries library_dirsruntime_library_dirsexport_symbolsrrrZ build_temprZ fixed_argsZlib_optsZldflagsZ export_optssymZld_argsZdll_nameZdll_extZ implib_filerrrrlinksl        zMSVCCompiler.linkcCsd|S)Nz /LIBPATH:rr*dirrrrlibrary_dir_optionszMSVCCompiler.library_dir_optioncCstd)Nzsj        -  9  PKH]:zMWpython3.10/site-packages/setuptools/_distutils/__pycache__/bcppcompiler.cpython-310.pycnu[o Xai.:@spdZddlZddlmZmZmZmZmZddlm Z m Z ddl m Z ddl mZddlmZGdd d e ZdS) zdistutils.bcppcompiler Contains BorlandCCompiler, an implementation of the abstract CCompiler class for the Borland C++ compiler. N)DistutilsExecError CompileErrorLibError LinkErrorUnknownFileError) CCompilergen_preprocess_options) write_file)newer)logc@seZdZdZdZiZdgZgdZeeZdZ dZ dZ dZ Z d Z dd d Z dddZ dddZ dddZdddZ d ddZ d!ddZd S)" BCPPCompilerzConcrete class that implements an interface to the Borland C/C++ compiler, as defined by the CCompiler abstract class. Zbcppz.c)z.ccz.cppz.cxxz.objz.libz.dllz%s%sz.exercCsnt||||d|_d|_d|_d|_gd|_gd|_gd|_gd|_ g|_ gd|_ gd|_ dS) Nz bcc32.exez ilink32.exeztlib.exe)/tWMz/O2/q/g0)r z/Odrr)z/Tpd/Gnr/x)rrr)rrrz/r) r__init__cclinkerlibZpreprocess_optionscompile_optionscompile_options_debugldflags_sharedldflags_shared_debugZldflags_static ldflags_exeldflags_exe_debug)selfverbosedry_runforcer /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/bcppcompiler.pyr5s     zBCPPCompiler.__init__Nc  Csn|||||||\}} }} } |pg} | d|r!| |jn| |j| D]} z| | \}}Wn ty<Yq)wtj|}tj| } | tj | |dkrWq)|dkrxz | dd| |gWnt yv}zt |d}~wwq)||jvrd}n ||jvrd}nd}d| }z| |jg| | ||g||gWq)t y}zt |d}~ww| S) Nz-c.res.rcZbrcc32z-foz-P-o)Z_setup_compileappendextendrrKeyErrorospathnormpathmkpathdirnamespawnrr _c_extensions_cpp_extensionsr)rsources output_dirmacros include_dirsdebug extra_preargsextra_postargsdependsobjectspp_optsbuildZ compile_optsobjsrcextmsgZ input_optZ output_optr r r!compileQs^          zBCPPCompiler.compilec Cs|||\}}|j||d}|||r;|dg|}|r z ||jg|WdSty:}zt|d}~wwtd|dS)N)r2z/uskipping %s (up-to-date)) _fix_object_argslibrary_filename _need_linkr.rrrr r5) rr9Zoutput_libnamer2r5 target_langoutput_filenameZlib_argsr?r r r!create_static_libs   zBCPPCompiler.create_static_libc Cs|||\}}||||\}}}|rtdt||dur'tj||}|||ra|t j krGd}| r?|j dd}n|j dd}nd}| rS|j dd}n|jdd}|durad}n?tj|\}}tj|\}}tj|d}tj|d|}dg}|pgD] }|d||fq|t||fd |ttjj|}|g}g}|D]}tjtj|\}}|d kr||q||q|D] }|d tj|q|d |||d |g|d|D]}|||| }|dur||q||q|d|d|d |g|d ||| r2| |dd<| r:|| |tj|z ||jg|WdSty`}zt|d}~wwtd|dS)Nz7I don't know what to do with 'runtime_library_dirs': %sZc0w32Zc0d32r$rz%s.defZEXPORTSz %s=_%sz writing %sr"z/L%sz/L.,z,,Zimport32Zcw32mtrA) rBZ _fix_lib_argsr warnstrr)r*joinrDrZ EXECUTABLErrrrsplitsplitextr-r&executer mapr+normcaser'find_library_filer,r.rrrr5) rZ target_descr9rFr2 libraries library_dirsruntime_library_dirsexport_symbolsr5r6r7Z build_temprEZ startup_objZld_argsZdef_fileheadtailmodnamer>temp_dircontentssymZobjects2 resourcesfilebaselrlibfiler?r r r!links                  zBCPPCompiler.linkc Csr|r|d}|d|d||f}n|d|f}|D]}|D]}tj|||}tj|r5|SqqdS)N_dZ_bcpp)r)r*rKrCexists) rdirsrr5ZdlibZ try_namesdirnamer`r r r!rQ4s    zBCPPCompiler.find_library_filer$cCs|durd}g}|D]V}tjtj|\}}||jddgvr)td||f|r1tj|}|dkrB|tj|||q |dkrS|tj||dq |tj|||j q |S)Nr$r#r"z"unknown file type '%s' (from '%s')) r)r*rMrPsrc_extensionsrbasenamer&rK obj_extension)rZsource_filenamesZ strip_dirr2Z obj_namessrc_namer^r>r r r!object_filenamesNs$   zBCPPCompiler.object_filenamesc Cs|d||\}}}t||}dg|} |dur| d||r'|| dd<|r.| || ||js?|dus?t||rg|rJ|tj |z| | WdSt yf} zt | t | d} ~ wwdS)Nz cpp32.exer%r)Z_fix_compile_argsrr&r'rr r,r)r*r-r.rprintr) rsourceZ output_filer3r4r6r7_r:Zpp_argsr?r r r! preprocessis,      zBCPPCompiler.preprocess)rrr)NNNrNNN)NrN) NNNNNrNNNN)r)rr$)NNNNN)__name__ __module__ __qualname____doc__ compiler_typeZ executablesr/r0rgriZstatic_lib_extensionshared_lib_extensionZstatic_lib_formatZshared_lib_formatZ exe_extensionrr@rGrarQrkror r r r!r sZ  D    r )rsr)distutils.errorsrrrrrZdistutils.ccompilerrrdistutils.file_utilr distutils.dep_utilr distutilsr r r r r r!s   PKH]*Upython3.10/site-packages/setuptools/_distutils/__pycache__/py38compat.cpython-310.pycnu[o Xai@s ddZdS)cCs4z ddl}|WStyYnwd|||fS)Nz%s-%s.%s) _aix_support aix_platform ImportError)osnameversionreleaserr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/py38compat.pyrs  rN)rrrrr s PKH]*33Spython3.10/site-packages/setuptools/_distutils/__pycache__/dir_util.cpython-310.pycnu[o Xaib@stdZddlZddlZddlmZmZddlmZiadddZ dd d Z  dd d Z d dZ dddZ ddZdS)zWdistutils.dir_util Utility functions for manipulating directories and directory trees.N)DistutilsFileErrorDistutilsInternalError)logc Csrt|ts td|ftj|}g}tj|s|dkr |Sttj |r+|Stj |\}}|g}|rX|rXtj|sXtj |\}}| d||rX|rXtj|r@|D]\}tj ||}tj |} t| roqZ|dkryt d||szt||Wn)ty} z| jtjkrtj|std|| jdfWYd} ~ nd} ~ ww||dt| <qZ|S) aCreate a directory and any missing ancestor directories. If the directory already exists (or if 'name' is the empty string, which means the current directory, which of course exists), then do nothing. Raise DistutilsFileError if unable to create some directory along the way (eg. some sub-path exists, but is a file rather than a directory). If 'verbose' is true, print a one-line summary of each mkdir to stdout. Return the list of directories actually created. z(mkpath: 'name' must be a string (got %r)rrz creating %szcould not create '%s': %sN) isinstancestrrospathnormpathisdir _path_createdgetabspathsplitinsertjoinrinfomkdirOSErrorerrnoEEXISTrargsappend) namemodeverbosedry_run created_dirsheadtailtailsdabs_headexcr'/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/dir_util.pymkpathsJ         r)c CsNt}|D]}|tj|tj|qt|D] }t||||dqdS)aCreate all the empty directories under 'base_dir' needed to put 'files' there. 'base_dir' is just the name of a directory which doesn't necessarily exist yet; 'files' is a list of filenames to be interpreted relative to 'base_dir'. 'base_dir' + the directory portion of every file in 'files' will be created if it doesn't already exist. 'mode', 'verbose' and 'dry_run' flags are as for 'mkpath()'. rrN)setaddr r rdirnamesortedr))base_dirfilesrrrneed_dirfiledirr'r'r( create_treePs   r4c CsZddlm}|stj|std|zt|} Wn ty;} z|r(g} n td|| jfWYd} ~ nd} ~ ww|sDt ||dg} | D]b} tj || } tj || }| dr^qH|rtj | rt | }|dkrvtd |||s~t||| |qHtj| r| t| |||||||d qH|| ||||||d | |qH| S) aCopy an entire directory tree 'src' to a new location 'dst'. Both 'src' and 'dst' must be directory names. If 'src' is not a directory, raise DistutilsFileError. If 'dst' does not exist, it is created with 'mkpath()'. The end result of the copy is that every file in 'src' is copied to 'dst', and directories under 'src' are recursively copied to 'dst'. Return the list of files that were copied or might have been copied, using their output name. The return value is unaffected by 'update' or 'dry_run': it is simply the list of all files under 'src', with the names changed to be under 'dst'. 'preserve_mode' and 'preserve_times' are the same as for 'copy_file'; note that they only apply to regular files, not to directories. If 'preserve_symlinks' is true, symlinks will be copied as symlinks (on platforms that support them!); otherwise (the default), the destination of the symlink will be copied. 'update' and 'verbose' are the same as for 'copy_file'. r) copy_filez&cannot copy tree '%s': not a directoryzerror listing files in '%s': %sN)rz.nfsrzlinking %s -> %sr*)distutils.file_utilr5r r rrlistdirrstrerrorr)r startswithislinkreadlinkrrsymlinkrextend copy_tree)srcdst preserve_modepreserve_timespreserve_symlinksupdaterrr5nameseoutputsnsrc_namedst_name link_destr'r'r(r>csX          r>cCsft|D]#}tj||}tj|r tj|s t||q|tj|fq|tj |fdS)zHelper for remove_tree().N) r r7r rrr:_build_cmdtuplerremovermdir)r cmdtuplesfreal_fr'r'r(rLs  rLc Cs|dkr td||rdSg}t|||D]4}z|d|dtj|d}|tvr1t|=WqtyK}z td||WYd}~qd}~wwdS)zRecursively remove an entire directory tree. Any errors are ignored (apart from being reported to stdout if 'verbose' is true). rz'removing '%s' (and everything under it)Nrzerror removing %s: %s) rrrLr r rrrwarn) directoryrrrOcmdrr&r'r'r( remove_trees$  rUcCs6tj|\}}|ddtjkr||dd}|S)zTake the full path 'path', and make it a relative path. This is useful to make 'path' the second argument to os.path.join(). rrN)r r splitdrivesep)r driver'r'r(ensure_relativesrY)rrr)rrrrrr)rr)__doc__r rdistutils.errorsrr distutilsrrr)r4r>rLrUrYr'r'r'r(s   ? E PKH]:е66Npython3.10/site-packages/setuptools/_distutils/__pycache__/cmd.cpython-310.pycnu[o XaiF@sbdZddlZddlZddlZddlmZddlmZmZm Z m Z m Z ddlm Z GdddZ dS)ztdistutils.cmd Provides the Command class, the base class for the command classes in the distutils.command package. N)DistutilsOptionError)utildir_util file_util archive_utildep_utillogc@s2eZdZdZgZddZddZddZdd Zd d Z dCddZ ddZ dDddZ ddZ dEddZdEddZddZ dEddZdd Zd!d"Zd#d$Zd%d&ZdDd'd(ZdFd*d+Zd,d-Zd.d/Zd0d1ZdGd2d3ZdHd5d6Z  dId7d8Z  dJd9d:ZdDd;d<ZdKd=d>Z dLd?d@Z! dMdAdBZ"d S)NCommanda}Abstract base class for defining command classes, the "worker bees" of the Distutils. A useful analogy for command classes is to think of them as subroutines with local variables called "options". The options are "declared" in 'initialize_options()' and "defined" (given their final values, aka "finalized") in 'finalize_options()', both of which must be defined by every command class. The distinction between the two is necessary because option values might come from the outside world (command line, config file, ...), and any options dependent on other options must be computed *after* these outside influences have been processed -- hence 'finalize_options()'. The "body" of the subroutine, where it does all its work based on the values of its options, is the 'run()' method, which must also be implemented by every command class. cCsbddlm}t||std|jturtd||_|d|_ |j |_ d|_ d|_ d|_ dS)zCreate and initialize a new Command object. Most importantly, invokes the 'initialize_options()' method, which is the real initializer and depends on the actual command being instantiated. r) Distributionz$dist must be a Distribution instancezCommand is an abstract classN)distutils.distr isinstance TypeError __class__r RuntimeError distributioninitialize_options_dry_runverboseforcehelp finalized)selfdistr r/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/cmd.py__init__/s     zCommand.__init__cCs6|dkrt|d|}|durt|j|S|St|)Ndry_run_)getattrrAttributeError)rattrmyvalrrr __getattr___s  zCommand.__getattr__cCs|js|d|_dSN)rfinalize_optionsrrrrensure_finalizedis zCommand.ensure_finalizedcCtd|j)aSet default values for all the options that this command supports. Note that these defaults may be overridden by other commands, by the setup script, by config files, or by the command-line. Thus, this is not the place to code dependencies between options; generally, 'initialize_options()' implementations are just a bunch of "self.foo = None" assignments. This method must be implemented by all command classes. ,abstract method -- subclass %s must overriderrr'rrrr{ zCommand.initialize_optionscCr))aSet final values for all the options that this command supports. This is always called as late as possible, ie. after any option assignments from the command-line or from other commands have been done. Thus, this is the place to code option dependencies: if 'foo' depends on 'bar', then it is safe to set 'foo' from 'bar' as long as 'foo' still has the same value it was assigned in 'initialize_options()'. This method must be implemented by all command classes. r*r+r'rrrr&s zCommand.finalize_optionsNcCsddlm}|durd|}|j||tjd|d}|jD])\}}}||}|ddkr7|dd}t||}|j|d||ftjdq!dS) Nr) longopt_xlatezcommand options for '%s':)levelz =z%s = %s) distutils.fancy_getoptr.get_command_nameannouncer INFO user_options translater)rheaderindentr.optionrvaluerrr dump_optionss      zCommand.dump_optionscCr))aA command's raison d'etre: carry out the action it exists to perform, controlled by the options initialized in 'initialize_options()', customized by other commands, the setup script, the command-line, and config files, and finalized in 'finalize_options()'. All terminal output and filesystem interaction should be done by 'run()'. This method must be implemented by all command classes. r*r+r'rrrrunr,z Command.runr%cCst||dS)zmIf the current verbosity level is of greater than or equal to 'level' print 'msg' to stdout. Nr)rmsgr/rrrr4szCommand.announcecCs*ddlm}|rt|tjdSdS)z~Print 'msg' to stdout if the global DEBUG (taken from the DISTUTILS_DEBUG environment variable) flag is true. r)DEBUGN)distutils.debugr?printsysstdoutflush)rr>r?rrr debug_prints zCommand.debug_printcCsBt||}|durt||||St|tstd|||f|S)Nz'%s' must be a %s (got `%s`))rsetattrr strr)rr:whatdefaultvalrrr_ensure_stringlikes   zCommand._ensure_stringlikecCs||d|dS)zWEnsure that 'option' is a string; if not defined, set it to 'default'. stringN)rK)rr:rIrrr ensure_stringszCommand.ensure_stringcCsrt||}|dur dSt|trt||td|dSt|tr+tdd|D}nd}|s7td||fdS)zEnsure that 'option' is a list of strings. If 'option' is currently a string, we split it either on /,\s*/ or /\s+/, so "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become ["foo", "bar", "baz"]. Nz,\s*|\s+css|]}t|tVqdSN)r rG).0vrrr sz-Command.ensure_string_list..Fz''%s' must be a list of strings (got %r)) rr rGrFresplitlistallr)rr:rJokrrrensure_string_lists   zCommand.ensure_string_listcCs:||||}|dur||std|||fdSdS)Nzerror in '%s' option: )rKr)rr:testerrH error_fmtrIrJrrr_ensure_tested_strings zCommand._ensure_tested_stringcCs||tjjdddS)z5Ensure that 'option' is the name of an existing file.filenamez$'%s' does not exist or is not a fileN)rZospathisfilerr:rrrensure_filenames zCommand.ensure_filenamecCs||tjjdddS)Nzdirectory namez)'%s' does not exist or is not a directory)rZr\r]isdirr_rrrensure_dirnames zCommand.ensure_dirnamecCst|dr|jS|jjS)N command_name)hasattrrcr__name__r'rrrr3 s zCommand.get_command_namecGsF|j|}||D]\}}t||dur t||t||q dS)a>Set the values of any "undefined" options from corresponding option values in some other command object. "Undefined" here means "is None", which is the convention used to indicate that an option has not been changed between 'initialize_options()' and 'finalize_options()'. Usually called from 'finalize_options()' for options that depend on some other command rather than another option of the same command. 'src_cmd' is the other command from which option values will be taken (a command object will be created for it if necessary); the remaining arguments are '(src_option,dst_option)' tuples which mean "take the value of 'src_option' in the 'src_cmd' command object, and copy it to 'dst_option' in the current command object". N)rget_command_objr(rrF)rsrc_cmd option_pairs src_cmd_obj src_option dst_optionrrrset_undefined_optionss  zCommand.set_undefined_optionscCs|j||}||S)zWrapper around Distribution's 'get_command_obj()' method: find (create if necessary and 'create' is true) the command object for 'command', call its 'ensure_finalized()' method, and return the finalized command object. )rrfr()rcommandcreatecmd_objrrrget_finalized_command$szCommand.get_finalized_commandrcCs|j||SrN)rreinitialize_command)rrmreinit_subcommandsrrrrq0szCommand.reinitialize_commandcCs|j|dS)zRun some other command: uses the 'run_command()' method of Distribution, which creates and finalizes the command object if necessary and then invokes its 'run()' method. N)r run_command)rrmrrrrs4szCommand.run_commandcCs2g}|jD]\}}|dus||r||q|S)akDetermine the sub-commands that are relevant in the current distribution (ie., that need to be run). This is based on the 'sub_commands' class attribute: each tuple in that list may include a method that we call to determine if the subcommand needs to be run for the current distribution. Return a list of command names. N) sub_commandsappend)rcommandscmd_namemethodrrrget_sub_commands;s  zCommand.get_sub_commandscCstd||dS)Nzwarning: %s: %s )r warnr3)rr>rrrrzKz Command.warncCstj||||jddSNr)rexecuter)rfuncargsr>r/rrrr~NszCommand.executecCstj|||jddSr|)rmkpathr)rnamemoderrrrQr{zCommand.mkpathc Cstj|||||j ||jdS)zCopy a file respecting verbose, dry-run and force flags. (The former two default to whatever is in the Distribution object, and the latter defaults to false for commands that don't define it.)r})r copy_filerr)rinfileoutfile preserve_modepreserve_timeslinkr/rrrrTs  zCommand.copy_filec Cstj||||||j |jdS)z\Copy an entire directory tree respecting verbose, dry-run, and force flags. r})r copy_treerr)rrrrrpreserve_symlinksr/rrrr]s  zCommand.copy_treecCstj|||jdS)z$Move a file respecting dry-run flag.r})r move_filer)rsrcdstr/rrrrfszCommand.move_filecCs ddlm}||||jddS)z2Spawn an external command respecting dry-run flag.r)spawnr}N)distutils.spawnrr)rcmd search_pathr/rrrrrjs z Command.spawnc Cstj|||||j||dS)N)rownergroup)r make_archiver)r base_nameformatroot_dirbase_dirrrrrrros zCommand.make_archivecCs|durd|}t|tr|f}n t|ttfstd|dur)d|d|f}|js2t||r<| ||||dSt |dS)aSpecial case of 'execute()' for operations that process one or more input files and generate one output file. Works just like 'execute()', except the operation is skipped and a different message printed if 'outfile' already exists and is newer than all files listed in 'infiles'. If the command defined 'self.force', and it is true, then the command is unconditionally run -- does no timestamp checks. Nzskipping %s (inputs unchanged)z9'infiles' must be a string, or a list or tuple of stringszgenerating %s from %sz, ) r rGrTtuplerjoinrr newer_groupr~r debug)rinfilesrrrexec_msgskip_msgr/rrr make_fileus  zCommand.make_file)Nr-)r%rN)rr$)r)r%r%Nr%)r%r%rr%)r%r%)NNNN)NNr%)#re __module__ __qualname____doc__rtrr#r(rr&r<r=r4rErKrMrWrZr`rbr3rlrprqrsryrzr~rrrrrrrrrrrr sR0              r )rrBr\rRdistutils.errorsr distutilsrrrrrr r rrrrs   PKH]s77Opython3.10/site-packages/setuptools/_distutils/__pycache__/util.cpython-310.pycnu[o XaiO@s0dZddlZddlZddlZddlZddlZddlmZddl m Z ddl m Z ddl mZddlmZdd lmZd d Zd d ZejdkrIdadZddZddZddZddZddZddZdaddZddZd/d!d"Z da!a"a#d#d$Z$d%d&Z%d0d'd(Z&d)d*Z'    d1d+d,Z(d-d.Z)dS)2zudistutils.util Miscellaneous utility functions -- anything that doesn't fit into one of the other *util.py modules. N)DistutilsPlatformError)newer)spawn)log)DistutilsByteCompileError)"_optim_args_from_interpreter_flagsc Cstjdkr#dtjvrdSdtjvrdSdtjvr dStjSdtjvr-tjdStjd ks7ttd s:tjSt\}}}}}| d d }| d d}| d d}|dddkred||fS|dddkr|ddkrd}dt |dd|ddf}ddd}|d|tj 7}nO|dddkrd d!l m }||||S|dd"d#krd#}td$tj}||}|r|}n|dd"d%krddl} ddl} | | j|||\}}}d&|||fS)'aReturn a string that identifies the current platform. This is used mainly to distinguish platform-specific build directories and platform-specific built distributions. Typically includes the OS name and version and the architecture (as supplied by 'os.uname()'), although the exact information included depends on the OS; eg. on Linux, the kernel version isn't particularly important. Examples of returned values: linux-i586 linux-alpha (?) solaris-2.6-sun4u Windows will return one of: win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) win32 (all others - specifically, sys.platform is returned) For other non-POSIX platforms, currently just returns 'sys.platform'. ntamd64 win-amd64z(arm) win-arm32z(arm64) win-arm64_PYTHON_HOST_PLATFORMposixuname/ _-Nlinuxz%s-%ssunosr5solarisz%d.%s32bit64bit)ilz.%saixr) aix_platformcygwinz[\d.]+darwinz%s-%s-%s)osnamesysversionlowerplatformenvironhasattrrreplaceintmaxsizeZ py38compatr recompileASCIImatchgroup _osx_supportdistutils.sysconfigget_platform_osx sysconfigget_config_vars) osnamehostreleaser'machinebitnessr rel_remr4 distutilsrA/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/util.pyget_host_platformsT             rCcCs6tjdkrddddd}|tjdptStS)Nr win32r r r )x86x64armarm64VSCMD_ARG_TGT_ARCH)r$r%getr*rC)TARGET_TO_PLATrArArB get_platformds rLr#MACOSX_DEPLOYMENT_TARGETcCsdadS)zFor testing only. Do not call.N)_syscfg_macosx_verrArArArB_clear_cached_macosx_verusrOcCs.tdurddlm}|tpd}|r|atS)zGet the version of macOS latched in the Python interpreter configuration. Returns the version as a string or None if can't obtain one. Cached.Nr)r7r)rNr@r7get_config_varMACOSX_VERSION_VAR)r7verrArArB!get_macosx_target_ver_from_syscfgzs  rScCs^t}tjt}|r-|r+t|ddgkr+t|ddgkr+dtd||f}t||S|S)aReturn the version of macOS for which we are building. The target version defaults to the version in sysconfig latched at time the Python interpreter was built, unless overridden by an environment variable. If neither source has a value, then None is returned r$zE mismatch: now "%s" but "%s" during configure; must use 10.3 or later)rSr$r*rJrQ split_versionr)Z syscfg_verZenv_vermy_msgrArArBget_macosx_target_vers rXcCsdd|dDS)zEConvert a dot-separated string into a list of numbers for comparisonscSsg|]}t|qSrA)r-).0nrArArB sz!split_version...)split)srArArBrVsrVcCstjdkr|S|s |S|ddkrtd||ddkr#td||d}d|vr5|dd|vs,|s:tjStjj|S)aReturn 'pathname' as a name that will work on the native filesystem, i.e. split it on '/' and put it back together again using the current directory separator. Needed because filenames in the setup script are always supplied in Unix style, and have to be converted to the local convention before we can actually use them in the filesystem. Raises ValueError on non-Unix-ish systems if 'pathname' either starts or ends with a slash. rrzpath '%s' cannot be absolutezpath '%s' cannot end with '/'r\)r$sep ValueErrorr]removecurdirpathjoin)pathnamepathsrArArB convert_paths        rhcCstjdkrtj|stj||Stj||ddStjdkr=tj|\}}|ddkr6|dd}tj||Stdtj)a Return 'pathname' with 'new_root' prepended. If 'pathname' is relative, this is equivalent to "os.path.join(new_root,pathname)". Otherwise, it requires making 'pathname' relative and then joining the two, which is tricky on DOS/Windows and Mac OS. rrNr r\z!nothing known about platform '%s')r$r%rdisabsre splitdriver)new_rootrfdriverdrArArB change_roots     rnc CsvtrdStjdkr,dtjvr,zddl}|tdtjd<Wn ttfy+Ynwdtjvr7t tjd<dadS)aLEnsure that 'os.environ' has all the environment variables we guarantee that users can use in config files, command-line options, etc. Currently this includes: HOME - user's home directory (Unix only) PLAT - description of the current platform, including hardware and OS (see 'get_platform()') NrHOMErrPLATr) _environ_checkedr$r%r*pwdgetpwuidgetuid ImportErrorKeyErrorrL)rrrArArB check_environs   rwc CsHt|fdd}ztd||WSty#}ztd|d}~ww)aPerform shell/Perl-style variable substitution on 'string'. Every occurrence of '$' followed by a name is considered a variable, and variable is substituted by the value found in the 'local_vars' dictionary, or in 'os.environ' if it's not in 'local_vars'. 'os.environ' is first checked/augmented to guarantee that it contains certain values: see 'check_environ()'. Raise ValueError for any variables not found in either 'local_vars' or 'os.environ'. cSs(|d}||vrt||Stj|S)Nr)r3strr$r*)r2 local_varsvar_namerArArB_substs   zsubst_vars.._substz\$([a-zA-Z_][a-zA-Z_0-9]*)zinvalid variable '$%s'N)rwr/subrvra)r^ryr{varrArArB subst_varss  r~error: cCs |t|S)N)rx)excprefixrArArBgrok_environment_error s rcCs(tdtjatdatdadS)Nz [^\\\'\"%s ]*z'(?:[^'\\]|\\.)*'z"(?:[^"\\]|\\.)*")r/r0string whitespace _wordchars_re _squote_re _dquote_rerArArArB _init_regexs rcCstdurt|}g}d}|rt||}|}|t|kr-||d| |S||tjvrH||d|||d }d}ni||dkra|d|||dd}|d}nP||dkrnt ||}n||dkr{t ||}nt d|||durt d|||\}}|d|||d|d||d}|d }|t|kr|| |S|s|S) aSplit a string up according to Unix shell-like rules for quotes and backslashes. In short: words are delimited by spaces, as long as those spaces are not escaped by a backslash, or inside a quoted string. Single and double quotes are equivalent, and the quote characters can be backslash-escaped. The backslash is stripped from any two-character escape sequence, leaving only the escaped character. The quote characters are stripped from any quoted string. Returns a list of words. Nrrir'"z!this can't happen (bad char '%c')z"bad string (mismatched %s quotes?)r)rrstripr2endlenappendrrlstriprr RuntimeErrorraspan)r^wordsposr?rbegrArArB split_quotedsD       ,   $rcCsT|durd|j|f}|dddkr|ddd}t||s(||dSdS)aPerform some action that affects the outside world (eg. by writing to the filesystem). Such actions are special because they are disabled by the 'dry_run' flag. This method takes care of all that bureaucracy for you; all you have to do is supply the function to call and an argument tuple for it (to embody the "external action" being performed), and an optional message to print. Nz%s%rz,)r))__name__rinfo)funcargsmsgverbosedry_runrArArBexecuteYs   rcCs.|}|dvr dS|dvrdStd|f)zConvert a string representation of truth to true (1) or false (0). True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if 'val' is anything else. )yyesttrueon1r)rZnoffalseoff0rzinvalid truth value %r)r(ra)valrArArB strtoboolls rc CsNddl}tjr td|dur|dk}|szddlm} | d\} } Wnty9ddlm} d| d} } Ynwt d| |s| durMt | d } nt | d } | &| d | d tt|d | d |||||fWdn1s}wYtjg}|t|| t||dtt j| fd| |ddSddlm}|D]w}|dddkrq|dkr|dkrdn|}tjj||d}ntj|}|}|r|dt||krtd||f|t|d}|rt j||}t j |}|r$|s t!||rt d|||s||||qt"d||qdS)a~Byte-compile a collection of Python source files to .pyc files in a __pycache__ subdirectory. 'py_files' is a list of files to compile; any files that don't end in ".py" are silently skipped. 'optimize' must be one of the following: 0 - don't optimize 1 - normal optimization (like "python -O") 2 - extra optimization (like "python -OO") If 'force' is true, all files are recompiled regardless of timestamps. The source filename encoded in each bytecode file defaults to the filenames listed in 'py_files'; you can modify these with 'prefix' and 'basedir'. 'prefix' is a string that will be stripped off of each source filename, and 'base_dir' is a directory name that will be prepended (after 'prefix' is stripped). You can supply either or both (or neither) of 'prefix' and 'base_dir', as you wish. If 'dry_run' is true, doesn't actually do anything that would affect the filesystem. Byte-compilation is either done directly in this interpreter process with the standard py_compile module, or indirectly by writing a temporary script and executing it. Normally, you should let 'byte_compile()' figure out to use direct compilation or not (see the source for details). The 'direct' flag is used by the script generated in indirect mode; unless you know what you're doing, leave it set to None. rNzbyte-compiling is disabled.T)mkstempz.py)mktempz$writing byte-compilation script '%s'wz2from distutils.util import byte_compile files = [ z, z] z byte_compile(files, optimize=%r, force=%r, prefix=%r, base_dir=%r, verbose=%r, dry_run=0, direct=1) )rz removing %s)r0r) optimizationz1invalid prefix: filename %r doesn't start with %rzbyte-compiling %s to %sz%skipping byte-compilation of %s to %s)# subprocessr&dont_write_bytecodertempfilerrurrrr$fdopenopenwriteremaprepr executableextendrrrrrb py_compiler0 importlibutilcache_from_sourcerrardbasenamerdebug)py_filesoptimizeforcerbase_dirrrdirectrr script_fd script_namerscriptcmdr0fileoptcfiledfile cfile_baserArArB byte_compile|s~$               rcCs|d}d}||S)zReturn a version of the string escaped for inclusion in an RFC-822 header, by ensuring there are 8 spaces space after each newline.  z )r]re)headerlinesr`rArArB rfc822_escapes  r)r)Nrr)rrNNrrN)*__doc__r$r/importlib.utilrrr&distutils.errorsrdistutils.dep_utilrdistutils.spawnrr@rrZ py35compatrrCrLr)rNrQrOrSrXrVrhrnrqrwr~rrrrrrrrrrrArArArBsN      P     =  PKH]:k[[>python3.10/site-packages/setuptools/_distutils/msvccompiler.pynu["""distutils.msvccompiler Contains MSVCCompiler, an implementation of the abstract CCompiler class for the Microsoft Visual Studio. """ # Written by Perry Stoll # hacked by Robin Becker and Thomas Heller to do a better job of # finding DevStudio (through the registry) import sys, os from distutils.errors import \ DistutilsExecError, DistutilsPlatformError, \ CompileError, LibError, LinkError from distutils.ccompiler import \ CCompiler, gen_lib_options from distutils import log _can_read_reg = False try: import winreg _can_read_reg = True hkey_mod = winreg RegOpenKeyEx = winreg.OpenKeyEx RegEnumKey = winreg.EnumKey RegEnumValue = winreg.EnumValue RegError = winreg.error except ImportError: try: import win32api import win32con _can_read_reg = True hkey_mod = win32con RegOpenKeyEx = win32api.RegOpenKeyEx RegEnumKey = win32api.RegEnumKey RegEnumValue = win32api.RegEnumValue RegError = win32api.error except ImportError: log.info("Warning: Can't read registry to find the " "necessary compiler setting\n" "Make sure that Python modules winreg, " "win32api or win32con are installed.") pass if _can_read_reg: HKEYS = (hkey_mod.HKEY_USERS, hkey_mod.HKEY_CURRENT_USER, hkey_mod.HKEY_LOCAL_MACHINE, hkey_mod.HKEY_CLASSES_ROOT) def read_keys(base, key): """Return list of registry keys.""" try: handle = RegOpenKeyEx(base, key) except RegError: return None L = [] i = 0 while True: try: k = RegEnumKey(handle, i) except RegError: break L.append(k) i += 1 return L def read_values(base, key): """Return dict of registry keys and values. All names are converted to lowercase. """ try: handle = RegOpenKeyEx(base, key) except RegError: return None d = {} i = 0 while True: try: name, value, type = RegEnumValue(handle, i) except RegError: break name = name.lower() d[convert_mbcs(name)] = convert_mbcs(value) i += 1 return d def convert_mbcs(s): dec = getattr(s, "decode", None) if dec is not None: try: s = dec("mbcs") except UnicodeError: pass return s class MacroExpander: def __init__(self, version): self.macros = {} self.load_macros(version) def set_macro(self, macro, path, key): for base in HKEYS: d = read_values(base, path) if d: self.macros["$(%s)" % macro] = d[key] break def load_macros(self, version): vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir") self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir") net = r"Software\Microsoft\.NETFramework" self.set_macro("FrameworkDir", net, "installroot") try: if version > 7.0: self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1") else: self.set_macro("FrameworkSDKDir", net, "sdkinstallroot") except KeyError as exc: # raise DistutilsPlatformError( """Python was built with Visual Studio 2003; extensions must be built with a compiler than can generate compatible binaries. Visual Studio 2003 was not found on this system. If you have Cygwin installed, you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") p = r"Software\Microsoft\NET Framework Setup\Product" for base in HKEYS: try: h = RegOpenKeyEx(base, p) except RegError: continue key = RegEnumKey(h, 0) d = read_values(base, r"%s\%s" % (p, key)) self.macros["$(FrameworkVersion)"] = d["version"] def sub(self, s): for k, v in self.macros.items(): s = s.replace(k, v) return s def get_build_version(): """Return the version of MSVC that was used to build Python. For Python 2.3 and up, the version number is included in sys.version. For earlier versions, assume the compiler is MSVC 6. """ prefix = "MSC v." i = sys.version.find(prefix) if i == -1: return 6 i = i + len(prefix) s, rest = sys.version[i:].split(" ", 1) majorVersion = int(s[:-2]) - 6 if majorVersion >= 13: # v13 was skipped and should be v14 majorVersion += 1 minorVersion = int(s[2:3]) / 10.0 # I don't think paths are affected by minor version in version 6 if majorVersion == 6: minorVersion = 0 if majorVersion >= 6: return majorVersion + minorVersion # else we don't know what version of the compiler this is return None def get_build_architecture(): """Return the processor architecture. Possible results are "Intel" or "AMD64". """ prefix = " bit (" i = sys.version.find(prefix) if i == -1: return "Intel" j = sys.version.find(")", i) return sys.version[i+len(prefix):j] def normalize_and_reduce_paths(paths): """Return a list of normalized paths with duplicates removed. The current order of paths is maintained. """ # Paths are normalized so things like: /a and /a/ aren't both preserved. reduced_paths = [] for p in paths: np = os.path.normpath(p) # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set. if np not in reduced_paths: reduced_paths.append(np) return reduced_paths class MSVCCompiler(CCompiler) : """Concrete class that implements an interface to Microsoft Visual C++, as defined by the CCompiler abstract class.""" compiler_type = 'msvc' # Just set this so CCompiler's constructor doesn't barf. We currently # don't use the 'set_executables()' bureaucracy provided by CCompiler, # as it really isn't necessary for this sort of single-compiler class. # Would be nice to have a consistent interface with UnixCCompiler, # though, so it's worth thinking about. executables = {} # Private class data (need to distinguish C from C++ source for compiler) _c_extensions = ['.c'] _cpp_extensions = ['.cc', '.cpp', '.cxx'] _rc_extensions = ['.rc'] _mc_extensions = ['.mc'] # Needed for the filename generation methods provided by the # base class, CCompiler. src_extensions = (_c_extensions + _cpp_extensions + _rc_extensions + _mc_extensions) res_extension = '.res' obj_extension = '.obj' static_lib_extension = '.lib' shared_lib_extension = '.dll' static_lib_format = shared_lib_format = '%s%s' exe_extension = '.exe' def __init__(self, verbose=0, dry_run=0, force=0): CCompiler.__init__ (self, verbose, dry_run, force) self.__version = get_build_version() self.__arch = get_build_architecture() if self.__arch == "Intel": # x86 if self.__version >= 7: self.__root = r"Software\Microsoft\VisualStudio" self.__macros = MacroExpander(self.__version) else: self.__root = r"Software\Microsoft\Devstudio" self.__product = "Visual Studio version %s" % self.__version else: # Win64. Assume this was built with the platform SDK self.__product = "Microsoft SDK compiler %s" % (self.__version + 6) self.initialized = False def initialize(self): self.__paths = [] if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"): # Assume that the SDK set up everything alright; don't try to be # smarter self.cc = "cl.exe" self.linker = "link.exe" self.lib = "lib.exe" self.rc = "rc.exe" self.mc = "mc.exe" else: self.__paths = self.get_msvc_paths("path") if len(self.__paths) == 0: raise DistutilsPlatformError("Python was built with %s, " "and extensions need to be built with the same " "version of the compiler, but it isn't installed." % self.__product) self.cc = self.find_exe("cl.exe") self.linker = self.find_exe("link.exe") self.lib = self.find_exe("lib.exe") self.rc = self.find_exe("rc.exe") # resource compiler self.mc = self.find_exe("mc.exe") # message compiler self.set_path_env_var('lib') self.set_path_env_var('include') # extend the MSVC path with the current path try: for p in os.environ['path'].split(';'): self.__paths.append(p) except KeyError: pass self.__paths = normalize_and_reduce_paths(self.__paths) os.environ['path'] = ";".join(self.__paths) self.preprocess_options = None if self.__arch == "Intel": self.compile_options = [ '/nologo', '/O2', '/MD', '/W3', '/GX' , '/DNDEBUG'] self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX', '/Z7', '/D_DEBUG'] else: # Win64 self.compile_options = [ '/nologo', '/O2', '/MD', '/W3', '/GS-' , '/DNDEBUG'] self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-', '/Z7', '/D_DEBUG'] self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] if self.__version >= 7: self.ldflags_shared_debug = [ '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG' ] else: self.ldflags_shared_debug = [ '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG' ] self.ldflags_static = [ '/nologo'] self.initialized = True # -- Worker methods ------------------------------------------------ def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): # Copied from ccompiler.py, extended to return .res as 'object'-file # for .rc input file if output_dir is None: output_dir = '' obj_names = [] for src_name in source_filenames: (base, ext) = os.path.splitext (src_name) base = os.path.splitdrive(base)[1] # Chop off the drive base = base[os.path.isabs(base):] # If abs, chop off leading / if ext not in self.src_extensions: # Better to raise an exception instead of silently continuing # and later complain about sources and targets having # different lengths raise CompileError ("Don't know how to compile %s" % src_name) if strip_dir: base = os.path.basename (base) if ext in self._rc_extensions: obj_names.append (os.path.join (output_dir, base + self.res_extension)) elif ext in self._mc_extensions: obj_names.append (os.path.join (output_dir, base + self.res_extension)) else: obj_names.append (os.path.join (output_dir, base + self.obj_extension)) return obj_names def compile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): if not self.initialized: self.initialize() compile_info = self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs) macros, objects, extra_postargs, pp_opts, build = compile_info compile_opts = extra_preargs or [] compile_opts.append ('/c') if debug: compile_opts.extend(self.compile_options_debug) else: compile_opts.extend(self.compile_options) for obj in objects: try: src, ext = build[obj] except KeyError: continue if debug: # pass the full pathname to MSVC in debug mode, # this allows the debugger to find the source file # without asking the user to browse for it src = os.path.abspath(src) if ext in self._c_extensions: input_opt = "/Tc" + src elif ext in self._cpp_extensions: input_opt = "/Tp" + src elif ext in self._rc_extensions: # compile .RC to .RES file input_opt = src output_opt = "/fo" + obj try: self.spawn([self.rc] + pp_opts + [output_opt] + [input_opt]) except DistutilsExecError as msg: raise CompileError(msg) continue elif ext in self._mc_extensions: # Compile .MC to .RC file to .RES file. # * '-h dir' specifies the directory for the # generated include file # * '-r dir' specifies the target directory of the # generated RC file and the binary message resource # it includes # # For now (since there are no options to change this), # we use the source-directory for the include file and # the build directory for the RC file and message # resources. This works at least for win32all. h_dir = os.path.dirname(src) rc_dir = os.path.dirname(obj) try: # first compile .MC to .RC and .H file self.spawn([self.mc] + ['-h', h_dir, '-r', rc_dir] + [src]) base, _ = os.path.splitext (os.path.basename (src)) rc_file = os.path.join (rc_dir, base + '.rc') # then compile .RC to .RES file self.spawn([self.rc] + ["/fo" + obj] + [rc_file]) except DistutilsExecError as msg: raise CompileError(msg) continue else: # how to handle this file? raise CompileError("Don't know how to compile %s to %s" % (src, obj)) output_opt = "/Fo" + obj try: self.spawn([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg) return objects def create_static_lib(self, objects, output_libname, output_dir=None, debug=0, target_lang=None): if not self.initialized: self.initialize() (objects, output_dir) = self._fix_object_args(objects, output_dir) output_filename = self.library_filename(output_libname, output_dir=output_dir) if self._need_link(objects, output_filename): lib_args = objects + ['/OUT:' + output_filename] if debug: pass # XXX what goes here? try: self.spawn([self.lib] + lib_args) except DistutilsExecError as msg: raise LibError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): if not self.initialized: self.initialize() (objects, output_dir) = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) (libraries, library_dirs, runtime_library_dirs) = fixed_args if runtime_library_dirs: self.warn ("I don't know what to do with 'runtime_library_dirs': " + str (runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): if target_desc == CCompiler.EXECUTABLE: if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] else: if debug: ldflags = self.ldflags_shared_debug else: ldflags = self.ldflags_shared export_opts = [] for sym in (export_symbols or []): export_opts.append("/EXPORT:" + sym) ld_args = (ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]) # The MSVC linker generates .lib and .exp files, which cannot be # suppressed by any linker switches. The .lib files may even be # needed! Make sure they are generated in the temporary build # directory. Since they have different names for debug and release # builds, they can go into the same directory. if export_symbols is not None: (dll_name, dll_ext) = os.path.splitext( os.path.basename(output_filename)) implib_file = os.path.join( os.path.dirname(objects[0]), self.library_filename(dll_name)) ld_args.append ('/IMPLIB:' + implib_file) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: self.spawn([self.linker] + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) # -- Miscellaneous methods ----------------------------------------- # These are all used by the 'gen_lib_options() function, in # ccompiler.py. def library_dir_option(self, dir): return "/LIBPATH:" + dir def runtime_library_dir_option(self, dir): raise DistutilsPlatformError( "don't know how to set runtime library search path for MSVC++") def library_option(self, lib): return self.library_filename(lib) def find_library_file(self, dirs, lib, debug=0): # Prefer a debugging library if found (and requested), but deal # with it if we don't have one. if debug: try_names = [lib + "_d", lib] else: try_names = [lib] for dir in dirs: for name in try_names: libfile = os.path.join(dir, self.library_filename (name)) if os.path.exists(libfile): return libfile else: # Oops, didn't find it in *any* of 'dirs' return None # Helper methods for using the MSVC registry settings def find_exe(self, exe): """Return path to an MSVC executable program. Tries to find the program in several places: first, one of the MSVC program search paths from the registry; next, the directories in the PATH environment variable. If any of those work, return an absolute path that is known to exist. If none of them work, just return the original program name, 'exe'. """ for p in self.__paths: fn = os.path.join(os.path.abspath(p), exe) if os.path.isfile(fn): return fn # didn't find it; try existing path for p in os.environ['Path'].split(';'): fn = os.path.join(os.path.abspath(p),exe) if os.path.isfile(fn): return fn return exe def get_msvc_paths(self, path, platform='x86'): """Get a list of devstudio directories (include, lib or path). Return a list of strings. The list will be empty if unable to access the registry or appropriate registry keys not found. """ if not _can_read_reg: return [] path = path + " dirs" if self.__version >= 7: key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories" % (self.__root, self.__version)) else: key = (r"%s\6.0\Build System\Components\Platforms" r"\Win32 (%s)\Directories" % (self.__root, platform)) for base in HKEYS: d = read_values(base, key) if d: if self.__version >= 7: return self.__macros.sub(d[path]).split(";") else: return d[path].split(";") # MSVC 6 seems to create the registry entries we need only when # the GUI is run. if self.__version == 6: for base in HKEYS: if read_values(base, r"%s\6.0" % self.__root) is not None: self.warn("It seems you have Visual Studio 6 installed, " "but the expected registry settings are not present.\n" "You must at least run the Visual Studio GUI once " "so that these entries are created.") break return [] def set_path_env_var(self, name): """Set environment variable 'name' to an MSVC path type value. This is equivalent to a SET command prior to execution of spawned commands. """ if name == "lib": p = self.get_msvc_paths("library") else: p = self.get_msvc_paths(name) if p: os.environ[name] = ';'.join(p) if get_build_version() >= 8.0: log.debug("Importing new compiler from distutils.msvc9compiler") OldMSVCCompiler = MSVCCompiler from distutils.msvc9compiler import MSVCCompiler # get_build_architecture not really relevant now we support cross-compile from distutils.msvc9compiler import MacroExpander PKH]1xExE>python3.10/site-packages/setuptools/_distutils/fancy_getopt.pynu["""distutils.fancy_getopt Wrapper around the standard getopt module that provides the following additional features: * short and long options are tied together * options have help strings, so fancy_getopt could potentially create a complete usage summary * options set attributes of a passed-in object """ import sys, string, re import getopt from distutils.errors import * # Much like command_re in distutils.core, this is close to but not quite # the same as a Python NAME -- except, in the spirit of most GNU # utilities, we use '-' in place of '_'. (The spirit of LISP lives on!) # The similarities to NAME are again not a coincidence... longopt_pat = r'[a-zA-Z](?:[a-zA-Z0-9-]*)' longopt_re = re.compile(r'^%s$' % longopt_pat) # For recognizing "negative alias" options, eg. "quiet=!verbose" neg_alias_re = re.compile("^(%s)=!(%s)$" % (longopt_pat, longopt_pat)) # This is used to translate long options to legitimate Python identifiers # (for use as attributes of some object). longopt_xlate = str.maketrans('-', '_') class FancyGetopt: """Wrapper around the standard 'getopt()' module that provides some handy extra functionality: * short and long options are tied together * options have help strings, and help text can be assembled from them * options set attributes of a passed-in object * boolean options can have "negative aliases" -- eg. if --quiet is the "negative alias" of --verbose, then "--quiet" on the command line sets 'verbose' to false """ def __init__(self, option_table=None): # The option table is (currently) a list of tuples. The # tuples may have 3 or four values: # (long_option, short_option, help_string [, repeatable]) # if an option takes an argument, its long_option should have '=' # appended; short_option should just be a single character, no ':' # in any case. If a long_option doesn't have a corresponding # short_option, short_option should be None. All option tuples # must have long options. self.option_table = option_table # 'option_index' maps long option names to entries in the option # table (ie. those 3-tuples). self.option_index = {} if self.option_table: self._build_index() # 'alias' records (duh) alias options; {'foo': 'bar'} means # --foo is an alias for --bar self.alias = {} # 'negative_alias' keeps track of options that are the boolean # opposite of some other option self.negative_alias = {} # These keep track of the information in the option table. We # don't actually populate these structures until we're ready to # parse the command-line, since the 'option_table' passed in here # isn't necessarily the final word. self.short_opts = [] self.long_opts = [] self.short2long = {} self.attr_name = {} self.takes_arg = {} # And 'option_order' is filled up in 'getopt()'; it records the # original order of options (and their values) on the command-line, # but expands short options, converts aliases, etc. self.option_order = [] def _build_index(self): self.option_index.clear() for option in self.option_table: self.option_index[option[0]] = option def set_option_table(self, option_table): self.option_table = option_table self._build_index() def add_option(self, long_option, short_option=None, help_string=None): if long_option in self.option_index: raise DistutilsGetoptError( "option conflict: already an option '%s'" % long_option) else: option = (long_option, short_option, help_string) self.option_table.append(option) self.option_index[long_option] = option def has_option(self, long_option): """Return true if the option table for this parser has an option with long name 'long_option'.""" return long_option in self.option_index def get_attr_name(self, long_option): """Translate long option name 'long_option' to the form it has as an attribute of some object: ie., translate hyphens to underscores.""" return long_option.translate(longopt_xlate) def _check_alias_dict(self, aliases, what): assert isinstance(aliases, dict) for (alias, opt) in aliases.items(): if alias not in self.option_index: raise DistutilsGetoptError(("invalid %s '%s': " "option '%s' not defined") % (what, alias, alias)) if opt not in self.option_index: raise DistutilsGetoptError(("invalid %s '%s': " "aliased option '%s' not defined") % (what, alias, opt)) def set_aliases(self, alias): """Set the aliases for this option parser.""" self._check_alias_dict(alias, "alias") self.alias = alias def set_negative_aliases(self, negative_alias): """Set the negative aliases for this option parser. 'negative_alias' should be a dictionary mapping option names to option names, both the key and value must already be defined in the option table.""" self._check_alias_dict(negative_alias, "negative alias") self.negative_alias = negative_alias def _grok_option_table(self): """Populate the various data structures that keep tabs on the option table. Called by 'getopt()' before it can do anything worthwhile. """ self.long_opts = [] self.short_opts = [] self.short2long.clear() self.repeat = {} for option in self.option_table: if len(option) == 3: long, short, help = option repeat = 0 elif len(option) == 4: long, short, help, repeat = option else: # the option table is part of the code, so simply # assert that it is correct raise ValueError("invalid option tuple: %r" % (option,)) # Type- and value-check the option names if not isinstance(long, str) or len(long) < 2: raise DistutilsGetoptError(("invalid long option '%s': " "must be a string of length >= 2") % long) if (not ((short is None) or (isinstance(short, str) and len(short) == 1))): raise DistutilsGetoptError("invalid short option '%s': " "must a single character or None" % short) self.repeat[long] = repeat self.long_opts.append(long) if long[-1] == '=': # option takes an argument? if short: short = short + ':' long = long[0:-1] self.takes_arg[long] = 1 else: # Is option is a "negative alias" for some other option (eg. # "quiet" == "!verbose")? alias_to = self.negative_alias.get(long) if alias_to is not None: if self.takes_arg[alias_to]: raise DistutilsGetoptError( "invalid negative alias '%s': " "aliased option '%s' takes a value" % (long, alias_to)) self.long_opts[-1] = long # XXX redundant?! self.takes_arg[long] = 0 # If this is an alias option, make sure its "takes arg" flag is # the same as the option it's aliased to. alias_to = self.alias.get(long) if alias_to is not None: if self.takes_arg[long] != self.takes_arg[alias_to]: raise DistutilsGetoptError( "invalid alias '%s': inconsistent with " "aliased option '%s' (one of them takes a value, " "the other doesn't" % (long, alias_to)) # Now enforce some bondage on the long option name, so we can # later translate it to an attribute name on some object. Have # to do this a bit late to make sure we've removed any trailing # '='. if not longopt_re.match(long): raise DistutilsGetoptError( "invalid long option name '%s' " "(must be letters, numbers, hyphens only" % long) self.attr_name[long] = self.get_attr_name(long) if short: self.short_opts.append(short) self.short2long[short[0]] = long def getopt(self, args=None, object=None): """Parse command-line options in args. Store as attributes on object. If 'args' is None or not supplied, uses 'sys.argv[1:]'. If 'object' is None or not supplied, creates a new OptionDummy object, stores option values there, and returns a tuple (args, object). If 'object' is supplied, it is modified in place and 'getopt()' just returns 'args'; in both cases, the returned 'args' is a modified copy of the passed-in 'args' list, which is left untouched. """ if args is None: args = sys.argv[1:] if object is None: object = OptionDummy() created_object = True else: created_object = False self._grok_option_table() short_opts = ' '.join(self.short_opts) try: opts, args = getopt.getopt(args, short_opts, self.long_opts) except getopt.error as msg: raise DistutilsArgError(msg) for opt, val in opts: if len(opt) == 2 and opt[0] == '-': # it's a short option opt = self.short2long[opt[1]] else: assert len(opt) > 2 and opt[:2] == '--' opt = opt[2:] alias = self.alias.get(opt) if alias: opt = alias if not self.takes_arg[opt]: # boolean option? assert val == '', "boolean option can't have value" alias = self.negative_alias.get(opt) if alias: opt = alias val = 0 else: val = 1 attr = self.attr_name[opt] # The only repeating option at the moment is 'verbose'. # It has a negative option -q quiet, which should set verbose = 0. if val and self.repeat.get(attr) is not None: val = getattr(object, attr, 0) + 1 setattr(object, attr, val) self.option_order.append((opt, val)) # for opts if created_object: return args, object else: return args def get_option_order(self): """Returns the list of (option, value) tuples processed by the previous run of 'getopt()'. Raises RuntimeError if 'getopt()' hasn't been called yet. """ if self.option_order is None: raise RuntimeError("'getopt()' hasn't been called yet") else: return self.option_order def generate_help(self, header=None): """Generate help text (a list of strings, one per suggested line of output) from the option table for this FancyGetopt object. """ # Blithely assume the option table is good: probably wouldn't call # 'generate_help()' unless you've already called 'getopt()'. # First pass: determine maximum length of long option names max_opt = 0 for option in self.option_table: long = option[0] short = option[1] l = len(long) if long[-1] == '=': l = l - 1 if short is not None: l = l + 5 # " (-x)" where short == 'x' if l > max_opt: max_opt = l opt_width = max_opt + 2 + 2 + 2 # room for indent + dashes + gutter # Typical help block looks like this: # --foo controls foonabulation # Help block for longest option looks like this: # --flimflam set the flim-flam level # and with wrapped text: # --flimflam set the flim-flam level (must be between # 0 and 100, except on Tuesdays) # Options with short names will have the short name shown (but # it doesn't contribute to max_opt): # --foo (-f) controls foonabulation # If adding the short option would make the left column too wide, # we push the explanation off to the next line # --flimflam (-l) # set the flim-flam level # Important parameters: # - 2 spaces before option block start lines # - 2 dashes for each long option name # - min. 2 spaces between option and explanation (gutter) # - 5 characters (incl. space) for short option name # Now generate lines of help text. (If 80 columns were good enough # for Jesus, then 78 columns are good enough for me!) line_width = 78 text_width = line_width - opt_width big_indent = ' ' * opt_width if header: lines = [header] else: lines = ['Option summary:'] for option in self.option_table: long, short, help = option[:3] text = wrap_text(help, text_width) if long[-1] == '=': long = long[0:-1] # Case 1: no short option at all (makes life easy) if short is None: if text: lines.append(" --%-*s %s" % (max_opt, long, text[0])) else: lines.append(" --%-*s " % (max_opt, long)) # Case 2: we have a short option, so we have to include it # just after the long option else: opt_names = "%s (-%s)" % (long, short) if text: lines.append(" --%-*s %s" % (max_opt, opt_names, text[0])) else: lines.append(" --%-*s" % opt_names) for l in text[1:]: lines.append(big_indent + l) return lines def print_help(self, header=None, file=None): if file is None: file = sys.stdout for line in self.generate_help(header): file.write(line + "\n") def fancy_getopt(options, negative_opt, object, args): parser = FancyGetopt(options) parser.set_negative_aliases(negative_opt) return parser.getopt(args, object) WS_TRANS = {ord(_wschar) : ' ' for _wschar in string.whitespace} def wrap_text(text, width): """wrap_text(text : string, width : int) -> [string] Split 'text' into multiple lines of no more than 'width' characters each, and return the list of strings that results. """ if text is None: return [] if len(text) <= width: return [text] text = text.expandtabs() text = text.translate(WS_TRANS) chunks = re.split(r'( +|-+)', text) chunks = [ch for ch in chunks if ch] # ' - ' results in empty strings lines = [] while chunks: cur_line = [] # list of chunks (to-be-joined) cur_len = 0 # length of current line while chunks: l = len(chunks[0]) if cur_len + l <= width: # can squeeze (at least) this chunk in cur_line.append(chunks[0]) del chunks[0] cur_len = cur_len + l else: # this line is full # drop last chunk if all space if cur_line and cur_line[-1][0] == ' ': del cur_line[-1] break if chunks: # any chunks left to process? # if the current line is still empty, then we had a single # chunk that's too big too fit on a line -- so we break # down and break it up at the line width if cur_len == 0: cur_line.append(chunks[0][0:width]) chunks[0] = chunks[0][width:] # all-whitespace chunks at the end of a line can be discarded # (and we know from the re.split above that if a chunk has # *any* whitespace, it is *all* whitespace) if chunks[0][0] == ' ': del chunks[0] # and store this line in the list-of-all-lines -- as a single # string, of course! lines.append(''.join(cur_line)) return lines def translate_longopt(opt): """Convert a long option name to a valid Python identifier by changing "-" to "_". """ return opt.translate(longopt_xlate) class OptionDummy: """Dummy class just used as a place to hold command-line option values as instance attributes.""" def __init__(self, options=[]): """Create a new OptionDummy instance. The attributes listed in 'options' will be initialized to None.""" for opt in options: setattr(self, opt, None) if __name__ == "__main__": text = """\ Tra-la-la, supercalifragilisticexpialidocious. How *do* you spell that odd word, anyways? (Someone ask Mary -- she'll know [or she'll say, "How should I know?"].)""" for w in (10, 20, 30, 40): print("width: %d" % w) print("\n".join(wrap_text(text, w))) print() PKH]<python3.10/site-packages/setuptools/_distutils/py38compat.pynu[def aix_platform(osname, version, release): try: import _aix_support return _aix_support.aix_platform() except ImportError: pass return "%s-%s.%s" % (osname, version, release) PKH] 7python3.10/site-packages/setuptools/_distutils/spawn.pynu["""distutils.spawn Provides the 'spawn()' function, a front-end to various platform- specific functions for launching another program in a sub-process. Also provides the 'find_executable()' to search the path for a given executable name. """ import sys import os import subprocess from distutils.errors import DistutilsPlatformError, DistutilsExecError from distutils.debug import DEBUG from distutils import log def spawn(cmd, search_path=1, verbose=0, dry_run=0, env=None): """Run another program, specified as a command list 'cmd', in a new process. 'cmd' is just the argument list for the new process, ie. cmd[0] is the program to run and cmd[1:] are the rest of its arguments. There is no way to run a program with a name different from that of its executable. If 'search_path' is true (the default), the system's executable search path will be used to find the program; otherwise, cmd[0] must be the exact path to the executable. If 'dry_run' is true, the command will not actually be run. Raise DistutilsExecError if running the program fails in any way; just return on success. """ # cmd is documented as a list, but just in case some code passes a tuple # in, protect our %-formatting code against horrible death cmd = list(cmd) log.info(subprocess.list2cmdline(cmd)) if dry_run: return if search_path: executable = find_executable(cmd[0]) if executable is not None: cmd[0] = executable env = env if env is not None else dict(os.environ) if sys.platform == 'darwin': from distutils.util import MACOSX_VERSION_VAR, get_macosx_target_ver macosx_target_ver = get_macosx_target_ver() if macosx_target_ver: env[MACOSX_VERSION_VAR] = macosx_target_ver try: proc = subprocess.Popen(cmd, env=env) proc.wait() exitcode = proc.returncode except OSError as exc: if not DEBUG: cmd = cmd[0] raise DistutilsExecError( "command %r failed: %s" % (cmd, exc.args[-1])) from exc if exitcode: if not DEBUG: cmd = cmd[0] raise DistutilsExecError( "command %r failed with exit code %s" % (cmd, exitcode)) def find_executable(executable, path=None): """Tries to find 'executable' in the directories listed in 'path'. A string listing directories separated by 'os.pathsep'; defaults to os.environ['PATH']. Returns the complete filename or None if not found. """ _, ext = os.path.splitext(executable) if (sys.platform == 'win32') and (ext != '.exe'): executable = executable + '.exe' if os.path.isfile(executable): return executable if path is None: path = os.environ.get('PATH', None) if path is None: try: path = os.confstr("CS_PATH") except (AttributeError, ValueError): # os.confstr() or CS_PATH is not available path = os.defpath # bpo-35755: Don't use os.defpath if the PATH environment variable is # set to an empty string # PATH='' doesn't match, whereas PATH=':' looks in the current directory if not path: return None paths = path.split(os.pathsep) for p in paths: f = os.path.join(p, executable) if os.path.isfile(f): # the file exists, we have a shot at spawn working return f return None PKH]ˆб5python3.10/site-packages/setuptools/_distutils/log.pynu["""A simple log mechanism styled after PEP 282.""" # The class here is styled after PEP 282 so that it could later be # replaced with a standard Python logging implementation. DEBUG = 1 INFO = 2 WARN = 3 ERROR = 4 FATAL = 5 import sys class Log: def __init__(self, threshold=WARN): self.threshold = threshold def _log(self, level, msg, args): if level not in (DEBUG, INFO, WARN, ERROR, FATAL): raise ValueError('%s wrong log level' % str(level)) if level >= self.threshold: if args: msg = msg % args if level in (WARN, ERROR, FATAL): stream = sys.stderr else: stream = sys.stdout try: stream.write('%s\n' % msg) except UnicodeEncodeError: # emulate backslashreplace error handler encoding = stream.encoding msg = msg.encode(encoding, "backslashreplace").decode(encoding) stream.write('%s\n' % msg) stream.flush() def log(self, level, msg, *args): self._log(level, msg, args) def debug(self, msg, *args): self._log(DEBUG, msg, args) def info(self, msg, *args): self._log(INFO, msg, args) def warn(self, msg, *args): self._log(WARN, msg, args) def error(self, msg, *args): self._log(ERROR, msg, args) def fatal(self, msg, *args): self._log(FATAL, msg, args) _global_log = Log() log = _global_log.log debug = _global_log.debug info = _global_log.info warn = _global_log.warn error = _global_log.error fatal = _global_log.fatal def set_threshold(level): # return the old threshold for use from tests old = _global_log.threshold _global_log.threshold = level return old def set_verbosity(v): if v <= 0: set_threshold(WARN) elif v == 1: set_threshold(INFO) elif v >= 2: set_threshold(DEBUG) PKH]5<*B*BApython3.10/site-packages/setuptools/_distutils/cygwinccompiler.pynu["""distutils.cygwinccompiler Provides the CygwinCCompiler class, a subclass of UnixCCompiler that handles the Cygwin port of the GNU C compiler to Windows. It also contains the Mingw32CCompiler class which handles the mingw32 port of GCC (same as cygwin in no-cygwin mode). """ # problems: # # * if you use a msvc compiled python version (1.5.2) # 1. you have to insert a __GNUC__ section in its config.h # 2. you have to generate an import library for its dll # - create a def-file for python??.dll # - create an import library using # dlltool --dllname python15.dll --def python15.def \ # --output-lib libpython15.a # # see also http://starship.python.net/crew/kernr/mingw32/Notes.html # # * We put export_symbols in a def-file, and don't use # --export-all-symbols because it doesn't worked reliable in some # tested configurations. And because other windows compilers also # need their symbols specified this no serious problem. # # tested configurations: # # * cygwin gcc 2.91.57/ld 2.9.4/dllwrap 0.2.4 works # (after patching python's config.h and for C++ some other include files) # see also http://starship.python.net/crew/kernr/mingw32/Notes.html # * mingw32 gcc 2.95.2/ld 2.9.4/dllwrap 0.2.4 works # (ld doesn't support -shared, so we use dllwrap) # * cygwin gcc 2.95.2/ld 2.10.90/dllwrap 2.10.90 works now # - its dllwrap doesn't work, there is a bug in binutils 2.10.90 # see also http://sources.redhat.com/ml/cygwin/2000-06/msg01274.html # - using gcc -mdll instead dllwrap doesn't work without -static because # it tries to link against dlls instead their import libraries. (If # it finds the dll first.) # By specifying -static we force ld to link against the import libraries, # this is windows standard and there are normally not the necessary symbols # in the dlls. # *** only the version of June 2000 shows these problems # * cygwin gcc 3.2/ld 2.13.90 works # (ld supports -shared) # * mingw gcc 3.2/ld 2.13 works # (ld supports -shared) # * llvm-mingw with Clang 11 works # (lld supports -shared) import os import sys import copy from subprocess import Popen, PIPE, check_output import re from distutils.unixccompiler import UnixCCompiler from distutils.file_util import write_file from distutils.errors import (DistutilsExecError, CCompilerError, CompileError, UnknownFileError) from distutils.version import LooseVersion from distutils.spawn import find_executable def get_msvcr(): """Include the appropriate MSVC runtime library if Python was built with MSVC 7.0 or later. """ msc_pos = sys.version.find('MSC v.') if msc_pos != -1: msc_ver = sys.version[msc_pos+6:msc_pos+10] if msc_ver == '1300': # MSVC 7.0 return ['msvcr70'] elif msc_ver == '1310': # MSVC 7.1 return ['msvcr71'] elif msc_ver == '1400': # VS2005 / MSVC 8.0 return ['msvcr80'] elif msc_ver == '1500': # VS2008 / MSVC 9.0 return ['msvcr90'] elif msc_ver == '1600': # VS2010 / MSVC 10.0 return ['msvcr100'] else: raise ValueError("Unknown MS Compiler version %s " % msc_ver) class CygwinCCompiler(UnixCCompiler): """ Handles the Cygwin port of the GNU C compiler to Windows. """ compiler_type = 'cygwin' obj_extension = ".o" static_lib_extension = ".a" shared_lib_extension = ".dll" static_lib_format = "lib%s%s" shared_lib_format = "%s%s" exe_extension = ".exe" def __init__(self, verbose=0, dry_run=0, force=0): UnixCCompiler.__init__(self, verbose, dry_run, force) status, details = check_config_h() self.debug_print("Python's GCC status: %s (details: %s)" % (status, details)) if status is not CONFIG_H_OK: self.warn( "Python's pyconfig.h doesn't seem to support your compiler. " "Reason: %s. " "Compiling may fail because of undefined preprocessor macros." % details) self.cc = os.environ.get('CC', 'gcc') self.cxx = os.environ.get('CXX', 'g++') if ('gcc' in self.cc): # Start gcc workaround self.gcc_version, self.ld_version, self.dllwrap_version = \ get_versions() self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" % (self.gcc_version, self.ld_version, self.dllwrap_version) ) # ld_version >= "2.10.90" and < "2.13" should also be able to use # gcc -mdll instead of dllwrap # Older dllwraps had own version numbers, newer ones use the # same as the rest of binutils ( also ld ) # dllwrap 2.10.90 is buggy if self.ld_version >= "2.10.90": self.linker_dll = self.cc else: self.linker_dll = "dllwrap" # ld_version >= "2.13" support -shared so use it instead of # -mdll -static if self.ld_version >= "2.13": shared_option = "-shared" else: shared_option = "-mdll -static" else: # Assume linker is up to date self.linker_dll = self.cc shared_option = "-shared" self.set_executables(compiler='%s -mcygwin -O -Wall' % self.cc, compiler_so='%s -mcygwin -mdll -O -Wall' % self.cc, compiler_cxx='%s -mcygwin -O -Wall' % self.cxx, linker_exe='%s -mcygwin' % self.cc, linker_so=('%s -mcygwin %s' % (self.linker_dll, shared_option))) # cygwin and mingw32 need different sets of libraries if ('gcc' in self.cc and self.gcc_version == "2.91.57"): # cygwin shouldn't need msvcrt, but without the dlls will crash # (gcc version 2.91.57) -- perhaps something about initialization self.dll_libraries=["msvcrt"] self.warn( "Consider upgrading to a newer version of gcc") else: # Include the appropriate MSVC runtime library if Python was built # with MSVC 7.0 or later. self.dll_libraries = get_msvcr() def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): """Compiles the source by spawning GCC and windres if needed.""" if ext == '.rc' or ext == '.res': # gcc needs '.res' and '.rc' compiled to object files !!! try: self.spawn(["windres", "-i", src, "-o", obj]) except DistutilsExecError as msg: raise CompileError(msg) else: # for other files use the C-compiler try: self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg) def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): """Link the objects.""" # use separate copies, so we can modify the lists extra_preargs = copy.copy(extra_preargs or []) libraries = copy.copy(libraries or []) objects = copy.copy(objects or []) # Additional libraries libraries.extend(self.dll_libraries) # handle export symbols by creating a def-file # with executables this only works with gcc/ld as linker if ((export_symbols is not None) and (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): # (The linker doesn't do anything if output is up-to-date. # So it would probably better to check if we really need this, # but for this we had to insert some unchanged parts of # UnixCCompiler, and this is not what we want.) # we want to put some files in the same directory as the # object files are, build_temp doesn't help much # where are the object files temp_dir = os.path.dirname(objects[0]) # name of dll to give the helper files the same base name (dll_name, dll_extension) = os.path.splitext( os.path.basename(output_filename)) # generate the filenames for these files def_file = os.path.join(temp_dir, dll_name + ".def") lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a") # Generate .def file contents = [ "LIBRARY %s" % os.path.basename(output_filename), "EXPORTS"] for sym in export_symbols: contents.append(sym) self.execute(write_file, (def_file, contents), "writing %s" % def_file) # next add options for def-file and to creating import libraries # dllwrap uses different options than gcc/ld if self.linker_dll == "dllwrap": extra_preargs.extend(["--output-lib", lib_file]) # for dllwrap we have to use a special option extra_preargs.extend(["--def", def_file]) # we use gcc/ld here and can be sure ld is >= 2.9.10 else: # doesn't work: bfd_close build\...\libfoo.a: Invalid operation #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file]) # for gcc/ld the def-file is specified as any object files objects.append(def_file) #end: if ((export_symbols is not None) and # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): # who wants symbols and a many times larger output file # should explicitly switch the debug mode on # otherwise we let dllwrap/ld strip the output file # (On my machine: 10KiB < stripped_file < ??100KiB # unstripped_file = stripped_file + XXX KiB # ( XXX=254 for a typical python extension)) if not debug: extra_preargs.append("-s") UnixCCompiler.link(self, target_desc, objects, output_filename, output_dir, libraries, library_dirs, runtime_library_dirs, None, # export_symbols, we do this in our def-file debug, extra_preargs, extra_postargs, build_temp, target_lang) # -- Miscellaneous methods ----------------------------------------- def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): """Adds supports for rc and res files.""" if output_dir is None: output_dir = '' obj_names = [] for src_name in source_filenames: # use normcase to make sure '.rc' is really '.rc' and not '.RC' base, ext = os.path.splitext(os.path.normcase(src_name)) if ext not in (self.src_extensions + ['.rc','.res']): raise UnknownFileError("unknown file type '%s' (from '%s')" % \ (ext, src_name)) if strip_dir: base = os.path.basename (base) if ext in ('.res', '.rc'): # these need to be compiled to object files obj_names.append (os.path.join(output_dir, base + ext + self.obj_extension)) else: obj_names.append (os.path.join(output_dir, base + self.obj_extension)) return obj_names # the same as cygwin plus some additional parameters class Mingw32CCompiler(CygwinCCompiler): """ Handles the Mingw32 port of the GNU C compiler to Windows. """ compiler_type = 'mingw32' def __init__(self, verbose=0, dry_run=0, force=0): CygwinCCompiler.__init__ (self, verbose, dry_run, force) # ld_version >= "2.13" support -shared so use it instead of # -mdll -static if ('gcc' in self.cc and self.ld_version < "2.13"): shared_option = "-mdll -static" else: shared_option = "-shared" # A real mingw32 doesn't need to specify a different entry point, # but cygwin 2.91.57 in no-cygwin-mode needs it. if ('gcc' in self.cc and self.gcc_version <= "2.91.57"): entry_point = '--entry _DllMain@12' else: entry_point = '' if is_cygwincc(self.cc): raise CCompilerError( 'Cygwin gcc cannot be used with --compiler=mingw32') self.set_executables(compiler='%s -O -Wall' % self.cc, compiler_so='%s -mdll -O -Wall' % self.cc, compiler_cxx='%s -O -Wall' % self.cxx, linker_exe='%s' % self.cc, linker_so='%s %s %s' % (self.linker_dll, shared_option, entry_point)) # Maybe we should also append -mthreads, but then the finished # dlls need another dll (mingwm10.dll see Mingw32 docs) # (-mthreads: Support thread-safe exception handling on `Mingw32') # no additional libraries needed self.dll_libraries=[] # Include the appropriate MSVC runtime library if Python was built # with MSVC 7.0 or later. self.dll_libraries = get_msvcr() # Because these compilers aren't configured in Python's pyconfig.h file by # default, we should at least warn the user if he is using an unmodified # version. CONFIG_H_OK = "ok" CONFIG_H_NOTOK = "not ok" CONFIG_H_UNCERTAIN = "uncertain" def check_config_h(): """Check if the current Python installation appears amenable to building extensions with GCC. Returns a tuple (status, details), where 'status' is one of the following constants: - CONFIG_H_OK: all is well, go ahead and compile - CONFIG_H_NOTOK: doesn't look good - CONFIG_H_UNCERTAIN: not sure -- unable to read pyconfig.h 'details' is a human-readable string explaining the situation. Note there are two ways to conclude "OK": either 'sys.version' contains the string "GCC" (implying that this Python was built with GCC), or the installed "pyconfig.h" contains the string "__GNUC__". """ # XXX since this function also checks sys.version, it's not strictly a # "pyconfig.h" check -- should probably be renamed... from distutils import sysconfig # if sys.version contains GCC then python was compiled with GCC, and the # pyconfig.h file should be OK if "GCC" in sys.version: return CONFIG_H_OK, "sys.version mentions 'GCC'" # Clang would also work if "Clang" in sys.version: return CONFIG_H_OK, "sys.version mentions 'Clang'" # let's see if __GNUC__ is mentioned in python.h fn = sysconfig.get_config_h_filename() try: config_h = open(fn) try: if "__GNUC__" in config_h.read(): return CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn else: return CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn finally: config_h.close() except OSError as exc: return (CONFIG_H_UNCERTAIN, "couldn't read '%s': %s" % (fn, exc.strerror)) RE_VERSION = re.compile(br'(\d+\.\d+(\.\d+)*)') def _find_exe_version(cmd): """Find the version of an executable by running `cmd` in the shell. If the command is not found, or the output does not match `RE_VERSION`, returns None. """ executable = cmd.split()[0] if find_executable(executable) is None: return None out = Popen(cmd, shell=True, stdout=PIPE).stdout try: out_string = out.read() finally: out.close() result = RE_VERSION.search(out_string) if result is None: return None # LooseVersion works with strings # so we need to decode our bytes return LooseVersion(result.group(1).decode()) def get_versions(): """ Try to find out the versions of gcc, ld and dllwrap. If not possible it returns None for it. """ commands = ['gcc -dumpversion', 'ld -v', 'dllwrap --version'] return tuple([_find_exe_version(cmd) for cmd in commands]) def is_cygwincc(cc): '''Try to determine if the compiler that would be used is from cygwin.''' out_string = check_output([cc, '-dumpmachine']) return out_string.strip().endswith(b'cygwin') PKH]188?python3.10/site-packages/setuptools/_distutils/unixccompiler.pynu["""distutils.unixccompiler Contains the UnixCCompiler class, a subclass of CCompiler that handles the "typical" Unix-style command-line C compiler: * macros defined with -Dname[=value] * macros undefined with -Uname * include search directories specified with -Idir * libraries specified with -lllib * library search directories specified with -Ldir * compile handled by 'cc' (or similar) executable with -c option: compiles .c to .o * link static library handled by 'ar' command (possibly with 'ranlib') * link shared library handled by 'cc -shared' """ import os, sys, re, shlex from distutils import sysconfig from distutils.dep_util import newer from distutils.ccompiler import \ CCompiler, gen_preprocess_options, gen_lib_options from distutils.errors import \ DistutilsExecError, CompileError, LibError, LinkError from distutils import log if sys.platform == 'darwin': import _osx_support # XXX Things not currently handled: # * optimization/debug/warning flags; we just use whatever's in Python's # Makefile and live with it. Is this adequate? If not, we might # have to have a bunch of subclasses GNUCCompiler, SGICCompiler, # SunCCompiler, and I suspect down that road lies madness. # * even if we don't know a warning flag from an optimization flag, # we need some way for outsiders to feed preprocessor/compiler/linker # flags in to us -- eg. a sysadmin might want to mandate certain flags # via a site config file, or a user might want to set something for # compiling this module distribution only via the setup.py command # line, whatever. As long as these options come from something on the # current system, they can be as system-dependent as they like, and we # should just happily stuff them into the preprocessor/compiler/linker # options and carry on. class UnixCCompiler(CCompiler): compiler_type = 'unix' # These are used by CCompiler in two places: the constructor sets # instance attributes 'preprocessor', 'compiler', etc. from them, and # 'set_executable()' allows any of these to be set. The defaults here # are pretty generic; they will probably have to be set by an outsider # (eg. using information discovered by the sysconfig about building # Python extensions). executables = {'preprocessor' : None, 'compiler' : ["cc"], 'compiler_so' : ["cc"], 'compiler_cxx' : ["cc"], 'linker_so' : ["cc", "-shared"], 'linker_exe' : ["cc"], 'archiver' : ["ar", "-cr"], 'ranlib' : None, } if sys.platform[:6] == "darwin": executables['ranlib'] = ["ranlib"] # Needed for the filename generation methods provided by the base # class, CCompiler. NB. whoever instantiates/uses a particular # UnixCCompiler instance should set 'shared_lib_ext' -- we set a # reasonable common default here, but it's not necessarily used on all # Unices! src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"] obj_extension = ".o" static_lib_extension = ".a" shared_lib_extension = ".so" dylib_lib_extension = ".dylib" xcode_stub_lib_extension = ".tbd" static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s" xcode_stub_lib_format = dylib_lib_format if sys.platform == "cygwin": exe_extension = ".exe" def preprocess(self, source, output_file=None, macros=None, include_dirs=None, extra_preargs=None, extra_postargs=None): fixed_args = self._fix_compile_args(None, macros, include_dirs) ignore, macros, include_dirs = fixed_args pp_opts = gen_preprocess_options(macros, include_dirs) pp_args = self.preprocessor + pp_opts if output_file: pp_args.extend(['-o', output_file]) if extra_preargs: pp_args[:0] = extra_preargs if extra_postargs: pp_args.extend(extra_postargs) pp_args.append(source) # We need to preprocess: either we're being forced to, or we're # generating output to stdout, or there's a target output file and # the source file is newer than the target (or the target doesn't # exist). if self.force or output_file is None or newer(source, output_file): if output_file: self.mkpath(os.path.dirname(output_file)) try: self.spawn(pp_args) except DistutilsExecError as msg: raise CompileError(msg) def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = self.compiler_so if sys.platform == 'darwin': compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) try: self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg) def create_static_lib(self, objects, output_libname, output_dir=None, debug=0, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) output_filename = \ self.library_filename(output_libname, output_dir=output_dir) if self._need_link(objects, output_filename): self.mkpath(os.path.dirname(output_filename)) self.spawn(self.archiver + [output_filename] + objects + self.objects) # Not many Unices required ranlib anymore -- SunOS 4.x is, I # think the only major Unix that does. Maybe we need some # platform intelligence here to skip ranlib if it's not # needed -- or maybe Python's configure script took care of # it for us, hence the check for leading colon. if self.ranlib: try: self.spawn(self.ranlib + [output_filename]) except DistutilsExecError as msg: raise LibError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not isinstance(output_dir, (str, type(None))): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i += 1 if os.path.basename(linker[i]) == 'ld_so_aix': # AIX platforms prefix the compiler with the ld_so_aix # script, so we need to adjust our linker index offset = 1 else: offset = 0 linker[i+offset] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _osx_support.compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) # -- Miscellaneous methods ----------------------------------------- # These are all used by the 'gen_lib_options() function, in # ccompiler.py. def library_dir_option(self, dir): return "-L" + dir def _is_gcc(self, compiler_name): return "gcc" in compiler_name or "g++" in compiler_name def runtime_library_dir_option(self, dir): # XXX Hackish, at the very least. See Python bug #445902: # http://sourceforge.net/tracker/index.php # ?func=detail&aid=445902&group_id=5470&atid=105470 # Linkers on different platforms need different options to # specify that directories need to be added to the list of # directories searched for dependencies when a dynamic library # is sought. GCC on GNU systems (Linux, FreeBSD, ...) has to # be told to pass the -R option through to the linker, whereas # other compilers and gcc on other systems just know this. # Other compilers may need something slightly different. At # this time, there's no way to determine this information from # the configuration data stored in the Python installation, so # we use this hack. compiler = os.path.basename(shlex.split(sysconfig.get_config_var("CC"))[0]) if sys.platform[:6] == "darwin": from distutils.util import get_macosx_target_ver, split_version macosx_target_ver = get_macosx_target_ver() if macosx_target_ver and split_version(macosx_target_ver) >= [10, 5]: return "-Wl,-rpath," + dir else: # no support for -rpath on earlier macOS versions return "-L" + dir elif sys.platform[:7] == "freebsd": return "-Wl,-rpath=" + dir elif sys.platform[:5] == "hp-ux": if self._is_gcc(compiler): return ["-Wl,+s", "-L" + dir] return ["+s", "-L" + dir] # For all compilers, `-Wl` is the presumed way to # pass a compiler option to the linker and `-R` is # the way to pass an RPATH. if sysconfig.get_config_var("GNULD") == "yes": # GNU ld needs an extra option to get a RUNPATH # instead of just an RPATH. return "-Wl,--enable-new-dtags,-R" + dir else: return "-Wl,-R" + dir def library_option(self, lib): return "-l" + lib def find_library_file(self, dirs, lib, debug=0): shared_f = self.library_filename(lib, lib_type='shared') dylib_f = self.library_filename(lib, lib_type='dylib') xcode_stub_f = self.library_filename(lib, lib_type='xcode_stub') static_f = self.library_filename(lib, lib_type='static') if sys.platform == 'darwin': # On OSX users can specify an alternate SDK using # '-isysroot', calculate the SDK root if it is specified # (and use it further on) # # Note that, as of Xcode 7, Apple SDKs may contain textual stub # libraries with .tbd extensions rather than the normal .dylib # shared libraries installed in /. The Apple compiler tool # chain handles this transparently but it can cause problems # for programs that are being built with an SDK and searching # for specific libraries. Callers of find_library_file need to # keep in mind that the base filename of the returned SDK library # file might have a different extension from that of the library # file installed on the running system, for example: # /Applications/Xcode.app/Contents/Developer/Platforms/ # MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/ # usr/lib/libedit.tbd # vs # /usr/lib/libedit.dylib cflags = sysconfig.get_config_var('CFLAGS') m = re.search(r'-isysroot\s*(\S+)', cflags) if m is None: sysroot = '/' else: sysroot = m.group(1) for dir in dirs: shared = os.path.join(dir, shared_f) dylib = os.path.join(dir, dylib_f) static = os.path.join(dir, static_f) xcode_stub = os.path.join(dir, xcode_stub_f) if sys.platform == 'darwin' and ( dir.startswith('/System/') or ( dir.startswith('/usr/') and not dir.startswith('/usr/local/'))): shared = os.path.join(sysroot, dir[1:], shared_f) dylib = os.path.join(sysroot, dir[1:], dylib_f) static = os.path.join(sysroot, dir[1:], static_f) xcode_stub = os.path.join(sysroot, dir[1:], xcode_stub_f) # We're second-guessing the linker here, with not much hard # data to go on: GCC seems to prefer the shared library, so I'm # assuming that *all* Unix C compilers do. And of course I'm # ignoring even GCC's "-static" option. So sue me. if os.path.exists(dylib): return dylib elif os.path.exists(xcode_stub): return xcode_stub elif os.path.exists(shared): return shared elif os.path.exists(static): return static # Oops, didn't find it in *any* of 'dirs' return None PKH]]4:));python3.10/site-packages/setuptools/_distutils/extension.pynu["""distutils.extension Provides the Extension class, used to describe C/C++ extension modules in setup scripts.""" import os import warnings # This class is really only used by the "build_ext" command, so it might # make sense to put it in distutils.command.build_ext. However, that # module is already big enough, and I want to make this class a bit more # complex to simplify some common cases ("foo" module in "foo.c") and do # better error-checking ("foo.c" actually exists). # # Also, putting this in build_ext.py means every setup script would have to # import that large-ish module (indirectly, through distutils.core) in # order to do anything. class Extension: """Just a collection of attributes that describes an extension module and everything needed to build it (hopefully in a portable way, but there are hooks that let you be as unportable as you need). Instance attributes: name : string the full name of the extension, including any packages -- ie. *not* a filename or pathname, but Python dotted name sources : [string] list of source filenames, relative to the distribution root (where the setup script lives), in Unix form (slash-separated) for portability. Source files may be C, C++, SWIG (.i), platform-specific resource files, or whatever else is recognized by the "build_ext" command as source for a Python extension. include_dirs : [string] list of directories to search for C/C++ header files (in Unix form for portability) define_macros : [(name : string, value : string|None)] list of macros to define; each macro is defined using a 2-tuple, where 'value' is either the string to define it to or None to define it without a particular value (equivalent of "#define FOO" in source or -DFOO on Unix C compiler command line) undef_macros : [string] list of macros to undefine explicitly library_dirs : [string] list of directories to search for C/C++ libraries at link time libraries : [string] list of library names (not filenames or paths) to link against runtime_library_dirs : [string] list of directories to search for C/C++ libraries at run time (for shared extensions, this is when the extension is loaded) extra_objects : [string] list of extra files to link with (eg. object files not implied by 'sources', static library that must be explicitly specified, binary resource files, etc.) extra_compile_args : [string] any extra platform- and compiler-specific information to use when compiling the source files in 'sources'. For platforms and compilers where "command line" makes sense, this is typically a list of command-line arguments, but for other platforms it could be anything. extra_link_args : [string] any extra platform- and compiler-specific information to use when linking object files together to create the extension (or to create a new static Python interpreter). Similar interpretation as for 'extra_compile_args'. export_symbols : [string] list of symbols to be exported from a shared extension. Not used on all platforms, and not generally necessary for Python extensions, which typically export exactly one symbol: "init" + extension_name. swig_opts : [string] any extra options to pass to SWIG if a source file has the .i extension. depends : [string] list of files that the extension depends on language : string extension language (i.e. "c", "c++", "objc"). Will be detected from the source extensions if not provided. optional : boolean specifies that a build failure in the extension should not abort the build process, but simply not install the failing extension. """ # When adding arguments to this constructor, be sure to update # setup_keywords in core.py. def __init__(self, name, sources, include_dirs=None, define_macros=None, undef_macros=None, library_dirs=None, libraries=None, runtime_library_dirs=None, extra_objects=None, extra_compile_args=None, extra_link_args=None, export_symbols=None, swig_opts = None, depends=None, language=None, optional=None, **kw # To catch unknown keywords ): if not isinstance(name, str): raise AssertionError("'name' must be a string") if not (isinstance(sources, list) and all(isinstance(v, str) for v in sources)): raise AssertionError("'sources' must be a list of strings") self.name = name self.sources = sources self.include_dirs = include_dirs or [] self.define_macros = define_macros or [] self.undef_macros = undef_macros or [] self.library_dirs = library_dirs or [] self.libraries = libraries or [] self.runtime_library_dirs = runtime_library_dirs or [] self.extra_objects = extra_objects or [] self.extra_compile_args = extra_compile_args or [] self.extra_link_args = extra_link_args or [] self.export_symbols = export_symbols or [] self.swig_opts = swig_opts or [] self.depends = depends or [] self.language = language self.optional = optional # If there are unknown keyword options, warn about them if len(kw) > 0: options = [repr(option) for option in kw] options = ', '.join(sorted(options)) msg = "Unknown Extension options: %s" % options warnings.warn(msg) def __repr__(self): return '<%s.%s(%r) at %#x>' % ( self.__class__.__module__, self.__class__.__qualname__, self.name, id(self)) def read_setup_file(filename): """Reads a Setup file and returns Extension instances.""" from distutils.sysconfig import (parse_makefile, expand_makefile_vars, _variable_rx) from distutils.text_file import TextFile from distutils.util import split_quoted # First pass over the file to gather "VAR = VALUE" assignments. vars = parse_makefile(filename) # Second pass to gobble up the real content: lines of the form # ... [ ...] [ ...] [ ...] file = TextFile(filename, strip_comments=1, skip_blanks=1, join_lines=1, lstrip_ws=1, rstrip_ws=1) try: extensions = [] while True: line = file.readline() if line is None: # eof break if _variable_rx.match(line): # VAR=VALUE, handled in first pass continue if line[0] == line[-1] == "*": file.warn("'%s' lines not handled yet" % line) continue line = expand_makefile_vars(line, vars) words = split_quoted(line) # NB. this parses a slightly different syntax than the old # makesetup script: here, there must be exactly one extension per # line, and it must be the first word of the line. I have no idea # why the old syntax supported multiple extensions per line, as # they all wind up being the same. module = words[0] ext = Extension(module, []) append_next_word = None for word in words[1:]: if append_next_word is not None: append_next_word.append(word) append_next_word = None continue suffix = os.path.splitext(word)[1] switch = word[0:2] ; value = word[2:] if suffix in (".c", ".cc", ".cpp", ".cxx", ".c++", ".m", ".mm"): # hmm, should we do something about C vs. C++ sources? # or leave it up to the CCompiler implementation to # worry about? ext.sources.append(word) elif switch == "-I": ext.include_dirs.append(value) elif switch == "-D": equals = value.find("=") if equals == -1: # bare "-DFOO" -- no value ext.define_macros.append((value, None)) else: # "-DFOO=blah" ext.define_macros.append((value[0:equals], value[equals+2:])) elif switch == "-U": ext.undef_macros.append(value) elif switch == "-C": # only here 'cause makesetup has it! ext.extra_compile_args.append(word) elif switch == "-l": ext.libraries.append(value) elif switch == "-L": ext.library_dirs.append(value) elif switch == "-R": ext.runtime_library_dirs.append(value) elif word == "-rpath": append_next_word = ext.runtime_library_dirs elif word == "-Xlinker": append_next_word = ext.extra_link_args elif word == "-Xcompiler": append_next_word = ext.extra_compile_args elif switch == "-u": ext.extra_link_args.append(word) if not value: append_next_word = ext.extra_link_args elif suffix in (".a", ".so", ".sl", ".o", ".dylib"): # NB. a really faithful emulation of makesetup would # append a .o file to extra_objects only if it # had a slash in it; otherwise, it would s/.o/.c/ # and append it to sources. Hmmmm. ext.extra_objects.append(word) else: file.warn("unrecognized argument '%s'" % word) extensions.append(ext) finally: file.close() return extensions PKH]5|!|!>python3.10/site-packages/setuptools/_distutils/archive_util.pynu["""distutils.archive_util Utility functions for creating archive files (tarballs, zip files, that sort of thing).""" import os from warnings import warn import sys try: import zipfile except ImportError: zipfile = None from distutils.errors import DistutilsExecError from distutils.spawn import spawn from distutils.dir_util import mkpath from distutils import log try: from pwd import getpwnam except ImportError: getpwnam = None try: from grp import getgrnam except ImportError: getgrnam = None def _get_gid(name): """Returns a gid, given a group name.""" if getgrnam is None or name is None: return None try: result = getgrnam(name) except KeyError: result = None if result is not None: return result[2] return None def _get_uid(name): """Returns an uid, given a user name.""" if getpwnam is None or name is None: return None try: result = getpwnam(name) except KeyError: result = None if result is not None: return result[2] return None def make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, owner=None, group=None): """Create a (possibly compressed) tar file from all the files under 'base_dir'. 'compress' must be "gzip" (the default), "bzip2", "xz", "compress", or None. ("compress" will be deprecated in Python 3.2) 'owner' and 'group' can be used to define an owner and a group for the archive that is being built. If not provided, the current owner and group will be used. The output tar file will be named 'base_dir' + ".tar", possibly plus the appropriate compression extension (".gz", ".bz2", ".xz" or ".Z"). Returns the output filename. """ tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', 'xz': 'xz', None: '', 'compress': ''} compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'xz': '.xz', 'compress': '.Z'} # flags for compression program, each element of list will be an argument if compress is not None and compress not in compress_ext.keys(): raise ValueError( "bad value for 'compress': must be None, 'gzip', 'bzip2', " "'xz' or 'compress'") archive_name = base_name + '.tar' if compress != 'compress': archive_name += compress_ext.get(compress, '') mkpath(os.path.dirname(archive_name), dry_run=dry_run) # creating the tarball import tarfile # late import so Python build itself doesn't break log.info('Creating tar archive') uid = _get_uid(owner) gid = _get_gid(group) def _set_uid_gid(tarinfo): if gid is not None: tarinfo.gid = gid tarinfo.gname = group if uid is not None: tarinfo.uid = uid tarinfo.uname = owner return tarinfo if not dry_run: tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) try: tar.add(base_dir, filter=_set_uid_gid) finally: tar.close() # compression using `compress` if compress == 'compress': warn("'compress' will be deprecated.", PendingDeprecationWarning) # the option varies depending on the platform compressed_name = archive_name + compress_ext[compress] if sys.platform == 'win32': cmd = [compress, archive_name, compressed_name] else: cmd = [compress, '-f', archive_name] spawn(cmd, dry_run=dry_run) return compressed_name return archive_name def make_zipfile(base_name, base_dir, verbose=0, dry_run=0): """Create a zip file from all the files under 'base_dir'. The output zip file will be named 'base_name' + ".zip". Uses either the "zipfile" Python module (if available) or the InfoZIP "zip" utility (if installed and found on the default search path). If neither tool is available, raises DistutilsExecError. Returns the name of the output zip file. """ zip_filename = base_name + ".zip" mkpath(os.path.dirname(zip_filename), dry_run=dry_run) # If zipfile module is not available, try spawning an external # 'zip' command. if zipfile is None: if verbose: zipoptions = "-r" else: zipoptions = "-rq" try: spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) except DistutilsExecError: # XXX really should distinguish between "couldn't find # external 'zip' command" and "zip failed". raise DistutilsExecError(("unable to create zip file '%s': " "could neither import the 'zipfile' module nor " "find a standalone zip utility") % zip_filename) else: log.info("creating '%s' and adding '%s' to it", zip_filename, base_dir) if not dry_run: try: zip = zipfile.ZipFile(zip_filename, "w", compression=zipfile.ZIP_DEFLATED) except RuntimeError: zip = zipfile.ZipFile(zip_filename, "w", compression=zipfile.ZIP_STORED) with zip: if base_dir != os.curdir: path = os.path.normpath(os.path.join(base_dir, '')) zip.write(path, path) log.info("adding '%s'", path) for dirpath, dirnames, filenames in os.walk(base_dir): for name in dirnames: path = os.path.normpath(os.path.join(dirpath, name, '')) zip.write(path, path) log.info("adding '%s'", path) for name in filenames: path = os.path.normpath(os.path.join(dirpath, name)) if os.path.isfile(path): zip.write(path, path) log.info("adding '%s'", path) return zip_filename ARCHIVE_FORMATS = { 'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), 'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), 'xztar': (make_tarball, [('compress', 'xz')], "xz'ed tar-file"), 'ztar': (make_tarball, [('compress', 'compress')], "compressed tar file"), 'tar': (make_tarball, [('compress', None)], "uncompressed tar file"), 'zip': (make_zipfile, [],"ZIP file") } def check_archive_formats(formats): """Returns the first format from the 'format' list that is unknown. If all formats are known, returns None """ for format in formats: if format not in ARCHIVE_FORMATS: return format return None def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, dry_run=0, owner=None, group=None): """Create an archive file (eg. zip or tar). 'base_name' is the name of the file to create, minus any format-specific extension; 'format' is the archive format: one of "zip", "tar", "gztar", "bztar", "xztar", or "ztar". 'root_dir' is a directory that will be the root directory of the archive; ie. we typically chdir into 'root_dir' before creating the archive. 'base_dir' is the directory where we start archiving from; ie. 'base_dir' will be the common prefix of all files and directories in the archive. 'root_dir' and 'base_dir' both default to the current directory. Returns the name of the archive file. 'owner' and 'group' are used when creating a tar archive. By default, uses the current owner and group. """ save_cwd = os.getcwd() if root_dir is not None: log.debug("changing into '%s'", root_dir) base_name = os.path.abspath(base_name) if not dry_run: os.chdir(root_dir) if base_dir is None: base_dir = os.curdir kwargs = {'dry_run': dry_run} try: format_info = ARCHIVE_FORMATS[format] except KeyError: raise ValueError("unknown archive format '%s'" % format) func = format_info[0] for arg, val in format_info[1]: kwargs[arg] = val if format != 'zip': kwargs['owner'] = owner kwargs['group'] = group try: filename = func(base_name, base_dir, **kwargs) finally: if root_dir is not None: log.debug("changing back to '%s'", save_cwd) os.chdir(save_cwd) return filename PKH]t=J=J?python3.10/site-packages/setuptools/_distutils/command/sdist.pynu["""distutils.command.sdist Implements the Distutils 'sdist' command (create a source distribution).""" import os import sys from glob import glob from warnings import warn from distutils.core import Command from distutils import dir_util from distutils import file_util from distutils import archive_util from distutils.text_file import TextFile from distutils.filelist import FileList from distutils import log from distutils.util import convert_path from distutils.errors import DistutilsTemplateError, DistutilsOptionError def show_formats(): """Print all possible values for the 'formats' option (used by the "--help-formats" command-line option). """ from distutils.fancy_getopt import FancyGetopt from distutils.archive_util import ARCHIVE_FORMATS formats = [] for format in ARCHIVE_FORMATS.keys(): formats.append(("formats=" + format, None, ARCHIVE_FORMATS[format][2])) formats.sort() FancyGetopt(formats).print_help( "List of available source distribution formats:") class sdist(Command): description = "create a source distribution (tarball, zip file, etc.)" def checking_metadata(self): """Callable used for the check sub-command. Placed here so user_options can view it""" return self.metadata_check user_options = [ ('template=', 't', "name of manifest template file [default: MANIFEST.in]"), ('manifest=', 'm', "name of manifest file [default: MANIFEST]"), ('use-defaults', None, "include the default file set in the manifest " "[default; disable with --no-defaults]"), ('no-defaults', None, "don't include the default file set"), ('prune', None, "specifically exclude files/directories that should not be " "distributed (build tree, RCS/CVS dirs, etc.) " "[default; disable with --no-prune]"), ('no-prune', None, "don't automatically exclude anything"), ('manifest-only', 'o', "just regenerate the manifest and then stop " "(implies --force-manifest)"), ('force-manifest', 'f', "forcibly regenerate the manifest and carry on as usual. " "Deprecated: now the manifest is always regenerated."), ('formats=', None, "formats for source distribution (comma-separated list)"), ('keep-temp', 'k', "keep the distribution tree around after creating " + "archive file(s)"), ('dist-dir=', 'd', "directory to put the source distribution archive(s) in " "[default: dist]"), ('metadata-check', None, "Ensure that all required elements of meta-data " "are supplied. Warn if any missing. [default]"), ('owner=', 'u', "Owner name used when creating a tar file [default: current user]"), ('group=', 'g', "Group name used when creating a tar file [default: current group]"), ] boolean_options = ['use-defaults', 'prune', 'manifest-only', 'force-manifest', 'keep-temp', 'metadata-check'] help_options = [ ('help-formats', None, "list available distribution formats", show_formats), ] negative_opt = {'no-defaults': 'use-defaults', 'no-prune': 'prune' } sub_commands = [('check', checking_metadata)] READMES = ('README', 'README.txt', 'README.rst') def initialize_options(self): # 'template' and 'manifest' are, respectively, the names of # the manifest template and manifest file. self.template = None self.manifest = None # 'use_defaults': if true, we will include the default file set # in the manifest self.use_defaults = 1 self.prune = 1 self.manifest_only = 0 self.force_manifest = 0 self.formats = ['gztar'] self.keep_temp = 0 self.dist_dir = None self.archive_files = None self.metadata_check = 1 self.owner = None self.group = None def finalize_options(self): if self.manifest is None: self.manifest = "MANIFEST" if self.template is None: self.template = "MANIFEST.in" self.ensure_string_list('formats') bad_format = archive_util.check_archive_formats(self.formats) if bad_format: raise DistutilsOptionError( "unknown archive format '%s'" % bad_format) if self.dist_dir is None: self.dist_dir = "dist" def run(self): # 'filelist' contains the list of files that will make up the # manifest self.filelist = FileList() # Run sub commands for cmd_name in self.get_sub_commands(): self.run_command(cmd_name) # Do whatever it takes to get the list of files to process # (process the manifest template, read an existing manifest, # whatever). File list is accumulated in 'self.filelist'. self.get_file_list() # If user just wanted us to regenerate the manifest, stop now. if self.manifest_only: return # Otherwise, go ahead and create the source distribution tarball, # or zipfile, or whatever. self.make_distribution() def check_metadata(self): """Deprecated API.""" warn("distutils.command.sdist.check_metadata is deprecated, \ use the check command instead", PendingDeprecationWarning) check = self.distribution.get_command_obj('check') check.ensure_finalized() check.run() def get_file_list(self): """Figure out the list of files to include in the source distribution, and put it in 'self.filelist'. This might involve reading the manifest template (and writing the manifest), or just reading the manifest, or just using the default file set -- it all depends on the user's options. """ # new behavior when using a template: # the file list is recalculated every time because # even if MANIFEST.in or setup.py are not changed # the user might have added some files in the tree that # need to be included. # # This makes --force the default and only behavior with templates. template_exists = os.path.isfile(self.template) if not template_exists and self._manifest_is_not_generated(): self.read_manifest() self.filelist.sort() self.filelist.remove_duplicates() return if not template_exists: self.warn(("manifest template '%s' does not exist " + "(using default file list)") % self.template) self.filelist.findall() if self.use_defaults: self.add_defaults() if template_exists: self.read_template() if self.prune: self.prune_file_list() self.filelist.sort() self.filelist.remove_duplicates() self.write_manifest() def add_defaults(self): """Add all the default files to self.filelist: - README or README.txt - setup.py - test/test*.py - all pure Python modules mentioned in setup script - all files pointed by package_data (build_py) - all files defined in data_files. - all files defined as scripts. - all C sources listed as part of extensions or C libraries in the setup script (doesn't catch C headers!) Warns if (README or README.txt) or setup.py are missing; everything else is optional. """ self._add_defaults_standards() self._add_defaults_optional() self._add_defaults_python() self._add_defaults_data_files() self._add_defaults_ext() self._add_defaults_c_libs() self._add_defaults_scripts() @staticmethod def _cs_path_exists(fspath): """ Case-sensitive path existence check >>> sdist._cs_path_exists(__file__) True >>> sdist._cs_path_exists(__file__.upper()) False """ if not os.path.exists(fspath): return False # make absolute so we always have a directory abspath = os.path.abspath(fspath) directory, filename = os.path.split(abspath) return filename in os.listdir(directory) def _add_defaults_standards(self): standards = [self.READMES, self.distribution.script_name] for fn in standards: if isinstance(fn, tuple): alts = fn got_it = False for fn in alts: if self._cs_path_exists(fn): got_it = True self.filelist.append(fn) break if not got_it: self.warn("standard file not found: should have one of " + ', '.join(alts)) else: if self._cs_path_exists(fn): self.filelist.append(fn) else: self.warn("standard file '%s' not found" % fn) def _add_defaults_optional(self): optional = ['test/test*.py', 'setup.cfg'] for pattern in optional: files = filter(os.path.isfile, glob(pattern)) self.filelist.extend(files) def _add_defaults_python(self): # build_py is used to get: # - python modules # - files defined in package_data build_py = self.get_finalized_command('build_py') # getting python files if self.distribution.has_pure_modules(): self.filelist.extend(build_py.get_source_files()) # getting package_data files # (computed in build_py.data_files by build_py.finalize_options) for pkg, src_dir, build_dir, filenames in build_py.data_files: for filename in filenames: self.filelist.append(os.path.join(src_dir, filename)) def _add_defaults_data_files(self): # getting distribution.data_files if self.distribution.has_data_files(): for item in self.distribution.data_files: if isinstance(item, str): # plain file item = convert_path(item) if os.path.isfile(item): self.filelist.append(item) else: # a (dirname, filenames) tuple dirname, filenames = item for f in filenames: f = convert_path(f) if os.path.isfile(f): self.filelist.append(f) def _add_defaults_ext(self): if self.distribution.has_ext_modules(): build_ext = self.get_finalized_command('build_ext') self.filelist.extend(build_ext.get_source_files()) def _add_defaults_c_libs(self): if self.distribution.has_c_libraries(): build_clib = self.get_finalized_command('build_clib') self.filelist.extend(build_clib.get_source_files()) def _add_defaults_scripts(self): if self.distribution.has_scripts(): build_scripts = self.get_finalized_command('build_scripts') self.filelist.extend(build_scripts.get_source_files()) def read_template(self): """Read and parse manifest template file named by self.template. (usually "MANIFEST.in") The parsing and processing is done by 'self.filelist', which updates itself accordingly. """ log.info("reading manifest template '%s'", self.template) template = TextFile(self.template, strip_comments=1, skip_blanks=1, join_lines=1, lstrip_ws=1, rstrip_ws=1, collapse_join=1) try: while True: line = template.readline() if line is None: # end of file break try: self.filelist.process_template_line(line) # the call above can raise a DistutilsTemplateError for # malformed lines, or a ValueError from the lower-level # convert_path function except (DistutilsTemplateError, ValueError) as msg: self.warn("%s, line %d: %s" % (template.filename, template.current_line, msg)) finally: template.close() def prune_file_list(self): """Prune off branches that might slip into the file list as created by 'read_template()', but really don't belong there: * the build tree (typically "build") * the release tree itself (only an issue if we ran "sdist" previously with --keep-temp, or it aborted) * any RCS, CVS, .svn, .hg, .git, .bzr, _darcs directories """ build = self.get_finalized_command('build') base_dir = self.distribution.get_fullname() self.filelist.exclude_pattern(None, prefix=build.build_base) self.filelist.exclude_pattern(None, prefix=base_dir) if sys.platform == 'win32': seps = r'/|\\' else: seps = '/' vcs_dirs = ['RCS', 'CVS', r'\.svn', r'\.hg', r'\.git', r'\.bzr', '_darcs'] vcs_ptrn = r'(^|%s)(%s)(%s).*' % (seps, '|'.join(vcs_dirs), seps) self.filelist.exclude_pattern(vcs_ptrn, is_regex=1) def write_manifest(self): """Write the file list in 'self.filelist' (presumably as filled in by 'add_defaults()' and 'read_template()') to the manifest file named by 'self.manifest'. """ if self._manifest_is_not_generated(): log.info("not writing to manually maintained " "manifest file '%s'" % self.manifest) return content = self.filelist.files[:] content.insert(0, '# file GENERATED by distutils, do NOT edit') self.execute(file_util.write_file, (self.manifest, content), "writing manifest file '%s'" % self.manifest) def _manifest_is_not_generated(self): # check for special comment used in 3.1.3 and higher if not os.path.isfile(self.manifest): return False fp = open(self.manifest) try: first_line = fp.readline() finally: fp.close() return first_line != '# file GENERATED by distutils, do NOT edit\n' def read_manifest(self): """Read the manifest file (named by 'self.manifest') and use it to fill in 'self.filelist', the list of files to include in the source distribution. """ log.info("reading manifest file '%s'", self.manifest) with open(self.manifest) as manifest: for line in manifest: # ignore comments and blank lines line = line.strip() if line.startswith('#') or not line: continue self.filelist.append(line) def make_release_tree(self, base_dir, files): """Create the directory tree that will become the source distribution archive. All directories implied by the filenames in 'files' are created under 'base_dir', and then we hard link or copy (if hard linking is unavailable) those files into place. Essentially, this duplicates the developer's source tree, but in a directory named after the distribution, containing only the files to be distributed. """ # Create all the directories under 'base_dir' necessary to # put 'files' there; the 'mkpath()' is just so we don't die # if the manifest happens to be empty. self.mkpath(base_dir) dir_util.create_tree(base_dir, files, dry_run=self.dry_run) # And walk over the list of files, either making a hard link (if # os.link exists) to each one that doesn't already exist in its # corresponding location under 'base_dir', or copying each file # that's out-of-date in 'base_dir'. (Usually, all files will be # out-of-date, because by default we blow away 'base_dir' when # we're done making the distribution archives.) if hasattr(os, 'link'): # can make hard links on this system link = 'hard' msg = "making hard links in %s..." % base_dir else: # nope, have to copy link = None msg = "copying files to %s..." % base_dir if not files: log.warn("no files to distribute -- empty manifest?") else: log.info(msg) for file in files: if not os.path.isfile(file): log.warn("'%s' not a regular file -- skipping", file) else: dest = os.path.join(base_dir, file) self.copy_file(file, dest, link=link) self.distribution.metadata.write_pkg_info(base_dir) def make_distribution(self): """Create the source distribution(s). First, we create the release tree with 'make_release_tree()'; then, we create all required archive files (according to 'self.formats') from the release tree. Finally, we clean up by blowing away the release tree (unless 'self.keep_temp' is true). The list of archive files created is stored so it can be retrieved later by 'get_archive_files()'. """ # Don't warn about missing meta-data here -- should be (and is!) # done elsewhere. base_dir = self.distribution.get_fullname() base_name = os.path.join(self.dist_dir, base_dir) self.make_release_tree(base_dir, self.filelist.files) archive_files = [] # remember names of files we create # tar archive must be created last to avoid overwrite and remove if 'tar' in self.formats: self.formats.append(self.formats.pop(self.formats.index('tar'))) for fmt in self.formats: file = self.make_archive(base_name, fmt, base_dir=base_dir, owner=self.owner, group=self.group) archive_files.append(file) self.distribution.dist_files.append(('sdist', '', file)) self.archive_files = archive_files if not self.keep_temp: dir_util.remove_tree(base_dir, dry_run=self.dry_run) def get_archive_files(self): """Return the list of archive files created when the command was run, or None if the command hasn't run yet. """ return self.archive_files PKH]p'Xpython3.10/site-packages/setuptools/_distutils/command/__pycache__/clean.cpython-310.pycnu[o Xai @sDdZddlZddlmZddlmZddlmZGdddeZdS)zBdistutils.command.clean Implements the Distutils 'clean' command.N)Command) remove_tree)logc@s6eZdZdZgdZdgZddZddZdd Zd S) cleanz-clean up temporary files from 'build' command))z build-base=bz2base build directory (default: 'build.build-base'))z build-lib=Nzs    PKH]Ъb b _python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_data.cpython-310.pycnu[o Xai @s<dZddlZddlmZddlmZmZGdddeZdS)zdistutils.command.install_data Implements the Distutils 'install_data' command, for installing platform-independent data files.N)Command) change_root convert_pathc@sFeZdZdZgdZdgZddZddZdd Zd d Z d d Z dS) install_datazinstall data files))z install-dir=dzIbase directory for installing data files (default: installation base dir))zroot=Nzs  PKH]F!!`python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_wininst.cpython-310.pycnu[o Xai>@stdZddlZddlZddlZddlmZddlmZddlm Z ddl Tddl m Z ddl mZGd d d eZdS) zzdistutils.command.bdist_wininst Implements the Distutils 'bdist_wininst' command: create a windows installer exe-program.N)Command) get_platform) remove_tree)*)get_python_version)logc seZdZdZddddefdddd d d d d dddg ZgdZejdkZ fddZ ddZ ddZ ddZ ddZd$ddZd d!Zd"d#ZZS)% bdist_wininstz-create an executable installer for MS Windows)z bdist-dir=Nz1temporary directory for creating the distributionz plat-name=pz;platform name to embed in generated filenames (default: %s)) keep-tempkzPkeep the pseudo-installation tree around after creating the distribution archive)ztarget-version=Nz6require a specific python version on the target system)no-target-compilecz/do not compile .py to .pyc on the target system)no-target-optimizeoz;do not compile .py to .pyo (optimized) on the target system)z dist-dir=dz-directory to put final built distributions in)zbitmap=bz>bitmap to use for the installer instead of python-powered logo)ztitle=tz?title to display on the installer background instead of default) skip-buildNz2skip rebuilding everything (for testing/debugging))zinstall-script=NzUbasename of installation script to be run after installation or before deinstallation)zpre-install-script=Nz{Fully qualified filename of a script to be run before any files are installed. This script need not be in the distribution)zuser-access-control=Nzspecify Vista's UAC handling - 'none'/default=no handling, 'auto'=use UAC if target Python installed for all users, 'force'=always use UAC)r r rrwin32cs$tj|i|tdtddS)Nz^bdist_wininst command is deprecated since Python 3.8, use bdist_wheel (wheel packages) instead)super__init__warningswarnDeprecationWarning)selfargskw __class__/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/bdist_wininst.pyr?szbdist_wininst.__init__cCsRd|_d|_d|_d|_d|_d|_d|_d|_d|_d|_ d|_ d|_ d|_ dS)Nr) bdist_dir plat_name keep_tempno_target_compileno_target_optimizetarget_versiondist_dirbitmaptitle skip_buildinstall_scriptpre_install_scriptuser_access_control)rr r r!initialize_optionsEs z bdist_wininst.initialize_optionscCs|dd|jdur)|jr|jr|jd}|j|_|dj}tj |d|_|j s/d|_ |jsL|j rLt }|j rI|j |krItd|f||_ |ddd|jrp|jjD]}|jtj |krhdSqZtd|jdS) Nbdist)r+r+ZwininstzMtarget version can only be %s, or the '--skip-build' option must be specified)r(r()r#r#z(install_script '%s' not found in scripts)set_undefined_optionsr"r+r# distributionget_command_objget_finalized_command bdist_baseospathjoinr'has_ext_modulesrDistutilsOptionErrorr,scriptsbasename)rr0r6Z short_versionscriptr r r!finalize_optionsUsB      zbdist_wininst.finalize_optionsc Cstjdkr|js|jrtd|js|d|jddd}|j |_ |j|_d|_ |j |_ |d}d|_ d|_|jrm|j}|sV|jsMJd d tjdd }d |j |f}|d}tj|jd ||_dD]}|}|dkr}|d}t|d||qotd|j |tjdtj|j d|tjd=ddlm}|} |j } |j!| d|j d} |"| | |j#|jrt$} nd} |jj%&d| |'| ft(d| t)| |j*st+|j |j,ddSdS)Nrz^distribution contains extensions and/or C libraries; must be compiled on a Windows 32 platformbuildinstall)reinit_subcommandsr install_libz Should have already checked thisz%d.%drz.%s-%slib)purelibplatlibheadersr<datarHz/Include/$dist_nameinstall_zinstalling to %sZPURELIB)mktempzip)root_diranyrzremoving temporary file '%s')dry_run)-sysplatformr3r:has_c_librariesDistutilsPlatformErrorr+ run_commandreinitialize_commandr"rootwarn_dirr#compileoptimizer' version_infor5r7r8r9 build_base build_libuppersetattrrinfoensure_finalizedinsertruntempfilerK get_fullname make_archive create_exer)r dist_filesappendget_installer_filenamedebugremover$rrO) rrArDr'Zplat_specifierr@keyvaluerKZarchive_basenamefullnamearcnameZ pyversionr r r!rb{sv            zbdist_wininst.runc CsXg}|jj}|d|jpdd}dd}dD]!}t||d}|r9|d|||f}|d|||fq|d |jrJ|d |j|d |||d |j |d |j |j rp|d|j |j r{|d|j |j p|j }|d||ddl }ddl} d|| | jf} |d| d|S)Nz [metadata]r1 cSs |ddS)Nrpz\n)replace)sr r r!escapes z)bdist_wininst.get_inidata..escape)author author_email description maintainermaintainer_emailnameurlversionz %s: %sz%s=%sz [Setup]zinstall_script=%szinfo=%sztarget_compile=%dztarget_optimize=%dztarget_version=%szuser_access_control=%sztitle=%srzBuilt %s with distutils-%sz build_info=%s)r3metadatarhlong_descriptiongetattr capitalizer,r%r&r'r.r*rdtime distutilsctime __version__r9) rlinesr|r_rsryrIr*rrZ build_infor r r! get_inidatas@    zbdist_wininst.get_inidataNc Csddl}||j|}||}|d||r:t|d }|}Wdn1s0wYt|} nd} t|d} | | |rP| |t |t rZ| d}|d}|jrt|jddd } |  d} Wdn1s{wY|| d }n|d}| ||d d t|| } | | t|d}| |Wdn1swYWddSWddS1swYdS) Nrz creating %srbwbmbcsrzlatin-1)encodings zZ script_dataheaderr r r!rfsP            #"zbdist_wininst.create_execCsF|jrtj|jd||j|jf}|Stj|jd||jf}|S)Nz%s.%s-py%s.exez %s.%s.exe)r'r7r8r9r(r#)rrnrr r r!ri1s   z$bdist_wininst.get_installer_filenamec Cs$t}|jr6|j|kr6|jdkrd}nB|jdkrd}n:|jdkr#d}n2|jdkr+d}n*|jdkr3d }n"d }nzd d lm}Wn tyId }Yn w|d d }|d}tjt }|j dkrq|j dddkrq|j dd}nd}tj |d||f}t |d}z | W|S|w)Nz2.4z6.0z7.1z2.5z8.0z3.2z9.0z3.4z10.0z14.0r)CRT_ASSEMBLY_VERSION.z.0rwinr1zwininst-%s%s.exer)rr'msvcrtr ImportError partitionr7r8dirname__file__r#r9rrclose) rZ cur_versionZbvrmajor directoryZsfixfilenamerr r r!r>s:         zbdist_wininst.get_exe_bytes)N)__name__ __module__ __qualname__rvr user_optionsboolean_optionsrPrQZ _unsupportedrr/r?rbrrfrir __classcell__r r rr!rs<%  &Q .7 r)__doc__r7rPrdistutils.corerdistutils.utilrdistutils.dir_utilrdistutils.errorsdistutils.sysconfigrrrrr r r r!s     PKH]JPPH((Ypython3.10/site-packages/setuptools/_distutils/command/__pycache__/config.cpython-310.pycnu[o Xai=3@sldZddlZddlZddlmZddlmZddlmZddl m Z ddd Z Gd d d eZ dd d Z dS)adistutils.command.config Implements the Distutils 'config' command, a (mostly) empty command class that exists mainly to be sub-classed by specific module distributions and applications. The idea is that while every "config" command is different, at least they're all named the same, and users always see "config" in the list of standard commands. Also, this is a good place to put common configure-like tasks: "try to compile this C code", or "figure out where this header file lives". N)Command)DistutilsExecError)customize_compiler)logz.cz.cxx)czc++c@seZdZdZgdZddZddZddZd d Zd d Z d dZ ddZ ddZ ddZ d(ddZ  d(ddZd)ddZ  d*ddZ  d*dd Z  !d+d"d#Zdddgfd$d%Z  d)d&d'ZdS),configzprepare to build) )z compiler=Nzspecify the compiler type)zcc=Nzspecify the compiler executable)z include-dirs=Iz.list of directories to search for header files)zdefine=DzC preprocessor macros to define)zundef=Uz!C preprocessor macros to undefine)z libraries=lz!external C libraries to link with)z library-dirs=Lz.directories to search for external C libraries)noisyNz1show every action (compile, link, run, ...) taken)z dump-sourceNz=dump generated source files before attempting to compile themcCs4d|_d|_d|_d|_d|_d|_d|_g|_dS)N)compilercc include_dirs libraries library_dirsr dump_source temp_filesselfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/config.pyinitialize_options3s zconfig.initialize_optionscCs|jdur |jjp g|_nt|jtr|jtj|_|jdur$g|_n t|jtr/|jg|_|jdur9g|_dSt|jtrI|jtj|_dSdSN) r distribution isinstancestrsplitospathseprrrrrrfinalize_optionsBs        zconfig.finalize_optionscCsdSrrrrrrrunRsz config.runcCsddlm}m}t|j|s=||j|jdd|_t|j|jr'|j|j|j r1|j |j |j r?|j |j dSdSdS)z^Check that 'self.compiler' really is a CCompiler object; if not, make it one. r) CCompiler new_compilerr)rdry_runforceN) distutils.ccompilerr$r%rrr&rrZset_include_dirsrZ set_librariesrZset_library_dirs)rr$r%rrr_check_compilerYs  zconfig._check_compilercCsdt|}t|d4}|r|D] }|d|q|d|||ddkr7|dWd|SWd|S1sBwY|S)NZ _configtestwz#include <%s>  )LANG_EXTopenwrite)rbodyheaderslangfilenamefileheaderrrr_gen_temp_sourcefileks        zconfig._gen_temp_sourcefilecCs<||||}d}|j||g|jj|||d||fS)Nz _configtest.ir)r6rextendr preprocess)rr0r1rr2srcoutrrr _preprocessws zconfig._preprocesscCs\||||}|jrt|d||j|g\}|j||g|jj|g|d||fS)Nzcompiling '%s':r7)r6r dump_filerZobject_filenamesrr8compile)rr0r1rr2r:objrrr_compile~szconfig._compilec Csr|||||\}}tjtj|d} |jj|g| |||d|jjdur.| |jj} |j | ||| fS)Nr)rrZ target_lang) r@r pathsplitextbasenamerZlink_executableZ exe_extensionrappend) rr0r1rrrr2r:r?progrrr_links     z config._linkc GsP|s|j}g|_tdd||D]}zt|Wqty%YqwdS)Nz removing: %s )rrinfojoinr removeOSError)r filenamesr3rrr_cleans z config._cleanNrcCsPddlm}|d}z |||||Wn |y!d}Ynw||S)aQConstruct a source file from 'body' (a string containing lines of C/C++ code) and 'headers' (a list of header files to include) and run it through the preprocessor. Return true if the preprocessor succeeded, false if there were any errors. ('body' probably isn't of much use, but what the heck.) r CompileErrorTF)r(rOr)r<rMrr0r1rr2rOokrrrtry_cpps  zconfig.try_cppc Cs||||||\}}t|trt|}t|}d} |} | dkr)n || r1d} nq Wdn1sr.readlinesearchrM) rpatternr0r1rr2r:r;r4matchlinerrr search_cpps$      zconfig.search_cppcCsbddlm}|z |||||d}Wn |y!d}Ynwt|r(dp)d||S)zwTry to compile a source file built from 'body' and 'headers'. Return true on success, false otherwise. rrNTFsuccess!failure.)r(rOr)r@rrHrMrPrrr try_compiles  zconfig.try_compilec Csnddlm}m}|z|||||||d} Wn ||fy'd} Ynwt| r.dp/d|| S)zTry to compile and link a source file, built from 'body' and 'headers', to executable form. Return true on success, false otherwise. rrO LinkErrorTFr[r\)r(rOr_r)rFrrHrM) rr0r1rrrr2rOr_rQrrrtry_links zconfig.try_linkc Csddlm}m}|z|||||||\} } } || gd} Wn||tfy1d} Ynwt| r8dp9d| | S)zTry to compile, link to an executable, and run a program built from 'body' and 'headers'. Return true on success, false otherwise. rr^TFr[r\) r(rOr_r)rFspawnrrrHrM) rr0r1rrrr2rOr_r:r?ZexerQrrrtry_runs  zconfig.try_runrc Cst|g}|r|d||d|r|d|n|d||dd|d}||||||S)aDetermine if function 'func' is available by constructing a source file that refers to 'func', and compiles and links it. If everything succeeds, returns true; otherwise returns false. The constructed source file starts out by including the header files listed in 'headers'. If 'decl' is true, it then declares 'func' (as "int func()"); you probably shouldn't supply 'headers' and set 'decl' true in the same call, or you might get errors about a conflicting declarations for 'func'. Finally, the constructed 'main()' function either references 'func' or (if 'call' is true) calls it. 'libraries' and 'library_dirs' are used when linking. z int %s ();z int main () {z %s();z %s;}r+)r)rDrIr`) rfuncr1rrrdeclcallr0rrr check_funcs   zconfig.check_funccCs ||d|||g||S)aDetermine if 'library' is available to be linked against, without actually checking that any particular symbols are provided by it. 'headers' will be used in constructing the source file to be compiled, but the only effect of this is to check if all the header files listed are available. Any libraries listed in 'other_libraries' will be included in the link, in case 'library' has symbols that depend on other libraries. zint main (void) { })r)r`)rlibraryrr1rZother_librariesrrr check_lib4s  zconfig.check_libcCs|jd|g|dS)zDetermine if the system header file named by 'header_file' exists and can be found by the preprocessor; return true if so, false otherwise. z /* No body */)r0r1r)rR)rr5rrr2rrr check_headerBs zconfig.check_header)NNNr)NNr)NNNNr)NNNNrr)__name__ __module__ __qualname__ description user_optionsrr"r#r)r6r<r@rFrMrRrZr]r`rbrgrirjrrrrrs@        rcCsP|dur td|nt|t|}zt|W|dS|w)zjDumps a file content into log.info. If head is not None, will be dumped before the file content. Nz%s)rrHr.readclose)r3headr4rrrr=Ks r=r)__doc__r rTdistutils.corerdistutils.errorsrdistutils.sysconfigr distutilsrr-rr=rrrrs     8PKH]llXpython3.10/site-packages/setuptools/_distutils/command/__pycache__/build.cpython-310.pycnu[o Xai@sTdZddlZddlZddlmZddlmZddlmZddZ Gdd d eZ dS) zBdistutils.command.build Implements the Distutils 'build' command.N)Command)DistutilsOptionError) get_platformcCsddlm}|dS)Nrshow_compilers)Zdistutils.ccompilerrrr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/build.pyr s  rc @seZdZdZdddddddd d efd d d ddg ZddgZdddefgZddZ ddZ ddZ ddZ ddZ dd Zd!d"Zd#e fd$e fd%efd&efgZdS)'buildz"build everything needed to install)z build-base=bz base directory for build library)zbuild-purelib=Nz2build directory for platform-neutral distributions)zbuild-platlib=Nz3build directory for platform-specific distributions)z build-lib=NzWbuild directory for all distribution (defaults to either build-purelib or build-platlib)zbuild-scripts=Nzbuild directory for scripts)z build-temp=tztemporary build directoryz plat-name=pz6platform name to build for, if supported (default: %s))z compiler=czspecify the compiler type)z parallel=jznumber of parallel build jobs)debuggz;compile extensions and libraries with debugging information)forcefz2forcibly build everything (ignore file timestamps))z executable=ez5specify final destination interpreter path (build.py)rrz help-compilerNzlist available compilerscCsLd|_d|_d|_d|_d|_d|_d|_d|_d|_d|_ d|_ d|_ dS)Nr r) build_base build_purelib build_platlib build_lib build_temp build_scriptscompiler plat_namerr executableparallelselfrrrinitialize_options8s zbuild.initialize_optionscCsZ|jdur t|_n tjdkrtdd|jgtjddR}ttdr*|d7}|jdur8tj |j d|_|j durHtj |j d||_ |j dur[|jrW|j |_ n|j|_ |jdurktj |j d||_|jdurtj |j d tjdd|_|jdurtjrtj tj|_t|jtrz t|j|_WdStytd wdS) NntzW--plat-name only supported on Windows (try using './configure --help' on your platform)z .%s-%d.%dgettotalrefcountz-pydebuglibtempz scripts-%d.%dzparallel should be an integer)rrosnamersys version_infohasattrrpathjoinrrr distributionhas_ext_modulesrrrnormpath isinstancerstrint ValueError)rZplat_specifierrrrfinalize_optionsHsH                zbuild.finalize_optionscCs|D]}||qdSN)get_sub_commands run_command)rcmd_namerrrruns  z build.runcC |jSr5)r-has_pure_modulesrrrrr; zbuild.has_pure_modulescCr:r5)r-has_c_librariesrrrrr=r<zbuild.has_c_librariescCr:r5)r-r.rrrrr.r<zbuild.has_ext_modulescCr:r5)r- has_scriptsrrrrr>r<zbuild.has_scriptsbuild_py build_clib build_extr)__name__ __module__ __qualname__ descriptionr user_optionsboolean_optionsr help_optionsr r4r9r;r=r.r> sub_commandsrrrrr sH8 r ) __doc__r(r&distutils.corerdistutils.errorsrdistutils.utilrrr rrrrs   PKH]hdbpython3.10/site-packages/setuptools/_distutils/command/__pycache__/install_scripts.cpython-310.pycnu[o Xai@sDdZddlZddlmZddlmZddlmZGdddeZdS)zudistutils.command.install_scripts Implements the Distutils 'install_scripts' command, for installing Python scripts.N)Command)log)ST_MODEc@sHeZdZdZgdZddgZddZddZd d Zd d Z d dZ dS)install_scriptsz%install scripts (Python or otherwise)))z install-dir=dzdirectory to install scripts to)z build-dir=bz'build directory (where to install from))forcefz-force installation (overwrite existing files)) skip-buildNzskip the build stepsrr cCsd|_d|_d|_d|_dS)Nr) install_dirr build_dir skip_buildselfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/install_scripts.pyinitialize_optionss z"install_scripts.initialize_optionscCs |dd|dddddS)Nbuild) build_scriptsr install)rr )rr)r r )set_undefined_optionsrrrrfinalize_options!s z install_scripts.finalize_optionscCs|js|d||j|j|_tjdkr?|D]&}|j r&t d|qt |t dBd@}t d||t||qdSdS)Nrposixzchanging mode of %simizchanging mode of %s to %o)r run_command copy_treer r outfilesosname get_outputsdry_runrinfostatrchmod)rfilemoderrrrun)s   zinstall_scripts.runcCs |jjpgSN) distributionscriptsrrrr get_inputs8s zinstall_scripts.get_inputscCs |jpgSr&)rrrrrr;s zinstall_scripts.get_outputsN) __name__ __module__ __qualname__ description user_optionsboolean_optionsrrr%r)rrrrrrs r) __doc__rdistutils.corer distutilsrr!rrrrrrs    PKH]1{66Ypython3.10/site-packages/setuptools/_distutils/command/__pycache__/upload.cpython-310.pycnu[o Xai@sdZddlZddlZddlZddlmZddlmZmZm Z ddl m Z ddl m Z mZddlmZddlmZdd lmZeed deed deed dd ZGdddeZdS)zm distutils.command.upload Implements the Distutils 'upload' subcommand (upload package to a package index). N)standard_b64encode)urlopenRequest HTTPError)urlparse)DistutilsErrorDistutilsOptionError) PyPIRCCommand)spawn)logmd5sha256blake2b)Z md5_digestZ sha256_digestZblake2_256_digestc@sJeZdZdZejddgZejdgZddZddZd d Z d d Z d S)uploadzupload binary package to PyPI)signszsign files to upload using gpg)z identity=izGPG identity used to sign filesrcCs,t|d|_d|_d|_d|_d|_dS)NrF)r initialize_optionsusernamepassword show_responseridentity)selfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/upload.pyr)s  zupload.initialize_optionscCszt||jr|jstd|}|ikr+|d|_|d|_|d|_|d|_ |js9|j jr;|j j|_dSdSdS)Nz.Must use --sign for --identity to have meaningrr repositoryrealm) r finalize_optionsrrr _read_pypircrrrr distribution)rconfigrrrr1s      zupload.finalize_optionscCs:|jjs d}t||jjD] \}}}||||qdS)NzHMust create and upload files in one command (e.g. setup.py sdist upload))r dist_filesr upload_file)rmsgcommand pyversionfilenamerrrrunCs z upload.runc" Cs>t|j\}}}}}} |s|s| rtd|j|dvr"td||jr>ddd|g} |jr7d|jg| dd<t| |jd t|d } z | } W| n| w|j j } id d d dd| d| dtj|| fd|d|ddd| d| d| d| d| d| d| d| d| | | | | d}d |d!<tD]\}}|durqz ||  ||<Wqt!yYqw|jrt|d"d } tj|d"| f|d#<Wdn 1swY|j"d$|j#$d%}d&t%|&d%}d'}d(|$d%}|d)}t'(}|D]J\}}d*|}t)|t*s@|g}|D]5}t+|t,urX|d+|d,7}|d-}nt-|$d.}|.||.|$d.|.d/|.|qBq/|.||/}d0||jf}|0|t1j2d1|t-t3||d2}t4|j||d3}z t5|}|6}|j7}Wn/t8y} z | j9}| j7}WYd} ~ nd} ~ wt:y} z |0t-| t1j;d} ~ ww|d4kr|0d5||ft1j2|j<r |=|}!d6>d7|!d7f}|0|t1j2dSdSd8||f}|0|t1j;t?|)9NzIncompatible url %s)httphttpszunsupported schema Zgpgz --detach-signz-az --local-user)dry_runrbz:actionZ file_uploadZprotocol_version1nameversioncontentfiletyper&metadata_versionz1.0summaryZ home_pageauthor author_emaillicense descriptionkeywordsplatform classifiers) download_urlprovidesrequires obsoletesrcommentz.ascZ gpg_signature:asciizBasic z3--------------GHSKFJDLGDS7543FJKLFHRE75642756743254s --s-- z+ Content-Disposition: form-data; name="%s"z; filename="%s"rzutf-8s zSubmitting %s to %sz multipart/form-data; boundary=%s)z Content-typezContent-length Authorization)dataheaderszServer response (%s): %s zK---------------------------------------------------------------------------zUpload failed (%s): %s)@rrAssertionErrorrrr r,openreadcloser metadataget_name get_versionospathbasenameget_descriptionget_url get_contactget_contact_email get_licenceget_long_description get_keywords get_platformsget_classifiersget_download_url get_provides get_requires get_obsoletes_FILE_CONTENT_DIGESTSitems hexdigest ValueErrorrrencoderdecodeioBytesIO isinstancelisttypetuplestrwritegetvalueannouncer INFOlenrrgetcoder$rcodeOSErrorERRORr_read_pypi_responsejoinr)"rr%r&r'Zschemanetlocurlparamsquery fragmentsZgpg_argsfr1metarEZ digest_name digest_cons user_passauthboundaryZ sep_boundaryZ end_boundarybodykeyvaluetitler$rFrequestresultstatusreasonetextrrrr#Ks                     zupload.upload_fileN) __name__ __module__ __qualname__r8r user_optionsboolean_optionsrrr(r#rrrrrs  r)__doc__rPrfhashlibbase64rurllib.requestrrr urllib.parserdistutils.errorsrrdistutils.corer distutils.spawnr distutilsr getattrr`rrrrrs         PKH]Xpython3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist.cpython-310.pycnu[o Xai@sHdZddlZddlmZddlTddlmZddZGdd d eZdS) zidistutils.command.bdist Implements the Distutils 'bdist' command (create a built [binary] distribution).N)Command)*) get_platformcCsPddlm}g}tjD]}|d|dtj|dfq ||}|ddS)zFPrint list of available formats (arguments to "--format" option). r) FancyGetoptformats=Nz'List of available distribution formats:)distutils.fancy_getoptrbdistformat_commandsappendformat_command print_help)rformatsformatZpretty_printerr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/bdist.py show_formats s    rc @seZdZdZddddefdddd d gZd gZd d defgZdZ dddZ gdZ dddddddddd Z ddZ dd Zd!d"Zd S)#r z$create a built (binary) distribution)z bdist-base=bz4temporary directory for creating built distributionsz plat-name=pz;platform name to embed in generated filenames (default: %s))rNz/formats for distribution (comma-separated list))z dist-dir=dz=directory to put final built distributions in [default: dist]) skip-buildNz2skip rebuilding everything (for testing/debugging))zowner=uz@Owner name used when creating a tar file [default: current user])zgroup=gzAGroup name used when creating a tar file [default: current group]rz help-formatsNz$lists available distribution formats) bdist_rpmgztarzip)posixnt) ZrpmrbztarxztarztartarZwininstrZmsi)rzRPM distribution) bdist_dumbzgzip'ed tar file)r"zbzip2'ed tar file)r"zxz'ed tar file)r"zcompressed tar file)r"ztar file)Z bdist_wininstzWindows executable installer)r"zZIP file)Z bdist_msizMicrosoft InstallercCs.d|_d|_d|_d|_d|_d|_d|_dS)Nr) bdist_base plat_namerdist_dir skip_buildgroupowner)selfrrrinitialize_optionsQs zbdist.initialize_optionscCs|jdur|jr t|_n|dj|_|jdur*|dj}tj|d|j|_| d|j durMz |j tj g|_ Wnt yLtdtj w|jdurWd|_dSdS)Nbuildzbdist.rz;don't know how to create built distributions on platform %sdist)r$r&rget_finalized_commandr# build_baseospathjoinensure_string_listrdefault_formatnameKeyErrorDistutilsPlatformErrorr%)r)r.rrrfinalize_optionsZs.         zbdist.finalize_optionsc Csg}|jD]}z ||j|dWqty td|wtt|jD]4}||}||}||jvr>|j||_ |dkrJ|j |_ |j |_ |||ddvrWd|_ | |q(dS)Nrzinvalid format '%s'r"r)rr r r5DistutilsOptionErrorrangelenreinitialize_commandno_format_optionrr(r'Z keep_temp run_command)r)commandsricmd_nameZsub_cmdrrrrunvs&       z bdist.run)__name__ __module__ __qualname__ descriptionr user_optionsboolean_optionsr help_optionsr<r3r r r*r7rArrrrr sJ  r ) __doc__r/distutils.corerdistutils.errorsdistutils.utilrrr rrrrs   PKH]p>GG]python3.10/site-packages/setuptools/_distutils/command/__pycache__/py37compat.cpython-310.pycnu[o Xai@sTddlZddZddZejdkr&ejdkr&ejddd kr&eeeZdSeZdS) NccsFddlm}|dsdSdtjd?tjd?d@|d VdS) zj On Python 3.7 and earlier, distutils would include the Python library. See pypa/distutils#9. r sysconfigZPy_ENABLED_SHAREDNz python{}.{}{}ABIFLAGS) distutilsrget_config_varformatsys hexversionrr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/py37compat.py_pythonlib_compats    rcsfddS)Ncs|i|S)Nr )argskwargsf1f2r rszcompose..r rr rrcomposesr)darwinraix)r rr version_infoplatformlistZ pythonlibr r r rs  PKH]igs PKH]mJJ[python3.10/site-packages/setuptools/_distutils/command/__pycache__/__init__.cpython-310.pycnu[o Xai@sdZgdZdS)z\distutils.command Package containing implementation of all the standard Distutils commands.)buildbuild_py build_ext build_clib build_scriptscleaninstall install_libinstall_headersinstall_scripts install_datasdistregisterbdist bdist_dumb bdist_rpmZ bdist_wininstcheckuploadN)__doc____all__rr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/__init__.pys PKH](2kk^python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_lib.cpython-310.pycnu[o Xai @sLdZddlZddlZddlZddlmZddlmZdZ GdddeZ dS)zkdistutils.command.install_lib Implements the Distutils 'install_lib' command (install all Python modules).N)Command)DistutilsOptionErrorz.pyc@sxeZdZdZgdZgdZddiZddZdd Zd d Z d d Z ddZ ddZ ddZ ddZddZddZdS) install_libz7install all Python modules (extensions and pure Python)))z install-dir=dzdirectory to install to)z build-dir=bz'build directory (where to install from))forcefz-force installation (overwrite existing files))compileczcompile .py to .pyc [default]) no-compileNzdon't compile .py files)z optimize=Ozlalso compile with optimization: -O1 for "python -O", -O2 for "python -OO", and -O0 to disable [default: -O0]) skip-buildNzskip the build steps)rr r r r cCs(d|_d|_d|_d|_d|_d|_dS)Nr) install_dir build_dirrr optimize skip_buildselfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/install_lib.pyinitialize_options3s  zinstall_lib.initialize_optionsc Cs|ddddddd|jdurd|_|jdurd |_t|jts?zt|j|_|jd vr/tWdSttfy>td wdS) Ninstall) build_libr)rr)rr)r r )rr)rrTF)rzoptimize must be 0, 1, or 2)set_undefined_optionsr r isinstanceintAssertionError ValueErrorrrrrrfinalize_options<s,     zinstall_lib.finalize_optionscCs8||}|dur|jr||dSdSdSN)buildr distributionhas_pure_modules byte_compilerZoutfilesrrrrunVs zinstall_lib.runcCs:|js|jr |d|jr|ddSdSdS)Nbuild_py build_ext)rr#r$ run_commandhas_ext_modulesrrrrr"fs   zinstall_lib.buildcCs6tj|jr||j|j}|S|d|jdS)Nz3'%s' does not exist -- no Python modules to install)ospathisdirr copy_treerwarnr&rrrrmszinstall_lib.installcCsvtjr |ddSddlm}|dj}|jr$||d|j||j d|j dkr9|||j |j||j |j ddSdS)Nz%byte-compiling is disabled, skipping.r)r%r)rrprefixdry_run)rrr1verboser2) sysdont_write_bytecoder0distutils.utilr%get_finalized_commandrootr rr2rr3)rfilesr%Z install_rootrrrr%vs      zinstall_lib.byte_compilec Csd|sgS||}|}t||}t|ttj}g}|D]} |tj|| |dq|Sr!) r7 get_outputsgetattrlenr,sepappendr-join) rZhas_anyZ build_cmdZ cmd_option output_dirZ build_filesr prefix_lenoutputsfilerrr_mutate_outputss  zinstall_lib._mutate_outputscCsrg}|D]2}tjtj|d}|tkrq|jr%|tjj |dd|j dkr6|tjj ||j dq|S)Nr) optimizationr) r,r-splitextnormcasePYTHON_SOURCE_EXTENSIONr r> importlibutilcache_from_sourcer)rZ py_filenamesZbytecode_filesZpy_fileextrrr_bytecode_filenamess   zinstall_lib._bytecode_filenamescCsR||jdd|j}|jr||}ng}||jdd|j}|||S)zReturn the list of files that would be installed if this command were actually run. Not affected by the "dry-run" flag or whether modules have actually been built yet. r(rr))rDr#r$rr rNr+)rZ pure_outputsZbytecode_outputsZ ext_outputsrrrr:s    zinstall_lib.get_outputscCsLg}|jr|d}|||jr$|d}|||S)zGet the list of files that are input to this command, ie. the files that get installed as they are named in the build tree. The files in this list correspond one-to-one to the output filenames returned by 'get_outputs()'. r(r))r#r$r7extendr:r+)rinputsr(r)rrr get_inputss    zinstall_lib.get_inputsN)__name__ __module__ __qualname__ description user_optionsboolean_options negative_optrr r'r"rr%rDrNr:rQrrrrrs    r) __doc__r,importlib.utilrJr4distutils.corerdistutils.errorsrrIrrrrrs  PKH]Ç88Xpython3.10/site-packages/setuptools/_distutils/command/__pycache__/sdist.cpython-310.pycnu[o Xai=J@sdZddlZddlZddlmZddlmZddlmZddlm Z ddlm Z ddlm Z dd l m Z dd lmZdd lmZdd lmZdd lmZmZddZGdddeZdS)zadistutils.command.sdist Implements the Distutils 'sdist' command (create a source distribution).N)glob)warn)Command)dir_util) file_util) archive_util)TextFile)FileList)log) convert_path)DistutilsTemplateErrorDistutilsOptionErrorcCs`ddlm}ddlm}g}|D]}|d|d||dfq|||ddS)zoPrint all possible values for the 'formats' option (used by the "--help-formats" command-line option). r) FancyGetopt)ARCHIVE_FORMATSformats=Nz.List of available source distribution formats:)distutils.fancy_getoptrZdistutils.archive_utilrkeysappendsort print_help)rrformatsformatr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/sdist.py show_formatss     rc@seZdZdZddZgdZgdZdddefgZd d d Z d efgZ d Z ddZ ddZ ddZddZddZddZeddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Z d6d7Z!d8d9Z"dS):sdistz6create a source distribution (tarball, zip file, etc.)cC|jS)zYCallable used for the check sub-command. Placed here so user_options can view it)metadata_checkselfrrrchecking_metadata(zsdist.checking_metadata))z template=tz5name of manifest template file [default: MANIFEST.in])z manifest=mz)name of manifest file [default: MANIFEST]) use-defaultsNzRinclude the default file set in the manifest [default; disable with --no-defaults]) no-defaultsNz"don't include the default file set)pruneNzspecifically exclude files/directories that should not be distributed (build tree, RCS/CVS dirs, etc.) [default; disable with --no-prune])no-pruneNz$don't automatically exclude anything) manifest-onlyozEjust regenerate the manifest and then stop (implies --force-manifest))force-manifestfzkforcibly regenerate the manifest and carry on as usual. Deprecated: now the manifest is always regenerated.)rNz6formats for source distribution (comma-separated list)) keep-tempkz@keep the distribution tree around after creating archive file(s))z dist-dir=dzFdirectory to put the source distribution archive(s) in [default: dist])metadata-checkNz[Ensure that all required elements of meta-data are supplied. Warn if any missing. [default])zowner=uz@Owner name used when creating a tar file [default: current user])zgroup=gzAGroup name used when creating a tar file [default: current group])r%r'r)r+r-r0z help-formatsNz#list available distribution formatsr%r')r&r(check)ZREADMEz README.txtz README.rstcCsTd|_d|_d|_d|_d|_d|_dg|_d|_d|_d|_ d|_ d|_ d|_ dS)Nrgztar) templatemanifest use_defaultsr' manifest_onlyZforce_manifestr keep_tempdist_dir archive_filesrownergrouprrrrinitialize_optionses zsdist.initialize_optionscCs^|jdurd|_|jdurd|_|dt|j}|r#td||jdur-d|_dSdS)NZMANIFESTz MANIFEST.inrzunknown archive format '%s'dist)r7r6ensure_string_listrcheck_archive_formatsrr r;)r Z bad_formatrrrfinalize_options|s      zsdist.finalize_optionscCs>t|_|D]}||q||jrdS|dSN)r filelistget_sub_commands run_command get_file_listr9make_distribution)r cmd_namerrrruns   z sdist.runcCs*tdt|jd}||dS)zDeprecated API.zadistutils.command.sdist.check_metadata is deprecated, use the check command insteadr3N)rPendingDeprecationWarning distributionget_command_objensure_finalizedrK)r r3rrrcheck_metadatas   zsdist.check_metadatacCstj|j}|s|r||j|jdS|s'| d|j|j |j r3| |r9| |jr@||j|j|dS)aCFigure out the list of files to include in the source distribution, and put it in 'self.filelist'. This might involve reading the manifest template (and writing the manifest), or just reading the manifest, or just using the default file set -- it all depends on the user's options. Nz?manifest template '%s' does not exist (using default file list))ospathisfiler6_manifest_is_not_generated read_manifestrErZremove_duplicatesrfindallr8 add_defaults read_templater'prune_file_listwrite_manifest)r Ztemplate_existsrrrrHs(       zsdist.get_file_listcCs<|||||||dS)a9Add all the default files to self.filelist: - README or README.txt - setup.py - test/test*.py - all pure Python modules mentioned in setup script - all files pointed by package_data (build_py) - all files defined in data_files. - all files defined as scripts. - all C sources listed as part of extensions or C libraries in the setup script (doesn't catch C headers!) Warns if (README or README.txt) or setup.py are missing; everything else is optional. N)_add_defaults_standards_add_defaults_optional_add_defaults_python_add_defaults_data_files_add_defaults_ext_add_defaults_c_libs_add_defaults_scriptsrrrrrWs zsdist.add_defaultscCs:tj|sdStj|}tj|\}}|t|vS)z Case-sensitive path existence check >>> sdist._cs_path_exists(__file__) True >>> sdist._cs_path_exists(__file__.upper()) False F)rQrRexistsabspathsplitlistdir)fspathrc directoryfilenamerrr_cs_path_existss  zsdist._cs_path_existscCs|j|jjg}|D]?}t|tr5|}d}|D]}||r'd}|j|nq|s4|dd |q ||rA|j|q |d|q dS)NFTz,standard file not found: should have one of z, zstandard file '%s' not found) READMESrM script_name isinstancetuplerirErrjoin)r Z standardsfnZaltsZgot_itrrrr[s(    zsdist._add_defaults_standardscCs4ddg}|D]}ttjjt|}|j|qdS)Nz test/test*.pyz setup.cfg)filterrQrRrSrrEextend)r optionalpatternfilesrrrr\s zsdist._add_defaults_optionalcCs\|d}|jr|j||jD]\}}}}|D] }|jtj ||qqdS)Nbuild_py) get_finalized_commandrMhas_pure_modulesrErqget_source_files data_filesrrQrRrn)r rupkgsrc_dir build_dir filenamesrhrrrr]s  zsdist._add_defaults_pythoncCs~|jr;|jjD]3}t|tr!t|}tj|r |j |q |\}}|D]}t|}tj|r9|j |q'q dSdSrD) rMhas_data_filesryrlstrr rQrRrSrEr)r itemdirnamer}r,rrrr^$s       zsdist._add_defaults_data_filescC,|jr|d}|j|dSdS)N build_ext)rMhas_ext_modulesrvrErqrx)r rrrrr_5  zsdist._add_defaults_extcCr)N build_clib)rMhas_c_librariesrvrErqrx)r rrrrr`:rzsdist._add_defaults_c_libscCr)N build_scripts)rM has_scriptsrvrErqrx)r rrrrra?rzsdist._add_defaults_scriptsc Cstd|jt|jddddddd}z; |}|durn*z|j|Wn ttfyF}z| d|j |j |fWYd}~nd}~wwqW| dS| w)zRead and parse manifest template file named by self.template. (usually "MANIFEST.in") The parsing and processing is done by 'self.filelist', which updates itself accordingly. zreading manifest template '%s'r4)strip_comments skip_blanks join_lines lstrip_ws rstrip_wsZ collapse_joinTNz%s, line %d: %s) r infor6rreadlinerEprocess_template_liner ValueErrorrrh current_lineclose)r r6linemsgrrrrXDs,   zsdist.read_templatecCsz|d}|j}|jjd|jd|jjd|dtjdkr#d}nd}gd}d|d ||f}|jj|d d dS) avPrune off branches that might slip into the file list as created by 'read_template()', but really don't belong there: * the build tree (typically "build") * the release tree itself (only an issue if we ran "sdist" previously with --keep-temp, or it aborted) * any RCS, CVS, .svn, .hg, .git, .bzr, _darcs directories buildN)prefixwin32z/|\\/)RCSCVSz\.svnz\.hgz\.gitz\.bzr_darcsz(^|%s)(%s)(%s).*|r4)Zis_regex) rvrM get_fullnamerEZexclude_pattern build_basesysplatformrn)r rbase_dirsepsZvcs_dirsZvcs_ptrnrrrrYas   zsdist.prune_file_listcCsX|rtd|jdS|jjdd}|dd|tj |j|fd|jdS)zWrite the file list in 'self.filelist' (presumably as filled in by 'add_defaults()' and 'read_template()') to the manifest file named by 'self.manifest'. z5not writing to manually maintained manifest file '%s'Nrz*# file GENERATED by distutils, do NOT editzwriting manifest file '%s') rTr rr7rErtinsertexecuter write_file)r contentrrrrZys zsdist.write_manifestcCsBtj|js dSt|j}z |}W||dkS|w)NFz+# file GENERATED by distutils, do NOT edit )rQrRrSr7openrr)r fp first_linerrrrTs   z sdist._manifest_is_not_generatedcCsltd|jt|j }|D]}|}|ds|sq|j|qWddS1s/wYdS)zRead the manifest file (named by 'self.manifest') and use it to fill in 'self.filelist', the list of files to include in the source distribution. zreading manifest file '%s'#N)r rr7rstrip startswithrEr)r r7rrrrrUs "zsdist.read_manifestcCs||tj|||jdttdrd}d|}nd}d|}|s(tdnt||D]}tj |s>td|q/tj ||}|j |||d q/|j j|dS) aCreate the directory tree that will become the source distribution archive. All directories implied by the filenames in 'files' are created under 'base_dir', and then we hard link or copy (if hard linking is unavailable) those files into place. Essentially, this duplicates the developer's source tree, but in a directory named after the distribution, containing only the files to be distributed. dry_runlinkhardzmaking hard links in %s...Nzcopying files to %s...z)no files to distribute -- empty manifest?z#'%s' not a regular file -- skipping)r)mkpathr create_treerhasattrrQr rrrRrSrn copy_filerMmetadatawrite_pkg_info)r rrtrrfiledestrrrmake_release_trees      zsdist.make_release_treecCs|j}tj|j|}|||jjg}d|j vr*|j |j |j d|j D]}|j ||||j|jd}| ||jj dd|fq-||_|js[tj||jddSdS)aCreate the source distribution(s). First, we create the release tree with 'make_release_tree()'; then, we create all required archive files (according to 'self.formats') from the release tree. Finally, we clean up by blowing away the release tree (unless 'self.keep_temp' is true). The list of archive files created is stored so it can be retrieved later by 'get_archive_files()'. tar)rr=r>rrN)rMrrQrRrnr;rrErtrrpopindex make_archiver=r> dist_filesr<r:r remove_treer)r r base_namer<fmtrrrrrIs     zsdist.make_distributioncCr)zzReturn the list of archive files created when the command was run, or None if the command hasn't run yet. )r<rrrrget_archive_filesr"zsdist.get_archive_files)#__name__ __module__ __qualname__ descriptionr! user_optionsboolean_optionsr help_options negative_opt sub_commandsrjr?rCrKrPrHrW staticmethodrir[r\r]r^r_r`rarXrYrZrTrUrrIrrrrrr$sJ' (  * r)__doc__rQrrwarningsrdistutils.corer distutilsrrrdistutils.text_filerdistutils.filelistr r distutils.utilr distutils.errorsr r rrrrrrs           PKH](9k;ss]python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-310.pycnu[o Xai1@shdZddlZddlmZddlmZddlmZmZddl Tddl m Z ddl m Z Gd d d eZdS) zdistutils.command.bdist_dumb Implements the Distutils 'bdist_dumb' command (create a "dumb" built distribution -- i.e., just an archive to be unpacked under $prefix or $exec_prefix).N)Command) get_platform) remove_treeensure_relative)*)get_python_version)logc @s\eZdZdZddddefdddd d d d g Zgd ZdddZddZddZ ddZ dS) bdist_dumbz"create a "dumb" built distribution)z bdist-dir=dz1temporary directory for creating the distributionz plat-name=pz;platform name to embed in generated filenames (default: %s))zformat=fz>archive format to create (tar, gztar, bztar, xztar, ztar, zip)) keep-tempkzPkeep the pseudo-installation tree around after creating the distribution archive)z dist-dir=r z-directory to put final built distributions in) skip-buildNz2skip rebuilding everything (for testing/debugging))relativeNz7build the archive using relative paths (default: false))zowner=uz@Owner name used when creating a tar file [default: current user])zgroup=gzAGroup name used when creating a tar file [default: current group])r rrgztarzip)posixntcCs:d|_d|_d|_d|_d|_d|_d|_d|_d|_dS)Nr) bdist_dir plat_nameformat keep_tempdist_dir skip_buildrownergroup)selfr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/bdist_dumb.pyinitialize_options2s zbdist_dumb.initialize_optionscCst|jdur|dj}tj|d|_|jdur0z |jtj|_Wnt y/t dtjw| dddddS)NbdistZdumbz@don't know how to create dumb built distributions on platform %s)rr)rr)rr) rget_finalized_command bdist_baseospathjoinrdefault_formatnameKeyErrorDistutilsPlatformErrorset_undefined_options)rr%r r r!finalize_options=s$    zbdist_dumb.finalize_optionscCs(|js|d|jddd}|j|_|j|_d|_td|j|dd|j |j f}t j |j|}|js?|j}n$|jrX|j|jkrXtdt|jt|jft j |jt|j}|j||j||j|jd }|jryt}nd }|jjd ||f|jst|j|jd dSdS) Nbuildinstall)reinit_subcommandsrzinstalling to %sz%s.%szScan't make a dumb built distribution where base and platbase are different (%s, %s))root_dirrranyr )dry_run) r run_commandreinitialize_commandrrootwarn_dirrinfo distribution get_fullnamerr&r'r(rrhas_ext_modules install_baseinstall_platbaser,reprr make_archiverrrr dist_filesappendrrr5)rr0Zarchive_basenameZpseudoinstall_rootZ archive_rootfilenameZ pyversionr r r!runOsN        zbdist_dumb.runN) __name__ __module__ __qualname__ descriptionr user_optionsboolean_optionsr)r"r.rEr r r r!r s. r )__doc__r&distutils.corerdistutils.utilrdistutils.dir_utilrrdistutils.errorsdistutils.sysconfigr distutilsrr r r r r!s    PKH]??\python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_ext.cpython-310.pycnu[o Xai{@sdZddlZddlZddlZddlZddlmZddlTddlm Z m Z ddlm Z ddl m Z ddlmZdd lmZdd lmZd d lmZdd lmZedZddZGdddeZdS)zdistutils.command.build_ext Implements the Distutils 'build_ext' command, for building extension modules (currently limited to C extensions, should accommodate C++ extensions ASAP).N)Command)*)customize_compilerget_python_version)get_config_h_filename) newer_group) Extension) get_platform)log) py37compat) USER_BASEz3^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$cCsddlm}|dS)Nrshow_compilers)distutils.ccompilerrrr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/build_ext.pyrs  rc@seZdZdZdejZdddddefdd d d efd d ddddefddddddddddgZgdZ ddde fgZ d d!Z d"d#Z d$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zejd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Zd@dAZdBdCZdS)D build_extz8build C/C++ extensions (compile/link to build directory)z (separated by '%s'))z build-lib=bz(directory for compiled extension modules)z build-temp=tz1directory for temporary files (build by-products)z plat-name=pz>platform name to cross-compile for, if supported (default: %s))inplaceiziignore build-lib and put compiled extensions into the source directory alongside your pure Python modulesz include-dirs=Iz.list of directories to search for header files)zdefine=DzC preprocessor macros to define)zundef=Uz!C preprocessor macros to undefine)z libraries=lz!external C libraries to link withz library-dirs=Lz.directories to search for external C libraries)zrpath=Rz7directories to search for shared C libraries at runtime)z link-objects=Oz2extra explicit link objects to include in the link)debuggz'compile/link with debugging information)forcefz2forcibly build everything (ignore file timestamps))z compiler=czspecify the compiler type)z parallel=jznumber of parallel build jobs)swig-cppNz)make SWIG create C++ files (default is C))z swig-opts=Nz!list of SWIG command line options)zswig=Nzpath to the SWIG executable)userNz#add user include, library and rpath)rr r"r&r'z help-compilerNzlist available compilerscCsd|_d|_d|_d|_d|_d|_d|_d|_d|_d|_ d|_ d|_ d|_ d|_ d|_d|_d|_d|_d|_d|_d|_dS)Nr) extensions build_lib plat_name build_temprpackage include_dirsdefineundef libraries library_dirsrpath link_objectsr r"compilerswigswig_cpp swig_optsr'parallelselfrrrinitialize_optionsks* zbuild_ext.initialize_optionsc Csddlm}|ddddddd d |jdur|jj|_|jj|_|}|jd d }|j dur7|jj p5g|_ t |j t rE|j t j|_ tjtjkrW|j t jtjd |j | t jj||krq|j | t jj|d|d|jdurg|_|jdurg|_nt |jt r|j t j|_|jdurg|_nt |jt r|j t j|_t jdkr-|jt jtjdtjtjkr|jt jtjd|jrt j|jd|_n t j|jd|_|j t jtt tdd}|r|j||j!dkrd}n|j!dd}t jtjd}|r't j||}|j|tj"dddkrS|j#sM|jt jtjddt$dn|jd|%drm|j#sg|j|%dn|jd|j&r|j& d }d!d"|D|_&|j'r|j' d |_'|j(durg|_(n|j( d#|_(|j)rt jt*d }t jt*d} t j+|r|j |t j+| r|j| |j| t |j,t rz t-|j,|_,WdSt.yt/d$wdS)%Nr) sysconfigbuild)r)r))r+r+)r4r4)r r )r"r")r8r8)r*r*r ) plat_specificincluder0r3ntZlibsZDebugZRelease_homewin32ZPCbuildcygwinlibpythonconfig.Py_ENABLE_SHAREDLIBDIR,cSsg|]}|dfqS)1r).0symbolrrr sz.build_ext.finalize_options.. zparallel should be an integer)0 distutilsr<set_undefined_optionsr, distribution ext_package ext_modulesr(get_python_incr- isinstancestrsplitospathsepsys exec_prefixbase_exec_prefixappendpathjoinextendensure_string_listr0r1r2nameprefixr r+dirnamergetattrr*platform python_buildrget_config_varr.r/r7r'r isdirr8int ValueErrorDistutilsOptionError) r:r<Z py_includeZplat_py_include _sys_homesuffixZnew_libZdefinesZ user_includeZuser_librrrfinalize_optionss                             zbuild_ext.finalize_optionscCsbddlm}|js dS|jr&|d}|j|pg|j |j ||j |j |j|jd|_ t|j tjdkrJ|jtkrJ|j |j|jdurV|j |j|jdurj|jD] \}}|j ||q^|jdur{|jD]}|j |qr|jdur|j |j|j dur|j |j |jdur|j |j|j dur|j !|j |"dS)Nr) new_compiler build_clib)r4verbosedry_runr"r@)#rrsr(rThas_c_librariesget_finalized_commandr0rcZget_library_namesr1r`rtr4rurvr"rr[rer*r Z initializer-Zset_include_dirsr.Z define_macror/Zundefine_macroZ set_librariesZset_library_dirsr2Zset_runtime_library_dirsr3Zset_link_objectsbuild_extensions)r:rsrtrevaluemacrorrrruns@             z build_ext.runc Csht|ts tdt|D]\}}t|trq t|tr"t|dkr&td|\}}td|t|t r:t |s>tdt|t sGtdt||d}dD]}| |}|d urat|||qP| d |_d |vrqtd | d }|rg|_g|_|D],} t| trt| dvstdt| dkr|j| dqt| dkr|j| q|||<q d S)aEnsure that the list of extensions (presumably provided as a command option 'extensions') is valid, i.e. it is a list of Extension objects. We also support the old-style list of 2-tuples, where the tuples are (ext_name, build_info), which are converted to Extension instances here. Raise DistutilsSetupError if the structure is invalid anywhere; just returns otherwise. z:'ext_modules' option must be a list of Extension instanceszMeach element of 'ext_modules' option must be an Extension instance or 2-tuplezvold-style (ext_name, build_info) tuple found in ext_modules for extension '%s' -- please convert to Extension instancezRfirst element of each tuple in 'ext_modules' must be the extension name (a string)zOsecond element of each tuple in 'ext_modules' must be a dictionary (build info)sources)r-r1r0 extra_objectsextra_compile_argsextra_link_argsNr2Zdef_filez9'def_file' element of build info dict no longer supportedmacros)r r}z9'macros' element of build info dict must be 1- or 2-tupler r)rXlistDistutilsSetupError enumeratertuplelenr warnrYextension_name_rematchdictgetsetattrruntime_library_dirs define_macros undef_macrosr`) r:r(rextext_nameZ build_infokeyvalrr{rrrcheck_extensions_listWsd             zbuild_ext.check_extensions_listcCs,||jg}|jD]}||jq |SN)rr(rcr~)r: filenamesrrrrget_source_filess  zbuild_ext.get_source_filescCs2||jg}|jD] }|||jq |Sr)rr(r`get_ext_fullpathre)r:outputsrrrr get_outputss  zbuild_ext.get_outputscCs*||j|jr|dS|dSr)rr(r8_build_extensions_parallel_build_extensions_serialr9rrrrys   zbuild_ext.build_extensionsc sj}jdur t}zddlm}Wn tyd}Ynw|dur*dS||d8fddjD}tj|D]\}} | | Wdn1sYwYqAWddS1sjwYdS)NTr)ThreadPoolExecutor) max_workerscsg|] }j|qSr)submitbuild_extension)rNrexecutorr:rrrPsz8build_ext._build_extensions_parallel..) r8r[ cpu_countconcurrent.futuresr ImportErrorrr(zip_filter_build_errorsresult)r:workersrfuturesrfutrrrrs,      "z$build_ext._build_extensions_parallelc CsD|jD]}|| ||Wdn1swYqdSr)r(rr)r:rrrrrs   z"build_ext._build_extensions_serialc csXzdVWdStttfy+}z|js|d|j|fWYd}~dSd}~ww)Nz"building extension "%s" failed: %s)CCompilerErrorDistutilsError CompileErroroptionalrre)r:rerrrrs zbuild_ext._filter_build_errorsc CsL|j}|dust|ttfstd|jt|}||j}||j}|j s6t ||ds6t d|jdSt d|j|||}|jpGg}|jdd}|jD]}||fqR|jj||j||j|j ||jd}|dd|_|jr|||j|jpg}|jp|j|} |jj|||||j|j ||!||j |j| d dS)Nzjin 'ext_modules' option (extension '%s'), 'sources' must be present and must be a list of source filenamesnewerz$skipping '%s' extension (up-to-date)zbuilding '%s' extension) output_dirrr-r extra_postargsdepends)r0r1rrexport_symbolsr r+Z target_lang)"r~rXrrrresortedrrr"rr r info swig_sourcesrrrr`r4compiler+r-Z_built_objectsrrcrlanguageZdetect_languageZlink_shared_object get_librariesr1rget_export_symbols) r:rr~ext_pathr extra_argsrr/ZobjectsrrrrrsV         zbuild_ext.build_extensioncCs$g}g}i}|jrtd|jsd|jvsd|jvrd}nd}|D](}tj|\}} | dkrE||d||||d||<q"||q"|sO|S|jpU| } | dg} | |j|jrh| d|jsv|jD]} | | qn|D]}||} t d || | | d | |gqx|S) zWalk the list of source files in 'sources', looking for SWIG interface (.i) files. Run SWIG on all that are found, and return a modified 'sources' list with SWIG source files replaced by the generated C (or C++) files. z/--swig-cpp is deprecated - use --swig-opts=-c++z-c++z.cppz.cz.i_wrapz-pythonzswigging %s to %sz-o) r6r rr7r[rasplitextr`r5 find_swigrcrspawn)r:r~ extensionZ new_sourcesrZ swig_targetsZ target_extsourcebaserr5Zswig_cmdotargetrrrr3s>        zbuild_ext.swig_sourcescCsZtjdkrdStjdkr&dD]}tjd|d}tj|r#|SqdStdtj)zReturn the name of the SWIG executable. On Unix, this is just "swig" -- it should be in the PATH. Tries a bit harder on Windows. posixr5r@)z1.3z1.2z1.1z c:\swig%szswig.exez>I don't know how to find (much less run) SWIG on platform '%s')r[rerarbisfileDistutilsPlatformError)r:versfnrrrris   zbuild_ext.find_swigcCs||}|d}||d}|js)tjj|dd|g}tj|j|Sd|dd}|d}tj | |}tj||S)zReturns the path of the filename for a given extension. The file is located in `build_lib` or directly in the package (inplace option). rIrNrbuild_py) get_ext_fullnamerZget_ext_filenamerr[rarbr)rxabspathZget_package_dir)r:rfullnamemodpathfilenamer,r package_dirrrrrs   zbuild_ext.get_ext_fullpathcCs|jdur|S|jd|S)zSReturns the fullname of a given extension name. Adds the `package.` prefixNrI)r,)r:rrrrrs zbuild_ext.get_ext_fullnamecCs.ddlm}|d}|d}tjj||S)zConvert the name of an extension (eg. "foo.bar") into the name of the file from which it will be loaded (eg. "foo/bar.so", or "foo\bar.pyd"). rrkrI EXT_SUFFIX)distutils.sysconfigrkrZr[rarb)r:rrkrZ ext_suffixrrrrs  zbuild_ext.get_ext_filenamecCsz|jdd}z|dWnty&d|dddd}Ynwd|}d |}||jvr:|j||jS) aReturn the list of symbols that a shared extension has to export. This either uses 'ext.export_symbols' or, if it's not provided, "PyInit_" + module_name. Only relevant on Windows, where the .pyd file (DLL) must export the module "PyInit_" function. rIrasciiZU_punycode-__ZPyInit)rerZencodeUnicodeEncodeErrorreplacedecoderr`)r:rrerqZ initfunc_namerrrrs    zbuild_ext.get_export_symbolscCstjdkr/ddlm}t|j|s.d}|jr|d}|tjd?tjd?d@f}|j|gSn@dd l m }d }|d rat td rCd }ntjdkrKd }ndt j vra|ddkrYd }n|ddkrad }|ro|d}|jd|gS|jtS)zReturn the list of libraries to link against when building a shared extension. On most platforms, this is just 'ext.libraries'; on Windows, we add the Python library (eg. python20.dll). rBr) MSVCCompilerz python%d%d_drFrJgetandroidapilevelTrE_PYTHON_HOST_PLATFORMANDROID_API_LEVELMACHDEP LDVERSIONrG)r]riZdistutils._msvccompilerrrXr4r hexversionr0rrkhasattrr[environr pythonlib)r:rrtemplaterrkZlink_libpython ldversionrrrrs6         zbuild_ext.get_libraries) __name__ __module__ __qualname__ descriptionr[r\Zsep_byr user_optionsboolean_optionsr help_optionsr;rrr|rrrryrr contextlibcontextmanagerrrrrrrrrrrrrrr"sp +@N   L6  r)__doc__rr[rer]distutils.corerdistutils.errorsrrrrdistutils.dep_utilrdistutils.extensionrdistutils.utilr rRr r siter rrrrrrrrs(        PKH]9Xpython3.10/site-packages/setuptools/_distutils/command/__pycache__/check.cpython-310.pycnu[o Xai@sdZddlmZddlmZz$ddlmZddlmZddl m Z ddl m Z Gdd d eZ d Z Wn ey=d Z YnwGd d d eZdS)zCdistutils.command.check Implements the Distutils 'check' command. )Command)DistutilsSetupError)Reporter)Parser)frontend)nodesc@s"eZdZ  d ddZddZdS) SilentReporterNrasciireplacec Cs"g|_t||||||||dSN)messagesr__init__)selfsource report_level halt_levelstreamdebugencoding error_handlerr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/check.pyr szSilentReporter.__init__cOs8|j||||ftj|g|R||j|d|S)N)leveltype)r appendrsystem_messageZlevels)rrmessagechildrenkwargsrrrrszSilentReporter.system_message)Nrr r )__name__ __module__ __qualname__r rrrrrrs  rTFc@s\eZdZdZdZgdZgdZddZddZd d Z d d Z d dZ ddZ ddZ dS)checkz6This command checks the meta-data of the package. z"perform some checks on the package))metadatamzVerify meta-data)restructuredtextrzEChecks if long string meta-data syntax are reStructuredText-compliant)strictsz(Will exit with an error if a check fails)r#r%r'cCsd|_d|_d|_d|_dS)z Sets default values for options.rN)r%r#r' _warningsrrrrinitialize_options0s zcheck.initialize_optionscCsdSr rr+rrrfinalize_options7szcheck.finalize_optionscCs|jd7_t||S)z*Counts the number of warnings that occurs.r))r*rwarn)rmsgrrrr.:s z check.warncCsP|jr||jrtr|n|jrtd|jr$|jdkr&tddSdS)zRuns the command.zThe docutils package is needed.rzPlease correct your package.N)r#check_metadatar% HAS_DOCUTILScheck_restructuredtextr'rr*r+rrrrun?s z check.runcCs|jj}g}dD]}t||rt||s||q|r&|dd||jr5|js3|ddSdS|j rD|j sB|ddSdS|ddS)a Ensures that all required elements of meta-data are supplied. Required fields: name, version, URL Recommended fields: (author and author_email) or (maintainer and maintainer_email)) Warns if any are missing. )nameversionurlzmissing required meta-data: %sz, zNmissing meta-data: if 'author' supplied, 'author_email' should be supplied toozVmissing meta-data: if 'maintainer' supplied, 'maintainer_email' should be supplied toozkmissing meta-data: either (author and author_email) or (maintainer and maintainer_email) should be suppliedN) distributionr#hasattrgetattrrr.joinauthor author_email maintainermaintainer_email)rr#missingattrrrrr0Os"  zcheck.check_metadatacCsX|j}||D]}|dd}|dur|d}nd|d|f}||q dS)z4Checks if the long string fields are reST-compliant.lineNr)z %s (line %s))r7get_long_description_check_rst_datagetr.)rdatawarningrBrrrr2ps   zcheck.check_restructuredtextc Cs|jjpd}t}tjtfd}d|_d|_d|_t ||j |j |j |j |j|jd}tj|||d}||dz |||W|jStyd}z|jdd|d ifWYd}~|jSd}~ww) z8Returns warnings when the provided data doesn't compile.zsetup.py) componentsN)rrrr)rrAz!Could not finish the parsing: %s.)r7 script_namerr OptionParserget_default_valuesZ tab_widthZpep_referencesZrfc_referencesrrrZwarning_streamrZerror_encodingZerror_encoding_error_handlerrdocumentZ note_sourceparseAttributeErrorr r)rrF source_pathparsersettingsreporterrNerrrrD{s4  zcheck._check_rst_dataN)rr r!__doc__ description user_optionsboolean_optionsr,r-r.r3r0r2rDrrrrr"#s! r"N)rVdistutils.corerdistutils.errorsrZdocutils.utilsrZdocutils.parsers.rstrZdocutilsrrrr1 Exceptionr"rrrrs       PKH]XB&&[python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_py.cpython-310.pycnu[o Xaio@@sddZddlZddlZddlZddlZddlmZddlTddl m Z ddl m Z GdddeZ dS) zHdistutils.command.build_py Implements the Distutils 'build_py' command.N)Command)*) convert_path)logc@seZdZdZgdZddgZddiZddZdd Zd d Z d d Z ddZ ddZ ddZ ddZddZddZddZddZddZd d!Zd.d#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-S)/build_pyz5"build" pure Python modules (copy to build directory)))z build-lib=dzdirectory to "build" (copy) to)compileczcompile .py to .pyc) no-compileNz!don't compile .py files [default])z optimize=Ozlalso compile with optimization: -O1 for "python -O", -O2 for "python -OO", and -O0 to disable [default: -O0])forcefz2forcibly build everything (ignore file timestamps)rr r cCs4d|_d|_d|_d|_d|_d|_d|_d|_dS)Nr) build_lib py_modulespackage package_data package_dirroptimizer selfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/build_py.pyinitialize_options s zbuild_py.initialize_optionsc Cs|ddd|jj|_|jj|_|jj|_i|_|jjr/|jjD] \}}t||j|<q#||_ t |j t s`zt |j |_ d|j krMdksPJJWdSt tfy_tdwdS)Nbuild)rr)r r rzoptimize must be 0, 1, or 2)set_undefined_options distributionpackagesrrritemsrget_data_files data_files isinstancerint ValueErrorAssertionErrorDistutilsOptionError)rnamepathrrrfinalize_options*s(      $zbuild_py.finalize_optionscCs:|jr||jr||||jdddS)Nr)include_bytecode)r build_modulesrbuild_packagesbuild_package_data byte_compile get_outputsrrrrrunCs z build_py.runcsg}|js|S|jD]4}||}tjj|jg|d}d|r(t|dfdd|||D}| ||||fq |S)z?Generate list of '(package,src_dir,build_dir,filenames)' tuples.rcsg|]}|dqSNr).0fileplenrr ss z+build_py.get_data_files..) rget_package_dirosr'joinrsplitlenfind_data_filesappend)rdatarsrc_dir build_dir filenamesrr5rras     zbuild_py.get_data_filescsd|jdg|j|g}g|D]}ttjt|t|}fdd|DqS)z6Return filenames for package's data files in 'src_dir'cs$g|]}|vrtj|r|qSr)r9r'isfile)r3fnfilesrrr7s  z,build_py.find_data_files..) rgetglobr9r'r:escaperextend)rrr@ZglobspatternfilelistrrFrr=ys  zbuild_py.find_data_filescCs`d}|jD](\}}}}|D]}tj||}|tj||jtj|||ddq qdS)z$Copy data files into build directoryNF preserve_mode)r r9r'r:mkpathdirname copy_file)rZlastdirrr@rArBfilenametargetrrrr,szbuild_py.build_package_datacCs|d}|js|rtjj|SdSg}|rCz |jd|}Wnty4|d|d|d=Yn w|d|tjj|S|s|jd}|durS|d||r[tjj|SdS)zReturn the directory, relative to the top of the source distribution, where package 'package' should be found (at least according to the 'package_dir' option, if any).r0rCrN)r;rr9r'r:KeyErrorinsertrH)rrr'tailZpdirrrrr8s,         zbuild_py.get_package_dircCsj|dkrtj|std|tj|std||r3tj|d}tj|r-|Std|dS)NrCz%package directory '%s' does not existz>supposed package directory '%s' exists, but is not a directoryz __init__.pyz8package init file '%s' not found (or not a regular file)) r9r'existsDistutilsFileErrorisdirr:rDrwarn)rrrinit_pyrrr check_packages&   zbuild_py.check_packagecCs"tj|std||dSdS)Nz!file %s (for module %s) not foundFT)r9r'rDrr\)rmodule module_filerrr check_modules zbuild_py.check_modulec Cs|||ttjt|d}g}tj|jj}|D](}tj|}||kr@tj tj |d}| |||fq| d|q|S)Nz*.pyrz excluding %s) r^rIr9r'r:rJabspathr script_namesplitextbasenamer> debug_print) rrrZ module_filesmodulesZ setup_scriptr Zabs_fr_rrrfind_package_moduless  zbuild_py.find_package_modulesc Csi}g}|jD]]}|d}d|dd}|d}z||\}}Wnty3||}d}Ynw|sL|||} |df||<| rL||d| ftj||d} | || s\q|||| fq|S)aFinds individually-specified Python modules, ie. those listed by module name in 'self.py_modules'. Returns a list of tuples (package, module_base, filename): 'package' is a tuple of the path through package-space to the module; 'module_base' is the bare (no packages, no dots) module name, and 'filename' is the path to the ".py" file (relative to the distribution root) that implements the module. r0rrUr1__init__.py) rr;r:rVr8r^r>r9r'ra) rrrgr_r'rZ module_basercheckedr]r`rrr find_moduless,       zbuild_py.find_modulescCsNg}|jr |||jr%|jD]}||}|||}||q|S)a4Compute the list of all modules that will be built, whether they are specified one-module-at-a-time ('self.py_modules') or by whole packages ('self.packages'). Return a list of tuples (package, module, module_file), just like 'find_modules()' and 'find_package_modules()' do.)rrKrlrr8rh)rrgrrmrrrfind_all_moduless    zbuild_py.find_all_modulescCsdd|DS)NcSsg|]}|dqS)rUr)r3r_rrrr7-sz-build_py.get_source_files..)rnrrrrget_source_files,szbuild_py.get_source_filescCs$|gt||dg}tjj|S)Nrj)listr9r'r:)rrArr_Z outfile_pathrrrget_module_outfile/s zbuild_py.get_module_outfiler1cCs|}g}|D]8\}}}|d}||j||}|||r@|jr/|tjj|dd|j dkr@|tjj||j dq|dd|j D7}|S)Nr0rC) optimizationrcSs,g|]\}}}}|D] }tj||q qSr)r9r'r:)r3rr@rArBrSrrrr7Bs  z(build_py.get_outputs..) rnr;rqrr>r importlibutilcache_from_sourcerr )rr)rgoutputsrr_r`rSrrrr.3s(     zbuild_py.get_outputscCsbt|tr |d}n t|ttfstd||j||}tj |}| ||j ||ddS)Nr0z:'package' must be a string (dot-separated), list, or tuplerrN) r!strr;rptuple TypeErrorrqrr9r'rQrPrR)rr_r`routfiledirrrr build_moduleJs    zbuild_py.build_modulecCs*|}|D] \}}}||||qdSr2)rlr|)rrgrr_r`rrrr*Yszbuild_py.build_modulescCsP|jD]"}||}|||}|D]\}}}||ksJ||||qqdSr2)rr8rhr|)rrrrgZpackage_r_r`rrrr+bs   zbuild_py.build_packagescCstjr |ddSddlm}|j}|dtjkr|tj}|jr-||d|j ||j d|j dkr@|||j |j ||j ddSdS)Nz%byte-compiling is disabled, skipping.r)r-rU)rr prefixdry_run) sysdont_write_bytecoder\distutils.utilr-rr9seprr r~r)rrGr-r}rrrr-vs        zbuild_py.byte_compileN)r1)__name__ __module__ __qualname__ description user_optionsboolean_options negative_optrr(r/rr=r,r8r^rarhrlrnrorqr.r|r*r+r-rrrrrs0    '4  r)__doc__r9importlib.utilrsrrIdistutils.corerdistutils.errorsrr distutilsrrrrrrs   PKH]s\7070\python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-310.pycnu[o Xai!T@stdZddlZddlZddlZddlmZddlmZddlm Z ddl Tddl m Z ddl mZGd d d eZdS) zwdistutils.command.bdist_rpm Implements the Distutils 'bdist_rpm' command (create RPM source and binary distributions).N)Command)DEBUG) write_file)*)get_python_version)logc@sdeZdZdZgdZgdZddddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ dS) bdist_rpmzcreate an RPM distribution)))z bdist-base=Nz/base directory for creating built distributions)z rpm-base=Nzdbase directory for creating RPMs (defaults to "rpm" under --bdist-base; must be specified for RPM 2))z dist-dir=dzDdirectory to put final RPM files in (and .spec files if --spec-only))zpython=NzMpath to Python interpreter to hard-code in the .spec file (default: "python"))z fix-pythonNzLhard-code the exact path to the current Python interpreter in the .spec file)z spec-onlyNzonly regenerate spec file)z source-onlyNzonly generate source RPM)z binary-onlyNzonly generate binary RPM)z use-bzip2Nz7use bzip2 instead of gzip to create source distribution)zdistribution-name=Nzgname of the (Linux) distribution to which this RPM applies (*not* the name of the module distribution!))zgroup=Nz9package classification [default: "Development/Libraries"])zrelease=NzRPM release number)zserial=NzRPM serial number)zvendor=NzaRPM "vendor" (eg. "Joe Blow ") [default: maintainer or author from setup script])z packager=NzBRPM packager (eg. "Jane Doe ") [default: vendor])z doc-files=Nz6list of documentation files (space or comma-separated))z changelog=Nz RPM changelog)zicon=Nzname of icon file)z provides=Nz%capabilities provided by this package)z requires=Nz%capabilities required by this package)z conflicts=Nz-capabilities which conflict with this package)zbuild-requires=Nz+capabilities required to build this package)z obsoletes=Nz*capabilities made obsolete by this package) no-autoreqNz+do not automatically calculate dependencies) keep-tempkz"don't clean up RPM build directory) no-keep-tempNz&clean up RPM build directory [default])use-rpm-opt-flagsNz8compile with RPM_OPT_FLAGS when building from source RPM)no-rpm-opt-flagsNz&do not pass any RPM CFLAGS to compiler) rpm3-modeNz"RPM 3 compatibility mode (default)) rpm2-modeNzRPM 2 compatibility mode)z prep-script=Nz3Specify a script for the PREP phase of RPM building)z build-script=Nz4Specify a script for the BUILD phase of RPM building)z pre-install=Nz:Specify a script for the pre-INSTALL phase of RPM building)zinstall-script=Nz6Specify a script for the INSTALL phase of RPM building)z post-install=Nz;Specify a script for the post-INSTALL phase of RPM building)zpre-uninstall=Nzfinalize_optionss6         zbdist_rpm.finalize_optionscCsT|dd|dd|j|jf|d|dt|jtrr#r$)ZREADMEz README.txtr 1r!rr%r&r'r(r)r*r+r,r-r.r/r1r2r3r4r5r:) ensure_stringrL get_contactget_contact_emailensure_string_list isinstancer$listrErFexistsappend_format_changelogr%ensure_filename)r<Zreadmer=r=r>rNsD                         zbdist_rpm.finalize_package_datacCstrtdtd|jtd|jtd|jtd|j|jr*|j}||ni}dD]}t j |j |||<|||q.|d}t j |d|j }|t||fd ||jrddS|j jdd}|d }|jryd g|_nd g|_|d ||j _|d }|d}||||jrt j |jr||j|ntd|jtddg} |jr| dn|j r| dn| d| !dd|j"g|j#r| !ddt j $|j g|j%s| d|j&r| d| |d} | d} d| d} d| | |f} t '| }zCg}d} |(}|s$n!|)*}t+|d ks3J||d!|durC|d }q|,}|rTt-d"t.| W|,n|,w|/| |j0s|j 1rrt2}nd#}|j st j |d$|}t j |sJ|3||jt j |j|}|j jd%||f|js|D]4}t j |d&|}t j |r|3||jt j |jt j 4|}|j jd%||fqdSdSdS)'Nzbefore _get_package_data():zvendor =z packager =z doc_files =z changelog =)SOURCESSPECSBUILDRPMSSRPMSr\z%s.specz writing '%s'sdistbztargztarrr[zicon file '%s' does not existz building RPMsZrpmbuildz-bsz-bbz-baz--definez __python %sz _topdir %sz--cleanz--quietz%{name}-%{version}-%{release}z.src.rpmz%{arch}/z .%{arch}.rpmz%rpm -q --qf '%s %s\n' --specfile '%s'TrzFailed to execute: %sanyr_rr^)5rprintr"r#r$r%rrmkpathrErFrGrrLget_nameexecuter_make_spec_file dist_filesreinitialize_commandrformats run_commandZget_archive_files copy_filer&rWDistutilsFileErrorrinforrXrextendrr8abspathr6rpopenreadlinestripsplitlencloseDistutilsExecErrorreprspawndry_runrMr move_filebasename)r<Zspec_dirZrpm_dirr Z spec_pathZsaved_dist_filesr`source source_dirZrpm_cmdZ nvr_stringZsrc_rpmZ non_src_rpmZq_cmdoutZ binary_rpmsZ source_rpmlinelstatusZ pyversionZsrpmfilenamerAr=r=r>runs                           z bdist_rpm.runcCstj|jtj|S)N)rErFrGrr~)r<rFr=r=r> _dist_pathszbdist_rpm._dist_pathc CsJd|jd|jddd|jd|jdddd|jg}td }d d d | D}d }d}|||}||krT| d| d|d | gd|j rd| dn| d| d|j d|jddg|js|js| dn| d|jdD](}t||}t|tr| d|d|fq|dur| d||fq|jdkr| d|j|jr| d |j|jr| d!d|j|jr| d"tj|j|jr| d#| dd$|jgd%|jtjtj d&f}d'|} |j!r!d(| } d)|} d*d+d,| fd-d.| fd/d0d1d2d3d4g } | D]C\} } }t|| }|sH|rz| dd5| g|rut"|}| |#$d Wdn 1snwYq8| |q8| gd6|j%r| d7d|j%|j&r| dd8g| |j&|S)9ziGenerate the text of an RPM spec file and return it as a list of strings (one per line). z %define name z%define version -_z%define unmangled_version z%define release z Summary: zrpm --eval %{__os_install_post} cSsg|]}d|qS)z %s \)ru).0rr=r=r> sz-bdist_rpm._make_spec_file..zbrp-python-bytecompile \ z%brp-python-bytecompile %{__python} \ z2# Workaround for http://bugs.python.org/issue14443z%define __os_install_post )z Name: %{name}zVersion: %{version}zRelease: %{release}z-Source0: %{name}-%{unmangled_version}.tar.bz2z,Source0: %{name}-%{unmangled_version}.tar.gzz License: zGroup: z>BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildrootzPrefix: %{_prefix}zBuildArch: noarchz BuildArch: %s)ZVendorZPackagerProvidesRequiresZ Conflicts Obsoletesz%s: %s NUNKNOWNzUrl: zDistribution: zBuildRequires: zIcon: z AutoReq: 0z %descriptionz%s %srz%s buildzenv CFLAGS="$RPM_OPT_FLAGS" z>%s install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES)r0r'z&%setup -n %{name}-%{unmangled_version}buildr(installr))cleanr*zrm -rf $RPM_BUILD_ROOT)Z verifyscriptr+N)prer,N)postr-N)Zpreunr.N)Zpostunr/N%)rz%files -f INSTALLED_FILESz%defattr(-,root,root)z%doc z %changelog)'rLrg get_versionreplacer get_description subprocess getoutputrG splitlinesrXrqr get_licenserr:rMgetattrlowerrUrVget_urlrr4r&rErFr~r9get_long_descriptionrrHargvr7openreadrvr$r%)r<Z spec_fileZ vendor_hookproblemfixedZ fixed_hookfieldvalZdef_setup_callZ def_buildZ install_cmdZscript_optionsZrpm_optattrdefaultfr=r=r>ris                    zbdist_rpm._make_spec_filecCs||s|Sg}|dD]'}|}|ddkr!|d|gq |ddkr-||q |d|q |ds<|d=|S)zKFormat the changelog correctly and convert it to a list of strings rrrrrz )rurvrqrX)r<r%Z new_changelogrr=r=r>rY0s   zbdist_rpm._format_changelogN)__name__ __module__ __qualname__ description user_optionsboolean_options negative_optr?rOrNrrrirYr=r=r=r>rs"m-- *r)__doc__rrHrEdistutils.corerdistutils.debugrdistutils.file_utilrdistutils.errorsdistutils.sysconfigr distutilsrrr=r=r=r>s     PKH]NU6U6Zpython3.10/site-packages/setuptools/_distutils/command/__pycache__/install.cpython-310.pycnu[o Xaik @s8dZddlZddlZddlmZddlmZddlmZddl m Z ddl m Z ddl mZdd lmZmZmZdd lmZdd l mZdd lmZdd lmZdZddddddZddddddddddddedddddddddddddZerdddd d!ded"<ddd#d$d!ded%<dZGd&d'd'eZdS)(zFdistutils.command.install Implements the Distutils 'install' command.N)log)Command)DEBUG)get_config_vars)DistutilsPlatformError) write_file) convert_path subst_vars change_root) get_platform)DistutilsOptionError) USER_BASE) USER_SITETz$base/Lib/site-packagesz$base/Include/$dist_namez $base/Scriptsz$base)purelibplatlibheadersscriptsdataz/$base/lib/python$py_version_short/site-packagesz;$platbase/$platlibdir/python$py_version_short/site-packagesz9$base/include/python$py_version_short$abiflags/$dist_namez $base/binz$base/lib/pythonz$base/$platlibdir/pythonz$base/include/python/$dist_namez$base/site-packagesz$base/include/$dist_name) unix_prefix unix_homentpypypypy_ntz $usersitez4$userbase/Python$py_version_nodot/Include/$dist_namez)$userbase/Python$py_version_nodot/Scriptsz $userbasent_userz=$userbase/include/python$py_version_short$abiflags/$dist_namez $userbase/bin unix_userc@seZdZdZgdZgdZeredddefedddiZ d d Z d d Z d dZ ddZ ddZddZddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3efd4efd5efd6efd7d8d9fgZdS):installz'install everything from build directory))zprefix=Nzinstallation prefix)z exec-prefix=Nz.(Unix only) prefix for platform-specific files)zhome=Nz+(Unix only) home directory to install under)z install-base=Nz;base installation directory (instead of --prefix or --home))zinstall-platbase=Nz\base installation directory for platform-specific files (instead of --exec-prefix or --home))zroot=Nzfinalize_optionss                        zinstall.finalize_optionscCstsdSddlm}t|d|jD]9}|d}|ddkr&|dd}||jvr<|j|}||}t|| }n ||}t||}td||qdS)zDumps the list of user options.Nr) longopt_xlate:=z %s: %s) rdistutils.fancy_getoptrurdebug user_options negative_opt translaterd)r<msgruoptopt_namevalr=r=r>rXs          zinstall.dump_dirscCs$|jdus |jdur.|jdur|jdur|jdus(|jdus(|jdus(|jdur,tddS|j rH|j dur:t d|j |_|_| ddS|j dur[|j |_|_| ddS|jdurz|jduritdtjtj|_tjtj|_n |jdur|j|_|j|_|j|_| ddS)z&Finalizes options for posix platforms.NzPinstall-base or install-platbase supplied, but installation scheme is incomplete$User base directory is not specifiedrrz*must not supply exec-prefix without prefixr)r(r)r.r+r,r-r/r0r r#r1r select_schemer'r%r&rUronormpathr[r;r=r=r>rYsB           zinstall.finalize_unixcCs|jr|jdur td|j|_|_|tjddS|jdur0|j|_|_|ddS|j dur=tj t j |_ |j |_|_z |tjWdSt y[tdtjw)z)Finalizes options for non-posix platformsNr_userrz)I don't know how to install stuff on '%s')r#r1rr(r)rrUrVr'r%rorr[KeyErrorr;r=r=r>rZs(    zinstall.finalize_othercCsnttdrtjdkr|dstjdkrd}nd}t|}tD]}d|}t||dur4t ||||qdS) z=Sets the install directories by applying the install schemes.pypy_version_info))r_homerrrinstall_N) hasattrr[rcendswithrUrVINSTALL_SCHEMES SCHEME_KEYSrdsetattr)r<rVschemekeyattrnamer=r=r>rs   zinstall.select_schemecCsX|D]'}t||}|dur)tjdkstjdkrtj|}t||j}t|||qdS)Nr@r)rdrUrVro expanduserr rer)r<attrsattrrr=r=r> _expand_attrss    zinstall._expand_attrscC|gddS)zNCalls `os.path.expanduser` on install_base, install_platbase and root.)r(r)r*Nrr;r=r=r>rgszinstall.expand_basedirscCr)z+Calls `os.path.expanduser` on install dirs.)r+r,r.r-r/r0Nrr;r=r=r>riszinstall.expand_dirscGs,|D]}d|}t||tt||qdS)z!Call `convert_path` over `names`.rN)rrrdr<namesrVrr=r=r>rlszinstall.convert_pathscCs|jdur |jj|_|jdurFtdt|jtr!|jd|_t|jdkr0|jd}}nt|jdkr=|j\}}ntdt |}nd}d}||_ ||_ dS) z4Set `path_file` and `extra_dirs` using `extra_path`.NzIDistribution option extra_path is deprecated. See issue27919 for details.,r$rrBzY'extra_path' option must be a list, tuple, or comma-separated string with 1 or 2 elementsrA) r4r_rrW isinstancestrr]lenr r path_filerq)r<rrqr=r=r>rms(       zinstall.handle_extra_pathc Gs0|D]}d|}t||t|jt||qdS)z:Change the install directories pointed by name using root.rN)rr r*rdrr=r=r>rr!szinstall.change_rootscCsb|jsdSttjd}|jD]\}}||r.tj|s.| d|t |dqdS)zCreate directories under ~.N~zos.makedirs('%s', 0o700)i) r#rrUrorreitems startswithisdir debug_printmakedirs)r<r'rVror=r=r>rj's zinstall.create_home_pathcCs&|js|d|jdj}|jr|tkrtd|D]}||q|j r.| |j r]| }|j rPt|j }tt|D] }|||d||<qC|t|j |fd|j ttjjtj}ttjj|}tjtj|j}|jr|j r|js||vrtd|jdSdSdSdS)zRuns the command.rTz"Can't install when cross-compilingNz'writing list of installed files to '%s'zmodules installed to '%s', which is not in Python's module search path (sys.path) -- you'll have to change the search path yourself)r6 run_commandr_get_command_obj plat_namer7r rget_sub_commandsrcreate_path_filer: get_outputsr*rrangeexecutermaprUrorr[normcaser.r5rrz)r< build_platcmd_nameoutputsroot_lencountersys_pathr.r=r=r>run3sH    z install.runcCsLtj|j|jd}|jr|t||jgfd|dS| d|dS)zCreates the .pth file.pthz creating %szpath file '%s' not createdN) rUrorprnrr5rrrqrW)r<filenamer=r=r>r_s  zinstall.create_path_filecCshg}|D]}||}|D] }||vr||qq|jr2|jr2|tj|j |jd|S)z.Assembles the outputs of all the sub-commands.r) rget_finalized_commandrappendrr5rUrorprn)r<rrcmdrr=r=r>rms     zinstall.get_outputscCs.g}|D]}||}||q|S)z*Returns the inputs of all the sub-commands)rrextend get_inputs)r<inputsrrr=r=r>r~s   zinstall.get_inputscCs|jp |jS)zSReturns true if the current distribution has any Python modules to install.)r_has_pure_modulesrkr;r=r=r>has_libs zinstall.has_libcC |jS)zLReturns true if the current distribution has any headers to install.)r_ has_headersr;r=r=r>r zinstall.has_headerscCr)zMReturns true if the current distribution has any scripts to. install.)r_ has_scriptsr;r=r=r>rrzinstall.has_scriptscCr)zJReturns true if the current distribution has any data to. install.)r_has_data_filesr;r=r=r>has_datarzinstall.has_datar.r-r/r0install_egg_infocCsdS)NTr=r;r=r=r>szinstall.) __name__ __module__ __qualname__ descriptionr{boolean_optionsrfrrr|r?rtrXrYrZrrrgrirlrmrrrjrrrrrrrr sub_commandsr=r=r=r>rWsL; N( " ,  r)__doc__r[rU distutilsrdistutils.corerdistutils.debugrdistutils.sysconfigrdistutils.errorsrdistutils.file_utilrdistutils.utilrr r r r siter rrfZWINDOWS_SCHEMErrrr=r=r=r>s|           !    PKH]}G G cpython3.10/site-packages/setuptools/_distutils/command/__pycache__/install_egg_info.cpython-310.pycnu[o Xai+ @sddZddlmZddlmZmZddlZddlZddlZGdddeZ ddZ d d Z d d Z dS) zdistutils.command.install_egg_info Implements the Distutils 'install_egg_info' command, for installing a package's PKG-INFO metadata.)Command)logdir_utilNc@s:eZdZdZdZdgZddZddZdd Zd d Z d S) install_egg_infoz)Install an .egg-info file for the packagez8Install package's PKG-INFO metadata as an .egg-info file)z install-dir=dzdirectory to install tocCs d|_dSN) install_dirselfr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/install_egg_info.pyinitialize_optionss z#install_egg_info.initialize_optionscCsd|dddtt|jtt|jgtjddR}t j |j ||_ |j g|_dS)N install_lib)rrz%s-%s-py%d.%d.egg-info)set_undefined_options to_filename safe_name distributionget_name safe_version get_versionsys version_infoospathjoinrtargetoutputs)r basenamer r r finalize_optionss  z!install_egg_info.finalize_optionscCs|j}tj|rtj|stj||jdn'tj|r+| tj |jfd|ntj|j s?| tj |j fd|j t d||jsit|ddd}|jj|WddS1sbwYdSdS)N)dry_runz Removing z Creating z Writing %swzUTF-8)encoding)rrrisdirislinkr remove_treer existsexecuteunlinkrmakedirsrinfoopenrmetadatawrite_pkg_file)r rfr r r run s  "zinstall_egg_info.runcCs|jSr)rr r r r get_outputs.szinstall_egg_info.get_outputsN) __name__ __module__ __qualname____doc__ description user_optionsr rr/r0r r r r r s rcCstdd|S)zConvert an arbitrary string to a standard distribution name Any runs of non-alphanumeric/. characters are replaced with a single '-'. [^A-Za-z0-9.]+-)resubnamer r r r6srcCs|dd}tdd|S)zConvert an arbitrary string to a standard version string Spaces become dots, and all other non-alphanumeric characters become dashes, with runs of multiple dashes condensed to a single dash.  .r7r8)replacer9r:)versionr r r r>s rcCs |ddS)z|Convert a project or version name to its filename-escaped form Any '-' characters are currently replaced with '_'. r8_)r?r;r r r rHs r) r4 distutils.cmdr distutilsrrrrr9rrrrr r r r s + PKH]hV==]python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_clib.cpython-310.pycnu[o XaiV@sTdZddlZddlmZddlTddlmZddlmZddZ Gd d d eZ dS) zdistutils.command.build_clib Implements the Distutils 'build_clib' command, to build a C/C++ library that is included in the module distribution and needed by an extension module.N)Command)*)customize_compiler)logcCsddlm}|dS)Nrshow_compilers)distutils.ccompilerrrr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/build_clib.pyrs  rc@sfeZdZdZgdZddgZdddefgZdd Zd d Z d d Z ddZ ddZ ddZ ddZdS) build_clibz/build C/C++ libraries used by Python extensions))z build-clib=bz%directory to build C/C++ libraries to)z build-temp=tz,directory to put temporary build by-products)debuggz"compile with debugging information)forcefz2forcibly build everything (ignore file timestamps))z compiler=czspecify the compiler typerrz help-compilerNzlist available compilerscCs:d|_d|_d|_d|_d|_d|_d|_d|_d|_dS)Nr) r build_temp libraries include_dirsdefineundefrrcompilerselfr r r initialize_options4s zbuild_clib.initialize_optionscCsl|dddddd|jj|_|jr||j|jdur$|jjp"g|_t|jtr4|jtj |_dSdS)Nbuild)rr )rr)rr)rr)rr) set_undefined_options distributionrcheck_library_listr isinstancestrsplitospathseprr r r finalize_optionsDs    zbuild_clib.finalize_optionscCs|jsdSddlm}||j|j|jd|_t|j|jdur'|j|j|j dur;|j D] \}}|j ||q/|j durL|j D]}|j |qC| |jdS)Nr) new_compiler)rdry_runr)rrr&rr'rrrZset_include_dirsrZ define_macrorZundefine_macrobuild_libraries)rr&namevalueZmacror r r run^s"      zbuild_clib.runcCst|ts td|D]=}t|tst|dkrtd|\}}t|ts)tdd|vs7tjdkr?tj|vr?td|dt|tsHtdq d S) a`Ensure that the list of libraries is valid. `library` is presumably provided as a command option 'libraries'. This method checks that it is a list of 2-tuples, where the tuples are (library_name, build_info_dict). Raise DistutilsSetupError if the structure is invalid anywhere; just returns otherwise. z+'libraries' option must be a list of tuplesz*each element of 'libraries' must a 2-tuplezNfirst element of each tuple in 'libraries' must be a string (the library name)/z;bad library name '%s': may not contain directory separatorsrzMsecond element of each tuple in 'libraries' must be a dictionary (build info)N) r listDistutilsSetupErrortuplelenr!r#sepdict)rrlibr) build_infor r r rvs0   zbuild_clib.check_library_listcCs,|jsdSg}|jD] \}}||q |S)N)rappend)rZ lib_nameslib_namer5r r r get_library_namess  zbuild_clib.get_library_namescCsZ||jg}|jD]\}}|d}|dust|ttfs%td|||q |S)Nsourcesfin 'libraries' option (library '%s'), 'sources' must be present and must be a list of source filenames)rrgetr r.r0r/extend)r filenamesr7r5r9r r r get_source_filess   zbuild_clib.get_source_filescCs|D]G\}}|d}|dust|ttfstd|t|}td||d}|d}|jj||j |||j d}|jj |||j |j dqdS)Nr9r:zbuilding '%s' librarymacrosr) output_dirr?rr)r@r) r;r r.r0r/rinforcompilerrZcreate_static_libr )rrr7r5r9r?rZobjectsr r r r(s.      zbuild_clib.build_libraries)__name__ __module__ __qualname__ description user_optionsboolean_optionsr help_optionsrr%r+rr8r>r(r r r r r s $ r ) __doc__r#distutils.corerdistutils.errorsdistutils.sysconfigr distutilsrrr r r r r s   PKH]Z~`python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_scripts.cpython-310.pycnu[o XaiK@sdZddlZddlZddlmZddlmZddlmZddl m Z ddl m Z ddlm Z ddlZed ZGd d d eZdS) zRdistutils.command.build_scripts Implements the Distutils 'build_scripts' command.N)ST_MODE) sysconfig)Command)newer) convert_path)logs^#!.*python[0-9.]*([ ].*)?$c@sFeZdZdZgdZdgZddZddZdd Zd d Z d d Z dS) build_scriptsz("build" scripts (copy and fixup #! line)))z build-dir=dzdirectory to "build" (copy) to)forcefz1forcibly build everything (ignore file timestamps)z executable=ez*specify final destination interpreter pathr cCs"d|_d|_d|_d|_d|_dSN) build_dirscriptsr executableoutfilesselfr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/build_scripts.pyinitialize_optionss  z build_scripts.initialize_optionscCs|dddd|jj|_dS)Nbuild)rr)r r )rr)set_undefined_options distributionrrrrrfinalize_options%s zbuild_scripts.finalize_optionscCs|jSr )rrrrrget_source_files,szbuild_scripts.get_source_filescCs|jsdS|dSr )r copy_scriptsrrrrrun/s zbuild_scripts.runc Cs||jg}g}|jD]}d}t|}tj|jtj|}|||j s6t ||s6t d|q zt |d}WntyL|jsHd}Yn,wt|j\}}|d|} | sh|d|q t| } | rxd}| dpwd } |r t d ||j|||jstjs|j} ntjtd d td tdf} t| } d| | d} z| dWntyt d!| wz| |Wntyt d!| |wt |d}|"| |#|$Wdn1swY|r |%q |r|%|||&||q tj'dkrW|D]1}|jr3t d|q%t(|t)d@}|dBd@}||krUt d|||t*||q%||fS)a"Copy each script listed in 'self.scripts'; if it's marked as a Python script in the Unix way (first line matches 'first_line_re', ie. starts with "\#!" and contains "python"), then adjust the first line to refer to the current Python interpreter as we copy. Fznot copying %s (up-to-date)rbNrz%s is an empty file (skipping)Tzcopying and adjusting %s -> %sBINDIRz python%s%sVERSIONEXEs#! zutf-8z.The shebang ({!r}) is not decodable from utf-8zAThe shebang ({!r}) is not decodable from the script encoding ({})wbposixzchanging mode of %siimz!changing mode of %s from %o to %o)+mkpathrrrospathjoinbasenameappendr rrdebugopenOSErrordry_runtokenizedetect_encodingreadlineseekwarn first_line_rematchgroupinfor python_buildrget_config_varfsencodedecodeUnicodeDecodeError ValueErrorformatwrite writelines readlinesclose copy_filenamestatrchmod)rrZ updated_filesscriptadjustoutfiler encodinglines first_liner7 post_interprshebangoutffileZoldmodeZnewmoderrrr5s                   zbuild_scripts.copy_scriptsN) __name__ __module__ __qualname__ description user_optionsboolean_optionsrrrrrrrrrrs r)__doc__r(rerGr distutilsrdistutils.corerdistutils.dep_utilrdistutils.utilrrr1compiler6rrrrrs       PKH]!u?M?M\python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_msi.cpython-310.pycnu[o Xai@sdZddlZddlZddlZddlmZddlmZddlm Z ddl m Z ddl m Z ddlmZdd lmZddlZdd lmZmZmZdd lmZmZmZmZGd d d eZGdddeZdS)z# Implements the bdist_msi command. N)Command) remove_tree)get_python_version) StrictVersion)DistutilsOptionError) get_platform)log)schemasequencetext) DirectoryFeatureDialogadd_datac@sFeZdZdZddZddZddd Zdd d ZdddZddZ dS)PyDialogzDialog class with a fixed layout: controls at the top, then a ruler, then a list of buttons: back, next, cancel. Optionally a bitmap at the left.cOs@tj|g|R|jd}d|d}|dd||jddS)zbDialog(database, name, x, y, w, h, attributes, title, first, default, cancel, bitmap=true)$iHZ BottomLinerN)r__init__hlinew)selfargskwZrulerZbmwidthr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/bdist_msi.pyrs  zPyDialog.__init__c Cs|ddddddd|dS) z,Set the title text of the dialog at the top.Title @<z{\VerdanaBold10}%sN)r )rtitlerrrr"%szPyDialog.titleBackc C,|rd}nd}||d|jddd|||S)zAdd a back button with a given title, the tab-next button, its name in the Control table, possibly initially disabled. Return the button, so that events can be associatedr$8 pushbuttonrrr"nextnameactiveflagsrrrback,z PyDialog.backCancelc Cr%)zAdd a cancel button with a given title, the tab-next button, its name in the Control table, possibly initially disabled. Return the button, so that events can be associatedr&r$i0r(r)r*r+r-rrrcancel7r3zPyDialog.cancelNextc Cr%)zAdd a Next button with a given title, the tab-next button, its name in the Control table, possibly initially disabled. Return the button, so that events can be associatedr&r$r(r)r*r+r-rrrr.Br3z PyDialog.nextc Cs,||t|j|d|jdddd||S)zAdd a button with a given title, the tab-next button, its name in the Control table, giving its x position; the y-position is aligned with the other buttons. Return the button, so that events can be associatedr(r)r*r&)r,intrr)rr/r"r.ZxposrrrxbuttonMs,zPyDialog.xbuttonN)r#r$)r4r$)r6r$) __name__ __module__ __qualname____doc__rr"r2r5r.r:rrrrrs  rc seZdZdZddddefdddd d d d d g ZgdZgdZdZfddZ ddZ ddZ ddZ ddZ ddZddZdd Zd!d"ZZS)# bdist_msiz7create a Microsoft Installer (.msi) binary distribution)z bdist-dir=Nz1temporary directory for creating the distributionz plat-name=pz;platform name to embed in generated filenames (default: %s)) keep-tempkzPkeep the pseudo-installation tree around after creating the distribution archive)ztarget-version=Nz6require a specific python version on the target system)no-target-compilecz/do not compile .py to .pyc on the target system)no-target-optimizeoz;do not compile .py to .pyo (optimized) on the target system)z dist-dir=dz-directory to put final built distributions in) skip-buildNz2skip rebuilding everything (for testing/debugging))zinstall-script=NzUbasename of installation script to be run after installation or before deinstallation)zpre-install-script=Nz{Fully qualified filename of a script to be run before any files are installed. This script need not be in the distribution)rArCrErH)z2.0z2.1z2.2z2.3z2.4z2.5z2.6z2.7z2.8z2.9z3.0z3.1z3.2z3.3z3.4z3.5z3.6z3.7z3.8z3.9Xcs$tj|i|tdtddS)NzZbdist_msi command is deprecated since Python 3.9, use bdist_wheel (wheel packages) instead)superrwarningswarnDeprecationWarning)rrr __class__rrrszbdist_msi.__init__cCsFd|_d|_d|_d|_d|_d|_d|_d|_d|_d|_ d|_ dS)Nr) bdist_dir plat_name keep_tempZno_target_compileZno_target_optimizetarget_versiondist_dir skip_buildinstall_scriptpre_install_scriptversions)rrrrinitialize_optionss zbdist_msi.initialize_optionscCs|dd|jdur|dj}tj|d|_t}|js'|j r'||_|jrD|jg|_ |j sC|j rC|j|krCt d|fnt|j|_ |ddd|jrXt d|jrt|j jD] }|jtj|krlnq_t d|jd|_dS) Nbdist)rVrVZmsizMtarget version can only be %s, or the '--skip-build' option must be specified)rUrU)rRrRz5the pre-install-script feature is not yet implementedz(install_script '%s' not found in scripts)set_undefined_optionsrQget_finalized_command bdist_baseospathjoinrrT distributionhas_ext_modulesrYrVrlist all_versionsrXrWscriptsbasenameinstall_script_key)rr^Z short_versionscriptrrrfinalize_optionssJ        zbdist_msi.finalize_optionscCs~|js|d|jddd}|j|_|j|_d|_|d}d|_d|_|j rV|j }|s?|js6Jddt j dd }d |j |f}|d}tj|jd ||_td |j|t jdtj|jd |t jd=||j|j}||}tj|}tj|rt||jj }|j!} | s|j"} | sd} |#} dt$| j%} |j}|j rd|j |f} nd|} t&'|t(| t&)| | |_*t&+|j*t,d| fg} |j-p|j.}|r| /d|f|j0r| /d|j0f| rt1|j*d| |2|3|4|5|j*6t7|jdr/d|j p%d|f}|jj8/||j9s=t:|j|j;ddSdS)Nbuildinstallr$)reinit_subcommandsr install_libz Should have already checked thisz%d.%drJz.%s-%slibzinstalling to %sZPURELIBUNKNOWNz%d.%d.%dz Python %s %sz Python %sZ DistVersionZ ARPCONTACTZARPURLINFOABOUTProperty dist_filesr?any)dry_run)    zbdist_msi.add_scriptscCs |j}d}}d}d}d}d}d}d} t|dgd t|d gd t|d gd t|dtjt|dtjt|d||||||ddd } | d| jdddd| jdddd| ddddddd| ddd dd!dd"| j dddd#} | d$d%t|d&||||||ddd } | d'| jdddd| jdddd| ddddddd(| ddd dd!dd"| j dddd#} | d$d%t|d)||||||ddd } | d*| jdddd| jdddd| d+dd,dd!dd"| j dddd#} | d$d-t|d.||||d/|d0d0d0d1d2 }|d3dd4d5ddd6|d+d!d7d8d!dd9|d:d!d;dd?d!d@dz [TARGETDIR]z [SourceDir])Zorderingz [TARGETDIR%s]z FEATURE_SELECTED AND &Python%s=3ZSpawnWaitDialogrJZFeaturesZ SelectionTreer ZFEATUREZPathEditz[FEATURE_SELECTED]1z!FEATURE_SELECTED AND &Python%s<>3ZOtherz$Provide an alternate Python locationZEnableZShowZDisableZHiderZ DiskCostDlgOKz&{\DlgFontBold8}Disk Space RequirementszFThe disk space required for the installation of the selected features.5aThe highlighted volumes (if any) do not have enough disk space available for the currently selected features. You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).Z VolumeListZVolumeCostListdiz{120}{70}{70}{70}{70}g?rZ AdminInstallzGSelect whether to install [ProductName] for all users of this computer.rrzInstall for all usersZJUSTMEzInstall just for mez [ALLUSERS]zWhichUsers="ALL"rz({\DlgFontBold8}[Progress1] [ProductName]#AzYPlease wait while the Installer [Progress2] [ProductName]. This may take several minutes.Z StatusLabelzStatus:Z ProgressBariz Progress doneZ SetProgressProgressrz)Welcome to the [ProductName] Setup WizardZBodyText?z:Select whether you want to repair or remove [ProductName].ZRepairRadioGrouplrrrz&Repair [ProductName]ZRemoverzRe&move [ProductName]z [REINSTALL]zMaintenanceForm_Action="Repair"z [Progress1]Z Repairingz [Progress2]ZrepairsZ Reinstallrz[REMOVE]zMaintenanceForm_Action="Remove" ZRemoving Zremoves z MaintenanceForm_Action<>"Change")rrr rrrr"r2r5r.eventcontrolrr,mappingrbrrYr conditionr:Z radiogroupadd)rrxyrrr"modalZmodelessZtrack_disk_spacefatalrDZ user_exitZ exit_dialogZinuseerrorr5ZcostingprepZseldlgorderrrZinstall_other_condZdont_install_other_condZcostZ whichusersgprogressZmaintrrrrs                                                    zbdist_msi.add_uicCs<|jr d||j|jf}nd||jf}tj|j|}|S)Nz%s.%s-py%s.msiz %s.%s.msi)rTrRr_r`rarU)rr base_namerrrrrsz bdist_msi.get_installer_filename)r;r<r= descriptionr user_optionsboolean_optionsrerrrZrjrrrrrr __classcell__rrrOrr?Us>  ([66&@r?)r>r_r{rLdistutils.corerdistutils.dir_utilrdistutils.sysconfigrZdistutils.versionrdistutils.errorsrdistutils.utilr distutilsrrr r r r r rrrr?rrrrs        >PKH]""""[python3.10/site-packages/setuptools/_distutils/command/__pycache__/register.cpython-310.pycnu[o Xai-@sddZddlZddlZddlZddlZddlmZddlm Z ddl Tddl m Z Gddde Z dS) zhdistutils.command.register Implements the Distutils 'register' command (register with the repository). N)warn) PyPIRCCommand)*)logc@seZdZdZejddgZejgdZdddfgZdd Zd d Z d d Z ddZ ddZ ddZ ddZddZddZdddZdS)registerz7register the distribution with the Python package index)list-classifiersNz list the valid Trove classifiers)strictNzBWill stop the registering if the meta-data are not fully compliant)verifyrrcheckcCsdS)NTselfr r /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_distutils/command/register.pyszregister.cCst|d|_d|_dS)Nr)rinitialize_optionslist_classifiersrr r r rrs  zregister.initialize_optionscCs*t|d|jfdd}||jjd<dS)Nr)r)rrestructuredtextr )rfinalize_optionsr distributioncommand_options)r check_optionsr r rr$s zregister.finalize_optionscCsX|||D]}||q |jr|dS|jr&|dS|dSN) r _set_configget_sub_commands run_commanddry_runverify_metadatar classifiers send_metadata)r cmd_namer r rrun+s     z register.runcCs8tdt|jd}||j|_d|_|dS)zDeprecated API.zddistutils.command.register.check_metadata is deprecated, use the check command insteadr rN)rPendingDeprecationWarningrget_command_objensure_finalizedrrr!)r r r r rcheck_metadata:s  zregister.check_metadatacCs||}|ikr!|d|_|d|_|d|_|d|_d|_d S|jd|jfvr0td|j|jdkr9|j|_d|_d S) z: Reads the configuration file and set attributes. usernamepassword repositoryrealmTpypiz%s not found in .pypircFN) _read_pypircr&r'r(r) has_configDEFAULT_REPOSITORY ValueError)r configr r rrDs       zregister._set_configcCs*|jd}tj|}t||dS)z8 Fetch the list of classifiers from the server. z?:action=list_classifiersN)r(urllibrequesturlopenrinfo_read_pypi_response)r urlresponser r rrUs  zregister.classifierscCs&||d\}}td||dS)zF Send the metadata to the package index server to be checked. r Server response (%s): %sN)post_to_serverbuild_post_datarr3)r coderesultr r rr\szregister.verify_metadatac Cs|jr d}|j}|j}nd}d}}d}||vr5|dtjt}|s)d}n||vr1td||vs|dkr|sAtd}|r;|sJt d}|rCt j }t j |jd }||j|||||d |\}}|d ||ftj|d kr|jr||j_dS|d tj|d|tjd}|dvrtd}|sd}|dvs|dkr|||dSdSdS|dkr\ddi} d| d<| d<| d<d| d<| dstd| d<| dr| d| dkr+| dst d| d<| dr| dst d| d<| dr| d| dkr#d| d<d| d<td| d| dks| ds;td| d<| dr0|| \}}|d krPtd ||dStdtd dS|d!krdd"i} d| d<| dsytd#| d<| drn|| \}}td ||dSdS)$a_ Send the metadata to the package index server. Well, do the following: 1. figure who the user is, and then 2. send the data as a Basic auth'ed POST. First we try to read the username/password from $HOME/.pypirc, which is a ConfigParser-formatted file with a section [distutils] containing username and password entries (both in clear text). Eg: [distutils] index-servers = pypi [pypi] username: fred password: sekrit Otherwise, to figure who the user is, we offer the user three choices: 1. use existing login, 2. register as a new user, or 3. set the password to a random string and email the user. 1xz1 2 3 4zWe need to know who you are, so please choose either: 1. use your existing login, 2. register as a new user, 3. have the server generate a new password for you (and email it to you), or 4. quit Your selection [default 1]: z&Please choose one of the four options!z Username: z Password: rsubmitr7zAI can store your PyPI login so future submissions will be faster.z (the login will be stored in %s)XZynzSave your login (y/N)?ny2:actionusernamer'emailNZconfirmz Confirm: z!Password and confirm don't match!z EMail: z"You will receive an email shortly.z7Follow the instructions in it to complete registration.3Zpassword_resetzYour email address: )r,r&r'splitannouncerINFOinputprintgetpassr0r1HTTPPasswordMgrparseurlparser( add_passwordr)r8r9r _get_rc_filelower _store_pypircr3) r choicer&r'choicesauthhostr:r;datar r rrcs                  zregister.send_metadatacCs|jj}id|ddd|d|d|d|d|d |d |d | d | d | d| d| d|d|d|}|dsc|dsc|drgd|d<|S)NrEmetadata_versionz1.0rGversionsummaryZ home_pageauthor author_emaillicense descriptionkeywordsplatformr download_urlprovidesrequires obsoletesz1.1)rmetadataget_name get_versionget_descriptionget_url get_contactget_contact_email get_licenceget_long_description get_keywords get_platformsget_classifiersget_download_url get_provides get_requires get_obsoletes)r actionmetar[r r rr9sN     zregister.build_post_dataNc Csd|vr|d|d|jftjd}d|}|d}t}|D]?\}}t|tgtdfvr7|g}|D])}t|}| || d|| d| ||rb|d d krb| d q9q$| || d | d }d |tt |d} t j|j|| } t jt jj|d} d}z| | } Wn;t jjy} z|jr| j}| j| jf} WYd} ~ n(d} ~ wt jjy} z dt| f} WYd} ~ nd} ~ ww|jr|| }d} |jrd d|df}||tj| S)zC Post a query to the server, and return a string response. rGzRegistering %s to %sz3--------------GHSKFJDLGDS7543FJKLFHRE75642756743254z --z--r z* Content-Disposition: form-data; name="%s"z   zutf-8z/multipart/form-data; boundary=%s; charset=utf-8)z Content-typezContent-length) password_mgrr>Ni)r@OKzK---------------------------------------------------------------------------)rKr(rrLioStringIOitemstypestrwritegetvalueencodelenr0r1Request build_openerHTTPBasicAuthHandleropenerror HTTPError show_responsefpreadr:msgURLErrorr4join)r r[rYboundaryZ sep_boundaryZ end_boundarybodykeyvalueheadersreqopenerr;err r rr8sh           zregister.post_to_serverr)__name__ __module__ __qualname__rbr user_optionsboolean_options sub_commandsrrr!r%rrrrr9r8r r r rrs$ zr)__doc__rOr urllib.parser0urllib.requestwarningsrdistutils.corerdistutils.errors distutilsrrr r r rs   PKH]ChDpython3.10/site-packages/setuptools/_distutils/command/py37compat.pynu[import sys def _pythonlib_compat(): """ On Python 3.7 and earlier, distutils would include the Python library. See pypa/distutils#9. """ from distutils import sysconfig if not sysconfig.get_config_var('Py_ENABLED_SHARED'): return yield 'python{}.{}{}'.format( sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff, sysconfig.get_config_var('ABIFLAGS'), ) def compose(f1, f2): return lambda *args, **kwargs: f1(f2(*args, **kwargs)) pythonlib = ( compose(list, _pythonlib_compat) if sys.version_info < (3, 8) and sys.platform != 'darwin' and sys.platform[:3] != 'aix' else list ) PKH]?python3.10/site-packages/setuptools/_distutils/command/build.pynu["""distutils.command.build Implements the Distutils 'build' command.""" import sys, os from distutils.core import Command from distutils.errors import DistutilsOptionError from distutils.util import get_platform def show_compilers(): from distutils.ccompiler import show_compilers show_compilers() class build(Command): description = "build everything needed to install" user_options = [ ('build-base=', 'b', "base directory for build library"), ('build-purelib=', None, "build directory for platform-neutral distributions"), ('build-platlib=', None, "build directory for platform-specific distributions"), ('build-lib=', None, "build directory for all distribution (defaults to either " + "build-purelib or build-platlib"), ('build-scripts=', None, "build directory for scripts"), ('build-temp=', 't', "temporary build directory"), ('plat-name=', 'p', "platform name to build for, if supported " "(default: %s)" % get_platform()), ('compiler=', 'c', "specify the compiler type"), ('parallel=', 'j', "number of parallel build jobs"), ('debug', 'g', "compile extensions and libraries with debugging information"), ('force', 'f', "forcibly build everything (ignore file timestamps)"), ('executable=', 'e', "specify final destination interpreter path (build.py)"), ] boolean_options = ['debug', 'force'] help_options = [ ('help-compiler', None, "list available compilers", show_compilers), ] def initialize_options(self): self.build_base = 'build' # these are decided only after 'build_base' has its final value # (unless overridden by the user or client) self.build_purelib = None self.build_platlib = None self.build_lib = None self.build_temp = None self.build_scripts = None self.compiler = None self.plat_name = None self.debug = None self.force = 0 self.executable = None self.parallel = None def finalize_options(self): if self.plat_name is None: self.plat_name = get_platform() else: # plat-name only supported for windows (other platforms are # supported via ./configure flags, if at all). Avoid misleading # other platforms. if os.name != 'nt': raise DistutilsOptionError( "--plat-name only supported on Windows (try " "using './configure --help' on your platform)") plat_specifier = ".%s-%d.%d" % (self.plat_name, *sys.version_info[:2]) # Make it so Python 2.x and Python 2.x with --with-pydebug don't # share the same build directories. Doing so confuses the build # process for C modules if hasattr(sys, 'gettotalrefcount'): plat_specifier += '-pydebug' # 'build_purelib' and 'build_platlib' just default to 'lib' and # 'lib.' under the base build directory. We only use one of # them for a given distribution, though -- if self.build_purelib is None: self.build_purelib = os.path.join(self.build_base, 'lib') if self.build_platlib is None: self.build_platlib = os.path.join(self.build_base, 'lib' + plat_specifier) # 'build_lib' is the actual directory that we will use for this # particular module distribution -- if user didn't supply it, pick # one of 'build_purelib' or 'build_platlib'. if self.build_lib is None: if self.distribution.has_ext_modules(): self.build_lib = self.build_platlib else: self.build_lib = self.build_purelib # 'build_temp' -- temporary directory for compiler turds, # "build/temp." if self.build_temp is None: self.build_temp = os.path.join(self.build_base, 'temp' + plat_specifier) if self.build_scripts is None: self.build_scripts = os.path.join(self.build_base, 'scripts-%d.%d' % sys.version_info[:2]) if self.executable is None and sys.executable: self.executable = os.path.normpath(sys.executable) if isinstance(self.parallel, str): try: self.parallel = int(self.parallel) except ValueError: raise DistutilsOptionError("parallel should be an integer") def run(self): # Run all relevant sub-commands. This will be some subset of: # - build_py - pure Python modules # - build_clib - standalone C libraries # - build_ext - Python extensions # - build_scripts - (Python) scripts for cmd_name in self.get_sub_commands(): self.run_command(cmd_name) # -- Predicates for the sub-command list --------------------------- def has_pure_modules(self): return self.distribution.has_pure_modules() def has_c_libraries(self): return self.distribution.has_c_libraries() def has_ext_modules(self): return self.distribution.has_ext_modules() def has_scripts(self): return self.distribution.has_scripts() sub_commands = [('build_py', has_pure_modules), ('build_clib', has_c_libraries), ('build_ext', has_ext_modules), ('build_scripts', has_scripts), ] PKH]n1?python3.10/site-packages/setuptools/_distutils/command/bdist.pynu["""distutils.command.bdist Implements the Distutils 'bdist' command (create a built [binary] distribution).""" import os from distutils.core import Command from distutils.errors import * from distutils.util import get_platform def show_formats(): """Print list of available formats (arguments to "--format" option). """ from distutils.fancy_getopt import FancyGetopt formats = [] for format in bdist.format_commands: formats.append(("formats=" + format, None, bdist.format_command[format][1])) pretty_printer = FancyGetopt(formats) pretty_printer.print_help("List of available distribution formats:") class bdist(Command): description = "create a built (binary) distribution" user_options = [('bdist-base=', 'b', "temporary directory for creating built distributions"), ('plat-name=', 'p', "platform name to embed in generated filenames " "(default: %s)" % get_platform()), ('formats=', None, "formats for distribution (comma-separated list)"), ('dist-dir=', 'd', "directory to put final built distributions in " "[default: dist]"), ('skip-build', None, "skip rebuilding everything (for testing/debugging)"), ('owner=', 'u', "Owner name used when creating a tar file" " [default: current user]"), ('group=', 'g', "Group name used when creating a tar file" " [default: current group]"), ] boolean_options = ['skip-build'] help_options = [ ('help-formats', None, "lists available distribution formats", show_formats), ] # The following commands do not take a format option from bdist no_format_option = ('bdist_rpm',) # This won't do in reality: will need to distinguish RPM-ish Linux, # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS. default_format = {'posix': 'gztar', 'nt': 'zip'} # Establish the preferred order (for the --help-formats option). format_commands = ['rpm', 'gztar', 'bztar', 'xztar', 'ztar', 'tar', 'wininst', 'zip', 'msi'] # And the real information. format_command = {'rpm': ('bdist_rpm', "RPM distribution"), 'gztar': ('bdist_dumb', "gzip'ed tar file"), 'bztar': ('bdist_dumb', "bzip2'ed tar file"), 'xztar': ('bdist_dumb', "xz'ed tar file"), 'ztar': ('bdist_dumb', "compressed tar file"), 'tar': ('bdist_dumb', "tar file"), 'wininst': ('bdist_wininst', "Windows executable installer"), 'zip': ('bdist_dumb', "ZIP file"), 'msi': ('bdist_msi', "Microsoft Installer") } def initialize_options(self): self.bdist_base = None self.plat_name = None self.formats = None self.dist_dir = None self.skip_build = 0 self.group = None self.owner = None def finalize_options(self): # have to finalize 'plat_name' before 'bdist_base' if self.plat_name is None: if self.skip_build: self.plat_name = get_platform() else: self.plat_name = self.get_finalized_command('build').plat_name # 'bdist_base' -- parent of per-built-distribution-format # temporary directories (eg. we'll probably have # "build/bdist./dumb", "build/bdist./rpm", etc.) if self.bdist_base is None: build_base = self.get_finalized_command('build').build_base self.bdist_base = os.path.join(build_base, 'bdist.' + self.plat_name) self.ensure_string_list('formats') if self.formats is None: try: self.formats = [self.default_format[os.name]] except KeyError: raise DistutilsPlatformError( "don't know how to create built distributions " "on platform %s" % os.name) if self.dist_dir is None: self.dist_dir = "dist" def run(self): # Figure out which sub-commands we need to run. commands = [] for format in self.formats: try: commands.append(self.format_command[format][0]) except KeyError: raise DistutilsOptionError("invalid format '%s'" % format) # Reinitialize and run each command. for i in range(len(self.formats)): cmd_name = commands[i] sub_cmd = self.reinitialize_command(cmd_name) if cmd_name not in self.no_format_option: sub_cmd.format = self.formats[i] # passing the owner and group names for tar archiving if cmd_name == 'bdist_dumb': sub_cmd.owner = self.owner sub_cmd.group = self.group # If we're going to need to run this command again, tell it to # keep its temporary files around so subsequent runs go faster. if cmd_name in commands[i+1:]: sub_cmd.keep_temp = 1 self.run_command(cmd_name) PKH]:Ipython3.10/site-packages/setuptools/_distutils/command/install_scripts.pynu["""distutils.command.install_scripts Implements the Distutils 'install_scripts' command, for installing Python scripts.""" # contributed by Bastian Kleineidam import os from distutils.core import Command from distutils import log from stat import ST_MODE class install_scripts(Command): description = "install scripts (Python or otherwise)" user_options = [ ('install-dir=', 'd', "directory to install scripts to"), ('build-dir=','b', "build directory (where to install from)"), ('force', 'f', "force installation (overwrite existing files)"), ('skip-build', None, "skip the build steps"), ] boolean_options = ['force', 'skip-build'] def initialize_options(self): self.install_dir = None self.force = 0 self.build_dir = None self.skip_build = None def finalize_options(self): self.set_undefined_options('build', ('build_scripts', 'build_dir')) self.set_undefined_options('install', ('install_scripts', 'install_dir'), ('force', 'force'), ('skip_build', 'skip_build'), ) def run(self): if not self.skip_build: self.run_command('build_scripts') self.outfiles = self.copy_tree(self.build_dir, self.install_dir) if os.name == 'posix': # Set the executable bits (owner, group, and world) on # all the scripts we just installed. for file in self.get_outputs(): if self.dry_run: log.info("changing mode of %s", file) else: mode = ((os.stat(file)[ST_MODE]) | 0o555) & 0o7777 log.info("changing mode of %s to %o", file, mode) os.chmod(file, mode) def get_inputs(self): return self.distribution.scripts or [] def get_outputs(self): return self.outfiles or [] PKH]d->>Gpython3.10/site-packages/setuptools/_distutils/command/bdist_wininst.pynu["""distutils.command.bdist_wininst Implements the Distutils 'bdist_wininst' command: create a windows installer exe-program.""" import os import sys import warnings from distutils.core import Command from distutils.util import get_platform from distutils.dir_util import remove_tree from distutils.errors import * from distutils.sysconfig import get_python_version from distutils import log class bdist_wininst(Command): description = "create an executable installer for MS Windows" user_options = [('bdist-dir=', None, "temporary directory for creating the distribution"), ('plat-name=', 'p', "platform name to embed in generated filenames " "(default: %s)" % get_platform()), ('keep-temp', 'k', "keep the pseudo-installation tree around after " + "creating the distribution archive"), ('target-version=', None, "require a specific python version" + " on the target system"), ('no-target-compile', 'c', "do not compile .py to .pyc on the target system"), ('no-target-optimize', 'o', "do not compile .py to .pyo (optimized) " "on the target system"), ('dist-dir=', 'd', "directory to put final built distributions in"), ('bitmap=', 'b', "bitmap to use for the installer instead of python-powered logo"), ('title=', 't', "title to display on the installer background instead of default"), ('skip-build', None, "skip rebuilding everything (for testing/debugging)"), ('install-script=', None, "basename of installation script to be run after " "installation or before deinstallation"), ('pre-install-script=', None, "Fully qualified filename of a script to be run before " "any files are installed. This script need not be in the " "distribution"), ('user-access-control=', None, "specify Vista's UAC handling - 'none'/default=no " "handling, 'auto'=use UAC if target Python installed for " "all users, 'force'=always use UAC"), ] boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize', 'skip-build'] # bpo-10945: bdist_wininst requires mbcs encoding only available on Windows _unsupported = (sys.platform != "win32") def __init__(self, *args, **kw): super().__init__(*args, **kw) warnings.warn("bdist_wininst command is deprecated since Python 3.8, " "use bdist_wheel (wheel packages) instead", DeprecationWarning, 2) def initialize_options(self): self.bdist_dir = None self.plat_name = None self.keep_temp = 0 self.no_target_compile = 0 self.no_target_optimize = 0 self.target_version = None self.dist_dir = None self.bitmap = None self.title = None self.skip_build = None self.install_script = None self.pre_install_script = None self.user_access_control = None def finalize_options(self): self.set_undefined_options('bdist', ('skip_build', 'skip_build')) if self.bdist_dir is None: if self.skip_build and self.plat_name: # If build is skipped and plat_name is overridden, bdist will # not see the correct 'plat_name' - so set that up manually. bdist = self.distribution.get_command_obj('bdist') bdist.plat_name = self.plat_name # next the command will be initialized using that name bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'wininst') if not self.target_version: self.target_version = "" if not self.skip_build and self.distribution.has_ext_modules(): short_version = get_python_version() if self.target_version and self.target_version != short_version: raise DistutilsOptionError( "target version can only be %s, or the '--skip-build'" \ " option must be specified" % (short_version,)) self.target_version = short_version self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'), ('plat_name', 'plat_name'), ) if self.install_script: for script in self.distribution.scripts: if self.install_script == os.path.basename(script): break else: raise DistutilsOptionError( "install_script '%s' not found in scripts" % self.install_script) def run(self): if (sys.platform != "win32" and (self.distribution.has_ext_modules() or self.distribution.has_c_libraries())): raise DistutilsPlatformError \ ("distribution contains extensions and/or C libraries; " "must be compiled on a Windows 32 platform") if not self.skip_build: self.run_command('build') install = self.reinitialize_command('install', reinit_subcommands=1) install.root = self.bdist_dir install.skip_build = self.skip_build install.warn_dir = 0 install.plat_name = self.plat_name install_lib = self.reinitialize_command('install_lib') # we do not want to include pyc or pyo files install_lib.compile = 0 install_lib.optimize = 0 if self.distribution.has_ext_modules(): # If we are building an installer for a Python version other # than the one we are currently running, then we need to ensure # our build_lib reflects the other Python version rather than ours. # Note that for target_version!=sys.version, we must have skipped the # build step, so there is no issue with enforcing the build of this # version. target_version = self.target_version if not target_version: assert self.skip_build, "Should have already checked this" target_version = '%d.%d' % sys.version_info[:2] plat_specifier = ".%s-%s" % (self.plat_name, target_version) build = self.get_finalized_command('build') build.build_lib = os.path.join(build.build_base, 'lib' + plat_specifier) # Use a custom scheme for the zip-file, because we have to decide # at installation time which scheme to use. for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): value = key.upper() if key == 'headers': value = value + '/Include/$dist_name' setattr(install, 'install_' + key, value) log.info("installing to %s", self.bdist_dir) install.ensure_finalized() # avoid warning of 'install_lib' about installing # into a directory not in sys.path sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB')) install.run() del sys.path[0] # And make an archive relative to the root of the # pseudo-installation tree. from tempfile import mktemp archive_basename = mktemp() fullname = self.distribution.get_fullname() arcname = self.make_archive(archive_basename, "zip", root_dir=self.bdist_dir) # create an exe containing the zip-file self.create_exe(arcname, fullname, self.bitmap) if self.distribution.has_ext_modules(): pyversion = get_python_version() else: pyversion = 'any' self.distribution.dist_files.append(('bdist_wininst', pyversion, self.get_installer_filename(fullname))) # remove the zip-file again log.debug("removing temporary file '%s'", arcname) os.remove(arcname) if not self.keep_temp: remove_tree(self.bdist_dir, dry_run=self.dry_run) def get_inidata(self): # Return data describing the installation. lines = [] metadata = self.distribution.metadata # Write the [metadata] section. lines.append("[metadata]") # 'info' will be displayed in the installer's dialog box, # describing the items to be installed. info = (metadata.long_description or '') + '\n' # Escape newline characters def escape(s): return s.replace("\n", "\\n") for name in ["author", "author_email", "description", "maintainer", "maintainer_email", "name", "url", "version"]: data = getattr(metadata, name, "") if data: info = info + ("\n %s: %s" % \ (name.capitalize(), escape(data))) lines.append("%s=%s" % (name, escape(data))) # The [setup] section contains entries controlling # the installer runtime. lines.append("\n[Setup]") if self.install_script: lines.append("install_script=%s" % self.install_script) lines.append("info=%s" % escape(info)) lines.append("target_compile=%d" % (not self.no_target_compile)) lines.append("target_optimize=%d" % (not self.no_target_optimize)) if self.target_version: lines.append("target_version=%s" % self.target_version) if self.user_access_control: lines.append("user_access_control=%s" % self.user_access_control) title = self.title or self.distribution.get_fullname() lines.append("title=%s" % escape(title)) import time import distutils build_info = "Built %s with distutils-%s" % \ (time.ctime(time.time()), distutils.__version__) lines.append("build_info=%s" % build_info) return "\n".join(lines) def create_exe(self, arcname, fullname, bitmap=None): import struct self.mkpath(self.dist_dir) cfgdata = self.get_inidata() installer_name = self.get_installer_filename(fullname) self.announce("creating %s" % installer_name) if bitmap: with open(bitmap, "rb") as f: bitmapdata = f.read() bitmaplen = len(bitmapdata) else: bitmaplen = 0 with open(installer_name, "wb") as file: file.write(self.get_exe_bytes()) if bitmap: file.write(bitmapdata) # Convert cfgdata from unicode to ascii, mbcs encoded if isinstance(cfgdata, str): cfgdata = cfgdata.encode("mbcs") # Append the pre-install script cfgdata = cfgdata + b"\0" if self.pre_install_script: # We need to normalize newlines, so we open in text mode and # convert back to bytes. "latin-1" simply avoids any possible # failures. with open(self.pre_install_script, "r", encoding="latin-1") as script: script_data = script.read().encode("latin-1") cfgdata = cfgdata + script_data + b"\n\0" else: # empty pre-install script cfgdata = cfgdata + b"\0" file.write(cfgdata) # The 'magic number' 0x1234567B is used to make sure that the # binary layout of 'cfgdata' is what the wininst.exe binary # expects. If the layout changes, increment that number, make # the corresponding changes to the wininst.exe sources, and # recompile them. header = struct.pack("> 24, (sys.hexversion >> 16) & 0xff)) # don't extend ext.libraries, it may be shared with other # extensions, it is a reference to the original list return ext.libraries + [pythonlib] else: # On Android only the main executable and LD_PRELOADs are considered # to be RTLD_GLOBAL, all the dependencies of the main executable # remain RTLD_LOCAL and so the shared libraries must be linked with # libpython when python is built with a shared python library (issue # bpo-21536). # On Cygwin (and if required, other POSIX-like platforms based on # Windows like MinGW) it is simply necessary that all symbols in # shared libraries are resolved at link time. from distutils.sysconfig import get_config_var link_libpython = False if get_config_var('Py_ENABLE_SHARED'): # A native build on an Android device or on Cygwin if hasattr(sys, 'getandroidapilevel'): link_libpython = True elif sys.platform == 'cygwin': link_libpython = True elif '_PYTHON_HOST_PLATFORM' in os.environ: # We are cross-compiling for one of the relevant platforms if get_config_var('ANDROID_API_LEVEL') != 0: link_libpython = True elif get_config_var('MACHDEP') == 'cygwin': link_libpython = True if link_libpython: ldversion = get_config_var('LDVERSION') return ext.libraries + ['python' + ldversion] return ext.libraries + py37compat.pythonlib() PKH] Epython3.10/site-packages/setuptools/_distutils/command/install_lib.pynu["""distutils.command.install_lib Implements the Distutils 'install_lib' command (install all Python modules).""" import os import importlib.util import sys from distutils.core import Command from distutils.errors import DistutilsOptionError # Extension for Python source files. PYTHON_SOURCE_EXTENSION = ".py" class install_lib(Command): description = "install all Python modules (extensions and pure Python)" # The byte-compilation options are a tad confusing. Here are the # possible scenarios: # 1) no compilation at all (--no-compile --no-optimize) # 2) compile .pyc only (--compile --no-optimize; default) # 3) compile .pyc and "opt-1" .pyc (--compile --optimize) # 4) compile "opt-1" .pyc only (--no-compile --optimize) # 5) compile .pyc and "opt-2" .pyc (--compile --optimize-more) # 6) compile "opt-2" .pyc only (--no-compile --optimize-more) # # The UI for this is two options, 'compile' and 'optimize'. # 'compile' is strictly boolean, and only decides whether to # generate .pyc files. 'optimize' is three-way (0, 1, or 2), and # decides both whether to generate .pyc files and what level of # optimization to use. user_options = [ ('install-dir=', 'd', "directory to install to"), ('build-dir=','b', "build directory (where to install from)"), ('force', 'f', "force installation (overwrite existing files)"), ('compile', 'c', "compile .py to .pyc [default]"), ('no-compile', None, "don't compile .py files"), ('optimize=', 'O', "also compile with optimization: -O1 for \"python -O\", " "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), ('skip-build', None, "skip the build steps"), ] boolean_options = ['force', 'compile', 'skip-build'] negative_opt = {'no-compile' : 'compile'} def initialize_options(self): # let the 'install' command dictate our installation directory self.install_dir = None self.build_dir = None self.force = 0 self.compile = None self.optimize = None self.skip_build = None def finalize_options(self): # Get all the information we need to install pure Python modules # from the umbrella 'install' command -- build (source) directory, # install (target) directory, and whether to compile .py files. self.set_undefined_options('install', ('build_lib', 'build_dir'), ('install_lib', 'install_dir'), ('force', 'force'), ('compile', 'compile'), ('optimize', 'optimize'), ('skip_build', 'skip_build'), ) if self.compile is None: self.compile = True if self.optimize is None: self.optimize = False if not isinstance(self.optimize, int): try: self.optimize = int(self.optimize) if self.optimize not in (0, 1, 2): raise AssertionError except (ValueError, AssertionError): raise DistutilsOptionError("optimize must be 0, 1, or 2") def run(self): # Make sure we have built everything we need first self.build() # Install everything: simply dump the entire contents of the build # directory to the installation directory (that's the beauty of # having a build directory!) outfiles = self.install() # (Optionally) compile .py to .pyc if outfiles is not None and self.distribution.has_pure_modules(): self.byte_compile(outfiles) # -- Top-level worker functions ------------------------------------ # (called from 'run()') def build(self): if not self.skip_build: if self.distribution.has_pure_modules(): self.run_command('build_py') if self.distribution.has_ext_modules(): self.run_command('build_ext') def install(self): if os.path.isdir(self.build_dir): outfiles = self.copy_tree(self.build_dir, self.install_dir) else: self.warn("'%s' does not exist -- no Python modules to install" % self.build_dir) return return outfiles def byte_compile(self, files): if sys.dont_write_bytecode: self.warn('byte-compiling is disabled, skipping.') return from distutils.util import byte_compile # Get the "--root" directory supplied to the "install" command, # and use it as a prefix to strip off the purported filename # encoded in bytecode files. This is far from complete, but it # should at least generate usable bytecode in RPM distributions. install_root = self.get_finalized_command('install').root if self.compile: byte_compile(files, optimize=0, force=self.force, prefix=install_root, dry_run=self.dry_run) if self.optimize > 0: byte_compile(files, optimize=self.optimize, force=self.force, prefix=install_root, verbose=self.verbose, dry_run=self.dry_run) # -- Utility methods ----------------------------------------------- def _mutate_outputs(self, has_any, build_cmd, cmd_option, output_dir): if not has_any: return [] build_cmd = self.get_finalized_command(build_cmd) build_files = build_cmd.get_outputs() build_dir = getattr(build_cmd, cmd_option) prefix_len = len(build_dir) + len(os.sep) outputs = [] for file in build_files: outputs.append(os.path.join(output_dir, file[prefix_len:])) return outputs def _bytecode_filenames(self, py_filenames): bytecode_files = [] for py_file in py_filenames: # Since build_py handles package data installation, the # list of outputs can contain more than just .py files. # Make sure we only report bytecode for the .py files. ext = os.path.splitext(os.path.normcase(py_file))[1] if ext != PYTHON_SOURCE_EXTENSION: continue if self.compile: bytecode_files.append(importlib.util.cache_from_source( py_file, optimization='')) if self.optimize > 0: bytecode_files.append(importlib.util.cache_from_source( py_file, optimization=self.optimize)) return bytecode_files # -- External interface -------------------------------------------- # (called by outsiders) def get_outputs(self): """Return the list of files that would be installed if this command were actually run. Not affected by the "dry-run" flag or whether modules have actually been built yet. """ pure_outputs = \ self._mutate_outputs(self.distribution.has_pure_modules(), 'build_py', 'build_lib', self.install_dir) if self.compile: bytecode_outputs = self._bytecode_filenames(pure_outputs) else: bytecode_outputs = [] ext_outputs = \ self._mutate_outputs(self.distribution.has_ext_modules(), 'build_ext', 'build_lib', self.install_dir) return pure_outputs + bytecode_outputs + ext_outputs def get_inputs(self): """Get the list of files that are input to this command, ie. the files that get installed as they are named in the build tree. The files in this list correspond one-to-one to the output filenames returned by 'get_outputs()'. """ inputs = [] if self.distribution.has_pure_modules(): build_py = self.get_finalized_command('build_py') inputs.extend(build_py.get_outputs()) if self.distribution.has_ext_modules(): build_ext = self.get_finalized_command('build_ext') inputs.extend(build_ext.get_outputs()) return inputs PKH]m?python3.10/site-packages/setuptools/_distutils/command/check.pynu["""distutils.command.check Implements the Distutils 'check' command. """ from distutils.core import Command from distutils.errors import DistutilsSetupError try: # docutils is installed from docutils.utils import Reporter from docutils.parsers.rst import Parser from docutils import frontend from docutils import nodes class SilentReporter(Reporter): def __init__(self, source, report_level, halt_level, stream=None, debug=0, encoding='ascii', error_handler='replace'): self.messages = [] Reporter.__init__(self, source, report_level, halt_level, stream, debug, encoding, error_handler) def system_message(self, level, message, *children, **kwargs): self.messages.append((level, message, children, kwargs)) return nodes.system_message(message, level=level, type=self.levels[level], *children, **kwargs) HAS_DOCUTILS = True except Exception: # Catch all exceptions because exceptions besides ImportError probably # indicate that docutils is not ported to Py3k. HAS_DOCUTILS = False class check(Command): """This command checks the meta-data of the package. """ description = ("perform some checks on the package") user_options = [('metadata', 'm', 'Verify meta-data'), ('restructuredtext', 'r', ('Checks if long string meta-data syntax ' 'are reStructuredText-compliant')), ('strict', 's', 'Will exit with an error if a check fails')] boolean_options = ['metadata', 'restructuredtext', 'strict'] def initialize_options(self): """Sets default values for options.""" self.restructuredtext = 0 self.metadata = 1 self.strict = 0 self._warnings = 0 def finalize_options(self): pass def warn(self, msg): """Counts the number of warnings that occurs.""" self._warnings += 1 return Command.warn(self, msg) def run(self): """Runs the command.""" # perform the various tests if self.metadata: self.check_metadata() if self.restructuredtext: if HAS_DOCUTILS: self.check_restructuredtext() elif self.strict: raise DistutilsSetupError('The docutils package is needed.') # let's raise an error in strict mode, if we have at least # one warning if self.strict and self._warnings > 0: raise DistutilsSetupError('Please correct your package.') def check_metadata(self): """Ensures that all required elements of meta-data are supplied. Required fields: name, version, URL Recommended fields: (author and author_email) or (maintainer and maintainer_email)) Warns if any are missing. """ metadata = self.distribution.metadata missing = [] for attr in ('name', 'version', 'url'): if not (hasattr(metadata, attr) and getattr(metadata, attr)): missing.append(attr) if missing: self.warn("missing required meta-data: %s" % ', '.join(missing)) if metadata.author: if not metadata.author_email: self.warn("missing meta-data: if 'author' supplied, " + "'author_email' should be supplied too") elif metadata.maintainer: if not metadata.maintainer_email: self.warn("missing meta-data: if 'maintainer' supplied, " + "'maintainer_email' should be supplied too") else: self.warn("missing meta-data: either (author and author_email) " + "or (maintainer and maintainer_email) " + "should be supplied") def check_restructuredtext(self): """Checks if the long string fields are reST-compliant.""" data = self.distribution.get_long_description() for warning in self._check_rst_data(data): line = warning[-1].get('line') if line is None: warning = warning[1] else: warning = '%s (line %s)' % (warning[1], line) self.warn(warning) def _check_rst_data(self, data): """Returns warnings when the provided data doesn't compile.""" # the include and csv_table directives need this to be a path source_path = self.distribution.script_name or 'setup.py' parser = Parser() settings = frontend.OptionParser(components=(Parser,)).get_default_values() settings.tab_width = 4 settings.pep_references = None settings.rfc_references = None reporter = SilentReporter(source_path, settings.report_level, settings.halt_level, stream=settings.warning_stream, debug=settings.debug, encoding=settings.error_encoding, error_handler=settings.error_encoding_error_handler) document = nodes.document(settings, reporter, source=source_path) document.note_source(source_path, -1) try: parser.parse(data, document) except AttributeError as e: reporter.messages.append( (-1, 'Could not finish the parsing: %s.' % e, '', {})) return reporter.messages PKH]--Bpython3.10/site-packages/setuptools/_distutils/command/register.pynu["""distutils.command.register Implements the Distutils 'register' command (register with the repository). """ # created 2002/10/21, Richard Jones import getpass import io import urllib.parse, urllib.request from warnings import warn from distutils.core import PyPIRCCommand from distutils.errors import * from distutils import log class register(PyPIRCCommand): description = ("register the distribution with the Python package index") user_options = PyPIRCCommand.user_options + [ ('list-classifiers', None, 'list the valid Trove classifiers'), ('strict', None , 'Will stop the registering if the meta-data are not fully compliant') ] boolean_options = PyPIRCCommand.boolean_options + [ 'verify', 'list-classifiers', 'strict'] sub_commands = [('check', lambda self: True)] def initialize_options(self): PyPIRCCommand.initialize_options(self) self.list_classifiers = 0 self.strict = 0 def finalize_options(self): PyPIRCCommand.finalize_options(self) # setting options for the `check` subcommand check_options = {'strict': ('register', self.strict), 'restructuredtext': ('register', 1)} self.distribution.command_options['check'] = check_options def run(self): self.finalize_options() self._set_config() # Run sub commands for cmd_name in self.get_sub_commands(): self.run_command(cmd_name) if self.dry_run: self.verify_metadata() elif self.list_classifiers: self.classifiers() else: self.send_metadata() def check_metadata(self): """Deprecated API.""" warn("distutils.command.register.check_metadata is deprecated, \ use the check command instead", PendingDeprecationWarning) check = self.distribution.get_command_obj('check') check.ensure_finalized() check.strict = self.strict check.restructuredtext = 1 check.run() def _set_config(self): ''' Reads the configuration file and set attributes. ''' config = self._read_pypirc() if config != {}: self.username = config['username'] self.password = config['password'] self.repository = config['repository'] self.realm = config['realm'] self.has_config = True else: if self.repository not in ('pypi', self.DEFAULT_REPOSITORY): raise ValueError('%s not found in .pypirc' % self.repository) if self.repository == 'pypi': self.repository = self.DEFAULT_REPOSITORY self.has_config = False def classifiers(self): ''' Fetch the list of classifiers from the server. ''' url = self.repository+'?:action=list_classifiers' response = urllib.request.urlopen(url) log.info(self._read_pypi_response(response)) def verify_metadata(self): ''' Send the metadata to the package index server to be checked. ''' # send the info to the server and report the result (code, result) = self.post_to_server(self.build_post_data('verify')) log.info('Server response (%s): %s', code, result) def send_metadata(self): ''' Send the metadata to the package index server. Well, do the following: 1. figure who the user is, and then 2. send the data as a Basic auth'ed POST. First we try to read the username/password from $HOME/.pypirc, which is a ConfigParser-formatted file with a section [distutils] containing username and password entries (both in clear text). Eg: [distutils] index-servers = pypi [pypi] username: fred password: sekrit Otherwise, to figure who the user is, we offer the user three choices: 1. use existing login, 2. register as a new user, or 3. set the password to a random string and email the user. ''' # see if we can short-cut and get the username/password from the # config if self.has_config: choice = '1' username = self.username password = self.password else: choice = 'x' username = password = '' # get the user's login info choices = '1 2 3 4'.split() while choice not in choices: self.announce('''\ We need to know who you are, so please choose either: 1. use your existing login, 2. register as a new user, 3. have the server generate a new password for you (and email it to you), or 4. quit Your selection [default 1]: ''', log.INFO) choice = input() if not choice: choice = '1' elif choice not in choices: print('Please choose one of the four options!') if choice == '1': # get the username and password while not username: username = input('Username: ') while not password: password = getpass.getpass('Password: ') # set up the authentication auth = urllib.request.HTTPPasswordMgr() host = urllib.parse.urlparse(self.repository)[1] auth.add_password(self.realm, host, username, password) # send the info to the server and report the result code, result = self.post_to_server(self.build_post_data('submit'), auth) self.announce('Server response (%s): %s' % (code, result), log.INFO) # possibly save the login if code == 200: if self.has_config: # sharing the password in the distribution instance # so the upload command can reuse it self.distribution.password = password else: self.announce(('I can store your PyPI login so future ' 'submissions will be faster.'), log.INFO) self.announce('(the login will be stored in %s)' % \ self._get_rc_file(), log.INFO) choice = 'X' while choice.lower() not in 'yn': choice = input('Save your login (y/N)?') if not choice: choice = 'n' if choice.lower() == 'y': self._store_pypirc(username, password) elif choice == '2': data = {':action': 'user'} data['name'] = data['password'] = data['email'] = '' data['confirm'] = None while not data['name']: data['name'] = input('Username: ') while data['password'] != data['confirm']: while not data['password']: data['password'] = getpass.getpass('Password: ') while not data['confirm']: data['confirm'] = getpass.getpass(' Confirm: ') if data['password'] != data['confirm']: data['password'] = '' data['confirm'] = None print("Password and confirm don't match!") while not data['email']: data['email'] = input(' EMail: ') code, result = self.post_to_server(data) if code != 200: log.info('Server response (%s): %s', code, result) else: log.info('You will receive an email shortly.') log.info(('Follow the instructions in it to ' 'complete registration.')) elif choice == '3': data = {':action': 'password_reset'} data['email'] = '' while not data['email']: data['email'] = input('Your email address: ') code, result = self.post_to_server(data) log.info('Server response (%s): %s', code, result) def build_post_data(self, action): # figure the data to send - the metadata plus some additional # information used by the package server meta = self.distribution.metadata data = { ':action': action, 'metadata_version' : '1.0', 'name': meta.get_name(), 'version': meta.get_version(), 'summary': meta.get_description(), 'home_page': meta.get_url(), 'author': meta.get_contact(), 'author_email': meta.get_contact_email(), 'license': meta.get_licence(), 'description': meta.get_long_description(), 'keywords': meta.get_keywords(), 'platform': meta.get_platforms(), 'classifiers': meta.get_classifiers(), 'download_url': meta.get_download_url(), # PEP 314 'provides': meta.get_provides(), 'requires': meta.get_requires(), 'obsoletes': meta.get_obsoletes(), } if data['provides'] or data['requires'] or data['obsoletes']: data['metadata_version'] = '1.1' return data def post_to_server(self, data, auth=None): ''' Post a query to the server, and return a string response. ''' if 'name' in data: self.announce('Registering %s to %s' % (data['name'], self.repository), log.INFO) # Build up the MIME payload for the urllib2 POST data boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = '\n--' + boundary end_boundary = sep_boundary + '--' body = io.StringIO() for key, value in data.items(): # handle multiple entries for the same name if type(value) not in (type([]), type( () )): value = [value] for value in value: value = str(value) body.write(sep_boundary) body.write('\nContent-Disposition: form-data; name="%s"'%key) body.write("\n\n") body.write(value) if value and value[-1] == '\r': body.write('\n') # write an extra newline (lurve Macs) body.write(end_boundary) body.write("\n") body = body.getvalue().encode("utf-8") # build the Request headers = { 'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'%boundary, 'Content-length': str(len(body)) } req = urllib.request.Request(self.repository, body, headers) # handle HTTP and include the Basic Auth handler opener = urllib.request.build_opener( urllib.request.HTTPBasicAuthHandler(password_mgr=auth) ) data = '' try: result = opener.open(req) except urllib.error.HTTPError as e: if self.show_response: data = e.fp.read() result = e.code, e.msg except urllib.error.URLError as e: result = 500, str(e) else: if self.show_response: data = self._read_pypi_response(result) result = 200, 'OK' if self.show_response: msg = '\n'.join(('-' * 75, data, '-' * 75)) self.announce(msg, log.INFO) return result PKH]jP@python3.10/site-packages/setuptools/_distutils/command/upload.pynu[""" distutils.command.upload Implements the Distutils 'upload' subcommand (upload package to a package index). """ import os import io import hashlib from base64 import standard_b64encode from urllib.request import urlopen, Request, HTTPError from urllib.parse import urlparse from distutils.errors import DistutilsError, DistutilsOptionError from distutils.core import PyPIRCCommand from distutils.spawn import spawn from distutils import log # PyPI Warehouse supports MD5, SHA256, and Blake2 (blake2-256) # https://bugs.python.org/issue40698 _FILE_CONTENT_DIGESTS = { "md5_digest": getattr(hashlib, "md5", None), "sha256_digest": getattr(hashlib, "sha256", None), "blake2_256_digest": getattr(hashlib, "blake2b", None), } class upload(PyPIRCCommand): description = "upload binary package to PyPI" user_options = PyPIRCCommand.user_options + [ ('sign', 's', 'sign files to upload using gpg'), ('identity=', 'i', 'GPG identity used to sign files'), ] boolean_options = PyPIRCCommand.boolean_options + ['sign'] def initialize_options(self): PyPIRCCommand.initialize_options(self) self.username = '' self.password = '' self.show_response = 0 self.sign = False self.identity = None def finalize_options(self): PyPIRCCommand.finalize_options(self) if self.identity and not self.sign: raise DistutilsOptionError( "Must use --sign for --identity to have meaning" ) config = self._read_pypirc() if config != {}: self.username = config['username'] self.password = config['password'] self.repository = config['repository'] self.realm = config['realm'] # getting the password from the distribution # if previously set by the register command if not self.password and self.distribution.password: self.password = self.distribution.password def run(self): if not self.distribution.dist_files: msg = ("Must create and upload files in one command " "(e.g. setup.py sdist upload)") raise DistutilsOptionError(msg) for command, pyversion, filename in self.distribution.dist_files: self.upload_file(command, pyversion, filename) def upload_file(self, command, pyversion, filename): # Makes sure the repository URL is compliant schema, netloc, url, params, query, fragments = \ urlparse(self.repository) if params or query or fragments: raise AssertionError("Incompatible url %s" % self.repository) if schema not in ('http', 'https'): raise AssertionError("unsupported schema " + schema) # Sign if requested if self.sign: gpg_args = ["gpg", "--detach-sign", "-a", filename] if self.identity: gpg_args[2:2] = ["--local-user", self.identity] spawn(gpg_args, dry_run=self.dry_run) # Fill in the data - send all the meta-data in case we need to # register a new release f = open(filename,'rb') try: content = f.read() finally: f.close() meta = self.distribution.metadata data = { # action ':action': 'file_upload', 'protocol_version': '1', # identify release 'name': meta.get_name(), 'version': meta.get_version(), # file content 'content': (os.path.basename(filename),content), 'filetype': command, 'pyversion': pyversion, # additional meta-data 'metadata_version': '1.0', 'summary': meta.get_description(), 'home_page': meta.get_url(), 'author': meta.get_contact(), 'author_email': meta.get_contact_email(), 'license': meta.get_licence(), 'description': meta.get_long_description(), 'keywords': meta.get_keywords(), 'platform': meta.get_platforms(), 'classifiers': meta.get_classifiers(), 'download_url': meta.get_download_url(), # PEP 314 'provides': meta.get_provides(), 'requires': meta.get_requires(), 'obsoletes': meta.get_obsoletes(), } data['comment'] = '' # file content digests for digest_name, digest_cons in _FILE_CONTENT_DIGESTS.items(): if digest_cons is None: continue try: data[digest_name] = digest_cons(content).hexdigest() except ValueError: # hash digest not available or blocked by security policy pass if self.sign: with open(filename + ".asc", "rb") as f: data['gpg_signature'] = (os.path.basename(filename) + ".asc", f.read()) # set up the authentication user_pass = (self.username + ":" + self.password).encode('ascii') # The exact encoding of the authentication string is debated. # Anyway PyPI only accepts ascii for both username or password. auth = "Basic " + standard_b64encode(user_pass).decode('ascii') # Build up the MIME payload for the POST data boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = b'\r\n--' + boundary.encode('ascii') end_boundary = sep_boundary + b'--\r\n' body = io.BytesIO() for key, value in data.items(): title = '\r\nContent-Disposition: form-data; name="%s"' % key # handle multiple entries for the same name if not isinstance(value, list): value = [value] for value in value: if type(value) is tuple: title += '; filename="%s"' % value[0] value = value[1] else: value = str(value).encode('utf-8') body.write(sep_boundary) body.write(title.encode('utf-8')) body.write(b"\r\n\r\n") body.write(value) body.write(end_boundary) body = body.getvalue() msg = "Submitting %s to %s" % (filename, self.repository) self.announce(msg, log.INFO) # build the Request headers = { 'Content-type': 'multipart/form-data; boundary=%s' % boundary, 'Content-length': str(len(body)), 'Authorization': auth, } request = Request(self.repository, data=body, headers=headers) # send the data try: result = urlopen(request) status = result.getcode() reason = result.msg except HTTPError as e: status = e.code reason = e.msg except OSError as e: self.announce(str(e), log.ERROR) raise if status == 200: self.announce('Server response (%s): %s' % (status, reason), log.INFO) if self.show_response: text = self._read_pypi_response(result) msg = '\n'.join(('-' * 75, text, '-' * 75)) self.announce(msg, log.INFO) else: msg = 'Upload failed (%s): %s' % (status, reason) self.announce(msg, log.ERROR) raise DistutilsError(msg) PKH], ?python3.10/site-packages/setuptools/_distutils/command/clean.pynu["""distutils.command.clean Implements the Distutils 'clean' command.""" # contributed by Bastian Kleineidam , added 2000-03-18 import os from distutils.core import Command from distutils.dir_util import remove_tree from distutils import log class clean(Command): description = "clean up temporary files from 'build' command" user_options = [ ('build-base=', 'b', "base build directory (default: 'build.build-base')"), ('build-lib=', None, "build directory for all modules (default: 'build.build-lib')"), ('build-temp=', 't', "temporary build directory (default: 'build.build-temp')"), ('build-scripts=', None, "build directory for scripts (default: 'build.build-scripts')"), ('bdist-base=', None, "temporary directory for built distributions"), ('all', 'a', "remove all build output, not just temporary by-products") ] boolean_options = ['all'] def initialize_options(self): self.build_base = None self.build_lib = None self.build_temp = None self.build_scripts = None self.bdist_base = None self.all = None def finalize_options(self): self.set_undefined_options('build', ('build_base', 'build_base'), ('build_lib', 'build_lib'), ('build_scripts', 'build_scripts'), ('build_temp', 'build_temp')) self.set_undefined_options('bdist', ('bdist_base', 'bdist_base')) def run(self): # remove the build/temp. directory (unless it's already # gone) if os.path.exists(self.build_temp): remove_tree(self.build_temp, dry_run=self.dry_run) else: log.debug("'%s' does not exist -- can't clean it", self.build_temp) if self.all: # remove build directories for directory in (self.build_lib, self.bdist_base, self.build_scripts): if os.path.exists(directory): remove_tree(directory, dry_run=self.dry_run) else: log.warn("'%s' does not exist -- can't clean it", directory) # just for the heck of it, try to remove the base build directory: # we might have emptied it right now, but if not we don't care if not self.dry_run: try: os.rmdir(self.build_base) log.info("removing '%s'", self.build_base) except OSError: pass PKH].o@o@Bpython3.10/site-packages/setuptools/_distutils/command/build_py.pynu["""distutils.command.build_py Implements the Distutils 'build_py' command.""" import os import importlib.util import sys import glob from distutils.core import Command from distutils.errors import * from distutils.util import convert_path from distutils import log class build_py (Command): description = "\"build\" pure Python modules (copy to build directory)" user_options = [ ('build-lib=', 'd', "directory to \"build\" (copy) to"), ('compile', 'c', "compile .py to .pyc"), ('no-compile', None, "don't compile .py files [default]"), ('optimize=', 'O', "also compile with optimization: -O1 for \"python -O\", " "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), ('force', 'f', "forcibly build everything (ignore file timestamps)"), ] boolean_options = ['compile', 'force'] negative_opt = {'no-compile' : 'compile'} def initialize_options(self): self.build_lib = None self.py_modules = None self.package = None self.package_data = None self.package_dir = None self.compile = 0 self.optimize = 0 self.force = None def finalize_options(self): self.set_undefined_options('build', ('build_lib', 'build_lib'), ('force', 'force')) # Get the distribution options that are aliases for build_py # options -- list of packages and list of modules. self.packages = self.distribution.packages self.py_modules = self.distribution.py_modules self.package_data = self.distribution.package_data self.package_dir = {} if self.distribution.package_dir: for name, path in self.distribution.package_dir.items(): self.package_dir[name] = convert_path(path) self.data_files = self.get_data_files() # Ick, copied straight from install_lib.py (fancy_getopt needs a # type system! Hell, *everything* needs a type system!!!) if not isinstance(self.optimize, int): try: self.optimize = int(self.optimize) assert 0 <= self.optimize <= 2 except (ValueError, AssertionError): raise DistutilsOptionError("optimize must be 0, 1, or 2") def run(self): # XXX copy_file by default preserves atime and mtime. IMHO this is # the right thing to do, but perhaps it should be an option -- in # particular, a site administrator might want installed files to # reflect the time of installation rather than the last # modification time before the installed release. # XXX copy_file by default preserves mode, which appears to be the # wrong thing to do: if a file is read-only in the working # directory, we want it to be installed read/write so that the next # installation of the same module distribution can overwrite it # without problems. (This might be a Unix-specific issue.) Thus # we turn off 'preserve_mode' when copying to the build directory, # since the build directory is supposed to be exactly what the # installation will look like (ie. we preserve mode when # installing). # Two options control which modules will be installed: 'packages' # and 'py_modules'. The former lets us work with whole packages, not # specifying individual modules at all; the latter is for # specifying modules one-at-a-time. if self.py_modules: self.build_modules() if self.packages: self.build_packages() self.build_package_data() self.byte_compile(self.get_outputs(include_bytecode=0)) def get_data_files(self): """Generate list of '(package,src_dir,build_dir,filenames)' tuples""" data = [] if not self.packages: return data for package in self.packages: # Locate package source directory src_dir = self.get_package_dir(package) # Compute package build directory build_dir = os.path.join(*([self.build_lib] + package.split('.'))) # Length of path to strip from found files plen = 0 if src_dir: plen = len(src_dir)+1 # Strip directory from globbed filenames filenames = [ file[plen:] for file in self.find_data_files(package, src_dir) ] data.append((package, src_dir, build_dir, filenames)) return data def find_data_files(self, package, src_dir): """Return filenames for package's data files in 'src_dir'""" globs = (self.package_data.get('', []) + self.package_data.get(package, [])) files = [] for pattern in globs: # Each pattern has to be converted to a platform-specific path filelist = glob.glob(os.path.join(glob.escape(src_dir), convert_path(pattern))) # Files that match more than one pattern are only added once files.extend([fn for fn in filelist if fn not in files and os.path.isfile(fn)]) return files def build_package_data(self): """Copy data files into build directory""" lastdir = None for package, src_dir, build_dir, filenames in self.data_files: for filename in filenames: target = os.path.join(build_dir, filename) self.mkpath(os.path.dirname(target)) self.copy_file(os.path.join(src_dir, filename), target, preserve_mode=False) def get_package_dir(self, package): """Return the directory, relative to the top of the source distribution, where package 'package' should be found (at least according to the 'package_dir' option, if any).""" path = package.split('.') if not self.package_dir: if path: return os.path.join(*path) else: return '' else: tail = [] while path: try: pdir = self.package_dir['.'.join(path)] except KeyError: tail.insert(0, path[-1]) del path[-1] else: tail.insert(0, pdir) return os.path.join(*tail) else: # Oops, got all the way through 'path' without finding a # match in package_dir. If package_dir defines a directory # for the root (nameless) package, then fallback on it; # otherwise, we might as well have not consulted # package_dir at all, as we just use the directory implied # by 'tail' (which should be the same as the original value # of 'path' at this point). pdir = self.package_dir.get('') if pdir is not None: tail.insert(0, pdir) if tail: return os.path.join(*tail) else: return '' def check_package(self, package, package_dir): # Empty dir name means current directory, which we can probably # assume exists. Also, os.path.exists and isdir don't know about # my "empty string means current dir" convention, so we have to # circumvent them. if package_dir != "": if not os.path.exists(package_dir): raise DistutilsFileError( "package directory '%s' does not exist" % package_dir) if not os.path.isdir(package_dir): raise DistutilsFileError( "supposed package directory '%s' exists, " "but is not a directory" % package_dir) # Require __init__.py for all but the "root package" if package: init_py = os.path.join(package_dir, "__init__.py") if os.path.isfile(init_py): return init_py else: log.warn(("package init file '%s' not found " + "(or not a regular file)"), init_py) # Either not in a package at all (__init__.py not expected), or # __init__.py doesn't exist -- so don't return the filename. return None def check_module(self, module, module_file): if not os.path.isfile(module_file): log.warn("file %s (for module %s) not found", module_file, module) return False else: return True def find_package_modules(self, package, package_dir): self.check_package(package, package_dir) module_files = glob.glob(os.path.join(glob.escape(package_dir), "*.py")) modules = [] setup_script = os.path.abspath(self.distribution.script_name) for f in module_files: abs_f = os.path.abspath(f) if abs_f != setup_script: module = os.path.splitext(os.path.basename(f))[0] modules.append((package, module, f)) else: self.debug_print("excluding %s" % setup_script) return modules def find_modules(self): """Finds individually-specified Python modules, ie. those listed by module name in 'self.py_modules'. Returns a list of tuples (package, module_base, filename): 'package' is a tuple of the path through package-space to the module; 'module_base' is the bare (no packages, no dots) module name, and 'filename' is the path to the ".py" file (relative to the distribution root) that implements the module. """ # Map package names to tuples of useful info about the package: # (package_dir, checked) # package_dir - the directory where we'll find source files for # this package # checked - true if we have checked that the package directory # is valid (exists, contains __init__.py, ... ?) packages = {} # List of (package, module, filename) tuples to return modules = [] # We treat modules-in-packages almost the same as toplevel modules, # just the "package" for a toplevel is empty (either an empty # string or empty list, depending on context). Differences: # - don't check for __init__.py in directory for empty package for module in self.py_modules: path = module.split('.') package = '.'.join(path[0:-1]) module_base = path[-1] try: (package_dir, checked) = packages[package] except KeyError: package_dir = self.get_package_dir(package) checked = 0 if not checked: init_py = self.check_package(package, package_dir) packages[package] = (package_dir, 1) if init_py: modules.append((package, "__init__", init_py)) # XXX perhaps we should also check for just .pyc files # (so greedy closed-source bastards can distribute Python # modules too) module_file = os.path.join(package_dir, module_base + ".py") if not self.check_module(module, module_file): continue modules.append((package, module_base, module_file)) return modules def find_all_modules(self): """Compute the list of all modules that will be built, whether they are specified one-module-at-a-time ('self.py_modules') or by whole packages ('self.packages'). Return a list of tuples (package, module, module_file), just like 'find_modules()' and 'find_package_modules()' do.""" modules = [] if self.py_modules: modules.extend(self.find_modules()) if self.packages: for package in self.packages: package_dir = self.get_package_dir(package) m = self.find_package_modules(package, package_dir) modules.extend(m) return modules def get_source_files(self): return [module[-1] for module in self.find_all_modules()] def get_module_outfile(self, build_dir, package, module): outfile_path = [build_dir] + list(package) + [module + ".py"] return os.path.join(*outfile_path) def get_outputs(self, include_bytecode=1): modules = self.find_all_modules() outputs = [] for (package, module, module_file) in modules: package = package.split('.') filename = self.get_module_outfile(self.build_lib, package, module) outputs.append(filename) if include_bytecode: if self.compile: outputs.append(importlib.util.cache_from_source( filename, optimization='')) if self.optimize > 0: outputs.append(importlib.util.cache_from_source( filename, optimization=self.optimize)) outputs += [ os.path.join(build_dir, filename) for package, src_dir, build_dir, filenames in self.data_files for filename in filenames ] return outputs def build_module(self, module, module_file, package): if isinstance(package, str): package = package.split('.') elif not isinstance(package, (list, tuple)): raise TypeError( "'package' must be a string (dot-separated), list, or tuple") # Now put the module source file into the "build" area -- this is # easy, we just copy it somewhere under self.build_lib (the build # directory for Python source). outfile = self.get_module_outfile(self.build_lib, package, module) dir = os.path.dirname(outfile) self.mkpath(dir) return self.copy_file(module_file, outfile, preserve_mode=0) def build_modules(self): modules = self.find_modules() for (package, module, module_file) in modules: # Now "build" the module -- ie. copy the source file to # self.build_lib (the build directory for Python source). # (Actually, it gets copied to the directory for this package # under self.build_lib.) self.build_module(module, module_file, package) def build_packages(self): for package in self.packages: # Get list of (package, module, module_file) tuples based on # scanning the package directory. 'package' is only included # in the tuple so that 'find_modules()' and # 'find_package_tuples()' have a consistent interface; it's # ignored here (apart from a sanity check). Also, 'module' is # the *unqualified* module name (ie. no dots, no package -- we # already know its package!), and 'module_file' is the path to # the .py file, relative to the current directory # (ie. including 'package_dir'). package_dir = self.get_package_dir(package) modules = self.find_package_modules(package, package_dir) # Now loop over the modules we found, "building" each one (just # copy it to self.build_lib). for (package_, module, module_file) in modules: assert package == package_ self.build_module(module, module_file, package) def byte_compile(self, files): if sys.dont_write_bytecode: self.warn('byte-compiling is disabled, skipping.') return from distutils.util import byte_compile prefix = self.build_lib if prefix[-1] != os.sep: prefix = prefix + os.sep # XXX this code is essentially the same as the 'byte_compile() # method of the "install_lib" command, except for the determination # of the 'prefix' string. Hmmm. if self.compile: byte_compile(files, optimize=0, force=self.force, prefix=prefix, dry_run=self.dry_run) if self.optimize > 0: byte_compile(files, optimize=self.optimize, force=self.force, prefix=prefix, dry_run=self.dry_run) PKH]iTkkApython3.10/site-packages/setuptools/_distutils/command/install.pynu["""distutils.command.install Implements the Distutils 'install' command.""" import sys import os from distutils import log from distutils.core import Command from distutils.debug import DEBUG from distutils.sysconfig import get_config_vars from distutils.errors import DistutilsPlatformError from distutils.file_util import write_file from distutils.util import convert_path, subst_vars, change_root from distutils.util import get_platform from distutils.errors import DistutilsOptionError from site import USER_BASE from site import USER_SITE HAS_USER_SITE = True WINDOWS_SCHEME = { 'purelib': '$base/Lib/site-packages', 'platlib': '$base/Lib/site-packages', 'headers': '$base/Include/$dist_name', 'scripts': '$base/Scripts', 'data' : '$base', } INSTALL_SCHEMES = { 'unix_prefix': { 'purelib': '$base/lib/python$py_version_short/site-packages', 'platlib': '$platbase/$platlibdir/python$py_version_short/site-packages', 'headers': '$base/include/python$py_version_short$abiflags/$dist_name', 'scripts': '$base/bin', 'data' : '$base', }, 'unix_home': { 'purelib': '$base/lib/python', 'platlib': '$base/$platlibdir/python', 'headers': '$base/include/python/$dist_name', 'scripts': '$base/bin', 'data' : '$base', }, 'nt': WINDOWS_SCHEME, 'pypy': { 'purelib': '$base/site-packages', 'platlib': '$base/site-packages', 'headers': '$base/include/$dist_name', 'scripts': '$base/bin', 'data' : '$base', }, 'pypy_nt': { 'purelib': '$base/site-packages', 'platlib': '$base/site-packages', 'headers': '$base/include/$dist_name', 'scripts': '$base/Scripts', 'data' : '$base', }, } # user site schemes if HAS_USER_SITE: INSTALL_SCHEMES['nt_user'] = { 'purelib': '$usersite', 'platlib': '$usersite', 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name', 'scripts': '$userbase/Python$py_version_nodot/Scripts', 'data' : '$userbase', } INSTALL_SCHEMES['unix_user'] = { 'purelib': '$usersite', 'platlib': '$usersite', 'headers': '$userbase/include/python$py_version_short$abiflags/$dist_name', 'scripts': '$userbase/bin', 'data' : '$userbase', } # The keys to an installation scheme; if any new types of files are to be # installed, be sure to add an entry to every installation scheme above, # and to SCHEME_KEYS here. SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data') class install(Command): description = "install everything from build directory" user_options = [ # Select installation scheme and set base director(y|ies) ('prefix=', None, "installation prefix"), ('exec-prefix=', None, "(Unix only) prefix for platform-specific files"), ('home=', None, "(Unix only) home directory to install under"), # Or, just set the base director(y|ies) ('install-base=', None, "base installation directory (instead of --prefix or --home)"), ('install-platbase=', None, "base installation directory for platform-specific files " + "(instead of --exec-prefix or --home)"), ('root=', None, "install everything relative to this alternate root directory"), # Or, explicitly set the installation scheme ('install-purelib=', None, "installation directory for pure Python module distributions"), ('install-platlib=', None, "installation directory for non-pure module distributions"), ('install-lib=', None, "installation directory for all module distributions " + "(overrides --install-purelib and --install-platlib)"), ('install-headers=', None, "installation directory for C/C++ headers"), ('install-scripts=', None, "installation directory for Python scripts"), ('install-data=', None, "installation directory for data files"), # Byte-compilation options -- see install_lib.py for details, as # these are duplicated from there (but only install_lib does # anything with them). ('compile', 'c', "compile .py to .pyc [default]"), ('no-compile', None, "don't compile .py files"), ('optimize=', 'O', "also compile with optimization: -O1 for \"python -O\", " "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), # Miscellaneous control options ('force', 'f', "force installation (overwrite any existing files)"), ('skip-build', None, "skip rebuilding everything (for testing/debugging)"), # Where to install documentation (eventually!) #('doc-format=', None, "format of documentation to generate"), #('install-man=', None, "directory for Unix man pages"), #('install-html=', None, "directory for HTML documentation"), #('install-info=', None, "directory for GNU info files"), ('record=', None, "filename in which to record list of installed files"), ] boolean_options = ['compile', 'force', 'skip-build'] if HAS_USER_SITE: user_options.append(('user', None, "install in user site-package '%s'" % USER_SITE)) boolean_options.append('user') negative_opt = {'no-compile' : 'compile'} def initialize_options(self): """Initializes options.""" # High-level options: these select both an installation base # and scheme. self.prefix = None self.exec_prefix = None self.home = None self.user = 0 # These select only the installation base; it's up to the user to # specify the installation scheme (currently, that means supplying # the --install-{platlib,purelib,scripts,data} options). self.install_base = None self.install_platbase = None self.root = None # These options are the actual installation directories; if not # supplied by the user, they are filled in using the installation # scheme implied by prefix/exec-prefix/home and the contents of # that installation scheme. self.install_purelib = None # for pure module distributions self.install_platlib = None # non-pure (dists w/ extensions) self.install_headers = None # for C/C++ headers self.install_lib = None # set to either purelib or platlib self.install_scripts = None self.install_data = None self.install_userbase = USER_BASE self.install_usersite = USER_SITE self.compile = None self.optimize = None # Deprecated # These two are for putting non-packagized distributions into their # own directory and creating a .pth file if it makes sense. # 'extra_path' comes from the setup file; 'install_path_file' can # be turned off if it makes no sense to install a .pth file. (But # better to install it uselessly than to guess wrong and not # install it when it's necessary and would be used!) Currently, # 'install_path_file' is always true unless some outsider meddles # with it. self.extra_path = None self.install_path_file = 1 # 'force' forces installation, even if target files are not # out-of-date. 'skip_build' skips running the "build" command, # handy if you know it's not necessary. 'warn_dir' (which is *not* # a user option, it's just there so the bdist_* commands can turn # it off) determines whether we warn about installing to a # directory not in sys.path. self.force = 0 self.skip_build = 0 self.warn_dir = 1 # These are only here as a conduit from the 'build' command to the # 'install_*' commands that do the real work. ('build_base' isn't # actually used anywhere, but it might be useful in future.) They # are not user options, because if the user told the install # command where the build directory is, that wouldn't affect the # build command. self.build_base = None self.build_lib = None # Not defined yet because we don't know anything about # documentation yet. #self.install_man = None #self.install_html = None #self.install_info = None self.record = None # -- Option finalizing methods ------------------------------------- # (This is rather more involved than for most commands, # because this is where the policy for installing third- # party Python modules on various platforms given a wide # array of user input is decided. Yes, it's quite complex!) def finalize_options(self): """Finalizes options.""" # This method (and its helpers, like 'finalize_unix()', # 'finalize_other()', and 'select_scheme()') is where the default # installation directories for modules, extension modules, and # anything else we care to install from a Python module # distribution. Thus, this code makes a pretty important policy # statement about how third-party stuff is added to a Python # installation! Note that the actual work of installation is done # by the relatively simple 'install_*' commands; they just take # their orders from the installation directory options determined # here. # Check for errors/inconsistencies in the options; first, stuff # that's wrong on any platform. if ((self.prefix or self.exec_prefix or self.home) and (self.install_base or self.install_platbase)): raise DistutilsOptionError( "must supply either prefix/exec-prefix/home or " + "install-base/install-platbase -- not both") if self.home and (self.prefix or self.exec_prefix): raise DistutilsOptionError( "must supply either home or prefix/exec-prefix -- not both") if self.user and (self.prefix or self.exec_prefix or self.home or self.install_base or self.install_platbase): raise DistutilsOptionError("can't combine user with prefix, " "exec_prefix/home, or install_(plat)base") # Next, stuff that's wrong (or dubious) only on certain platforms. if os.name != "posix": if self.exec_prefix: self.warn("exec-prefix option ignored on this platform") self.exec_prefix = None # Now the interesting logic -- so interesting that we farm it out # to other methods. The goal of these methods is to set the final # values for the install_{lib,scripts,data,...} options, using as # input a heady brew of prefix, exec_prefix, home, install_base, # install_platbase, user-supplied versions of # install_{purelib,platlib,lib,scripts,data,...}, and the # INSTALL_SCHEME dictionary above. Phew! self.dump_dirs("pre-finalize_{unix,other}") if os.name == 'posix': self.finalize_unix() else: self.finalize_other() self.dump_dirs("post-finalize_{unix,other}()") # Expand configuration variables, tilde, etc. in self.install_base # and self.install_platbase -- that way, we can use $base or # $platbase in the other installation directories and not worry # about needing recursive variable expansion (shudder). py_version = sys.version.split()[0] (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix') try: abiflags = sys.abiflags except AttributeError: # sys.abiflags may not be defined on all platforms. abiflags = '' self.config_vars = {'dist_name': self.distribution.get_name(), 'dist_version': self.distribution.get_version(), 'dist_fullname': self.distribution.get_fullname(), 'py_version': py_version, 'py_version_short': '%d.%d' % sys.version_info[:2], 'py_version_nodot': '%d%d' % sys.version_info[:2], 'sys_prefix': prefix, 'prefix': prefix, 'sys_exec_prefix': exec_prefix, 'exec_prefix': exec_prefix, 'abiflags': abiflags, 'platlibdir': getattr(sys, 'platlibdir', 'lib'), } if HAS_USER_SITE: self.config_vars['userbase'] = self.install_userbase self.config_vars['usersite'] = self.install_usersite self.expand_basedirs() self.dump_dirs("post-expand_basedirs()") # Now define config vars for the base directories so we can expand # everything else. self.config_vars['base'] = self.install_base self.config_vars['platbase'] = self.install_platbase if DEBUG: from pprint import pprint print("config vars:") pprint(self.config_vars) # Expand "~" and configuration variables in the installation # directories. self.expand_dirs() self.dump_dirs("post-expand_dirs()") # Create directories in the home dir: if self.user: self.create_home_path() # Pick the actual directory to install all modules to: either # install_purelib or install_platlib, depending on whether this # module distribution is pure or not. Of course, if the user # already specified install_lib, use their selection. if self.install_lib is None: if self.distribution.has_ext_modules(): # has extensions: non-pure self.install_lib = self.install_platlib else: self.install_lib = self.install_purelib # Convert directories from Unix /-separated syntax to the local # convention. self.convert_paths('lib', 'purelib', 'platlib', 'scripts', 'data', 'headers', 'userbase', 'usersite') # Deprecated # Well, we're not actually fully completely finalized yet: we still # have to deal with 'extra_path', which is the hack for allowing # non-packagized module distributions (hello, Numerical Python!) to # get their own directories. self.handle_extra_path() self.install_libbase = self.install_lib # needed for .pth file self.install_lib = os.path.join(self.install_lib, self.extra_dirs) # If a new root directory was supplied, make all the installation # dirs relative to it. if self.root is not None: self.change_roots('libbase', 'lib', 'purelib', 'platlib', 'scripts', 'data', 'headers') self.dump_dirs("after prepending root") # Find out the build directories, ie. where to install from. self.set_undefined_options('build', ('build_base', 'build_base'), ('build_lib', 'build_lib')) # Punt on doc directories for now -- after all, we're punting on # documentation completely! def dump_dirs(self, msg): """Dumps the list of user options.""" if not DEBUG: return from distutils.fancy_getopt import longopt_xlate log.debug(msg + ":") for opt in self.user_options: opt_name = opt[0] if opt_name[-1] == "=": opt_name = opt_name[0:-1] if opt_name in self.negative_opt: opt_name = self.negative_opt[opt_name] opt_name = opt_name.translate(longopt_xlate) val = not getattr(self, opt_name) else: opt_name = opt_name.translate(longopt_xlate) val = getattr(self, opt_name) log.debug(" %s: %s", opt_name, val) def finalize_unix(self): """Finalizes options for posix platforms.""" if self.install_base is not None or self.install_platbase is not None: if ((self.install_lib is None and self.install_purelib is None and self.install_platlib is None) or self.install_headers is None or self.install_scripts is None or self.install_data is None): raise DistutilsOptionError( "install-base or install-platbase supplied, but " "installation scheme is incomplete") return if self.user: if self.install_userbase is None: raise DistutilsPlatformError( "User base directory is not specified") self.install_base = self.install_platbase = self.install_userbase self.select_scheme("unix_user") elif self.home is not None: self.install_base = self.install_platbase = self.home self.select_scheme("unix_home") else: if self.prefix is None: if self.exec_prefix is not None: raise DistutilsOptionError( "must not supply exec-prefix without prefix") self.prefix = os.path.normpath(sys.prefix) self.exec_prefix = os.path.normpath(sys.exec_prefix) else: if self.exec_prefix is None: self.exec_prefix = self.prefix self.install_base = self.prefix self.install_platbase = self.exec_prefix self.select_scheme("unix_prefix") def finalize_other(self): """Finalizes options for non-posix platforms""" if self.user: if self.install_userbase is None: raise DistutilsPlatformError( "User base directory is not specified") self.install_base = self.install_platbase = self.install_userbase self.select_scheme(os.name + "_user") elif self.home is not None: self.install_base = self.install_platbase = self.home self.select_scheme("unix_home") else: if self.prefix is None: self.prefix = os.path.normpath(sys.prefix) self.install_base = self.install_platbase = self.prefix try: self.select_scheme(os.name) except KeyError: raise DistutilsPlatformError( "I don't know how to install stuff on '%s'" % os.name) def select_scheme(self, name): """Sets the install directories by applying the install schemes.""" # it's the caller's problem if they supply a bad name! if (hasattr(sys, 'pypy_version_info') and sys.version_info < (3, 8) and not name.endswith(('_user', '_home'))): if os.name == 'nt': name = 'pypy_nt' else: name = 'pypy' scheme = INSTALL_SCHEMES[name] for key in SCHEME_KEYS: attrname = 'install_' + key if getattr(self, attrname) is None: setattr(self, attrname, scheme[key]) def _expand_attrs(self, attrs): for attr in attrs: val = getattr(self, attr) if val is not None: if os.name == 'posix' or os.name == 'nt': val = os.path.expanduser(val) val = subst_vars(val, self.config_vars) setattr(self, attr, val) def expand_basedirs(self): """Calls `os.path.expanduser` on install_base, install_platbase and root.""" self._expand_attrs(['install_base', 'install_platbase', 'root']) def expand_dirs(self): """Calls `os.path.expanduser` on install dirs.""" self._expand_attrs(['install_purelib', 'install_platlib', 'install_lib', 'install_headers', 'install_scripts', 'install_data',]) def convert_paths(self, *names): """Call `convert_path` over `names`.""" for name in names: attr = "install_" + name setattr(self, attr, convert_path(getattr(self, attr))) def handle_extra_path(self): """Set `path_file` and `extra_dirs` using `extra_path`.""" if self.extra_path is None: self.extra_path = self.distribution.extra_path if self.extra_path is not None: log.warn( "Distribution option extra_path is deprecated. " "See issue27919 for details." ) if isinstance(self.extra_path, str): self.extra_path = self.extra_path.split(',') if len(self.extra_path) == 1: path_file = extra_dirs = self.extra_path[0] elif len(self.extra_path) == 2: path_file, extra_dirs = self.extra_path else: raise DistutilsOptionError( "'extra_path' option must be a list, tuple, or " "comma-separated string with 1 or 2 elements") # convert to local form in case Unix notation used (as it # should be in setup scripts) extra_dirs = convert_path(extra_dirs) else: path_file = None extra_dirs = '' # XXX should we warn if path_file and not extra_dirs? (in which # case the path file would be harmless but pointless) self.path_file = path_file self.extra_dirs = extra_dirs def change_roots(self, *names): """Change the install directories pointed by name using root.""" for name in names: attr = "install_" + name setattr(self, attr, change_root(self.root, getattr(self, attr))) def create_home_path(self): """Create directories under ~.""" if not self.user: return home = convert_path(os.path.expanduser("~")) for name, path in self.config_vars.items(): if path.startswith(home) and not os.path.isdir(path): self.debug_print("os.makedirs('%s', 0o700)" % path) os.makedirs(path, 0o700) # -- Command execution methods ------------------------------------- def run(self): """Runs the command.""" # Obviously have to build before we can install if not self.skip_build: self.run_command('build') # If we built for any other platform, we can't install. build_plat = self.distribution.get_command_obj('build').plat_name # check warn_dir - it is a clue that the 'install' is happening # internally, and not to sys.path, so we don't check the platform # matches what we are running. if self.warn_dir and build_plat != get_platform(): raise DistutilsPlatformError("Can't install when " "cross-compiling") # Run all sub-commands (at least those that need to be run) for cmd_name in self.get_sub_commands(): self.run_command(cmd_name) if self.path_file: self.create_path_file() # write list of installed files, if requested. if self.record: outputs = self.get_outputs() if self.root: # strip any package prefix root_len = len(self.root) for counter in range(len(outputs)): outputs[counter] = outputs[counter][root_len:] self.execute(write_file, (self.record, outputs), "writing list of installed files to '%s'" % self.record) sys_path = map(os.path.normpath, sys.path) sys_path = map(os.path.normcase, sys_path) install_lib = os.path.normcase(os.path.normpath(self.install_lib)) if (self.warn_dir and not (self.path_file and self.install_path_file) and install_lib not in sys_path): log.debug(("modules installed to '%s', which is not in " "Python's module search path (sys.path) -- " "you'll have to change the search path yourself"), self.install_lib) def create_path_file(self): """Creates the .pth file""" filename = os.path.join(self.install_libbase, self.path_file + ".pth") if self.install_path_file: self.execute(write_file, (filename, [self.extra_dirs]), "creating %s" % filename) else: self.warn("path file '%s' not created" % filename) # -- Reporting methods --------------------------------------------- def get_outputs(self): """Assembles the outputs of all the sub-commands.""" outputs = [] for cmd_name in self.get_sub_commands(): cmd = self.get_finalized_command(cmd_name) # Add the contents of cmd.get_outputs(), ensuring # that outputs doesn't contain duplicate entries for filename in cmd.get_outputs(): if filename not in outputs: outputs.append(filename) if self.path_file and self.install_path_file: outputs.append(os.path.join(self.install_libbase, self.path_file + ".pth")) return outputs def get_inputs(self): """Returns the inputs of all the sub-commands""" # XXX gee, this looks familiar ;-( inputs = [] for cmd_name in self.get_sub_commands(): cmd = self.get_finalized_command(cmd_name) inputs.extend(cmd.get_inputs()) return inputs # -- Predicates for sub-command list ------------------------------- def has_lib(self): """Returns true if the current distribution has any Python modules to install.""" return (self.distribution.has_pure_modules() or self.distribution.has_ext_modules()) def has_headers(self): """Returns true if the current distribution has any headers to install.""" return self.distribution.has_headers() def has_scripts(self): """Returns true if the current distribution has any scripts to. install.""" return self.distribution.has_scripts() def has_data(self): """Returns true if the current distribution has any data to. install.""" return self.distribution.has_data_files() # 'sub_commands': a list of commands this command might have to run to # get its work done. See cmd.py for more info. sub_commands = [('install_lib', has_lib), ('install_headers', has_headers), ('install_scripts', has_scripts), ('install_data', has_data), ('install_egg_info', lambda self:True), ] PKH]d]!T!TCpython3.10/site-packages/setuptools/_distutils/command/bdist_rpm.pynu["""distutils.command.bdist_rpm Implements the Distutils 'bdist_rpm' command (create RPM source and binary distributions).""" import subprocess, sys, os from distutils.core import Command from distutils.debug import DEBUG from distutils.file_util import write_file from distutils.errors import * from distutils.sysconfig import get_python_version from distutils import log class bdist_rpm(Command): description = "create an RPM distribution" user_options = [ ('bdist-base=', None, "base directory for creating built distributions"), ('rpm-base=', None, "base directory for creating RPMs (defaults to \"rpm\" under " "--bdist-base; must be specified for RPM 2)"), ('dist-dir=', 'd', "directory to put final RPM files in " "(and .spec files if --spec-only)"), ('python=', None, "path to Python interpreter to hard-code in the .spec file " "(default: \"python\")"), ('fix-python', None, "hard-code the exact path to the current Python interpreter in " "the .spec file"), ('spec-only', None, "only regenerate spec file"), ('source-only', None, "only generate source RPM"), ('binary-only', None, "only generate binary RPM"), ('use-bzip2', None, "use bzip2 instead of gzip to create source distribution"), # More meta-data: too RPM-specific to put in the setup script, # but needs to go in the .spec file -- so we make these options # to "bdist_rpm". The idea is that packagers would put this # info in setup.cfg, although they are of course free to # supply it on the command line. ('distribution-name=', None, "name of the (Linux) distribution to which this " "RPM applies (*not* the name of the module distribution!)"), ('group=', None, "package classification [default: \"Development/Libraries\"]"), ('release=', None, "RPM release number"), ('serial=', None, "RPM serial number"), ('vendor=', None, "RPM \"vendor\" (eg. \"Joe Blow \") " "[default: maintainer or author from setup script]"), ('packager=', None, "RPM packager (eg. \"Jane Doe \") " "[default: vendor]"), ('doc-files=', None, "list of documentation files (space or comma-separated)"), ('changelog=', None, "RPM changelog"), ('icon=', None, "name of icon file"), ('provides=', None, "capabilities provided by this package"), ('requires=', None, "capabilities required by this package"), ('conflicts=', None, "capabilities which conflict with this package"), ('build-requires=', None, "capabilities required to build this package"), ('obsoletes=', None, "capabilities made obsolete by this package"), ('no-autoreq', None, "do not automatically calculate dependencies"), # Actions to take when building RPM ('keep-temp', 'k', "don't clean up RPM build directory"), ('no-keep-temp', None, "clean up RPM build directory [default]"), ('use-rpm-opt-flags', None, "compile with RPM_OPT_FLAGS when building from source RPM"), ('no-rpm-opt-flags', None, "do not pass any RPM CFLAGS to compiler"), ('rpm3-mode', None, "RPM 3 compatibility mode (default)"), ('rpm2-mode', None, "RPM 2 compatibility mode"), # Add the hooks necessary for specifying custom scripts ('prep-script=', None, "Specify a script for the PREP phase of RPM building"), ('build-script=', None, "Specify a script for the BUILD phase of RPM building"), ('pre-install=', None, "Specify a script for the pre-INSTALL phase of RPM building"), ('install-script=', None, "Specify a script for the INSTALL phase of RPM building"), ('post-install=', None, "Specify a script for the post-INSTALL phase of RPM building"), ('pre-uninstall=', None, "Specify a script for the pre-UNINSTALL phase of RPM building"), ('post-uninstall=', None, "Specify a script for the post-UNINSTALL phase of RPM building"), ('clean-script=', None, "Specify a script for the CLEAN phase of RPM building"), ('verify-script=', None, "Specify a script for the VERIFY phase of the RPM build"), # Allow a packager to explicitly force an architecture ('force-arch=', None, "Force an architecture onto the RPM build process"), ('quiet', 'q', "Run the INSTALL phase of RPM building in quiet mode"), ] boolean_options = ['keep-temp', 'use-rpm-opt-flags', 'rpm3-mode', 'no-autoreq', 'quiet'] negative_opt = {'no-keep-temp': 'keep-temp', 'no-rpm-opt-flags': 'use-rpm-opt-flags', 'rpm2-mode': 'rpm3-mode'} def initialize_options(self): self.bdist_base = None self.rpm_base = None self.dist_dir = None self.python = None self.fix_python = None self.spec_only = None self.binary_only = None self.source_only = None self.use_bzip2 = None self.distribution_name = None self.group = None self.release = None self.serial = None self.vendor = None self.packager = None self.doc_files = None self.changelog = None self.icon = None self.prep_script = None self.build_script = None self.install_script = None self.clean_script = None self.verify_script = None self.pre_install = None self.post_install = None self.pre_uninstall = None self.post_uninstall = None self.prep = None self.provides = None self.requires = None self.conflicts = None self.build_requires = None self.obsoletes = None self.keep_temp = 0 self.use_rpm_opt_flags = 1 self.rpm3_mode = 1 self.no_autoreq = 0 self.force_arch = None self.quiet = 0 def finalize_options(self): self.set_undefined_options('bdist', ('bdist_base', 'bdist_base')) if self.rpm_base is None: if not self.rpm3_mode: raise DistutilsOptionError( "you must specify --rpm-base in RPM 2 mode") self.rpm_base = os.path.join(self.bdist_base, "rpm") if self.python is None: if self.fix_python: self.python = sys.executable else: self.python = "python3" elif self.fix_python: raise DistutilsOptionError( "--python and --fix-python are mutually exclusive options") if os.name != 'posix': raise DistutilsPlatformError("don't know how to create RPM " "distributions on platform %s" % os.name) if self.binary_only and self.source_only: raise DistutilsOptionError( "cannot supply both '--source-only' and '--binary-only'") # don't pass CFLAGS to pure python distributions if not self.distribution.has_ext_modules(): self.use_rpm_opt_flags = 0 self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) self.finalize_package_data() def finalize_package_data(self): self.ensure_string('group', "Development/Libraries") self.ensure_string('vendor', "%s <%s>" % (self.distribution.get_contact(), self.distribution.get_contact_email())) self.ensure_string('packager') self.ensure_string_list('doc_files') if isinstance(self.doc_files, list): for readme in ('README', 'README.txt'): if os.path.exists(readme) and readme not in self.doc_files: self.doc_files.append(readme) self.ensure_string('release', "1") self.ensure_string('serial') # should it be an int? self.ensure_string('distribution_name') self.ensure_string('changelog') # Format changelog correctly self.changelog = self._format_changelog(self.changelog) self.ensure_filename('icon') self.ensure_filename('prep_script') self.ensure_filename('build_script') self.ensure_filename('install_script') self.ensure_filename('clean_script') self.ensure_filename('verify_script') self.ensure_filename('pre_install') self.ensure_filename('post_install') self.ensure_filename('pre_uninstall') self.ensure_filename('post_uninstall') # XXX don't forget we punted on summaries and descriptions -- they # should be handled here eventually! # Now *this* is some meta-data that belongs in the setup script... self.ensure_string_list('provides') self.ensure_string_list('requires') self.ensure_string_list('conflicts') self.ensure_string_list('build_requires') self.ensure_string_list('obsoletes') self.ensure_string('force_arch') def run(self): if DEBUG: print("before _get_package_data():") print("vendor =", self.vendor) print("packager =", self.packager) print("doc_files =", self.doc_files) print("changelog =", self.changelog) # make directories if self.spec_only: spec_dir = self.dist_dir self.mkpath(spec_dir) else: rpm_dir = {} for d in ('SOURCES', 'SPECS', 'BUILD', 'RPMS', 'SRPMS'): rpm_dir[d] = os.path.join(self.rpm_base, d) self.mkpath(rpm_dir[d]) spec_dir = rpm_dir['SPECS'] # Spec file goes into 'dist_dir' if '--spec-only specified', # build/rpm. otherwise. spec_path = os.path.join(spec_dir, "%s.spec" % self.distribution.get_name()) self.execute(write_file, (spec_path, self._make_spec_file()), "writing '%s'" % spec_path) if self.spec_only: # stop if requested return # Make a source distribution and copy to SOURCES directory with # optional icon. saved_dist_files = self.distribution.dist_files[:] sdist = self.reinitialize_command('sdist') if self.use_bzip2: sdist.formats = ['bztar'] else: sdist.formats = ['gztar'] self.run_command('sdist') self.distribution.dist_files = saved_dist_files source = sdist.get_archive_files()[0] source_dir = rpm_dir['SOURCES'] self.copy_file(source, source_dir) if self.icon: if os.path.exists(self.icon): self.copy_file(self.icon, source_dir) else: raise DistutilsFileError( "icon file '%s' does not exist" % self.icon) # build package log.info("building RPMs") rpm_cmd = ['rpmbuild'] if self.source_only: # what kind of RPMs? rpm_cmd.append('-bs') elif self.binary_only: rpm_cmd.append('-bb') else: rpm_cmd.append('-ba') rpm_cmd.extend(['--define', '__python %s' % self.python]) if self.rpm3_mode: rpm_cmd.extend(['--define', '_topdir %s' % os.path.abspath(self.rpm_base)]) if not self.keep_temp: rpm_cmd.append('--clean') if self.quiet: rpm_cmd.append('--quiet') rpm_cmd.append(spec_path) # Determine the binary rpm names that should be built out of this spec # file # Note that some of these may not be really built (if the file # list is empty) nvr_string = "%{name}-%{version}-%{release}" src_rpm = nvr_string + ".src.rpm" non_src_rpm = "%{arch}/" + nvr_string + ".%{arch}.rpm" q_cmd = r"rpm -q --qf '%s %s\n' --specfile '%s'" % ( src_rpm, non_src_rpm, spec_path) out = os.popen(q_cmd) try: binary_rpms = [] source_rpm = None while True: line = out.readline() if not line: break l = line.strip().split() assert(len(l) == 2) binary_rpms.append(l[1]) # The source rpm is named after the first entry in the spec file if source_rpm is None: source_rpm = l[0] status = out.close() if status: raise DistutilsExecError("Failed to execute: %s" % repr(q_cmd)) finally: out.close() self.spawn(rpm_cmd) if not self.dry_run: if self.distribution.has_ext_modules(): pyversion = get_python_version() else: pyversion = 'any' if not self.binary_only: srpm = os.path.join(rpm_dir['SRPMS'], source_rpm) assert(os.path.exists(srpm)) self.move_file(srpm, self.dist_dir) filename = os.path.join(self.dist_dir, source_rpm) self.distribution.dist_files.append( ('bdist_rpm', pyversion, filename)) if not self.source_only: for rpm in binary_rpms: rpm = os.path.join(rpm_dir['RPMS'], rpm) if os.path.exists(rpm): self.move_file(rpm, self.dist_dir) filename = os.path.join(self.dist_dir, os.path.basename(rpm)) self.distribution.dist_files.append( ('bdist_rpm', pyversion, filename)) def _dist_path(self, path): return os.path.join(self.dist_dir, os.path.basename(path)) def _make_spec_file(self): """Generate the text of an RPM spec file and return it as a list of strings (one per line). """ # definitions and headers spec_file = [ '%define name ' + self.distribution.get_name(), '%define version ' + self.distribution.get_version().replace('-','_'), '%define unmangled_version ' + self.distribution.get_version(), '%define release ' + self.release.replace('-','_'), '', 'Summary: ' + self.distribution.get_description(), ] # Workaround for #14443 which affects some RPM based systems such as # RHEL6 (and probably derivatives) vendor_hook = subprocess.getoutput('rpm --eval %{__os_install_post}') # Generate a potential replacement value for __os_install_post (whilst # normalizing the whitespace to simplify the test for whether the # invocation of brp-python-bytecompile passes in __python): vendor_hook = '\n'.join([' %s \\' % line.strip() for line in vendor_hook.splitlines()]) problem = "brp-python-bytecompile \\\n" fixed = "brp-python-bytecompile %{__python} \\\n" fixed_hook = vendor_hook.replace(problem, fixed) if fixed_hook != vendor_hook: spec_file.append('# Workaround for http://bugs.python.org/issue14443') spec_file.append('%define __os_install_post ' + fixed_hook + '\n') # put locale summaries into spec file # XXX not supported for now (hard to put a dictionary # in a config file -- arg!) #for locale in self.summaries.keys(): # spec_file.append('Summary(%s): %s' % (locale, # self.summaries[locale])) spec_file.extend([ 'Name: %{name}', 'Version: %{version}', 'Release: %{release}',]) # XXX yuck! this filename is available from the "sdist" command, # but only after it has run: and we create the spec file before # running "sdist", in case of --spec-only. if self.use_bzip2: spec_file.append('Source0: %{name}-%{unmangled_version}.tar.bz2') else: spec_file.append('Source0: %{name}-%{unmangled_version}.tar.gz') spec_file.extend([ 'License: ' + self.distribution.get_license(), 'Group: ' + self.group, 'BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot', 'Prefix: %{_prefix}', ]) if not self.force_arch: # noarch if no extension modules if not self.distribution.has_ext_modules(): spec_file.append('BuildArch: noarch') else: spec_file.append( 'BuildArch: %s' % self.force_arch ) for field in ('Vendor', 'Packager', 'Provides', 'Requires', 'Conflicts', 'Obsoletes', ): val = getattr(self, field.lower()) if isinstance(val, list): spec_file.append('%s: %s' % (field, ' '.join(val))) elif val is not None: spec_file.append('%s: %s' % (field, val)) if self.distribution.get_url() != 'UNKNOWN': spec_file.append('Url: ' + self.distribution.get_url()) if self.distribution_name: spec_file.append('Distribution: ' + self.distribution_name) if self.build_requires: spec_file.append('BuildRequires: ' + ' '.join(self.build_requires)) if self.icon: spec_file.append('Icon: ' + os.path.basename(self.icon)) if self.no_autoreq: spec_file.append('AutoReq: 0') spec_file.extend([ '', '%description', self.distribution.get_long_description() ]) # put locale descriptions into spec file # XXX again, suppressed because config file syntax doesn't # easily support this ;-( #for locale in self.descriptions.keys(): # spec_file.extend([ # '', # '%description -l ' + locale, # self.descriptions[locale], # ]) # rpm scripts # figure out default build script def_setup_call = "%s %s" % (self.python,os.path.basename(sys.argv[0])) def_build = "%s build" % def_setup_call if self.use_rpm_opt_flags: def_build = 'env CFLAGS="$RPM_OPT_FLAGS" ' + def_build # insert contents of files # XXX this is kind of misleading: user-supplied options are files # that we open and interpolate into the spec file, but the defaults # are just text that we drop in as-is. Hmmm. install_cmd = ('%s install -O1 --root=$RPM_BUILD_ROOT ' '--record=INSTALLED_FILES') % def_setup_call script_options = [ ('prep', 'prep_script', "%setup -n %{name}-%{unmangled_version}"), ('build', 'build_script', def_build), ('install', 'install_script', install_cmd), ('clean', 'clean_script', "rm -rf $RPM_BUILD_ROOT"), ('verifyscript', 'verify_script', None), ('pre', 'pre_install', None), ('post', 'post_install', None), ('preun', 'pre_uninstall', None), ('postun', 'post_uninstall', None), ] for (rpm_opt, attr, default) in script_options: # Insert contents of file referred to, if no file is referred to # use 'default' as contents of script val = getattr(self, attr) if val or default: spec_file.extend([ '', '%' + rpm_opt,]) if val: with open(val) as f: spec_file.extend(f.read().split('\n')) else: spec_file.append(default) # files section spec_file.extend([ '', '%files -f INSTALLED_FILES', '%defattr(-,root,root)', ]) if self.doc_files: spec_file.append('%doc ' + ' '.join(self.doc_files)) if self.changelog: spec_file.extend([ '', '%changelog',]) spec_file.extend(self.changelog) return spec_file def _format_changelog(self, changelog): """Format the changelog correctly and convert it to a list of strings """ if not changelog: return changelog new_changelog = [] for line in changelog.strip().split('\n'): line = line.strip() if line[0] == '*': new_changelog.extend(['', line]) elif line[0] == '-': new_changelog.append(line) else: new_changelog.append(' ' + line) # strip trailing newline inserted by first changelog entry if not new_changelog[0]: del new_changelog[0] return new_changelog PKH]w11Dpython3.10/site-packages/setuptools/_distutils/command/bdist_dumb.pynu["""distutils.command.bdist_dumb Implements the Distutils 'bdist_dumb' command (create a "dumb" built distribution -- i.e., just an archive to be unpacked under $prefix or $exec_prefix).""" import os from distutils.core import Command from distutils.util import get_platform from distutils.dir_util import remove_tree, ensure_relative from distutils.errors import * from distutils.sysconfig import get_python_version from distutils import log class bdist_dumb(Command): description = "create a \"dumb\" built distribution" user_options = [('bdist-dir=', 'd', "temporary directory for creating the distribution"), ('plat-name=', 'p', "platform name to embed in generated filenames " "(default: %s)" % get_platform()), ('format=', 'f', "archive format to create (tar, gztar, bztar, xztar, " "ztar, zip)"), ('keep-temp', 'k', "keep the pseudo-installation tree around after " + "creating the distribution archive"), ('dist-dir=', 'd', "directory to put final built distributions in"), ('skip-build', None, "skip rebuilding everything (for testing/debugging)"), ('relative', None, "build the archive using relative paths " "(default: false)"), ('owner=', 'u', "Owner name used when creating a tar file" " [default: current user]"), ('group=', 'g', "Group name used when creating a tar file" " [default: current group]"), ] boolean_options = ['keep-temp', 'skip-build', 'relative'] default_format = { 'posix': 'gztar', 'nt': 'zip' } def initialize_options(self): self.bdist_dir = None self.plat_name = None self.format = None self.keep_temp = 0 self.dist_dir = None self.skip_build = None self.relative = 0 self.owner = None self.group = None def finalize_options(self): if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'dumb') if self.format is None: try: self.format = self.default_format[os.name] except KeyError: raise DistutilsPlatformError( "don't know how to create dumb built distributions " "on platform %s" % os.name) self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'), ('plat_name', 'plat_name'), ('skip_build', 'skip_build')) def run(self): if not self.skip_build: self.run_command('build') install = self.reinitialize_command('install', reinit_subcommands=1) install.root = self.bdist_dir install.skip_build = self.skip_build install.warn_dir = 0 log.info("installing to %s", self.bdist_dir) self.run_command('install') # And make an archive relative to the root of the # pseudo-installation tree. archive_basename = "%s.%s" % (self.distribution.get_fullname(), self.plat_name) pseudoinstall_root = os.path.join(self.dist_dir, archive_basename) if not self.relative: archive_root = self.bdist_dir else: if (self.distribution.has_ext_modules() and (install.install_base != install.install_platbase)): raise DistutilsPlatformError( "can't make a dumb built distribution where " "base and platbase are different (%s, %s)" % (repr(install.install_base), repr(install.install_platbase))) else: archive_root = os.path.join(self.bdist_dir, ensure_relative(install.install_base)) # Make the archive filename = self.make_archive(pseudoinstall_root, self.format, root_dir=archive_root, owner=self.owner, group=self.group) if self.distribution.has_ext_modules(): pyversion = get_python_version() else: pyversion = 'any' self.distribution.dist_files.append(('bdist_dumb', pyversion, filename)) if not self.keep_temp: remove_tree(self.bdist_dir, dry_run=self.dry_run) PKH]84,KKGpython3.10/site-packages/setuptools/_distutils/command/build_scripts.pynu["""distutils.command.build_scripts Implements the Distutils 'build_scripts' command.""" import os, re from stat import ST_MODE from distutils import sysconfig from distutils.core import Command from distutils.dep_util import newer from distutils.util import convert_path from distutils import log import tokenize # check if Python is called on the first line with this expression first_line_re = re.compile(b'^#!.*python[0-9.]*([ \t].*)?$') class build_scripts(Command): description = "\"build\" scripts (copy and fixup #! line)" user_options = [ ('build-dir=', 'd', "directory to \"build\" (copy) to"), ('force', 'f', "forcibly build everything (ignore file timestamps"), ('executable=', 'e', "specify final destination interpreter path"), ] boolean_options = ['force'] def initialize_options(self): self.build_dir = None self.scripts = None self.force = None self.executable = None self.outfiles = None def finalize_options(self): self.set_undefined_options('build', ('build_scripts', 'build_dir'), ('force', 'force'), ('executable', 'executable')) self.scripts = self.distribution.scripts def get_source_files(self): return self.scripts def run(self): if not self.scripts: return self.copy_scripts() def copy_scripts(self): r"""Copy each script listed in 'self.scripts'; if it's marked as a Python script in the Unix way (first line matches 'first_line_re', ie. starts with "\#!" and contains "python"), then adjust the first line to refer to the current Python interpreter as we copy. """ self.mkpath(self.build_dir) outfiles = [] updated_files = [] for script in self.scripts: adjust = False script = convert_path(script) outfile = os.path.join(self.build_dir, os.path.basename(script)) outfiles.append(outfile) if not self.force and not newer(script, outfile): log.debug("not copying %s (up-to-date)", script) continue # Always open the file, but ignore failures in dry-run mode -- # that way, we'll get accurate feedback if we can read the # script. try: f = open(script, "rb") except OSError: if not self.dry_run: raise f = None else: encoding, lines = tokenize.detect_encoding(f.readline) f.seek(0) first_line = f.readline() if not first_line: self.warn("%s is an empty file (skipping)" % script) continue match = first_line_re.match(first_line) if match: adjust = True post_interp = match.group(1) or b'' if adjust: log.info("copying and adjusting %s -> %s", script, self.build_dir) updated_files.append(outfile) if not self.dry_run: if not sysconfig.python_build: executable = self.executable else: executable = os.path.join( sysconfig.get_config_var("BINDIR"), "python%s%s" % (sysconfig.get_config_var("VERSION"), sysconfig.get_config_var("EXE"))) executable = os.fsencode(executable) shebang = b"#!" + executable + post_interp + b"\n" # Python parser starts to read a script using UTF-8 until # it gets a #coding:xxx cookie. The shebang has to be the # first line of a file, the #coding:xxx cookie cannot be # written before. So the shebang has to be decodable from # UTF-8. try: shebang.decode('utf-8') except UnicodeDecodeError: raise ValueError( "The shebang ({!r}) is not decodable " "from utf-8".format(shebang)) # If the script is encoded to a custom encoding (use a # #coding:xxx cookie), the shebang has to be decodable from # the script encoding too. try: shebang.decode(encoding) except UnicodeDecodeError: raise ValueError( "The shebang ({!r}) is not decodable " "from the script encoding ({})" .format(shebang, encoding)) with open(outfile, "wb") as outf: outf.write(shebang) outf.writelines(f.readlines()) if f: f.close() else: if f: f.close() updated_files.append(outfile) self.copy_file(script, outfile) if os.name == 'posix': for file in outfiles: if self.dry_run: log.info("changing mode of %s", file) else: oldmode = os.stat(file)[ST_MODE] & 0o7777 newmode = (oldmode | 0o555) & 0o7777 if newmode != oldmode: log.info("changing mode of %s from %o to %o", file, oldmode, newmode) os.chmod(file, newmode) # XXX should we modify self.outfiles? return outfiles, updated_files PKH]7=3=3@python3.10/site-packages/setuptools/_distutils/command/config.pynu["""distutils.command.config Implements the Distutils 'config' command, a (mostly) empty command class that exists mainly to be sub-classed by specific module distributions and applications. The idea is that while every "config" command is different, at least they're all named the same, and users always see "config" in the list of standard commands. Also, this is a good place to put common configure-like tasks: "try to compile this C code", or "figure out where this header file lives". """ import os, re from distutils.core import Command from distutils.errors import DistutilsExecError from distutils.sysconfig import customize_compiler from distutils import log LANG_EXT = {"c": ".c", "c++": ".cxx"} class config(Command): description = "prepare to build" user_options = [ ('compiler=', None, "specify the compiler type"), ('cc=', None, "specify the compiler executable"), ('include-dirs=', 'I', "list of directories to search for header files"), ('define=', 'D', "C preprocessor macros to define"), ('undef=', 'U', "C preprocessor macros to undefine"), ('libraries=', 'l', "external C libraries to link with"), ('library-dirs=', 'L', "directories to search for external C libraries"), ('noisy', None, "show every action (compile, link, run, ...) taken"), ('dump-source', None, "dump generated source files before attempting to compile them"), ] # The three standard command methods: since the "config" command # does nothing by default, these are empty. def initialize_options(self): self.compiler = None self.cc = None self.include_dirs = None self.libraries = None self.library_dirs = None # maximal output for now self.noisy = 1 self.dump_source = 1 # list of temporary files generated along-the-way that we have # to clean at some point self.temp_files = [] def finalize_options(self): if self.include_dirs is None: self.include_dirs = self.distribution.include_dirs or [] elif isinstance(self.include_dirs, str): self.include_dirs = self.include_dirs.split(os.pathsep) if self.libraries is None: self.libraries = [] elif isinstance(self.libraries, str): self.libraries = [self.libraries] if self.library_dirs is None: self.library_dirs = [] elif isinstance(self.library_dirs, str): self.library_dirs = self.library_dirs.split(os.pathsep) def run(self): pass # Utility methods for actual "config" commands. The interfaces are # loosely based on Autoconf macros of similar names. Sub-classes # may use these freely. def _check_compiler(self): """Check that 'self.compiler' really is a CCompiler object; if not, make it one. """ # We do this late, and only on-demand, because this is an expensive # import. from distutils.ccompiler import CCompiler, new_compiler if not isinstance(self.compiler, CCompiler): self.compiler = new_compiler(compiler=self.compiler, dry_run=self.dry_run, force=1) customize_compiler(self.compiler) if self.include_dirs: self.compiler.set_include_dirs(self.include_dirs) if self.libraries: self.compiler.set_libraries(self.libraries) if self.library_dirs: self.compiler.set_library_dirs(self.library_dirs) def _gen_temp_sourcefile(self, body, headers, lang): filename = "_configtest" + LANG_EXT[lang] with open(filename, "w") as file: if headers: for header in headers: file.write("#include <%s>\n" % header) file.write("\n") file.write(body) if body[-1] != "\n": file.write("\n") return filename def _preprocess(self, body, headers, include_dirs, lang): src = self._gen_temp_sourcefile(body, headers, lang) out = "_configtest.i" self.temp_files.extend([src, out]) self.compiler.preprocess(src, out, include_dirs=include_dirs) return (src, out) def _compile(self, body, headers, include_dirs, lang): src = self._gen_temp_sourcefile(body, headers, lang) if self.dump_source: dump_file(src, "compiling '%s':" % src) (obj,) = self.compiler.object_filenames([src]) self.temp_files.extend([src, obj]) self.compiler.compile([src], include_dirs=include_dirs) return (src, obj) def _link(self, body, headers, include_dirs, libraries, library_dirs, lang): (src, obj) = self._compile(body, headers, include_dirs, lang) prog = os.path.splitext(os.path.basename(src))[0] self.compiler.link_executable([obj], prog, libraries=libraries, library_dirs=library_dirs, target_lang=lang) if self.compiler.exe_extension is not None: prog = prog + self.compiler.exe_extension self.temp_files.append(prog) return (src, obj, prog) def _clean(self, *filenames): if not filenames: filenames = self.temp_files self.temp_files = [] log.info("removing: %s", ' '.join(filenames)) for filename in filenames: try: os.remove(filename) except OSError: pass # XXX these ignore the dry-run flag: what to do, what to do? even if # you want a dry-run build, you still need some sort of configuration # info. My inclination is to make it up to the real config command to # consult 'dry_run', and assume a default (minimal) configuration if # true. The problem with trying to do it here is that you'd have to # return either true or false from all the 'try' methods, neither of # which is correct. # XXX need access to the header search path and maybe default macros. def try_cpp(self, body=None, headers=None, include_dirs=None, lang="c"): """Construct a source file from 'body' (a string containing lines of C/C++ code) and 'headers' (a list of header files to include) and run it through the preprocessor. Return true if the preprocessor succeeded, false if there were any errors. ('body' probably isn't of much use, but what the heck.) """ from distutils.ccompiler import CompileError self._check_compiler() ok = True try: self._preprocess(body, headers, include_dirs, lang) except CompileError: ok = False self._clean() return ok def search_cpp(self, pattern, body=None, headers=None, include_dirs=None, lang="c"): """Construct a source file (just like 'try_cpp()'), run it through the preprocessor, and return true if any line of the output matches 'pattern'. 'pattern' should either be a compiled regex object or a string containing a regex. If both 'body' and 'headers' are None, preprocesses an empty file -- which can be useful to determine the symbols the preprocessor and compiler set by default. """ self._check_compiler() src, out = self._preprocess(body, headers, include_dirs, lang) if isinstance(pattern, str): pattern = re.compile(pattern) with open(out) as file: match = False while True: line = file.readline() if line == '': break if pattern.search(line): match = True break self._clean() return match def try_compile(self, body, headers=None, include_dirs=None, lang="c"): """Try to compile a source file built from 'body' and 'headers'. Return true on success, false otherwise. """ from distutils.ccompiler import CompileError self._check_compiler() try: self._compile(body, headers, include_dirs, lang) ok = True except CompileError: ok = False log.info(ok and "success!" or "failure.") self._clean() return ok def try_link(self, body, headers=None, include_dirs=None, libraries=None, library_dirs=None, lang="c"): """Try to compile and link a source file, built from 'body' and 'headers', to executable form. Return true on success, false otherwise. """ from distutils.ccompiler import CompileError, LinkError self._check_compiler() try: self._link(body, headers, include_dirs, libraries, library_dirs, lang) ok = True except (CompileError, LinkError): ok = False log.info(ok and "success!" or "failure.") self._clean() return ok def try_run(self, body, headers=None, include_dirs=None, libraries=None, library_dirs=None, lang="c"): """Try to compile, link to an executable, and run a program built from 'body' and 'headers'. Return true on success, false otherwise. """ from distutils.ccompiler import CompileError, LinkError self._check_compiler() try: src, obj, exe = self._link(body, headers, include_dirs, libraries, library_dirs, lang) self.spawn([exe]) ok = True except (CompileError, LinkError, DistutilsExecError): ok = False log.info(ok and "success!" or "failure.") self._clean() return ok # -- High-level methods -------------------------------------------- # (these are the ones that are actually likely to be useful # when implementing a real-world config command!) def check_func(self, func, headers=None, include_dirs=None, libraries=None, library_dirs=None, decl=0, call=0): """Determine if function 'func' is available by constructing a source file that refers to 'func', and compiles and links it. If everything succeeds, returns true; otherwise returns false. The constructed source file starts out by including the header files listed in 'headers'. If 'decl' is true, it then declares 'func' (as "int func()"); you probably shouldn't supply 'headers' and set 'decl' true in the same call, or you might get errors about a conflicting declarations for 'func'. Finally, the constructed 'main()' function either references 'func' or (if 'call' is true) calls it. 'libraries' and 'library_dirs' are used when linking. """ self._check_compiler() body = [] if decl: body.append("int %s ();" % func) body.append("int main () {") if call: body.append(" %s();" % func) else: body.append(" %s;" % func) body.append("}") body = "\n".join(body) + "\n" return self.try_link(body, headers, include_dirs, libraries, library_dirs) def check_lib(self, library, library_dirs=None, headers=None, include_dirs=None, other_libraries=[]): """Determine if 'library' is available to be linked against, without actually checking that any particular symbols are provided by it. 'headers' will be used in constructing the source file to be compiled, but the only effect of this is to check if all the header files listed are available. Any libraries listed in 'other_libraries' will be included in the link, in case 'library' has symbols that depend on other libraries. """ self._check_compiler() return self.try_link("int main (void) { }", headers, include_dirs, [library] + other_libraries, library_dirs) def check_header(self, header, include_dirs=None, library_dirs=None, lang="c"): """Determine if the system header file named by 'header_file' exists and can be found by the preprocessor; return true if so, false otherwise. """ return self.try_cpp(body="/* No body */", headers=[header], include_dirs=include_dirs) def dump_file(filename, head=None): """Dumps a file content into log.info. If head is not None, will be dumped before the file content. """ if head is None: log.info('%s', filename) else: log.info(head) file = open(filename) try: log.info(file.read()) finally: file.close() PKH];Bpython3.10/site-packages/setuptools/_distutils/command/__init__.pynu["""distutils.command Package containing implementation of all the standard Distutils commands.""" __all__ = ['build', 'build_py', 'build_ext', 'build_clib', 'build_scripts', 'clean', 'install', 'install_lib', 'install_headers', 'install_scripts', 'install_data', 'sdist', 'register', 'bdist', 'bdist_dumb', 'bdist_rpm', 'bdist_wininst', 'check', 'upload', # These two are reserved for future use: #'bdist_sdux', #'bdist_pkgtool', # Note: # bdist_packager is not included because it only provides # an abstract base class ] PKH]oYCpython3.10/site-packages/setuptools/_distutils/command/bdist_msi.pynu[# Copyright (C) 2005, 2006 Martin von Löwis # Licensed to PSF under a Contributor Agreement. # The bdist_wininst command proper # based on bdist_wininst """ Implements the bdist_msi command. """ import os import sys import warnings from distutils.core import Command from distutils.dir_util import remove_tree from distutils.sysconfig import get_python_version from distutils.version import StrictVersion from distutils.errors import DistutilsOptionError from distutils.util import get_platform from distutils import log import msilib from msilib import schema, sequence, text from msilib import Directory, Feature, Dialog, add_data class PyDialog(Dialog): """Dialog class with a fixed layout: controls at the top, then a ruler, then a list of buttons: back, next, cancel. Optionally a bitmap at the left.""" def __init__(self, *args, **kw): """Dialog(database, name, x, y, w, h, attributes, title, first, default, cancel, bitmap=true)""" Dialog.__init__(self, *args) ruler = self.h - 36 bmwidth = 152*ruler/328 #if kw.get("bitmap", True): # self.bitmap("Bitmap", 0, 0, bmwidth, ruler, "PythonWin") self.line("BottomLine", 0, ruler, self.w, 0) def title(self, title): "Set the title text of the dialog at the top." # name, x, y, w, h, flags=Visible|Enabled|Transparent|NoPrefix, # text, in VerdanaBold10 self.text("Title", 15, 10, 320, 60, 0x30003, r"{\VerdanaBold10}%s" % title) def back(self, title, next, name = "Back", active = 1): """Add a back button with a given title, the tab-next button, its name in the Control table, possibly initially disabled. Return the button, so that events can be associated""" if active: flags = 3 # Visible|Enabled else: flags = 1 # Visible return self.pushbutton(name, 180, self.h-27 , 56, 17, flags, title, next) def cancel(self, title, next, name = "Cancel", active = 1): """Add a cancel button with a given title, the tab-next button, its name in the Control table, possibly initially disabled. Return the button, so that events can be associated""" if active: flags = 3 # Visible|Enabled else: flags = 1 # Visible return self.pushbutton(name, 304, self.h-27, 56, 17, flags, title, next) def next(self, title, next, name = "Next", active = 1): """Add a Next button with a given title, the tab-next button, its name in the Control table, possibly initially disabled. Return the button, so that events can be associated""" if active: flags = 3 # Visible|Enabled else: flags = 1 # Visible return self.pushbutton(name, 236, self.h-27, 56, 17, flags, title, next) def xbutton(self, name, title, next, xpos): """Add a button with a given title, the tab-next button, its name in the Control table, giving its x position; the y-position is aligned with the other buttons. Return the button, so that events can be associated""" return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next) class bdist_msi(Command): description = "create a Microsoft Installer (.msi) binary distribution" user_options = [('bdist-dir=', None, "temporary directory for creating the distribution"), ('plat-name=', 'p', "platform name to embed in generated filenames " "(default: %s)" % get_platform()), ('keep-temp', 'k', "keep the pseudo-installation tree around after " + "creating the distribution archive"), ('target-version=', None, "require a specific python version" + " on the target system"), ('no-target-compile', 'c', "do not compile .py to .pyc on the target system"), ('no-target-optimize', 'o', "do not compile .py to .pyo (optimized) " "on the target system"), ('dist-dir=', 'd', "directory to put final built distributions in"), ('skip-build', None, "skip rebuilding everything (for testing/debugging)"), ('install-script=', None, "basename of installation script to be run after " "installation or before deinstallation"), ('pre-install-script=', None, "Fully qualified filename of a script to be run before " "any files are installed. This script need not be in the " "distribution"), ] boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize', 'skip-build'] all_versions = ['2.0', '2.1', '2.2', '2.3', '2.4', '2.5', '2.6', '2.7', '2.8', '2.9', '3.0', '3.1', '3.2', '3.3', '3.4', '3.5', '3.6', '3.7', '3.8', '3.9'] other_version = 'X' def __init__(self, *args, **kw): super().__init__(*args, **kw) warnings.warn("bdist_msi command is deprecated since Python 3.9, " "use bdist_wheel (wheel packages) instead", DeprecationWarning, 2) def initialize_options(self): self.bdist_dir = None self.plat_name = None self.keep_temp = 0 self.no_target_compile = 0 self.no_target_optimize = 0 self.target_version = None self.dist_dir = None self.skip_build = None self.install_script = None self.pre_install_script = None self.versions = None def finalize_options(self): self.set_undefined_options('bdist', ('skip_build', 'skip_build')) if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'msi') short_version = get_python_version() if (not self.target_version) and self.distribution.has_ext_modules(): self.target_version = short_version if self.target_version: self.versions = [self.target_version] if not self.skip_build and self.distribution.has_ext_modules()\ and self.target_version != short_version: raise DistutilsOptionError( "target version can only be %s, or the '--skip-build'" " option must be specified" % (short_version,)) else: self.versions = list(self.all_versions) self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'), ('plat_name', 'plat_name'), ) if self.pre_install_script: raise DistutilsOptionError( "the pre-install-script feature is not yet implemented") if self.install_script: for script in self.distribution.scripts: if self.install_script == os.path.basename(script): break else: raise DistutilsOptionError( "install_script '%s' not found in scripts" % self.install_script) self.install_script_key = None def run(self): if not self.skip_build: self.run_command('build') install = self.reinitialize_command('install', reinit_subcommands=1) install.prefix = self.bdist_dir install.skip_build = self.skip_build install.warn_dir = 0 install_lib = self.reinitialize_command('install_lib') # we do not want to include pyc or pyo files install_lib.compile = 0 install_lib.optimize = 0 if self.distribution.has_ext_modules(): # If we are building an installer for a Python version other # than the one we are currently running, then we need to ensure # our build_lib reflects the other Python version rather than ours. # Note that for target_version!=sys.version, we must have skipped the # build step, so there is no issue with enforcing the build of this # version. target_version = self.target_version if not target_version: assert self.skip_build, "Should have already checked this" target_version = '%d.%d' % sys.version_info[:2] plat_specifier = ".%s-%s" % (self.plat_name, target_version) build = self.get_finalized_command('build') build.build_lib = os.path.join(build.build_base, 'lib' + plat_specifier) log.info("installing to %s", self.bdist_dir) install.ensure_finalized() # avoid warning of 'install_lib' about installing # into a directory not in sys.path sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB')) install.run() del sys.path[0] self.mkpath(self.dist_dir) fullname = self.distribution.get_fullname() installer_name = self.get_installer_filename(fullname) installer_name = os.path.abspath(installer_name) if os.path.exists(installer_name): os.unlink(installer_name) metadata = self.distribution.metadata author = metadata.author if not author: author = metadata.maintainer if not author: author = "UNKNOWN" version = metadata.get_version() # ProductVersion must be strictly numeric # XXX need to deal with prerelease versions sversion = "%d.%d.%d" % StrictVersion(version).version # Prefix ProductName with Python x.y, so that # it sorts together with the other Python packages # in Add-Remove-Programs (APR) fullname = self.distribution.get_fullname() if self.target_version: product_name = "Python %s %s" % (self.target_version, fullname) else: product_name = "Python %s" % (fullname) self.db = msilib.init_database(installer_name, schema, product_name, msilib.gen_uuid(), sversion, author) msilib.add_tables(self.db, sequence) props = [('DistVersion', version)] email = metadata.author_email or metadata.maintainer_email if email: props.append(("ARPCONTACT", email)) if metadata.url: props.append(("ARPURLINFOABOUT", metadata.url)) if props: add_data(self.db, 'Property', props) self.add_find_python() self.add_files() self.add_scripts() self.add_ui() self.db.Commit() if hasattr(self.distribution, 'dist_files'): tup = 'bdist_msi', self.target_version or 'any', fullname self.distribution.dist_files.append(tup) if not self.keep_temp: remove_tree(self.bdist_dir, dry_run=self.dry_run) def add_files(self): db = self.db cab = msilib.CAB("distfiles") rootdir = os.path.abspath(self.bdist_dir) root = Directory(db, cab, None, rootdir, "TARGETDIR", "SourceDir") f = Feature(db, "Python", "Python", "Everything", 0, 1, directory="TARGETDIR") items = [(f, root, '')] for version in self.versions + [self.other_version]: target = "TARGETDIR" + version name = default = "Python" + version desc = "Everything" if version is self.other_version: title = "Python from another location" level = 2 else: title = "Python %s from registry" % version level = 1 f = Feature(db, name, title, desc, 1, level, directory=target) dir = Directory(db, cab, root, rootdir, target, default) items.append((f, dir, version)) db.Commit() seen = {} for feature, dir, version in items: todo = [dir] while todo: dir = todo.pop() for file in os.listdir(dir.absolute): afile = os.path.join(dir.absolute, file) if os.path.isdir(afile): short = "%s|%s" % (dir.make_short(file), file) default = file + version newdir = Directory(db, cab, dir, file, default, short) todo.append(newdir) else: if not dir.component: dir.start_component(dir.logical, feature, 0) if afile not in seen: key = seen[afile] = dir.add_file(file) if file==self.install_script: if self.install_script_key: raise DistutilsOptionError( "Multiple files with name %s" % file) self.install_script_key = '[#%s]' % key else: key = seen[afile] add_data(self.db, "DuplicateFile", [(key + version, dir.component, key, None, dir.logical)]) db.Commit() cab.commit(db) def add_find_python(self): """Adds code to the installer to compute the location of Python. Properties PYTHON.MACHINE.X.Y and PYTHON.USER.X.Y will be set from the registry for each version of Python. Properties TARGETDIRX.Y will be set from PYTHON.USER.X.Y if defined, else from PYTHON.MACHINE.X.Y. Properties PYTHONX.Y will be set to TARGETDIRX.Y\\python.exe""" start = 402 for ver in self.versions: install_path = r"SOFTWARE\Python\PythonCore\%s\InstallPath" % ver machine_reg = "python.machine." + ver user_reg = "python.user." + ver machine_prop = "PYTHON.MACHINE." + ver user_prop = "PYTHON.USER." + ver machine_action = "PythonFromMachine" + ver user_action = "PythonFromUser" + ver exe_action = "PythonExe" + ver target_dir_prop = "TARGETDIR" + ver exe_prop = "PYTHON" + ver if msilib.Win64: # type: msidbLocatorTypeRawValue + msidbLocatorType64bit Type = 2+16 else: Type = 2 add_data(self.db, "RegLocator", [(machine_reg, 2, install_path, None, Type), (user_reg, 1, install_path, None, Type)]) add_data(self.db, "AppSearch", [(machine_prop, machine_reg), (user_prop, user_reg)]) add_data(self.db, "CustomAction", [(machine_action, 51+256, target_dir_prop, "[" + machine_prop + "]"), (user_action, 51+256, target_dir_prop, "[" + user_prop + "]"), (exe_action, 51+256, exe_prop, "[" + target_dir_prop + "]\\python.exe"), ]) add_data(self.db, "InstallExecuteSequence", [(machine_action, machine_prop, start), (user_action, user_prop, start + 1), (exe_action, None, start + 2), ]) add_data(self.db, "InstallUISequence", [(machine_action, machine_prop, start), (user_action, user_prop, start + 1), (exe_action, None, start + 2), ]) add_data(self.db, "Condition", [("Python" + ver, 0, "NOT TARGETDIR" + ver)]) start += 4 assert start < 500 def add_scripts(self): if self.install_script: start = 6800 for ver in self.versions + [self.other_version]: install_action = "install_script." + ver exe_prop = "PYTHON" + ver add_data(self.db, "CustomAction", [(install_action, 50, exe_prop, self.install_script_key)]) add_data(self.db, "InstallExecuteSequence", [(install_action, "&Python%s=3" % ver, start)]) start += 1 # XXX pre-install scripts are currently refused in finalize_options() # but if this feature is completed, it will also need to add # entries for each version as the above code does if self.pre_install_script: scriptfn = os.path.join(self.bdist_dir, "preinstall.bat") with open(scriptfn, "w") as f: # The batch file will be executed with [PYTHON], so that %1 # is the path to the Python interpreter; %0 will be the path # of the batch file. # rem =""" # %1 %0 # exit # """ # f.write('rem ="""\n%1 %0\nexit\n"""\n') with open(self.pre_install_script) as fin: f.write(fin.read()) add_data(self.db, "Binary", [("PreInstall", msilib.Binary(scriptfn)) ]) add_data(self.db, "CustomAction", [("PreInstall", 2, "PreInstall", None) ]) add_data(self.db, "InstallExecuteSequence", [("PreInstall", "NOT Installed", 450)]) def add_ui(self): db = self.db x = y = 50 w = 370 h = 300 title = "[ProductName] Setup" # see "Dialog Style Bits" modal = 3 # visible | modal modeless = 1 # visible track_disk_space = 32 # UI customization properties add_data(db, "Property", # See "DefaultUIFont Property" [("DefaultUIFont", "DlgFont8"), # See "ErrorDialog Style Bit" ("ErrorDialog", "ErrorDlg"), ("Progress1", "Install"), # modified in maintenance type dlg ("Progress2", "installs"), ("MaintenanceForm_Action", "Repair"), # possible values: ALL, JUSTME ("WhichUsers", "ALL") ]) # Fonts, see "TextStyle Table" add_data(db, "TextStyle", [("DlgFont8", "Tahoma", 9, None, 0), ("DlgFontBold8", "Tahoma", 8, None, 1), #bold ("VerdanaBold10", "Verdana", 10, None, 1), ("VerdanaRed9", "Verdana", 9, 255, 0), ]) # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table" # Numbers indicate sequence; see sequence.py for how these action integrate add_data(db, "InstallUISequence", [("PrepareDlg", "Not Privileged or Windows9x or Installed", 140), ("WhichUsersDlg", "Privileged and not Windows9x and not Installed", 141), # In the user interface, assume all-users installation if privileged. ("SelectFeaturesDlg", "Not Installed", 1230), # XXX no support for resume installations yet #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240), ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250), ("ProgressDlg", None, 1280)]) add_data(db, 'ActionText', text.ActionText) add_data(db, 'UIText', text.UIText) ##################################################################### # Standard dialogs: FatalError, UserExit, ExitDialog fatal=PyDialog(db, "FatalError", x, y, w, h, modal, title, "Finish", "Finish", "Finish") fatal.title("[ProductName] Installer ended prematurely") fatal.back("< Back", "Finish", active = 0) fatal.cancel("Cancel", "Back", active = 0) fatal.text("Description1", 15, 70, 320, 80, 0x30003, "[ProductName] setup ended prematurely because of an error. Your system has not been modified. To install this program at a later time, please run the installation again.") fatal.text("Description2", 15, 155, 320, 20, 0x30003, "Click the Finish button to exit the Installer.") c=fatal.next("Finish", "Cancel", name="Finish") c.event("EndDialog", "Exit") user_exit=PyDialog(db, "UserExit", x, y, w, h, modal, title, "Finish", "Finish", "Finish") user_exit.title("[ProductName] Installer was interrupted") user_exit.back("< Back", "Finish", active = 0) user_exit.cancel("Cancel", "Back", active = 0) user_exit.text("Description1", 15, 70, 320, 80, 0x30003, "[ProductName] setup was interrupted. Your system has not been modified. " "To install this program at a later time, please run the installation again.") user_exit.text("Description2", 15, 155, 320, 20, 0x30003, "Click the Finish button to exit the Installer.") c = user_exit.next("Finish", "Cancel", name="Finish") c.event("EndDialog", "Exit") exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title, "Finish", "Finish", "Finish") exit_dialog.title("Completing the [ProductName] Installer") exit_dialog.back("< Back", "Finish", active = 0) exit_dialog.cancel("Cancel", "Back", active = 0) exit_dialog.text("Description", 15, 235, 320, 20, 0x30003, "Click the Finish button to exit the Installer.") c = exit_dialog.next("Finish", "Cancel", name="Finish") c.event("EndDialog", "Return") ##################################################################### # Required dialog: FilesInUse, ErrorDlg inuse = PyDialog(db, "FilesInUse", x, y, w, h, 19, # KeepModeless|Modal|Visible title, "Retry", "Retry", "Retry", bitmap=False) inuse.text("Title", 15, 6, 200, 15, 0x30003, r"{\DlgFontBold8}Files in Use") inuse.text("Description", 20, 23, 280, 20, 0x30003, "Some files that need to be updated are currently in use.") inuse.text("Text", 20, 55, 330, 50, 3, "The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.") inuse.control("List", "ListBox", 20, 107, 330, 130, 7, "FileInUseProcess", None, None, None) c=inuse.back("Exit", "Ignore", name="Exit") c.event("EndDialog", "Exit") c=inuse.next("Ignore", "Retry", name="Ignore") c.event("EndDialog", "Ignore") c=inuse.cancel("Retry", "Exit", name="Retry") c.event("EndDialog","Retry") # See "Error Dialog". See "ICE20" for the required names of the controls. error = Dialog(db, "ErrorDlg", 50, 10, 330, 101, 65543, # Error|Minimize|Modal|Visible title, "ErrorText", None, None) error.text("ErrorText", 50,9,280,48,3, "") #error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None) error.pushbutton("N",120,72,81,21,3,"No",None).event("EndDialog","ErrorNo") error.pushbutton("Y",240,72,81,21,3,"Yes",None).event("EndDialog","ErrorYes") error.pushbutton("A",0,72,81,21,3,"Abort",None).event("EndDialog","ErrorAbort") error.pushbutton("C",42,72,81,21,3,"Cancel",None).event("EndDialog","ErrorCancel") error.pushbutton("I",81,72,81,21,3,"Ignore",None).event("EndDialog","ErrorIgnore") error.pushbutton("O",159,72,81,21,3,"Ok",None).event("EndDialog","ErrorOk") error.pushbutton("R",198,72,81,21,3,"Retry",None).event("EndDialog","ErrorRetry") ##################################################################### # Global "Query Cancel" dialog cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title, "No", "No", "No") cancel.text("Text", 48, 15, 194, 30, 3, "Are you sure you want to cancel [ProductName] installation?") #cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None, # "py.ico", None, None) c=cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No") c.event("EndDialog", "Exit") c=cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes") c.event("EndDialog", "Return") ##################################################################### # Global "Wait for costing" dialog costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal, title, "Return", "Return", "Return") costing.text("Text", 48, 15, 194, 30, 3, "Please wait while the installer finishes determining your disk space requirements.") c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None) c.event("EndDialog", "Exit") ##################################################################### # Preparation dialog: no user input except cancellation prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title, "Cancel", "Cancel", "Cancel") prep.text("Description", 15, 70, 320, 40, 0x30003, "Please wait while the Installer prepares to guide you through the installation.") prep.title("Welcome to the [ProductName] Installer") c=prep.text("ActionText", 15, 110, 320, 20, 0x30003, "Pondering...") c.mapping("ActionText", "Text") c=prep.text("ActionData", 15, 135, 320, 30, 0x30003, None) c.mapping("ActionData", "Text") prep.back("Back", None, active=0) prep.next("Next", None, active=0) c=prep.cancel("Cancel", None) c.event("SpawnDialog", "CancelDlg") ##################################################################### # Feature (Python directory) selection seldlg = PyDialog(db, "SelectFeaturesDlg", x, y, w, h, modal, title, "Next", "Next", "Cancel") seldlg.title("Select Python Installations") seldlg.text("Hint", 15, 30, 300, 20, 3, "Select the Python locations where %s should be installed." % self.distribution.get_fullname()) seldlg.back("< Back", None, active=0) c = seldlg.next("Next >", "Cancel") order = 1 c.event("[TARGETDIR]", "[SourceDir]", ordering=order) for version in self.versions + [self.other_version]: order += 1 c.event("[TARGETDIR]", "[TARGETDIR%s]" % version, "FEATURE_SELECTED AND &Python%s=3" % version, ordering=order) c.event("SpawnWaitDialog", "WaitForCostingDlg", ordering=order + 1) c.event("EndDialog", "Return", ordering=order + 2) c = seldlg.cancel("Cancel", "Features") c.event("SpawnDialog", "CancelDlg") c = seldlg.control("Features", "SelectionTree", 15, 60, 300, 120, 3, "FEATURE", None, "PathEdit", None) c.event("[FEATURE_SELECTED]", "1") ver = self.other_version install_other_cond = "FEATURE_SELECTED AND &Python%s=3" % ver dont_install_other_cond = "FEATURE_SELECTED AND &Python%s<>3" % ver c = seldlg.text("Other", 15, 200, 300, 15, 3, "Provide an alternate Python location") c.condition("Enable", install_other_cond) c.condition("Show", install_other_cond) c.condition("Disable", dont_install_other_cond) c.condition("Hide", dont_install_other_cond) c = seldlg.control("PathEdit", "PathEdit", 15, 215, 300, 16, 1, "TARGETDIR" + ver, None, "Next", None) c.condition("Enable", install_other_cond) c.condition("Show", install_other_cond) c.condition("Disable", dont_install_other_cond) c.condition("Hide", dont_install_other_cond) ##################################################################### # Disk cost cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title, "OK", "OK", "OK", bitmap=False) cost.text("Title", 15, 6, 200, 15, 0x30003, r"{\DlgFontBold8}Disk Space Requirements") cost.text("Description", 20, 20, 280, 20, 0x30003, "The disk space required for the installation of the selected features.") cost.text("Text", 20, 53, 330, 60, 3, "The highlighted volumes (if any) do not have enough disk space " "available for the currently selected features. You can either " "remove some files from the highlighted volumes, or choose to " "install less features onto local drive(s), or select different " "destination drive(s).") cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223, None, "{120}{70}{70}{70}{70}", None, None) cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return") ##################################################################### # WhichUsers Dialog. Only available on NT, and for privileged users. # This must be run before FindRelatedProducts, because that will # take into account whether the previous installation was per-user # or per-machine. We currently don't support going back to this # dialog after "Next" was selected; to support this, we would need to # find how to reset the ALLUSERS property, and how to re-run # FindRelatedProducts. # On Windows9x, the ALLUSERS property is ignored on the command line # and in the Property table, but installer fails according to the documentation # if a dialog attempts to set ALLUSERS. whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title, "AdminInstall", "Next", "Cancel") whichusers.title("Select whether to install [ProductName] for all users of this computer.") # A radio group with two options: allusers, justme g = whichusers.radiogroup("AdminInstall", 15, 60, 260, 50, 3, "WhichUsers", "", "Next") g.add("ALL", 0, 5, 150, 20, "Install for all users") g.add("JUSTME", 0, 25, 150, 20, "Install just for me") whichusers.back("Back", None, active=0) c = whichusers.next("Next >", "Cancel") c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1) c.event("EndDialog", "Return", ordering = 2) c = whichusers.cancel("Cancel", "AdminInstall") c.event("SpawnDialog", "CancelDlg") ##################################################################### # Installation Progress dialog (modeless) progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title, "Cancel", "Cancel", "Cancel", bitmap=False) progress.text("Title", 20, 15, 200, 15, 0x30003, r"{\DlgFontBold8}[Progress1] [ProductName]") progress.text("Text", 35, 65, 300, 30, 3, "Please wait while the Installer [Progress2] [ProductName]. " "This may take several minutes.") progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:") c=progress.text("ActionText", 70, 100, w-70, 20, 3, "Pondering...") c.mapping("ActionText", "Text") #c=progress.text("ActionData", 35, 140, 300, 20, 3, None) #c.mapping("ActionData", "Text") c=progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10, 65537, None, "Progress done", None, None) c.mapping("SetProgress", "Progress") progress.back("< Back", "Next", active=False) progress.next("Next >", "Cancel", active=False) progress.cancel("Cancel", "Back").event("SpawnDialog", "CancelDlg") ################################################################### # Maintenance type: repair/uninstall maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title, "Next", "Next", "Cancel") maint.title("Welcome to the [ProductName] Setup Wizard") maint.text("BodyText", 15, 63, 330, 42, 3, "Select whether you want to repair or remove [ProductName].") g=maint.radiogroup("RepairRadioGroup", 15, 108, 330, 60, 3, "MaintenanceForm_Action", "", "Next") #g.add("Change", 0, 0, 200, 17, "&Change [ProductName]") g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]") g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]") maint.back("< Back", None, active=False) c=maint.next("Finish", "Cancel") # Change installation: Change progress dialog to "Change", then ask # for feature selection #c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1) #c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2) # Reinstall: Change progress dialog to "Repair", then invoke reinstall # Also set list of reinstalled features to "ALL" c.event("[REINSTALL]", "ALL", 'MaintenanceForm_Action="Repair"', 5) c.event("[Progress1]", "Repairing", 'MaintenanceForm_Action="Repair"', 6) c.event("[Progress2]", "repairs", 'MaintenanceForm_Action="Repair"', 7) c.event("Reinstall", "ALL", 'MaintenanceForm_Action="Repair"', 8) # Uninstall: Change progress to "Remove", then invoke uninstall # Also set list of removed features to "ALL" c.event("[REMOVE]", "ALL", 'MaintenanceForm_Action="Remove"', 11) c.event("[Progress1]", "Removing", 'MaintenanceForm_Action="Remove"', 12) c.event("[Progress2]", "removes", 'MaintenanceForm_Action="Remove"', 13) c.event("Remove", "ALL", 'MaintenanceForm_Action="Remove"', 14) # Close dialog when maintenance action scheduled c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20) #c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21) maint.cancel("Cancel", "RepairRadioGroup").event("SpawnDialog", "CancelDlg") def get_installer_filename(self, fullname): # Factored out to allow overriding in subclasses if self.target_version: base_name = "%s.%s-py%s.msi" % (fullname, self.plat_name, self.target_version) else: base_name = "%s.%s.msi" % (fullname, self.plat_name) installer_name = os.path.join(self.dist_dir, base_name) return installer_name PKH]*Rj&Ipython3.10/site-packages/setuptools/_distutils/command/install_headers.pynu["""distutils.command.install_headers Implements the Distutils 'install_headers' command, to install C/C++ header files to the Python include directory.""" from distutils.core import Command # XXX force is never used class install_headers(Command): description = "install C/C++ header files" user_options = [('install-dir=', 'd', "directory to install header files to"), ('force', 'f', "force installation (overwrite existing files)"), ] boolean_options = ['force'] def initialize_options(self): self.install_dir = None self.force = 0 self.outfiles = [] def finalize_options(self): self.set_undefined_options('install', ('install_headers', 'install_dir'), ('force', 'force')) def run(self): headers = self.distribution.headers if not headers: return self.mkpath(self.install_dir) for header in headers: (out, _) = self.copy_file(header, self.install_dir) self.outfiles.append(out) def get_inputs(self): return self.distribution.headers or [] def get_outputs(self): return self.outfiles PKH]v3;VVDpython3.10/site-packages/setuptools/_distutils/command/build_clib.pynu["""distutils.command.build_clib Implements the Distutils 'build_clib' command, to build a C/C++ library that is included in the module distribution and needed by an extension module.""" # XXX this module has *lots* of code ripped-off quite transparently from # build_ext.py -- not surprisingly really, as the work required to build # a static library from a collection of C source files is not really all # that different from what's required to build a shared object file from # a collection of C source files. Nevertheless, I haven't done the # necessary refactoring to account for the overlap in code between the # two modules, mainly because a number of subtle details changed in the # cut 'n paste. Sigh. import os from distutils.core import Command from distutils.errors import * from distutils.sysconfig import customize_compiler from distutils import log def show_compilers(): from distutils.ccompiler import show_compilers show_compilers() class build_clib(Command): description = "build C/C++ libraries used by Python extensions" user_options = [ ('build-clib=', 'b', "directory to build C/C++ libraries to"), ('build-temp=', 't', "directory to put temporary build by-products"), ('debug', 'g', "compile with debugging information"), ('force', 'f', "forcibly build everything (ignore file timestamps)"), ('compiler=', 'c', "specify the compiler type"), ] boolean_options = ['debug', 'force'] help_options = [ ('help-compiler', None, "list available compilers", show_compilers), ] def initialize_options(self): self.build_clib = None self.build_temp = None # List of libraries to build self.libraries = None # Compilation options for all libraries self.include_dirs = None self.define = None self.undef = None self.debug = None self.force = 0 self.compiler = None def finalize_options(self): # This might be confusing: both build-clib and build-temp default # to build-temp as defined by the "build" command. This is because # I think that C libraries are really just temporary build # by-products, at least from the point of view of building Python # extensions -- but I want to keep my options open. self.set_undefined_options('build', ('build_temp', 'build_clib'), ('build_temp', 'build_temp'), ('compiler', 'compiler'), ('debug', 'debug'), ('force', 'force')) self.libraries = self.distribution.libraries if self.libraries: self.check_library_list(self.libraries) if self.include_dirs is None: self.include_dirs = self.distribution.include_dirs or [] if isinstance(self.include_dirs, str): self.include_dirs = self.include_dirs.split(os.pathsep) # XXX same as for build_ext -- what about 'self.define' and # 'self.undef' ? def run(self): if not self.libraries: return # Yech -- this is cut 'n pasted from build_ext.py! from distutils.ccompiler import new_compiler self.compiler = new_compiler(compiler=self.compiler, dry_run=self.dry_run, force=self.force) customize_compiler(self.compiler) if self.include_dirs is not None: self.compiler.set_include_dirs(self.include_dirs) if self.define is not None: # 'define' option is a list of (name,value) tuples for (name,value) in self.define: self.compiler.define_macro(name, value) if self.undef is not None: for macro in self.undef: self.compiler.undefine_macro(macro) self.build_libraries(self.libraries) def check_library_list(self, libraries): """Ensure that the list of libraries is valid. `library` is presumably provided as a command option 'libraries'. This method checks that it is a list of 2-tuples, where the tuples are (library_name, build_info_dict). Raise DistutilsSetupError if the structure is invalid anywhere; just returns otherwise. """ if not isinstance(libraries, list): raise DistutilsSetupError( "'libraries' option must be a list of tuples") for lib in libraries: if not isinstance(lib, tuple) and len(lib) != 2: raise DistutilsSetupError( "each element of 'libraries' must a 2-tuple") name, build_info = lib if not isinstance(name, str): raise DistutilsSetupError( "first element of each tuple in 'libraries' " "must be a string (the library name)") if '/' in name or (os.sep != '/' and os.sep in name): raise DistutilsSetupError("bad library name '%s': " "may not contain directory separators" % lib[0]) if not isinstance(build_info, dict): raise DistutilsSetupError( "second element of each tuple in 'libraries' " "must be a dictionary (build info)") def get_library_names(self): # Assume the library list is valid -- 'check_library_list()' is # called from 'finalize_options()', so it should be! if not self.libraries: return None lib_names = [] for (lib_name, build_info) in self.libraries: lib_names.append(lib_name) return lib_names def get_source_files(self): self.check_library_list(self.libraries) filenames = [] for (lib_name, build_info) in self.libraries: sources = build_info.get('sources') if sources is None or not isinstance(sources, (list, tuple)): raise DistutilsSetupError( "in 'libraries' option (library '%s'), " "'sources' must be present and must be " "a list of source filenames" % lib_name) filenames.extend(sources) return filenames def build_libraries(self, libraries): for (lib_name, build_info) in libraries: sources = build_info.get('sources') if sources is None or not isinstance(sources, (list, tuple)): raise DistutilsSetupError( "in 'libraries' option (library '%s'), " "'sources' must be present and must be " "a list of source filenames" % lib_name) sources = list(sources) log.info("building '%s' library", lib_name) # First, compile the source code to object files in the library # directory. (This should probably change to putting object # files in a temporary build directory.) macros = build_info.get('macros') include_dirs = build_info.get('include_dirs') objects = self.compiler.compile(sources, output_dir=self.build_temp, macros=macros, include_dirs=include_dirs, debug=self.debug) # Now "link" the object files together into a static library. # (On Unix at least, this isn't really linking -- it just # builds an archive. Whatever.) self.compiler.create_static_lib(objects, lib_name, output_dir=self.build_clib, debug=self.debug) PKH] OO6python3.10/site-packages/setuptools/_distutils/util.pynu["""distutils.util Miscellaneous utility functions -- anything that doesn't fit into one of the other *util.py modules. """ import os import re import importlib.util import string import sys from distutils.errors import DistutilsPlatformError from distutils.dep_util import newer from distutils.spawn import spawn from distutils import log from distutils.errors import DistutilsByteCompileError from .py35compat import _optim_args_from_interpreter_flags def get_host_platform(): """Return a string that identifies the current platform. This is used mainly to distinguish platform-specific build directories and platform-specific built distributions. Typically includes the OS name and version and the architecture (as supplied by 'os.uname()'), although the exact information included depends on the OS; eg. on Linux, the kernel version isn't particularly important. Examples of returned values: linux-i586 linux-alpha (?) solaris-2.6-sun4u Windows will return one of: win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) win32 (all others - specifically, sys.platform is returned) For other non-POSIX platforms, currently just returns 'sys.platform'. """ if os.name == 'nt': if 'amd64' in sys.version.lower(): return 'win-amd64' if '(arm)' in sys.version.lower(): return 'win-arm32' if '(arm64)' in sys.version.lower(): return 'win-arm64' return sys.platform # Set for cross builds explicitly if "_PYTHON_HOST_PLATFORM" in os.environ: return os.environ["_PYTHON_HOST_PLATFORM"] if os.name != "posix" or not hasattr(os, 'uname'): # XXX what about the architecture? NT is Intel or Alpha, # Mac OS is M68k or PPC, etc. return sys.platform # Try to distinguish various flavours of Unix (osname, host, release, version, machine) = os.uname() # Convert the OS name to lowercase, remove '/' characters, and translate # spaces (for "Power Macintosh") osname = osname.lower().replace('/', '') machine = machine.replace(' ', '_') machine = machine.replace('/', '-') if osname[:5] == "linux": # At least on Linux/Intel, 'machine' is the processor -- # i386, etc. # XXX what about Alpha, SPARC, etc? return "%s-%s" % (osname, machine) elif osname[:5] == "sunos": if release[0] >= "5": # SunOS 5 == Solaris 2 osname = "solaris" release = "%d.%s" % (int(release[0]) - 3, release[2:]) # We can't use "platform.architecture()[0]" because a # bootstrap problem. We use a dict to get an error # if some suspicious happens. bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} machine += ".%s" % bitness[sys.maxsize] # fall through to standard osname-release-machine representation elif osname[:3] == "aix": from .py38compat import aix_platform return aix_platform(osname, version, release) elif osname[:6] == "cygwin": osname = "cygwin" rel_re = re.compile (r'[\d.]+', re.ASCII) m = rel_re.match(release) if m: release = m.group() elif osname[:6] == "darwin": import _osx_support, distutils.sysconfig osname, release, machine = _osx_support.get_platform_osx( distutils.sysconfig.get_config_vars(), osname, release, machine) return "%s-%s-%s" % (osname, release, machine) def get_platform(): if os.name == 'nt': TARGET_TO_PLAT = { 'x86' : 'win32', 'x64' : 'win-amd64', 'arm' : 'win-arm32', 'arm64': 'win-arm64', } return TARGET_TO_PLAT.get(os.environ.get('VSCMD_ARG_TGT_ARCH')) or get_host_platform() else: return get_host_platform() if sys.platform == 'darwin': _syscfg_macosx_ver = None # cache the version pulled from sysconfig MACOSX_VERSION_VAR = 'MACOSX_DEPLOYMENT_TARGET' def _clear_cached_macosx_ver(): """For testing only. Do not call.""" global _syscfg_macosx_ver _syscfg_macosx_ver = None def get_macosx_target_ver_from_syscfg(): """Get the version of macOS latched in the Python interpreter configuration. Returns the version as a string or None if can't obtain one. Cached.""" global _syscfg_macosx_ver if _syscfg_macosx_ver is None: from distutils import sysconfig ver = sysconfig.get_config_var(MACOSX_VERSION_VAR) or '' if ver: _syscfg_macosx_ver = ver return _syscfg_macosx_ver def get_macosx_target_ver(): """Return the version of macOS for which we are building. The target version defaults to the version in sysconfig latched at time the Python interpreter was built, unless overridden by an environment variable. If neither source has a value, then None is returned""" syscfg_ver = get_macosx_target_ver_from_syscfg() env_ver = os.environ.get(MACOSX_VERSION_VAR) if env_ver: # Validate overridden version against sysconfig version, if have both. # Ensure that the deployment target of the build process is not less # than 10.3 if the interpreter was built for 10.3 or later. This # ensures extension modules are built with correct compatibility # values, specifically LDSHARED which can use # '-undefined dynamic_lookup' which only works on >= 10.3. if syscfg_ver and split_version(syscfg_ver) >= [10, 3] and \ split_version(env_ver) < [10, 3]: my_msg = ('$' + MACOSX_VERSION_VAR + ' mismatch: ' 'now "%s" but "%s" during configure; ' 'must use 10.3 or later' % (env_ver, syscfg_ver)) raise DistutilsPlatformError(my_msg) return env_ver return syscfg_ver def split_version(s): """Convert a dot-separated string into a list of numbers for comparisons""" return [int(n) for n in s.split('.')] def convert_path (pathname): """Return 'pathname' as a name that will work on the native filesystem, i.e. split it on '/' and put it back together again using the current directory separator. Needed because filenames in the setup script are always supplied in Unix style, and have to be converted to the local convention before we can actually use them in the filesystem. Raises ValueError on non-Unix-ish systems if 'pathname' either starts or ends with a slash. """ if os.sep == '/': return pathname if not pathname: return pathname if pathname[0] == '/': raise ValueError("path '%s' cannot be absolute" % pathname) if pathname[-1] == '/': raise ValueError("path '%s' cannot end with '/'" % pathname) paths = pathname.split('/') while '.' in paths: paths.remove('.') if not paths: return os.curdir return os.path.join(*paths) # convert_path () def change_root (new_root, pathname): """Return 'pathname' with 'new_root' prepended. If 'pathname' is relative, this is equivalent to "os.path.join(new_root,pathname)". Otherwise, it requires making 'pathname' relative and then joining the two, which is tricky on DOS/Windows and Mac OS. """ if os.name == 'posix': if not os.path.isabs(pathname): return os.path.join(new_root, pathname) else: return os.path.join(new_root, pathname[1:]) elif os.name == 'nt': (drive, path) = os.path.splitdrive(pathname) if path[0] == '\\': path = path[1:] return os.path.join(new_root, path) else: raise DistutilsPlatformError("nothing known about platform '%s'" % os.name) _environ_checked = 0 def check_environ (): """Ensure that 'os.environ' has all the environment variables we guarantee that users can use in config files, command-line options, etc. Currently this includes: HOME - user's home directory (Unix only) PLAT - description of the current platform, including hardware and OS (see 'get_platform()') """ global _environ_checked if _environ_checked: return if os.name == 'posix' and 'HOME' not in os.environ: try: import pwd os.environ['HOME'] = pwd.getpwuid(os.getuid())[5] except (ImportError, KeyError): # bpo-10496: if the current user identifier doesn't exist in the # password database, do nothing pass if 'PLAT' not in os.environ: os.environ['PLAT'] = get_platform() _environ_checked = 1 def subst_vars (s, local_vars): """Perform shell/Perl-style variable substitution on 'string'. Every occurrence of '$' followed by a name is considered a variable, and variable is substituted by the value found in the 'local_vars' dictionary, or in 'os.environ' if it's not in 'local_vars'. 'os.environ' is first checked/augmented to guarantee that it contains certain values: see 'check_environ()'. Raise ValueError for any variables not found in either 'local_vars' or 'os.environ'. """ check_environ() def _subst (match, local_vars=local_vars): var_name = match.group(1) if var_name in local_vars: return str(local_vars[var_name]) else: return os.environ[var_name] try: return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s) except KeyError as var: raise ValueError("invalid variable '$%s'" % var) # subst_vars () def grok_environment_error (exc, prefix="error: "): # Function kept for backward compatibility. # Used to try clever things with EnvironmentErrors, # but nowadays str(exception) produces good messages. return prefix + str(exc) # Needed by 'split_quoted()' _wordchars_re = _squote_re = _dquote_re = None def _init_regex(): global _wordchars_re, _squote_re, _dquote_re _wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace) _squote_re = re.compile(r"'(?:[^'\\]|\\.)*'") _dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"') def split_quoted (s): """Split a string up according to Unix shell-like rules for quotes and backslashes. In short: words are delimited by spaces, as long as those spaces are not escaped by a backslash, or inside a quoted string. Single and double quotes are equivalent, and the quote characters can be backslash-escaped. The backslash is stripped from any two-character escape sequence, leaving only the escaped character. The quote characters are stripped from any quoted string. Returns a list of words. """ # This is a nice algorithm for splitting up a single string, since it # doesn't require character-by-character examination. It was a little # bit of a brain-bender to get it working right, though... if _wordchars_re is None: _init_regex() s = s.strip() words = [] pos = 0 while s: m = _wordchars_re.match(s, pos) end = m.end() if end == len(s): words.append(s[:end]) break if s[end] in string.whitespace: # unescaped, unquoted whitespace: now words.append(s[:end]) # we definitely have a word delimiter s = s[end:].lstrip() pos = 0 elif s[end] == '\\': # preserve whatever is being escaped; # will become part of the current word s = s[:end] + s[end+1:] pos = end+1 else: if s[end] == "'": # slurp singly-quoted string m = _squote_re.match(s, end) elif s[end] == '"': # slurp doubly-quoted string m = _dquote_re.match(s, end) else: raise RuntimeError("this can't happen (bad char '%c')" % s[end]) if m is None: raise ValueError("bad string (mismatched %s quotes?)" % s[end]) (beg, end) = m.span() s = s[:beg] + s[beg+1:end-1] + s[end:] pos = m.end() - 2 if pos >= len(s): words.append(s) break return words # split_quoted () def execute (func, args, msg=None, verbose=0, dry_run=0): """Perform some action that affects the outside world (eg. by writing to the filesystem). Such actions are special because they are disabled by the 'dry_run' flag. This method takes care of all that bureaucracy for you; all you have to do is supply the function to call and an argument tuple for it (to embody the "external action" being performed), and an optional message to print. """ if msg is None: msg = "%s%r" % (func.__name__, args) if msg[-2:] == ',)': # correct for singleton tuple msg = msg[0:-2] + ')' log.info(msg) if not dry_run: func(*args) def strtobool (val): """Convert a string representation of truth to true (1) or false (0). True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if 'val' is anything else. """ val = val.lower() if val in ('y', 'yes', 't', 'true', 'on', '1'): return 1 elif val in ('n', 'no', 'f', 'false', 'off', '0'): return 0 else: raise ValueError("invalid truth value %r" % (val,)) def byte_compile (py_files, optimize=0, force=0, prefix=None, base_dir=None, verbose=1, dry_run=0, direct=None): """Byte-compile a collection of Python source files to .pyc files in a __pycache__ subdirectory. 'py_files' is a list of files to compile; any files that don't end in ".py" are silently skipped. 'optimize' must be one of the following: 0 - don't optimize 1 - normal optimization (like "python -O") 2 - extra optimization (like "python -OO") If 'force' is true, all files are recompiled regardless of timestamps. The source filename encoded in each bytecode file defaults to the filenames listed in 'py_files'; you can modify these with 'prefix' and 'basedir'. 'prefix' is a string that will be stripped off of each source filename, and 'base_dir' is a directory name that will be prepended (after 'prefix' is stripped). You can supply either or both (or neither) of 'prefix' and 'base_dir', as you wish. If 'dry_run' is true, doesn't actually do anything that would affect the filesystem. Byte-compilation is either done directly in this interpreter process with the standard py_compile module, or indirectly by writing a temporary script and executing it. Normally, you should let 'byte_compile()' figure out to use direct compilation or not (see the source for details). The 'direct' flag is used by the script generated in indirect mode; unless you know what you're doing, leave it set to None. """ # Late import to fix a bootstrap issue: _posixsubprocess is built by # setup.py, but setup.py uses distutils. import subprocess # nothing is done if sys.dont_write_bytecode is True if sys.dont_write_bytecode: raise DistutilsByteCompileError('byte-compiling is disabled.') # First, if the caller didn't force us into direct or indirect mode, # figure out which mode we should be in. We take a conservative # approach: choose direct mode *only* if the current interpreter is # in debug mode and optimize is 0. If we're not in debug mode (-O # or -OO), we don't know which level of optimization this # interpreter is running with, so we can't do direct # byte-compilation and be certain that it's the right thing. Thus, # always compile indirectly if the current interpreter is in either # optimize mode, or if either optimization level was requested by # the caller. if direct is None: direct = (__debug__ and optimize == 0) # "Indirect" byte-compilation: write a temporary script and then # run it with the appropriate flags. if not direct: try: from tempfile import mkstemp (script_fd, script_name) = mkstemp(".py") except ImportError: from tempfile import mktemp (script_fd, script_name) = None, mktemp(".py") log.info("writing byte-compilation script '%s'", script_name) if not dry_run: if script_fd is not None: script = os.fdopen(script_fd, "w") else: script = open(script_name, "w") with script: script.write("""\ from distutils.util import byte_compile files = [ """) # XXX would be nice to write absolute filenames, just for # safety's sake (script should be more robust in the face of # chdir'ing before running it). But this requires abspath'ing # 'prefix' as well, and that breaks the hack in build_lib's # 'byte_compile()' method that carefully tacks on a trailing # slash (os.sep really) to make sure the prefix here is "just # right". This whole prefix business is rather delicate -- the # problem is that it's really a directory, but I'm treating it # as a dumb string, so trailing slashes and so forth matter. #py_files = map(os.path.abspath, py_files) #if prefix: # prefix = os.path.abspath(prefix) script.write(",\n".join(map(repr, py_files)) + "]\n") script.write(""" byte_compile(files, optimize=%r, force=%r, prefix=%r, base_dir=%r, verbose=%r, dry_run=0, direct=1) """ % (optimize, force, prefix, base_dir, verbose)) cmd = [sys.executable] cmd.extend(_optim_args_from_interpreter_flags()) cmd.append(script_name) spawn(cmd, dry_run=dry_run) execute(os.remove, (script_name,), "removing %s" % script_name, dry_run=dry_run) # "Direct" byte-compilation: use the py_compile module to compile # right here, right now. Note that the script generated in indirect # mode simply calls 'byte_compile()' in direct mode, a weird sort of # cross-process recursion. Hey, it works! else: from py_compile import compile for file in py_files: if file[-3:] != ".py": # This lets us be lazy and not filter filenames in # the "install_lib" command. continue # Terminology from the py_compile module: # cfile - byte-compiled file # dfile - purported source filename (same as 'file' by default) if optimize >= 0: opt = '' if optimize == 0 else optimize cfile = importlib.util.cache_from_source( file, optimization=opt) else: cfile = importlib.util.cache_from_source(file) dfile = file if prefix: if file[:len(prefix)] != prefix: raise ValueError("invalid prefix: filename %r doesn't start with %r" % (file, prefix)) dfile = dfile[len(prefix):] if base_dir: dfile = os.path.join(base_dir, dfile) cfile_base = os.path.basename(cfile) if direct: if force or newer(file, cfile): log.info("byte-compiling %s to %s", file, cfile_base) if not dry_run: compile(file, cfile, dfile) else: log.debug("skipping byte-compilation of %s to %s", file, cfile_base) # byte_compile () def rfc822_escape (header): """Return a version of the string escaped for inclusion in an RFC-822 header, by ensuring there are 8 spaces space after each newline. """ lines = header.split('\n') sep = '\n' + 8 * ' ' return sep.join(lines) PKH]>vv?python3.10/site-packages/setuptools/_distutils/msvc9compiler.pynu["""distutils.msvc9compiler Contains MSVCCompiler, an implementation of the abstract CCompiler class for the Microsoft Visual Studio 2008. The module is compatible with VS 2005 and VS 2008. You can find legacy support for older versions of VS in distutils.msvccompiler. """ # Written by Perry Stoll # hacked by Robin Becker and Thomas Heller to do a better job of # finding DevStudio (through the registry) # ported to VS2005 and VS 2008 by Christian Heimes import os import subprocess import sys import re from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ CompileError, LibError, LinkError from distutils.ccompiler import CCompiler, gen_lib_options from distutils import log from distutils.util import get_platform import winreg RegOpenKeyEx = winreg.OpenKeyEx RegEnumKey = winreg.EnumKey RegEnumValue = winreg.EnumValue RegError = winreg.error HKEYS = (winreg.HKEY_USERS, winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CLASSES_ROOT) NATIVE_WIN64 = (sys.platform == 'win32' and sys.maxsize > 2**32) if NATIVE_WIN64: # Visual C++ is a 32-bit application, so we need to look in # the corresponding registry branch, if we're running a # 64-bit Python on Win64 VS_BASE = r"Software\Wow6432Node\Microsoft\VisualStudio\%0.1f" WINSDK_BASE = r"Software\Wow6432Node\Microsoft\Microsoft SDKs\Windows" NET_BASE = r"Software\Wow6432Node\Microsoft\.NETFramework" else: VS_BASE = r"Software\Microsoft\VisualStudio\%0.1f" WINSDK_BASE = r"Software\Microsoft\Microsoft SDKs\Windows" NET_BASE = r"Software\Microsoft\.NETFramework" # A map keyed by get_platform() return values to values accepted by # 'vcvarsall.bat'. Note a cross-compile may combine these (eg, 'x86_amd64' is # the param to cross-compile on x86 targeting amd64.) PLAT_TO_VCVARS = { 'win32' : 'x86', 'win-amd64' : 'amd64', } class Reg: """Helper class to read values from the registry """ def get_value(cls, path, key): for base in HKEYS: d = cls.read_values(base, path) if d and key in d: return d[key] raise KeyError(key) get_value = classmethod(get_value) def read_keys(cls, base, key): """Return list of registry keys.""" try: handle = RegOpenKeyEx(base, key) except RegError: return None L = [] i = 0 while True: try: k = RegEnumKey(handle, i) except RegError: break L.append(k) i += 1 return L read_keys = classmethod(read_keys) def read_values(cls, base, key): """Return dict of registry keys and values. All names are converted to lowercase. """ try: handle = RegOpenKeyEx(base, key) except RegError: return None d = {} i = 0 while True: try: name, value, type = RegEnumValue(handle, i) except RegError: break name = name.lower() d[cls.convert_mbcs(name)] = cls.convert_mbcs(value) i += 1 return d read_values = classmethod(read_values) def convert_mbcs(s): dec = getattr(s, "decode", None) if dec is not None: try: s = dec("mbcs") except UnicodeError: pass return s convert_mbcs = staticmethod(convert_mbcs) class MacroExpander: def __init__(self, version): self.macros = {} self.vsbase = VS_BASE % version self.load_macros(version) def set_macro(self, macro, path, key): self.macros["$(%s)" % macro] = Reg.get_value(path, key) def load_macros(self, version): self.set_macro("VCInstallDir", self.vsbase + r"\Setup\VC", "productdir") self.set_macro("VSInstallDir", self.vsbase + r"\Setup\VS", "productdir") self.set_macro("FrameworkDir", NET_BASE, "installroot") try: if version >= 8.0: self.set_macro("FrameworkSDKDir", NET_BASE, "sdkinstallrootv2.0") else: raise KeyError("sdkinstallrootv2.0") except KeyError: raise DistutilsPlatformError( """Python was built with Visual Studio 2008; extensions must be built with a compiler than can generate compatible binaries. Visual Studio 2008 was not found on this system. If you have Cygwin installed, you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") if version >= 9.0: self.set_macro("FrameworkVersion", self.vsbase, "clr version") self.set_macro("WindowsSdkDir", WINSDK_BASE, "currentinstallfolder") else: p = r"Software\Microsoft\NET Framework Setup\Product" for base in HKEYS: try: h = RegOpenKeyEx(base, p) except RegError: continue key = RegEnumKey(h, 0) d = Reg.get_value(base, r"%s\%s" % (p, key)) self.macros["$(FrameworkVersion)"] = d["version"] def sub(self, s): for k, v in self.macros.items(): s = s.replace(k, v) return s def get_build_version(): """Return the version of MSVC that was used to build Python. For Python 2.3 and up, the version number is included in sys.version. For earlier versions, assume the compiler is MSVC 6. """ prefix = "MSC v." i = sys.version.find(prefix) if i == -1: return 6 i = i + len(prefix) s, rest = sys.version[i:].split(" ", 1) majorVersion = int(s[:-2]) - 6 if majorVersion >= 13: # v13 was skipped and should be v14 majorVersion += 1 minorVersion = int(s[2:3]) / 10.0 # I don't think paths are affected by minor version in version 6 if majorVersion == 6: minorVersion = 0 if majorVersion >= 6: return majorVersion + minorVersion # else we don't know what version of the compiler this is return None def normalize_and_reduce_paths(paths): """Return a list of normalized paths with duplicates removed. The current order of paths is maintained. """ # Paths are normalized so things like: /a and /a/ aren't both preserved. reduced_paths = [] for p in paths: np = os.path.normpath(p) # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set. if np not in reduced_paths: reduced_paths.append(np) return reduced_paths def removeDuplicates(variable): """Remove duplicate values of an environment variable. """ oldList = variable.split(os.pathsep) newList = [] for i in oldList: if i not in newList: newList.append(i) newVariable = os.pathsep.join(newList) return newVariable def find_vcvarsall(version): """Find the vcvarsall.bat file At first it tries to find the productdir of VS 2008 in the registry. If that fails it falls back to the VS90COMNTOOLS env var. """ vsbase = VS_BASE % version try: productdir = Reg.get_value(r"%s\Setup\VC" % vsbase, "productdir") except KeyError: log.debug("Unable to find productdir in registry") productdir = None if not productdir or not os.path.isdir(productdir): toolskey = "VS%0.f0COMNTOOLS" % version toolsdir = os.environ.get(toolskey, None) if toolsdir and os.path.isdir(toolsdir): productdir = os.path.join(toolsdir, os.pardir, os.pardir, "VC") productdir = os.path.abspath(productdir) if not os.path.isdir(productdir): log.debug("%s is not a valid directory" % productdir) return None else: log.debug("Env var %s is not set or invalid" % toolskey) if not productdir: log.debug("No productdir found") return None vcvarsall = os.path.join(productdir, "vcvarsall.bat") if os.path.isfile(vcvarsall): return vcvarsall log.debug("Unable to find vcvarsall.bat") return None def query_vcvarsall(version, arch="x86"): """Launch vcvarsall.bat and read the settings from its environment """ vcvarsall = find_vcvarsall(version) interesting = {"include", "lib", "libpath", "path"} result = {} if vcvarsall is None: raise DistutilsPlatformError("Unable to find vcvarsall.bat") log.debug("Calling 'vcvarsall.bat %s' (version=%s)", arch, version) popen = subprocess.Popen('"%s" %s & set' % (vcvarsall, arch), stdout=subprocess.PIPE, stderr=subprocess.PIPE) try: stdout, stderr = popen.communicate() if popen.wait() != 0: raise DistutilsPlatformError(stderr.decode("mbcs")) stdout = stdout.decode("mbcs") for line in stdout.split("\n"): line = Reg.convert_mbcs(line) if '=' not in line: continue line = line.strip() key, value = line.split('=', 1) key = key.lower() if key in interesting: if value.endswith(os.pathsep): value = value[:-1] result[key] = removeDuplicates(value) finally: popen.stdout.close() popen.stderr.close() if len(result) != len(interesting): raise ValueError(str(list(result.keys()))) return result # More globals VERSION = get_build_version() if VERSION < 8.0: raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION) # MACROS = MacroExpander(VERSION) class MSVCCompiler(CCompiler) : """Concrete class that implements an interface to Microsoft Visual C++, as defined by the CCompiler abstract class.""" compiler_type = 'msvc' # Just set this so CCompiler's constructor doesn't barf. We currently # don't use the 'set_executables()' bureaucracy provided by CCompiler, # as it really isn't necessary for this sort of single-compiler class. # Would be nice to have a consistent interface with UnixCCompiler, # though, so it's worth thinking about. executables = {} # Private class data (need to distinguish C from C++ source for compiler) _c_extensions = ['.c'] _cpp_extensions = ['.cc', '.cpp', '.cxx'] _rc_extensions = ['.rc'] _mc_extensions = ['.mc'] # Needed for the filename generation methods provided by the # base class, CCompiler. src_extensions = (_c_extensions + _cpp_extensions + _rc_extensions + _mc_extensions) res_extension = '.res' obj_extension = '.obj' static_lib_extension = '.lib' shared_lib_extension = '.dll' static_lib_format = shared_lib_format = '%s%s' exe_extension = '.exe' def __init__(self, verbose=0, dry_run=0, force=0): CCompiler.__init__ (self, verbose, dry_run, force) self.__version = VERSION self.__root = r"Software\Microsoft\VisualStudio" # self.__macros = MACROS self.__paths = [] # target platform (.plat_name is consistent with 'bdist') self.plat_name = None self.__arch = None # deprecated name self.initialized = False def initialize(self, plat_name=None): # multi-init means we would need to check platform same each time... assert not self.initialized, "don't init multiple times" if plat_name is None: plat_name = get_platform() # sanity check for platforms to prevent obscure errors later. ok_plats = 'win32', 'win-amd64' if plat_name not in ok_plats: raise DistutilsPlatformError("--plat-name must be one of %s" % (ok_plats,)) if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"): # Assume that the SDK set up everything alright; don't try to be # smarter self.cc = "cl.exe" self.linker = "link.exe" self.lib = "lib.exe" self.rc = "rc.exe" self.mc = "mc.exe" else: # On x86, 'vcvars32.bat amd64' creates an env that doesn't work; # to cross compile, you use 'x86_amd64'. # On AMD64, 'vcvars32.bat amd64' is a native build env; to cross # compile use 'x86' (ie, it runs the x86 compiler directly) if plat_name == get_platform() or plat_name == 'win32': # native build or cross-compile to win32 plat_spec = PLAT_TO_VCVARS[plat_name] else: # cross compile from win32 -> some 64bit plat_spec = PLAT_TO_VCVARS[get_platform()] + '_' + \ PLAT_TO_VCVARS[plat_name] vc_env = query_vcvarsall(VERSION, plat_spec) self.__paths = vc_env['path'].split(os.pathsep) os.environ['lib'] = vc_env['lib'] os.environ['include'] = vc_env['include'] if len(self.__paths) == 0: raise DistutilsPlatformError("Python was built with %s, " "and extensions need to be built with the same " "version of the compiler, but it isn't installed." % self.__product) self.cc = self.find_exe("cl.exe") self.linker = self.find_exe("link.exe") self.lib = self.find_exe("lib.exe") self.rc = self.find_exe("rc.exe") # resource compiler self.mc = self.find_exe("mc.exe") # message compiler #self.set_path_env_var('lib') #self.set_path_env_var('include') # extend the MSVC path with the current path try: for p in os.environ['path'].split(';'): self.__paths.append(p) except KeyError: pass self.__paths = normalize_and_reduce_paths(self.__paths) os.environ['path'] = ";".join(self.__paths) self.preprocess_options = None if self.__arch == "x86": self.compile_options = [ '/nologo', '/O2', '/MD', '/W3', '/DNDEBUG'] self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/Z7', '/D_DEBUG'] else: # Win64 self.compile_options = [ '/nologo', '/O2', '/MD', '/W3', '/GS-' , '/DNDEBUG'] self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-', '/Z7', '/D_DEBUG'] self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] if self.__version >= 7: self.ldflags_shared_debug = [ '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG' ] self.ldflags_static = [ '/nologo'] self.initialized = True # -- Worker methods ------------------------------------------------ def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): # Copied from ccompiler.py, extended to return .res as 'object'-file # for .rc input file if output_dir is None: output_dir = '' obj_names = [] for src_name in source_filenames: (base, ext) = os.path.splitext (src_name) base = os.path.splitdrive(base)[1] # Chop off the drive base = base[os.path.isabs(base):] # If abs, chop off leading / if ext not in self.src_extensions: # Better to raise an exception instead of silently continuing # and later complain about sources and targets having # different lengths raise CompileError ("Don't know how to compile %s" % src_name) if strip_dir: base = os.path.basename (base) if ext in self._rc_extensions: obj_names.append (os.path.join (output_dir, base + self.res_extension)) elif ext in self._mc_extensions: obj_names.append (os.path.join (output_dir, base + self.res_extension)) else: obj_names.append (os.path.join (output_dir, base + self.obj_extension)) return obj_names def compile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): if not self.initialized: self.initialize() compile_info = self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs) macros, objects, extra_postargs, pp_opts, build = compile_info compile_opts = extra_preargs or [] compile_opts.append ('/c') if debug: compile_opts.extend(self.compile_options_debug) else: compile_opts.extend(self.compile_options) for obj in objects: try: src, ext = build[obj] except KeyError: continue if debug: # pass the full pathname to MSVC in debug mode, # this allows the debugger to find the source file # without asking the user to browse for it src = os.path.abspath(src) if ext in self._c_extensions: input_opt = "/Tc" + src elif ext in self._cpp_extensions: input_opt = "/Tp" + src elif ext in self._rc_extensions: # compile .RC to .RES file input_opt = src output_opt = "/fo" + obj try: self.spawn([self.rc] + pp_opts + [output_opt] + [input_opt]) except DistutilsExecError as msg: raise CompileError(msg) continue elif ext in self._mc_extensions: # Compile .MC to .RC file to .RES file. # * '-h dir' specifies the directory for the # generated include file # * '-r dir' specifies the target directory of the # generated RC file and the binary message resource # it includes # # For now (since there are no options to change this), # we use the source-directory for the include file and # the build directory for the RC file and message # resources. This works at least for win32all. h_dir = os.path.dirname(src) rc_dir = os.path.dirname(obj) try: # first compile .MC to .RC and .H file self.spawn([self.mc] + ['-h', h_dir, '-r', rc_dir] + [src]) base, _ = os.path.splitext (os.path.basename (src)) rc_file = os.path.join (rc_dir, base + '.rc') # then compile .RC to .RES file self.spawn([self.rc] + ["/fo" + obj] + [rc_file]) except DistutilsExecError as msg: raise CompileError(msg) continue else: # how to handle this file? raise CompileError("Don't know how to compile %s to %s" % (src, obj)) output_opt = "/Fo" + obj try: self.spawn([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg) return objects def create_static_lib(self, objects, output_libname, output_dir=None, debug=0, target_lang=None): if not self.initialized: self.initialize() (objects, output_dir) = self._fix_object_args(objects, output_dir) output_filename = self.library_filename(output_libname, output_dir=output_dir) if self._need_link(objects, output_filename): lib_args = objects + ['/OUT:' + output_filename] if debug: pass # XXX what goes here? try: self.spawn([self.lib] + lib_args) except DistutilsExecError as msg: raise LibError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): if not self.initialized: self.initialize() (objects, output_dir) = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) (libraries, library_dirs, runtime_library_dirs) = fixed_args if runtime_library_dirs: self.warn ("I don't know what to do with 'runtime_library_dirs': " + str (runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): if target_desc == CCompiler.EXECUTABLE: if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] else: if debug: ldflags = self.ldflags_shared_debug else: ldflags = self.ldflags_shared export_opts = [] for sym in (export_symbols or []): export_opts.append("/EXPORT:" + sym) ld_args = (ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]) # The MSVC linker generates .lib and .exp files, which cannot be # suppressed by any linker switches. The .lib files may even be # needed! Make sure they are generated in the temporary build # directory. Since they have different names for debug and release # builds, they can go into the same directory. build_temp = os.path.dirname(objects[0]) if export_symbols is not None: (dll_name, dll_ext) = os.path.splitext( os.path.basename(output_filename)) implib_file = os.path.join( build_temp, self.library_filename(dll_name)) ld_args.append ('/IMPLIB:' + implib_file) self.manifest_setup_ldargs(output_filename, build_temp, ld_args) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: self.spawn([self.linker] + ld_args) except DistutilsExecError as msg: raise LinkError(msg) # embed the manifest # XXX - this is somewhat fragile - if mt.exe fails, distutils # will still consider the DLL up-to-date, but it will not have a # manifest. Maybe we should link to a temp file? OTOH, that # implies a build environment error that shouldn't go undetected. mfinfo = self.manifest_get_embed_info(target_desc, ld_args) if mfinfo is not None: mffilename, mfid = mfinfo out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', mffilename, out_arg]) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) def manifest_setup_ldargs(self, output_filename, build_temp, ld_args): # If we need a manifest at all, an embedded manifest is recommended. # See MSDN article titled # "How to: Embed a Manifest Inside a C/C++ Application" # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx) # Ask the linker to generate the manifest in the temp dir, so # we can check it, and possibly embed it, later. temp_manifest = os.path.join( build_temp, os.path.basename(output_filename) + ".manifest") ld_args.append('/MANIFESTFILE:' + temp_manifest) def manifest_get_embed_info(self, target_desc, ld_args): # If a manifest should be embedded, return a tuple of # (manifest_filename, resource_id). Returns None if no manifest # should be embedded. See http://bugs.python.org/issue7833 for why # we want to avoid any manifest for extension modules if we can) for arg in ld_args: if arg.startswith("/MANIFESTFILE:"): temp_manifest = arg.split(":", 1)[1] break else: # no /MANIFESTFILE so nothing to do. return None if target_desc == CCompiler.EXECUTABLE: # by default, executables always get the manifest with the # CRT referenced. mfid = 1 else: # Extension modules try and avoid any manifest if possible. mfid = 2 temp_manifest = self._remove_visual_c_ref(temp_manifest) if temp_manifest is None: return None return temp_manifest, mfid def _remove_visual_c_ref(self, manifest_file): try: # Remove references to the Visual C runtime, so they will # fall through to the Visual C dependency of Python.exe. # This way, when installed for a restricted user (e.g. # runtimes are not in WinSxS folder, but in Python's own # folder), the runtimes do not need to be in every folder # with .pyd's. # Returns either the filename of the modified manifest or # None if no manifest should be embedded. manifest_f = open(manifest_file) try: manifest_buf = manifest_f.read() finally: manifest_f.close() pattern = re.compile( r"""|)""", re.DOTALL) manifest_buf = re.sub(pattern, "", manifest_buf) pattern = r"\s*" manifest_buf = re.sub(pattern, "", manifest_buf) # Now see if any other assemblies are referenced - if not, we # don't want a manifest embedded. pattern = re.compile( r"""|)""", re.DOTALL) if re.search(pattern, manifest_buf) is None: return None manifest_f = open(manifest_file, 'w') try: manifest_f.write(manifest_buf) return manifest_file finally: manifest_f.close() except OSError: pass # -- Miscellaneous methods ----------------------------------------- # These are all used by the 'gen_lib_options() function, in # ccompiler.py. def library_dir_option(self, dir): return "/LIBPATH:" + dir def runtime_library_dir_option(self, dir): raise DistutilsPlatformError( "don't know how to set runtime library search path for MSVC++") def library_option(self, lib): return self.library_filename(lib) def find_library_file(self, dirs, lib, debug=0): # Prefer a debugging library if found (and requested), but deal # with it if we don't have one. if debug: try_names = [lib + "_d", lib] else: try_names = [lib] for dir in dirs: for name in try_names: libfile = os.path.join(dir, self.library_filename (name)) if os.path.exists(libfile): return libfile else: # Oops, didn't find it in *any* of 'dirs' return None # Helper methods for using the MSVC registry settings def find_exe(self, exe): """Return path to an MSVC executable program. Tries to find the program in several places: first, one of the MSVC program search paths from the registry; next, the directories in the PATH environment variable. If any of those work, return an absolute path that is known to exist. If none of them work, just return the original program name, 'exe'. """ for p in self.__paths: fn = os.path.join(os.path.abspath(p), exe) if os.path.isfile(fn): return fn # didn't find it; try existing path for p in os.environ['Path'].split(';'): fn = os.path.join(os.path.abspath(p),exe) if os.path.isfile(fn): return fn return exe PKH]| ;python3.10/site-packages/setuptools/_distutils/ccompiler.pynu["""distutils.ccompiler Contains CCompiler, an abstract base class that defines the interface for the Distutils compiler abstraction model.""" import sys, os, re from distutils.errors import * from distutils.spawn import spawn from distutils.file_util import move_file from distutils.dir_util import mkpath from distutils.dep_util import newer_group from distutils.util import split_quoted, execute from distutils import log class CCompiler: """Abstract base class to define the interface that must be implemented by real compiler classes. Also has some utility methods used by several compiler classes. The basic idea behind a compiler abstraction class is that each instance can be used for all the compile/link steps in building a single project. Thus, attributes common to all of those compile and link steps -- include directories, macros to define, libraries to link against, etc. -- are attributes of the compiler instance. To allow for variability in how individual files are treated, most of those attributes may be varied on a per-compilation or per-link basis. """ # 'compiler_type' is a class attribute that identifies this class. It # keeps code that wants to know what kind of compiler it's dealing with # from having to import all possible compiler classes just to do an # 'isinstance'. In concrete CCompiler subclasses, 'compiler_type' # should really, really be one of the keys of the 'compiler_class' # dictionary (see below -- used by the 'new_compiler()' factory # function) -- authors of new compiler interface classes are # responsible for updating 'compiler_class'! compiler_type = None # XXX things not handled by this compiler abstraction model: # * client can't provide additional options for a compiler, # e.g. warning, optimization, debugging flags. Perhaps this # should be the domain of concrete compiler abstraction classes # (UnixCCompiler, MSVCCompiler, etc.) -- or perhaps the base # class should have methods for the common ones. # * can't completely override the include or library searchg # path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2". # I'm not sure how widely supported this is even by Unix # compilers, much less on other platforms. And I'm even less # sure how useful it is; maybe for cross-compiling, but # support for that is a ways off. (And anyways, cross # compilers probably have a dedicated binary with the # right paths compiled in. I hope.) # * can't do really freaky things with the library list/library # dirs, e.g. "-Ldir1 -lfoo -Ldir2 -lfoo" to link against # different versions of libfoo.a in different locations. I # think this is useless without the ability to null out the # library search path anyways. # Subclasses that rely on the standard filename generation methods # implemented below should override these; see the comment near # those methods ('object_filenames()' et. al.) for details: src_extensions = None # list of strings obj_extension = None # string static_lib_extension = None shared_lib_extension = None # string static_lib_format = None # format string shared_lib_format = None # prob. same as static_lib_format exe_extension = None # string # Default language settings. language_map is used to detect a source # file or Extension target language, checking source filenames. # language_order is used to detect the language precedence, when deciding # what language to use when mixing source types. For example, if some # extension has two files with ".c" extension, and one with ".cpp", it # is still linked as c++. language_map = {".c" : "c", ".cc" : "c++", ".cpp" : "c++", ".cxx" : "c++", ".m" : "objc", } language_order = ["c++", "objc", "c"] def __init__(self, verbose=0, dry_run=0, force=0): self.dry_run = dry_run self.force = force self.verbose = verbose # 'output_dir': a common output directory for object, library, # shared object, and shared library files self.output_dir = None # 'macros': a list of macro definitions (or undefinitions). A # macro definition is a 2-tuple (name, value), where the value is # either a string or None (no explicit value). A macro # undefinition is a 1-tuple (name,). self.macros = [] # 'include_dirs': a list of directories to search for include files self.include_dirs = [] # 'libraries': a list of libraries to include in any link # (library names, not filenames: eg. "foo" not "libfoo.a") self.libraries = [] # 'library_dirs': a list of directories to search for libraries self.library_dirs = [] # 'runtime_library_dirs': a list of directories to search for # shared libraries/objects at runtime self.runtime_library_dirs = [] # 'objects': a list of object files (or similar, such as explicitly # named library files) to include on any link self.objects = [] for key in self.executables.keys(): self.set_executable(key, self.executables[key]) def set_executables(self, **kwargs): """Define the executables (and options for them) that will be run to perform the various stages of compilation. The exact set of executables that may be specified here depends on the compiler class (via the 'executables' class attribute), but most will have: compiler the C/C++ compiler linker_so linker used to create shared objects and libraries linker_exe linker used to create binary executables archiver static library creator On platforms with a command-line (Unix, DOS/Windows), each of these is a string that will be split into executable name and (optional) list of arguments. (Splitting the string is done similarly to how Unix shells operate: words are delimited by spaces, but quotes and backslashes can override this. See 'distutils.util.split_quoted()'.) """ # Note that some CCompiler implementation classes will define class # attributes 'cpp', 'cc', etc. with hard-coded executable names; # this is appropriate when a compiler class is for exactly one # compiler/OS combination (eg. MSVCCompiler). Other compiler # classes (UnixCCompiler, in particular) are driven by information # discovered at run-time, since there are many different ways to do # basically the same things with Unix C compilers. for key in kwargs: if key not in self.executables: raise ValueError("unknown executable '%s' for class %s" % (key, self.__class__.__name__)) self.set_executable(key, kwargs[key]) def set_executable(self, key, value): if isinstance(value, str): setattr(self, key, split_quoted(value)) else: setattr(self, key, value) def _find_macro(self, name): i = 0 for defn in self.macros: if defn[0] == name: return i i += 1 return None def _check_macro_definitions(self, definitions): """Ensures that every element of 'definitions' is a valid macro definition, ie. either (name,value) 2-tuple or a (name,) tuple. Do nothing if all definitions are OK, raise TypeError otherwise. """ for defn in definitions: if not (isinstance(defn, tuple) and (len(defn) in (1, 2) and (isinstance (defn[1], str) or defn[1] is None)) and isinstance (defn[0], str)): raise TypeError(("invalid macro definition '%s': " % defn) + \ "must be tuple (string,), (string, string), or " + \ "(string, None)") # -- Bookkeeping methods ------------------------------------------- def define_macro(self, name, value=None): """Define a preprocessor macro for all compilations driven by this compiler object. The optional parameter 'value' should be a string; if it is not supplied, then the macro will be defined without an explicit value and the exact outcome depends on the compiler used (XXX true? does ANSI say anything about this?) """ # Delete from the list of macro definitions/undefinitions if # already there (so that this one will take precedence). i = self._find_macro (name) if i is not None: del self.macros[i] self.macros.append((name, value)) def undefine_macro(self, name): """Undefine a preprocessor macro for all compilations driven by this compiler object. If the same macro is defined by 'define_macro()' and undefined by 'undefine_macro()' the last call takes precedence (including multiple redefinitions or undefinitions). If the macro is redefined/undefined on a per-compilation basis (ie. in the call to 'compile()'), then that takes precedence. """ # Delete from the list of macro definitions/undefinitions if # already there (so that this one will take precedence). i = self._find_macro (name) if i is not None: del self.macros[i] undefn = (name,) self.macros.append(undefn) def add_include_dir(self, dir): """Add 'dir' to the list of directories that will be searched for header files. The compiler is instructed to search directories in the order in which they are supplied by successive calls to 'add_include_dir()'. """ self.include_dirs.append(dir) def set_include_dirs(self, dirs): """Set the list of directories that will be searched to 'dirs' (a list of strings). Overrides any preceding calls to 'add_include_dir()'; subsequence calls to 'add_include_dir()' add to the list passed to 'set_include_dirs()'. This does not affect any list of standard include directories that the compiler may search by default. """ self.include_dirs = dirs[:] def add_library(self, libname): """Add 'libname' to the list of libraries that will be included in all links driven by this compiler object. Note that 'libname' should *not* be the name of a file containing a library, but the name of the library itself: the actual filename will be inferred by the linker, the compiler, or the compiler class (depending on the platform). The linker will be instructed to link against libraries in the order they were supplied to 'add_library()' and/or 'set_libraries()'. It is perfectly valid to duplicate library names; the linker will be instructed to link against libraries as many times as they are mentioned. """ self.libraries.append(libname) def set_libraries(self, libnames): """Set the list of libraries to be included in all links driven by this compiler object to 'libnames' (a list of strings). This does not affect any standard system libraries that the linker may include by default. """ self.libraries = libnames[:] def add_library_dir(self, dir): """Add 'dir' to the list of directories that will be searched for libraries specified to 'add_library()' and 'set_libraries()'. The linker will be instructed to search for libraries in the order they are supplied to 'add_library_dir()' and/or 'set_library_dirs()'. """ self.library_dirs.append(dir) def set_library_dirs(self, dirs): """Set the list of library search directories to 'dirs' (a list of strings). This does not affect any standard library search path that the linker may search by default. """ self.library_dirs = dirs[:] def add_runtime_library_dir(self, dir): """Add 'dir' to the list of directories that will be searched for shared libraries at runtime. """ self.runtime_library_dirs.append(dir) def set_runtime_library_dirs(self, dirs): """Set the list of directories to search for shared libraries at runtime to 'dirs' (a list of strings). This does not affect any standard search path that the runtime linker may search by default. """ self.runtime_library_dirs = dirs[:] def add_link_object(self, object): """Add 'object' to the list of object files (or analogues, such as explicitly named library files or the output of "resource compilers") to be included in every link driven by this compiler object. """ self.objects.append(object) def set_link_objects(self, objects): """Set the list of object files (or analogues) to be included in every link to 'objects'. This does not affect any standard object files that the linker may include by default (such as system libraries). """ self.objects = objects[:] # -- Private utility methods -------------------------------------- # (here for the convenience of subclasses) # Helper method to prep compiler in subclass compile() methods def _setup_compile(self, outdir, macros, incdirs, sources, depends, extra): """Process arguments and decide which source files to compile.""" if outdir is None: outdir = self.output_dir elif not isinstance(outdir, str): raise TypeError("'output_dir' must be a string or None") if macros is None: macros = self.macros elif isinstance(macros, list): macros = macros + (self.macros or []) else: raise TypeError("'macros' (if supplied) must be a list of tuples") if incdirs is None: incdirs = self.include_dirs elif isinstance(incdirs, (list, tuple)): incdirs = list(incdirs) + (self.include_dirs or []) else: raise TypeError( "'include_dirs' (if supplied) must be a list of strings") if extra is None: extra = [] # Get the list of expected output (object) files objects = self.object_filenames(sources, strip_dir=0, output_dir=outdir) assert len(objects) == len(sources) pp_opts = gen_preprocess_options(macros, incdirs) build = {} for i in range(len(sources)): src = sources[i] obj = objects[i] ext = os.path.splitext(src)[1] self.mkpath(os.path.dirname(obj)) build[obj] = (src, ext) return macros, objects, extra, pp_opts, build def _get_cc_args(self, pp_opts, debug, before): # works for unixccompiler, cygwinccompiler cc_args = pp_opts + ['-c'] if debug: cc_args[:0] = ['-g'] if before: cc_args[:0] = before return cc_args def _fix_compile_args(self, output_dir, macros, include_dirs): """Typecheck and fix-up some of the arguments to the 'compile()' method, and return fixed-up values. Specifically: if 'output_dir' is None, replaces it with 'self.output_dir'; ensures that 'macros' is a list, and augments it with 'self.macros'; ensures that 'include_dirs' is a list, and augments it with 'self.include_dirs'. Guarantees that the returned values are of the correct type, i.e. for 'output_dir' either string or None, and for 'macros' and 'include_dirs' either list or None. """ if output_dir is None: output_dir = self.output_dir elif not isinstance(output_dir, str): raise TypeError("'output_dir' must be a string or None") if macros is None: macros = self.macros elif isinstance(macros, list): macros = macros + (self.macros or []) else: raise TypeError("'macros' (if supplied) must be a list of tuples") if include_dirs is None: include_dirs = self.include_dirs elif isinstance(include_dirs, (list, tuple)): include_dirs = list(include_dirs) + (self.include_dirs or []) else: raise TypeError( "'include_dirs' (if supplied) must be a list of strings") return output_dir, macros, include_dirs def _prep_compile(self, sources, output_dir, depends=None): """Decide which source files must be recompiled. Determine the list of object files corresponding to 'sources', and figure out which ones really need to be recompiled. Return a list of all object files and a dictionary telling which source files can be skipped. """ # Get the list of expected output (object) files objects = self.object_filenames(sources, output_dir=output_dir) assert len(objects) == len(sources) # Return an empty dict for the "which source files can be skipped" # return value to preserve API compatibility. return objects, {} def _fix_object_args(self, objects, output_dir): """Typecheck and fix up some arguments supplied to various methods. Specifically: ensure that 'objects' is a list; if output_dir is None, replace with self.output_dir. Return fixed versions of 'objects' and 'output_dir'. """ if not isinstance(objects, (list, tuple)): raise TypeError("'objects' must be a list or tuple of strings") objects = list(objects) if output_dir is None: output_dir = self.output_dir elif not isinstance(output_dir, str): raise TypeError("'output_dir' must be a string or None") return (objects, output_dir) def _fix_lib_args(self, libraries, library_dirs, runtime_library_dirs): """Typecheck and fix up some of the arguments supplied to the 'link_*' methods. Specifically: ensure that all arguments are lists, and augment them with their permanent versions (eg. 'self.libraries' augments 'libraries'). Return a tuple with fixed versions of all arguments. """ if libraries is None: libraries = self.libraries elif isinstance(libraries, (list, tuple)): libraries = list (libraries) + (self.libraries or []) else: raise TypeError( "'libraries' (if supplied) must be a list of strings") if library_dirs is None: library_dirs = self.library_dirs elif isinstance(library_dirs, (list, tuple)): library_dirs = list (library_dirs) + (self.library_dirs or []) else: raise TypeError( "'library_dirs' (if supplied) must be a list of strings") if runtime_library_dirs is None: runtime_library_dirs = self.runtime_library_dirs elif isinstance(runtime_library_dirs, (list, tuple)): runtime_library_dirs = (list(runtime_library_dirs) + (self.runtime_library_dirs or [])) else: raise TypeError("'runtime_library_dirs' (if supplied) " "must be a list of strings") return (libraries, library_dirs, runtime_library_dirs) def _need_link(self, objects, output_file): """Return true if we need to relink the files listed in 'objects' to recreate 'output_file'. """ if self.force: return True else: if self.dry_run: newer = newer_group (objects, output_file, missing='newer') else: newer = newer_group (objects, output_file) return newer def detect_language(self, sources): """Detect the language of a given file, or list of files. Uses language_map, and language_order to do the job. """ if not isinstance(sources, list): sources = [sources] lang = None index = len(self.language_order) for source in sources: base, ext = os.path.splitext(source) extlang = self.language_map.get(ext) try: extindex = self.language_order.index(extlang) if extindex < index: lang = extlang index = extindex except ValueError: pass return lang # -- Worker methods ------------------------------------------------ # (must be implemented by subclasses) def preprocess(self, source, output_file=None, macros=None, include_dirs=None, extra_preargs=None, extra_postargs=None): """Preprocess a single C/C++ source file, named in 'source'. Output will be written to file named 'output_file', or stdout if 'output_file' not supplied. 'macros' is a list of macro definitions as for 'compile()', which will augment the macros set with 'define_macro()' and 'undefine_macro()'. 'include_dirs' is a list of directory names that will be added to the default list. Raises PreprocessError on failure. """ pass def compile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): """Compile one or more source files. 'sources' must be a list of filenames, most likely C/C++ files, but in reality anything that can be handled by a particular compiler and compiler class (eg. MSVCCompiler can handle resource files in 'sources'). Return a list of object filenames, one per source filename in 'sources'. Depending on the implementation, not all source files will necessarily be compiled, but all corresponding object filenames will be returned. If 'output_dir' is given, object files will be put under it, while retaining their original path component. That is, "foo/bar.c" normally compiles to "foo/bar.o" (for a Unix implementation); if 'output_dir' is "build", then it would compile to "build/foo/bar.o". 'macros', if given, must be a list of macro definitions. A macro definition is either a (name, value) 2-tuple or a (name,) 1-tuple. The former defines a macro; if the value is None, the macro is defined without an explicit value. The 1-tuple case undefines a macro. Later definitions/redefinitions/ undefinitions take precedence. 'include_dirs', if given, must be a list of strings, the directories to add to the default include file search path for this compilation only. 'debug' is a boolean; if true, the compiler will be instructed to output debug symbols in (or alongside) the object file(s). 'extra_preargs' and 'extra_postargs' are implementation- dependent. On platforms that have the notion of a command-line (e.g. Unix, DOS/Windows), they are most likely lists of strings: extra command-line arguments to prepend/append to the compiler command line. On other platforms, consult the implementation class documentation. In any event, they are intended as an escape hatch for those occasions when the abstract compiler framework doesn't cut the mustard. 'depends', if given, is a list of filenames that all targets depend on. If a source file is older than any file in depends, then the source file will be recompiled. This supports dependency tracking, but only at a coarse granularity. Raises CompileError on failure. """ # A concrete compiler class can either override this method # entirely or implement _compile(). macros, objects, extra_postargs, pp_opts, build = \ self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs) cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) for obj in objects: try: src, ext = build[obj] except KeyError: continue self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) # Return *all* object filenames, not just the ones we just built. return objects def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): """Compile 'src' to product 'obj'.""" # A concrete compiler class that does not override compile() # should implement _compile(). pass def create_static_lib(self, objects, output_libname, output_dir=None, debug=0, target_lang=None): """Link a bunch of stuff together to create a static library file. The "bunch of stuff" consists of the list of object files supplied as 'objects', the extra object files supplied to 'add_link_object()' and/or 'set_link_objects()', the libraries supplied to 'add_library()' and/or 'set_libraries()', and the libraries supplied as 'libraries' (if any). 'output_libname' should be a library name, not a filename; the filename will be inferred from the library name. 'output_dir' is the directory where the library file will be put. 'debug' is a boolean; if true, debugging information will be included in the library (note that on most platforms, it is the compile step where this matters: the 'debug' flag is included here just for consistency). 'target_lang' is the target language for which the given objects are being compiled. This allows specific linkage time treatment of certain languages. Raises LibError on failure. """ pass # values for target_desc parameter in link() SHARED_OBJECT = "shared_object" SHARED_LIBRARY = "shared_library" EXECUTABLE = "executable" def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): """Link a bunch of stuff together to create an executable or shared library file. The "bunch of stuff" consists of the list of object files supplied as 'objects'. 'output_filename' should be a filename. If 'output_dir' is supplied, 'output_filename' is relative to it (i.e. 'output_filename' can provide directory components if needed). 'libraries' is a list of libraries to link against. These are library names, not filenames, since they're translated into filenames in a platform-specific way (eg. "foo" becomes "libfoo.a" on Unix and "foo.lib" on DOS/Windows). However, they can include a directory component, which means the linker will look in that specific directory rather than searching all the normal locations. 'library_dirs', if supplied, should be a list of directories to search for libraries that were specified as bare library names (ie. no directory component). These are on top of the system default and those supplied to 'add_library_dir()' and/or 'set_library_dirs()'. 'runtime_library_dirs' is a list of directories that will be embedded into the shared library and used to search for other shared libraries that *it* depends on at run-time. (This may only be relevant on Unix.) 'export_symbols' is a list of symbols that the shared library will export. (This appears to be relevant only on Windows.) 'debug' is as for 'compile()' and 'create_static_lib()', with the slight distinction that it actually matters on most platforms (as opposed to 'create_static_lib()', which includes a 'debug' flag mostly for form's sake). 'extra_preargs' and 'extra_postargs' are as for 'compile()' (except of course that they supply command-line arguments for the particular linker being used). 'target_lang' is the target language for which the given objects are being compiled. This allows specific linkage time treatment of certain languages. Raises LinkError on failure. """ raise NotImplementedError # Old 'link_*()' methods, rewritten to use the new 'link()' method. def link_shared_lib(self, objects, output_libname, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): self.link(CCompiler.SHARED_LIBRARY, objects, self.library_filename(output_libname, lib_type='shared'), output_dir, libraries, library_dirs, runtime_library_dirs, export_symbols, debug, extra_preargs, extra_postargs, build_temp, target_lang) def link_shared_object(self, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): self.link(CCompiler.SHARED_OBJECT, objects, output_filename, output_dir, libraries, library_dirs, runtime_library_dirs, export_symbols, debug, extra_preargs, extra_postargs, build_temp, target_lang) def link_executable(self, objects, output_progname, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, target_lang=None): self.link(CCompiler.EXECUTABLE, objects, self.executable_filename(output_progname), output_dir, libraries, library_dirs, runtime_library_dirs, None, debug, extra_preargs, extra_postargs, None, target_lang) # -- Miscellaneous methods ----------------------------------------- # These are all used by the 'gen_lib_options() function; there is # no appropriate default implementation so subclasses should # implement all of these. def library_dir_option(self, dir): """Return the compiler option to add 'dir' to the list of directories searched for libraries. """ raise NotImplementedError def runtime_library_dir_option(self, dir): """Return the compiler option to add 'dir' to the list of directories searched for runtime libraries. """ raise NotImplementedError def library_option(self, lib): """Return the compiler option to add 'lib' to the list of libraries linked into the shared library or executable. """ raise NotImplementedError def has_function(self, funcname, includes=None, include_dirs=None, libraries=None, library_dirs=None): """Return a boolean indicating whether funcname is supported on the current platform. The optional arguments can be used to augment the compilation environment. """ # this can't be included at module scope because it tries to # import math which might not be available at that point - maybe # the necessary logic should just be inlined? import tempfile if includes is None: includes = [] if include_dirs is None: include_dirs = [] if libraries is None: libraries = [] if library_dirs is None: library_dirs = [] fd, fname = tempfile.mkstemp(".c", funcname, text=True) f = os.fdopen(fd, "w") try: for incl in includes: f.write("""#include "%s"\n""" % incl) f.write("""\ int main (int argc, char **argv) { %s(); return 0; } """ % funcname) finally: f.close() try: objects = self.compile([fname], include_dirs=include_dirs) except CompileError: return False finally: os.remove(fname) try: self.link_executable(objects, "a.out", libraries=libraries, library_dirs=library_dirs) except (LinkError, TypeError): return False else: os.remove("a.out") finally: for fn in objects: os.remove(fn) return True def find_library_file (self, dirs, lib, debug=0): """Search the specified list of directories for a static or shared library file 'lib' and return the full path to that file. If 'debug' true, look for a debugging version (if that makes sense on the current platform). Return None if 'lib' wasn't found in any of the specified directories. """ raise NotImplementedError # -- Filename generation methods ----------------------------------- # The default implementation of the filename generating methods are # prejudiced towards the Unix/DOS/Windows view of the world: # * object files are named by replacing the source file extension # (eg. .c/.cpp -> .o/.obj) # * library files (shared or static) are named by plugging the # library name and extension into a format string, eg. # "lib%s.%s" % (lib_name, ".a") for Unix static libraries # * executables are named by appending an extension (possibly # empty) to the program name: eg. progname + ".exe" for # Windows # # To reduce redundant code, these methods expect to find # several attributes in the current object (presumably defined # as class attributes): # * src_extensions - # list of C/C++ source file extensions, eg. ['.c', '.cpp'] # * obj_extension - # object file extension, eg. '.o' or '.obj' # * static_lib_extension - # extension for static library files, eg. '.a' or '.lib' # * shared_lib_extension - # extension for shared library/object files, eg. '.so', '.dll' # * static_lib_format - # format string for generating static library filenames, # eg. 'lib%s.%s' or '%s.%s' # * shared_lib_format # format string for generating shared library filenames # (probably same as static_lib_format, since the extension # is one of the intended parameters to the format string) # * exe_extension - # extension for executable files, eg. '' or '.exe' def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): if output_dir is None: output_dir = '' obj_names = [] for src_name in source_filenames: base, ext = os.path.splitext(src_name) base = os.path.splitdrive(base)[1] # Chop off the drive base = base[os.path.isabs(base):] # If abs, chop off leading / if ext not in self.src_extensions: raise UnknownFileError( "unknown file type '%s' (from '%s')" % (ext, src_name)) if strip_dir: base = os.path.basename(base) obj_names.append(os.path.join(output_dir, base + self.obj_extension)) return obj_names def shared_object_filename(self, basename, strip_dir=0, output_dir=''): assert output_dir is not None if strip_dir: basename = os.path.basename(basename) return os.path.join(output_dir, basename + self.shared_lib_extension) def executable_filename(self, basename, strip_dir=0, output_dir=''): assert output_dir is not None if strip_dir: basename = os.path.basename(basename) return os.path.join(output_dir, basename + (self.exe_extension or '')) def library_filename(self, libname, lib_type='static', # or 'shared' strip_dir=0, output_dir=''): assert output_dir is not None if lib_type not in ("static", "shared", "dylib", "xcode_stub"): raise ValueError( "'lib_type' must be \"static\", \"shared\", \"dylib\", or \"xcode_stub\"") fmt = getattr(self, lib_type + "_lib_format") ext = getattr(self, lib_type + "_lib_extension") dir, base = os.path.split(libname) filename = fmt % (base, ext) if strip_dir: dir = '' return os.path.join(output_dir, dir, filename) # -- Utility methods ----------------------------------------------- def announce(self, msg, level=1): log.debug(msg) def debug_print(self, msg): from distutils.debug import DEBUG if DEBUG: print(msg) def warn(self, msg): sys.stderr.write("warning: %s\n" % msg) def execute(self, func, args, msg=None, level=1): execute(func, args, msg, self.dry_run) def spawn(self, cmd, **kwargs): spawn(cmd, dry_run=self.dry_run, **kwargs) def move_file(self, src, dst): return move_file(src, dst, dry_run=self.dry_run) def mkpath (self, name, mode=0o777): mkpath(name, mode, dry_run=self.dry_run) # Map a sys.platform/os.name ('posix', 'nt') to the default compiler # type for that platform. Keys are interpreted as re match # patterns. Order is important; platform mappings are preferred over # OS names. _default_compilers = ( # Platform string mappings # on a cygwin built python we can use gcc like an ordinary UNIXish # compiler ('cygwin.*', 'unix'), # OS name mappings ('posix', 'unix'), ('nt', 'msvc'), ) def get_default_compiler(osname=None, platform=None): """Determine the default compiler to use for the given platform. osname should be one of the standard Python OS names (i.e. the ones returned by os.name) and platform the common value returned by sys.platform for the platform in question. The default values are os.name and sys.platform in case the parameters are not given. """ if osname is None: osname = os.name if platform is None: platform = sys.platform for pattern, compiler in _default_compilers: if re.match(pattern, platform) is not None or \ re.match(pattern, osname) is not None: return compiler # Default to Unix compiler return 'unix' # Map compiler types to (module_name, class_name) pairs -- ie. where to # find the code that implements an interface to this compiler. (The module # is assumed to be in the 'distutils' package.) compiler_class = { 'unix': ('unixccompiler', 'UnixCCompiler', "standard UNIX-style compiler"), 'msvc': ('_msvccompiler', 'MSVCCompiler', "Microsoft Visual C++"), 'cygwin': ('cygwinccompiler', 'CygwinCCompiler', "Cygwin port of GNU C Compiler for Win32"), 'mingw32': ('cygwinccompiler', 'Mingw32CCompiler', "Mingw32 port of GNU C Compiler for Win32"), 'bcpp': ('bcppcompiler', 'BCPPCompiler', "Borland C++ Compiler"), } def show_compilers(): """Print list of available compilers (used by the "--help-compiler" options to "build", "build_ext", "build_clib"). """ # XXX this "knows" that the compiler option it's describing is # "--compiler", which just happens to be the case for the three # commands that use it. from distutils.fancy_getopt import FancyGetopt compilers = [] for compiler in compiler_class.keys(): compilers.append(("compiler="+compiler, None, compiler_class[compiler][2])) compilers.sort() pretty_printer = FancyGetopt(compilers) pretty_printer.print_help("List of available compilers:") def new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0): """Generate an instance of some CCompiler subclass for the supplied platform/compiler combination. 'plat' defaults to 'os.name' (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler for that platform. Currently only 'posix' and 'nt' are supported, and the default compilers are "traditional Unix interface" (UnixCCompiler class) and Visual C++ (MSVCCompiler class). Note that it's perfectly possible to ask for a Unix compiler object under Windows, and a Microsoft compiler object under Unix -- if you supply a value for 'compiler', 'plat' is ignored. """ if plat is None: plat = os.name try: if compiler is None: compiler = get_default_compiler(plat) (module_name, class_name, long_description) = compiler_class[compiler] except KeyError: msg = "don't know how to compile C/C++ code on platform '%s'" % plat if compiler is not None: msg = msg + " with '%s' compiler" % compiler raise DistutilsPlatformError(msg) try: module_name = "distutils." + module_name __import__ (module_name) module = sys.modules[module_name] klass = vars(module)[class_name] except ImportError: raise DistutilsModuleError( "can't compile C/C++ code: unable to load module '%s'" % \ module_name) except KeyError: raise DistutilsModuleError( "can't compile C/C++ code: unable to find class '%s' " "in module '%s'" % (class_name, module_name)) # XXX The None is necessary to preserve backwards compatibility # with classes that expect verbose to be the first positional # argument. return klass(None, dry_run, force) def gen_preprocess_options(macros, include_dirs): """Generate C pre-processor options (-D, -U, -I) as used by at least two types of compilers: the typical Unix compiler and Visual C++. 'macros' is the usual thing, a list of 1- or 2-tuples, where (name,) means undefine (-U) macro 'name', and (name,value) means define (-D) macro 'name' to 'value'. 'include_dirs' is just a list of directory names to be added to the header file search path (-I). Returns a list of command-line options suitable for either Unix compilers or Visual C++. """ # XXX it would be nice (mainly aesthetic, and so we don't generate # stupid-looking command lines) to go over 'macros' and eliminate # redundant definitions/undefinitions (ie. ensure that only the # latest mention of a particular macro winds up on the command # line). I don't think it's essential, though, since most (all?) # Unix C compilers only pay attention to the latest -D or -U # mention of a macro on their command line. Similar situation for # 'include_dirs'. I'm punting on both for now. Anyways, weeding out # redundancies like this should probably be the province of # CCompiler, since the data structures used are inherited from it # and therefore common to all CCompiler classes. pp_opts = [] for macro in macros: if not (isinstance(macro, tuple) and 1 <= len(macro) <= 2): raise TypeError( "bad macro definition '%s': " "each element of 'macros' list must be a 1- or 2-tuple" % macro) if len(macro) == 1: # undefine this macro pp_opts.append("-U%s" % macro[0]) elif len(macro) == 2: if macro[1] is None: # define with no explicit value pp_opts.append("-D%s" % macro[0]) else: # XXX *don't* need to be clever about quoting the # macro value here, because we're going to avoid the # shell at all costs when we spawn the command! pp_opts.append("-D%s=%s" % macro) for dir in include_dirs: pp_opts.append("-I%s" % dir) return pp_opts def gen_lib_options (compiler, library_dirs, runtime_library_dirs, libraries): """Generate linker options for searching library directories and linking with specific libraries. 'libraries' and 'library_dirs' are, respectively, lists of library names (not filenames!) and search directories. Returns a list of command-line options suitable for use with some compiler (depending on the two format strings passed in). """ lib_opts = [] for dir in library_dirs: lib_opts.append(compiler.library_dir_option(dir)) for dir in runtime_library_dirs: opt = compiler.runtime_library_dir_option(dir) if isinstance(opt, list): lib_opts = lib_opts + opt else: lib_opts.append(opt) # XXX it's important that we *not* remove redundant library mentions! # sometimes you really do have to say "-lfoo -lbar -lfoo" in order to # resolve all symbols. I just hope we never have to say "-lfoo obj.o # -lbar" to get things to work -- that's certainly a possibility, but a # pretty nasty way to arrange your C code. for lib in libraries: (lib_dir, lib_name) = os.path.split(lib) if lib_dir: lib_file = compiler.find_library_file([lib_dir], lib_name) if lib_file: lib_opts.append(lib_file) else: compiler.warn("no library file corresponding to " "'%s' found (skipping)" % lib) else: lib_opts.append(compiler.library_option (lib)) return lib_opts PKH]3bb:python3.10/site-packages/setuptools/_distutils/dir_util.pynu["""distutils.dir_util Utility functions for manipulating directories and directory trees.""" import os import errno from distutils.errors import DistutilsFileError, DistutilsInternalError from distutils import log # cache for by mkpath() -- in addition to cheapening redundant calls, # eliminates redundant "creating /foo/bar/baz" messages in dry-run mode _path_created = {} # I don't use os.makedirs because a) it's new to Python 1.5.2, and # b) it blows up if the directory already exists (I want to silently # succeed in that case). def mkpath(name, mode=0o777, verbose=1, dry_run=0): """Create a directory and any missing ancestor directories. If the directory already exists (or if 'name' is the empty string, which means the current directory, which of course exists), then do nothing. Raise DistutilsFileError if unable to create some directory along the way (eg. some sub-path exists, but is a file rather than a directory). If 'verbose' is true, print a one-line summary of each mkdir to stdout. Return the list of directories actually created. """ global _path_created # Detect a common bug -- name is None if not isinstance(name, str): raise DistutilsInternalError( "mkpath: 'name' must be a string (got %r)" % (name,)) # XXX what's the better way to handle verbosity? print as we create # each directory in the path (the current behaviour), or only announce # the creation of the whole path? (quite easy to do the latter since # we're not using a recursive algorithm) name = os.path.normpath(name) created_dirs = [] if os.path.isdir(name) or name == '': return created_dirs if _path_created.get(os.path.abspath(name)): return created_dirs (head, tail) = os.path.split(name) tails = [tail] # stack of lone dirs to create while head and tail and not os.path.isdir(head): (head, tail) = os.path.split(head) tails.insert(0, tail) # push next higher dir onto stack # now 'head' contains the deepest directory that already exists # (that is, the child of 'head' in 'name' is the highest directory # that does *not* exist) for d in tails: #print "head = %s, d = %s: " % (head, d), head = os.path.join(head, d) abs_head = os.path.abspath(head) if _path_created.get(abs_head): continue if verbose >= 1: log.info("creating %s", head) if not dry_run: try: os.mkdir(head, mode) except OSError as exc: if not (exc.errno == errno.EEXIST and os.path.isdir(head)): raise DistutilsFileError( "could not create '%s': %s" % (head, exc.args[-1])) created_dirs.append(head) _path_created[abs_head] = 1 return created_dirs def create_tree(base_dir, files, mode=0o777, verbose=1, dry_run=0): """Create all the empty directories under 'base_dir' needed to put 'files' there. 'base_dir' is just the name of a directory which doesn't necessarily exist yet; 'files' is a list of filenames to be interpreted relative to 'base_dir'. 'base_dir' + the directory portion of every file in 'files' will be created if it doesn't already exist. 'mode', 'verbose' and 'dry_run' flags are as for 'mkpath()'. """ # First get the list of directories to create need_dir = set() for file in files: need_dir.add(os.path.join(base_dir, os.path.dirname(file))) # Now create them for dir in sorted(need_dir): mkpath(dir, mode, verbose=verbose, dry_run=dry_run) def copy_tree(src, dst, preserve_mode=1, preserve_times=1, preserve_symlinks=0, update=0, verbose=1, dry_run=0): """Copy an entire directory tree 'src' to a new location 'dst'. Both 'src' and 'dst' must be directory names. If 'src' is not a directory, raise DistutilsFileError. If 'dst' does not exist, it is created with 'mkpath()'. The end result of the copy is that every file in 'src' is copied to 'dst', and directories under 'src' are recursively copied to 'dst'. Return the list of files that were copied or might have been copied, using their output name. The return value is unaffected by 'update' or 'dry_run': it is simply the list of all files under 'src', with the names changed to be under 'dst'. 'preserve_mode' and 'preserve_times' are the same as for 'copy_file'; note that they only apply to regular files, not to directories. If 'preserve_symlinks' is true, symlinks will be copied as symlinks (on platforms that support them!); otherwise (the default), the destination of the symlink will be copied. 'update' and 'verbose' are the same as for 'copy_file'. """ from distutils.file_util import copy_file if not dry_run and not os.path.isdir(src): raise DistutilsFileError( "cannot copy tree '%s': not a directory" % src) try: names = os.listdir(src) except OSError as e: if dry_run: names = [] else: raise DistutilsFileError( "error listing files in '%s': %s" % (src, e.strerror)) if not dry_run: mkpath(dst, verbose=verbose) outputs = [] for n in names: src_name = os.path.join(src, n) dst_name = os.path.join(dst, n) if n.startswith('.nfs'): # skip NFS rename files continue if preserve_symlinks and os.path.islink(src_name): link_dest = os.readlink(src_name) if verbose >= 1: log.info("linking %s -> %s", dst_name, link_dest) if not dry_run: os.symlink(link_dest, dst_name) outputs.append(dst_name) elif os.path.isdir(src_name): outputs.extend( copy_tree(src_name, dst_name, preserve_mode, preserve_times, preserve_symlinks, update, verbose=verbose, dry_run=dry_run)) else: copy_file(src_name, dst_name, preserve_mode, preserve_times, update, verbose=verbose, dry_run=dry_run) outputs.append(dst_name) return outputs def _build_cmdtuple(path, cmdtuples): """Helper for remove_tree().""" for f in os.listdir(path): real_f = os.path.join(path,f) if os.path.isdir(real_f) and not os.path.islink(real_f): _build_cmdtuple(real_f, cmdtuples) else: cmdtuples.append((os.remove, real_f)) cmdtuples.append((os.rmdir, path)) def remove_tree(directory, verbose=1, dry_run=0): """Recursively remove an entire directory tree. Any errors are ignored (apart from being reported to stdout if 'verbose' is true). """ global _path_created if verbose >= 1: log.info("removing '%s' (and everything under it)", directory) if dry_run: return cmdtuples = [] _build_cmdtuple(directory, cmdtuples) for cmd in cmdtuples: try: cmd[0](cmd[1]) # remove dir from cache if it's already there abspath = os.path.abspath(cmd[1]) if abspath in _path_created: del _path_created[abspath] except OSError as exc: log.warn("error removing %s: %s", directory, exc) def ensure_relative(path): """Take the full path 'path', and make it a relative path. This is useful to make 'path' the second argument to os.path.join(). """ drive, path = os.path.splitdrive(path) if path[0:1] == os.sep: path = drive + path[1:] return path PKH]87009python3.10/site-packages/setuptools/_distutils/version.pynu[# # distutils/version.py # # Implements multiple version numbering conventions for the # Python Module Distribution Utilities. # # $Id$ # """Provides classes to represent module version numbers (one class for each style of version numbering). There are currently two such classes implemented: StrictVersion and LooseVersion. Every version number class implements the following interface: * the 'parse' method takes a string and parses it to some internal representation; if the string is an invalid version number, 'parse' raises a ValueError exception * the class constructor takes an optional string argument which, if supplied, is passed to 'parse' * __str__ reconstructs the string that was passed to 'parse' (or an equivalent string -- ie. one that will generate an equivalent version number instance) * __repr__ generates Python code to recreate the version number instance * _cmp compares the current instance with either another instance of the same class or a string (which will be parsed to an instance of the same class, thus must follow the same rules) """ import re class Version: """Abstract base class for version numbering classes. Just provides constructor (__init__) and reproducer (__repr__), because those seem to be the same for all version numbering classes; and route rich comparisons to _cmp. """ def __init__ (self, vstring=None): if vstring: self.parse(vstring) def __repr__ (self): return "%s ('%s')" % (self.__class__.__name__, str(self)) def __eq__(self, other): c = self._cmp(other) if c is NotImplemented: return c return c == 0 def __lt__(self, other): c = self._cmp(other) if c is NotImplemented: return c return c < 0 def __le__(self, other): c = self._cmp(other) if c is NotImplemented: return c return c <= 0 def __gt__(self, other): c = self._cmp(other) if c is NotImplemented: return c return c > 0 def __ge__(self, other): c = self._cmp(other) if c is NotImplemented: return c return c >= 0 # Interface for version-number classes -- must be implemented # by the following classes (the concrete ones -- Version should # be treated as an abstract class). # __init__ (string) - create and take same action as 'parse' # (string parameter is optional) # parse (string) - convert a string representation to whatever # internal representation is appropriate for # this style of version numbering # __str__ (self) - convert back to a string; should be very similar # (if not identical to) the string supplied to parse # __repr__ (self) - generate Python code to recreate # the instance # _cmp (self, other) - compare two version numbers ('other' may # be an unparsed version string, or another # instance of your version class) class StrictVersion (Version): """Version numbering for anal retentives and software idealists. Implements the standard interface for version number classes as described above. A version number consists of two or three dot-separated numeric components, with an optional "pre-release" tag on the end. The pre-release tag consists of the letter 'a' or 'b' followed by a number. If the numeric components of two version numbers are equal, then one with a pre-release tag will always be deemed earlier (lesser) than one without. The following are valid version numbers (shown in the order that would be obtained by sorting according to the supplied cmp function): 0.4 0.4.0 (these two are equivalent) 0.4.1 0.5a1 0.5b3 0.5 0.9.6 1.0 1.0.4a3 1.0.4b1 1.0.4 The following are examples of invalid version numbers: 1 2.7.2.2 1.3.a4 1.3pl1 1.3c4 The rationale for this version numbering system will be explained in the distutils documentation. """ version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$', re.VERBOSE | re.ASCII) def parse (self, vstring): match = self.version_re.match(vstring) if not match: raise ValueError("invalid version number '%s'" % vstring) (major, minor, patch, prerelease, prerelease_num) = \ match.group(1, 2, 4, 5, 6) if patch: self.version = tuple(map(int, [major, minor, patch])) else: self.version = tuple(map(int, [major, minor])) + (0,) if prerelease: self.prerelease = (prerelease[0], int(prerelease_num)) else: self.prerelease = None def __str__ (self): if self.version[2] == 0: vstring = '.'.join(map(str, self.version[0:2])) else: vstring = '.'.join(map(str, self.version)) if self.prerelease: vstring = vstring + self.prerelease[0] + str(self.prerelease[1]) return vstring def _cmp (self, other): if isinstance(other, str): other = StrictVersion(other) elif not isinstance(other, StrictVersion): return NotImplemented if self.version != other.version: # numeric versions don't match # prerelease stuff doesn't matter if self.version < other.version: return -1 else: return 1 # have to compare prerelease # case 1: neither has prerelease; they're equal # case 2: self has prerelease, other doesn't; other is greater # case 3: self doesn't have prerelease, other does: self is greater # case 4: both have prerelease: must compare them! if (not self.prerelease and not other.prerelease): return 0 elif (self.prerelease and not other.prerelease): return -1 elif (not self.prerelease and other.prerelease): return 1 elif (self.prerelease and other.prerelease): if self.prerelease == other.prerelease: return 0 elif self.prerelease < other.prerelease: return -1 else: return 1 else: assert False, "never get here" # end class StrictVersion # The rules according to Greg Stein: # 1) a version number has 1 or more numbers separated by a period or by # sequences of letters. If only periods, then these are compared # left-to-right to determine an ordering. # 2) sequences of letters are part of the tuple for comparison and are # compared lexicographically # 3) recognize the numeric components may have leading zeroes # # The LooseVersion class below implements these rules: a version number # string is split up into a tuple of integer and string components, and # comparison is a simple tuple comparison. This means that version # numbers behave in a predictable and obvious way, but a way that might # not necessarily be how people *want* version numbers to behave. There # wouldn't be a problem if people could stick to purely numeric version # numbers: just split on period and compare the numbers as tuples. # However, people insist on putting letters into their version numbers; # the most common purpose seems to be: # - indicating a "pre-release" version # ('alpha', 'beta', 'a', 'b', 'pre', 'p') # - indicating a post-release patch ('p', 'pl', 'patch') # but of course this can't cover all version number schemes, and there's # no way to know what a programmer means without asking him. # # The problem is what to do with letters (and other non-numeric # characters) in a version number. The current implementation does the # obvious and predictable thing: keep them as strings and compare # lexically within a tuple comparison. This has the desired effect if # an appended letter sequence implies something "post-release": # eg. "0.99" < "0.99pl14" < "1.0", and "5.001" < "5.001m" < "5.002". # # However, if letters in a version number imply a pre-release version, # the "obvious" thing isn't correct. Eg. you would expect that # "1.5.1" < "1.5.2a2" < "1.5.2", but under the tuple/lexical comparison # implemented here, this just isn't so. # # Two possible solutions come to mind. The first is to tie the # comparison algorithm to a particular set of semantic rules, as has # been done in the StrictVersion class above. This works great as long # as everyone can go along with bondage and discipline. Hopefully a # (large) subset of Python module programmers will agree that the # particular flavour of bondage and discipline provided by StrictVersion # provides enough benefit to be worth using, and will submit their # version numbering scheme to its domination. The free-thinking # anarchists in the lot will never give in, though, and something needs # to be done to accommodate them. # # Perhaps a "moderately strict" version class could be implemented that # lets almost anything slide (syntactically), and makes some heuristic # assumptions about non-digits in version number strings. This could # sink into special-case-hell, though; if I was as talented and # idiosyncratic as Larry Wall, I'd go ahead and implement a class that # somehow knows that "1.2.1" < "1.2.2a2" < "1.2.2" < "1.2.2pl3", and is # just as happy dealing with things like "2g6" and "1.13++". I don't # think I'm smart enough to do it right though. # # In any case, I've coded the test suite for this module (see # ../test/test_version.py) specifically to fail on things like comparing # "1.2a2" and "1.2". That's not because the *code* is doing anything # wrong, it's because the simple, obvious design doesn't match my # complicated, hairy expectations for real-world version numbers. It # would be a snap to fix the test suite to say, "Yep, LooseVersion does # the Right Thing" (ie. the code matches the conception). But I'd rather # have a conception that matches common notions about version numbers. class LooseVersion (Version): """Version numbering for anarchists and software realists. Implements the standard interface for version number classes as described above. A version number consists of a series of numbers, separated by either periods or strings of letters. When comparing version numbers, the numeric components will be compared numerically, and the alphabetic components lexically. The following are all valid version numbers, in no particular order: 1.5.1 1.5.2b2 161 3.10a 8.02 3.4j 1996.07.12 3.2.pl0 3.1.1.6 2g6 11g 0.960923 2.2beta29 1.13++ 5.5.kw 2.0b1pl0 In fact, there is no such thing as an invalid version number under this scheme; the rules for comparison are simple and predictable, but may not always give the results you want (for some definition of "want"). """ component_re = re.compile(r'(\d+ | [a-z]+ | \.)', re.VERBOSE) def __init__ (self, vstring=None): if vstring: self.parse(vstring) def parse (self, vstring): # I've given up on thinking I can reconstruct the version string # from the parsed tuple -- so I just store the string here for # use by __str__ self.vstring = vstring components = [x for x in self.component_re.split(vstring) if x and x != '.'] for i, obj in enumerate(components): try: components[i] = int(obj) except ValueError: pass self.version = components def __str__ (self): return self.vstring def __repr__ (self): return "LooseVersion ('%s')" % str(self) def _cmp (self, other): if isinstance(other, str): other = LooseVersion(other) elif not isinstance(other, LooseVersion): return NotImplemented if self.version == other.version: return 0 if self.version < other.version: return -1 if self.version > other.version: return 1 # end class LooseVersion PKH];python3.10/site-packages/setuptools/_distutils/file_util.pynu["""distutils.file_util Utility functions for operating on single files. """ import os from distutils.errors import DistutilsFileError from distutils import log # for generating verbose output in 'copy_file()' _copy_action = { None: 'copying', 'hard': 'hard linking', 'sym': 'symbolically linking' } def _copy_file_contents(src, dst, buffer_size=16*1024): """Copy the file 'src' to 'dst'; both must be filenames. Any error opening either file, reading from 'src', or writing to 'dst', raises DistutilsFileError. Data is read/written in chunks of 'buffer_size' bytes (default 16k). No attempt is made to handle anything apart from regular files. """ # Stolen from shutil module in the standard library, but with # custom error-handling added. fsrc = None fdst = None try: try: fsrc = open(src, 'rb') except OSError as e: raise DistutilsFileError("could not open '%s': %s" % (src, e.strerror)) if os.path.exists(dst): try: os.unlink(dst) except OSError as e: raise DistutilsFileError( "could not delete '%s': %s" % (dst, e.strerror)) try: fdst = open(dst, 'wb') except OSError as e: raise DistutilsFileError( "could not create '%s': %s" % (dst, e.strerror)) while True: try: buf = fsrc.read(buffer_size) except OSError as e: raise DistutilsFileError( "could not read from '%s': %s" % (src, e.strerror)) if not buf: break try: fdst.write(buf) except OSError as e: raise DistutilsFileError( "could not write to '%s': %s" % (dst, e.strerror)) finally: if fdst: fdst.close() if fsrc: fsrc.close() def copy_file(src, dst, preserve_mode=1, preserve_times=1, update=0, link=None, verbose=1, dry_run=0): """Copy a file 'src' to 'dst'. If 'dst' is a directory, then 'src' is copied there with the same name; otherwise, it must be a filename. (If the file exists, it will be ruthlessly clobbered.) If 'preserve_mode' is true (the default), the file's mode (type and permission bits, or whatever is analogous on the current platform) is copied. If 'preserve_times' is true (the default), the last-modified and last-access times are copied as well. If 'update' is true, 'src' will only be copied if 'dst' does not exist, or if 'dst' does exist but is older than 'src'. 'link' allows you to make hard links (os.link) or symbolic links (os.symlink) instead of copying: set it to "hard" or "sym"; if it is None (the default), files are copied. Don't set 'link' on systems that don't support it: 'copy_file()' doesn't check if hard or symbolic linking is available. If hardlink fails, falls back to _copy_file_contents(). Under Mac OS, uses the native file copy function in macostools; on other systems, uses '_copy_file_contents()' to copy file contents. Return a tuple (dest_name, copied): 'dest_name' is the actual name of the output file, and 'copied' is true if the file was copied (or would have been copied, if 'dry_run' true). """ # XXX if the destination file already exists, we clobber it if # copying, but blow up if linking. Hmmm. And I don't know what # macostools.copyfile() does. Should definitely be consistent, and # should probably blow up if destination exists and we would be # changing it (ie. it's not already a hard/soft link to src OR # (not update) and (src newer than dst). from distutils.dep_util import newer from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE if not os.path.isfile(src): raise DistutilsFileError( "can't copy '%s': doesn't exist or not a regular file" % src) if os.path.isdir(dst): dir = dst dst = os.path.join(dst, os.path.basename(src)) else: dir = os.path.dirname(dst) if update and not newer(src, dst): if verbose >= 1: log.debug("not copying %s (output up-to-date)", src) return (dst, 0) try: action = _copy_action[link] except KeyError: raise ValueError("invalid value '%s' for 'link' argument" % link) if verbose >= 1: if os.path.basename(dst) == os.path.basename(src): log.info("%s %s -> %s", action, src, dir) else: log.info("%s %s -> %s", action, src, dst) if dry_run: return (dst, 1) # If linking (hard or symbolic), use the appropriate system call # (Unix only, of course, but that's the caller's responsibility) elif link == 'hard': if not (os.path.exists(dst) and os.path.samefile(src, dst)): try: os.link(src, dst) return (dst, 1) except OSError: # If hard linking fails, fall back on copying file # (some special filesystems don't support hard linking # even under Unix, see issue #8876). pass elif link == 'sym': if not (os.path.exists(dst) and os.path.samefile(src, dst)): os.symlink(src, dst) return (dst, 1) # Otherwise (non-Mac, not linking), copy the file contents and # (optionally) copy the times and mode. _copy_file_contents(src, dst) if preserve_mode or preserve_times: st = os.stat(src) # According to David Ascher , utime() should be done # before chmod() (at least under NT). if preserve_times: os.utime(dst, (st[ST_ATIME], st[ST_MTIME])) if preserve_mode: os.chmod(dst, S_IMODE(st[ST_MODE])) return (dst, 1) # XXX I suspect this is Unix-specific -- need porting help! def move_file (src, dst, verbose=1, dry_run=0): """Move a file 'src' to 'dst'. If 'dst' is a directory, the file will be moved into it with the same name; otherwise, 'src' is just renamed to 'dst'. Return the new full name of the file. Handles cross-device moves on Unix using 'copy_file()'. What about other systems??? """ from os.path import exists, isfile, isdir, basename, dirname import errno if verbose >= 1: log.info("moving %s -> %s", src, dst) if dry_run: return dst if not isfile(src): raise DistutilsFileError("can't move '%s': not a regular file" % src) if isdir(dst): dst = os.path.join(dst, basename(src)) elif exists(dst): raise DistutilsFileError( "can't move '%s': destination '%s' already exists" % (src, dst)) if not isdir(dirname(dst)): raise DistutilsFileError( "can't move '%s': destination '%s' not a valid path" % (src, dst)) copy_it = False try: os.rename(src, dst) except OSError as e: (num, msg) = e.args if num == errno.EXDEV: copy_it = True else: raise DistutilsFileError( "couldn't move '%s' to '%s': %s" % (src, dst, msg)) if copy_it: copy_file(src, dst, verbose=verbose) try: os.unlink(src) except OSError as e: (num, msg) = e.args try: os.unlink(dst) except OSError: pass raise DistutilsFileError( "couldn't move '%s' to '%s' by copy/delete: " "delete '%s' failed: %s" % (src, dst, src, msg)) return dst def write_file (filename, contents): """Create a file with the specified name and write 'contents' (a sequence of strings without line terminators) to it. """ f = open(filename, "w") try: for line in contents: f.write(line + "\n") finally: f.close() PKH]v<python3.10/site-packages/setuptools/_distutils/py35compat.pynu[import sys import subprocess def __optim_args_from_interpreter_flags(): """Return a list of command-line arguments reproducing the current optimization settings in sys.flags.""" args = [] value = sys.flags.optimize if value > 0: args.append("-" + "O" * value) return args _optim_args_from_interpreter_flags = getattr( subprocess, "_optim_args_from_interpreter_flags", __optim_args_from_interpreter_flags, ) PKH]IS^""6python3.10/site-packages/setuptools/_distutils/core.pynu["""distutils.core The only module that needs to be imported to use the Distutils; provides the 'setup' function (which is to be called from the setup script). Also indirectly provides the Distribution and Command classes, although they are really defined in distutils.dist and distutils.cmd. """ import os import sys from distutils.debug import DEBUG from distutils.errors import * # Mainly import these so setup scripts can "from distutils.core import" them. from distutils.dist import Distribution from distutils.cmd import Command from distutils.config import PyPIRCCommand from distutils.extension import Extension # This is a barebones help message generated displayed when the user # runs the setup script with no arguments at all. More useful help # is generated with various --help options: global help, list commands, # and per-command help. USAGE = """\ usage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] or: %(script)s --help [cmd1 cmd2 ...] or: %(script)s --help-commands or: %(script)s cmd --help """ def gen_usage (script_name): script = os.path.basename(script_name) return USAGE % vars() # Some mild magic to control the behaviour of 'setup()' from 'run_setup()'. _setup_stop_after = None _setup_distribution = None # Legal keyword arguments for the setup() function setup_keywords = ('distclass', 'script_name', 'script_args', 'options', 'name', 'version', 'author', 'author_email', 'maintainer', 'maintainer_email', 'url', 'license', 'description', 'long_description', 'keywords', 'platforms', 'classifiers', 'download_url', 'requires', 'provides', 'obsoletes', ) # Legal keyword arguments for the Extension constructor extension_keywords = ('name', 'sources', 'include_dirs', 'define_macros', 'undef_macros', 'library_dirs', 'libraries', 'runtime_library_dirs', 'extra_objects', 'extra_compile_args', 'extra_link_args', 'swig_opts', 'export_symbols', 'depends', 'language') def setup (**attrs): """The gateway to the Distutils: do everything your setup script needs to do, in a highly flexible and user-driven way. Briefly: create a Distribution instance; find and parse config files; parse the command line; run each Distutils command found there, customized by the options supplied to 'setup()' (as keyword arguments), in config files, and on the command line. The Distribution instance might be an instance of a class supplied via the 'distclass' keyword argument to 'setup'; if no such class is supplied, then the Distribution class (in dist.py) is instantiated. All other arguments to 'setup' (except for 'cmdclass') are used to set attributes of the Distribution instance. The 'cmdclass' argument, if supplied, is a dictionary mapping command names to command classes. Each command encountered on the command line will be turned into a command class, which is in turn instantiated; any class found in 'cmdclass' is used in place of the default, which is (for command 'foo_bar') class 'foo_bar' in module 'distutils.command.foo_bar'. The command class must provide a 'user_options' attribute which is a list of option specifiers for 'distutils.fancy_getopt'. Any command-line options between the current and the next command are used to set attributes of the current command object. When the entire command-line has been successfully parsed, calls the 'run()' method on each command object in turn. This method will be driven entirely by the Distribution object (which each command object has a reference to, thanks to its constructor), and the command-specific options that became attributes of each command object. """ global _setup_stop_after, _setup_distribution # Determine the distribution class -- either caller-supplied or # our Distribution (see below). klass = attrs.get('distclass') if klass: del attrs['distclass'] else: klass = Distribution if 'script_name' not in attrs: attrs['script_name'] = os.path.basename(sys.argv[0]) if 'script_args' not in attrs: attrs['script_args'] = sys.argv[1:] # Create the Distribution instance, using the remaining arguments # (ie. everything except distclass) to initialize it try: _setup_distribution = dist = klass(attrs) except DistutilsSetupError as msg: if 'name' not in attrs: raise SystemExit("error in setup command: %s" % msg) else: raise SystemExit("error in %s setup command: %s" % \ (attrs['name'], msg)) if _setup_stop_after == "init": return dist # Find and parse the config file(s): they will override options from # the setup script, but be overridden by the command line. dist.parse_config_files() if DEBUG: print("options (after parsing config files):") dist.dump_option_dicts() if _setup_stop_after == "config": return dist # Parse the command line and override config files; any # command-line errors are the end user's fault, so turn them into # SystemExit to suppress tracebacks. try: ok = dist.parse_command_line() except DistutilsArgError as msg: raise SystemExit(gen_usage(dist.script_name) + "\nerror: %s" % msg) if DEBUG: print("options (after parsing command line):") dist.dump_option_dicts() if _setup_stop_after == "commandline": return dist # And finally, run all the commands found on the command line. if ok: try: dist.run_commands() except KeyboardInterrupt: raise SystemExit("interrupted") except OSError as exc: if DEBUG: sys.stderr.write("error: %s\n" % (exc,)) raise else: raise SystemExit("error: %s" % (exc,)) except (DistutilsError, CCompilerError) as msg: if DEBUG: raise else: raise SystemExit("error: " + str(msg)) return dist # setup () def run_setup (script_name, script_args=None, stop_after="run"): """Run a setup script in a somewhat controlled environment, and return the Distribution instance that drives things. This is useful if you need to find out the distribution meta-data (passed as keyword args from 'script' to 'setup()', or the contents of the config files or command-line. 'script_name' is a file that will be read and run with 'exec()'; 'sys.argv[0]' will be replaced with 'script' for the duration of the call. 'script_args' is a list of strings; if supplied, 'sys.argv[1:]' will be replaced by 'script_args' for the duration of the call. 'stop_after' tells 'setup()' when to stop processing; possible values: init stop after the Distribution instance has been created and populated with the keyword arguments to 'setup()' config stop after config files have been parsed (and their data stored in the Distribution instance) commandline stop after the command-line ('sys.argv[1:]' or 'script_args') have been parsed (and the data stored in the Distribution) run [default] stop after all commands have been run (the same as if 'setup()' had been called in the usual way Returns the Distribution instance, which provides all information used to drive the Distutils. """ if stop_after not in ('init', 'config', 'commandline', 'run'): raise ValueError("invalid value for 'stop_after': %r" % (stop_after,)) global _setup_stop_after, _setup_distribution _setup_stop_after = stop_after save_argv = sys.argv.copy() g = {'__file__': script_name} try: try: sys.argv[0] = script_name if script_args is not None: sys.argv[1:] = script_args with open(script_name, 'rb') as f: exec(f.read(), g) finally: sys.argv = save_argv _setup_stop_after = None except SystemExit: # Hmm, should we do something if exiting with a non-zero code # (ie. error)? pass if _setup_distribution is None: raise RuntimeError(("'distutils.core.setup()' was never called -- " "perhaps '%s' is not a Distutils setup script?") % \ script_name) # I wonder if the setup script's namespace -- g and l -- would be of # any interest to callers? #print "_setup_distribution:", _setup_distribution return _setup_distribution # run_setup () PKH]2  Bpython3.10/site-packages/setuptools/_distutils/versionpredicate.pynu["""Module for parsing and testing package version predicate strings. """ import re import distutils.version import operator re_validPackage = re.compile(r"(?i)^\s*([a-z_]\w*(?:\.[a-z_]\w*)*)(.*)", re.ASCII) # (package) (rest) re_paren = re.compile(r"^\s*\((.*)\)\s*$") # (list) inside of parentheses re_splitComparison = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$") # (comp) (version) def splitUp(pred): """Parse a single version comparison. Return (comparison string, StrictVersion) """ res = re_splitComparison.match(pred) if not res: raise ValueError("bad package restriction syntax: %r" % pred) comp, verStr = res.groups() return (comp, distutils.version.StrictVersion(verStr)) compmap = {"<": operator.lt, "<=": operator.le, "==": operator.eq, ">": operator.gt, ">=": operator.ge, "!=": operator.ne} class VersionPredicate: """Parse and test package version predicates. >>> v = VersionPredicate('pyepat.abc (>1.0, <3333.3a1, !=1555.1b3)') The `name` attribute provides the full dotted name that is given:: >>> v.name 'pyepat.abc' The str() of a `VersionPredicate` provides a normalized human-readable version of the expression:: >>> print(v) pyepat.abc (> 1.0, < 3333.3a1, != 1555.1b3) The `satisfied_by()` method can be used to determine with a given version number is included in the set described by the version restrictions:: >>> v.satisfied_by('1.1') True >>> v.satisfied_by('1.4') True >>> v.satisfied_by('1.0') False >>> v.satisfied_by('4444.4') False >>> v.satisfied_by('1555.1b3') False `VersionPredicate` is flexible in accepting extra whitespace:: >>> v = VersionPredicate(' pat( == 0.1 ) ') >>> v.name 'pat' >>> v.satisfied_by('0.1') True >>> v.satisfied_by('0.2') False If any version numbers passed in do not conform to the restrictions of `StrictVersion`, a `ValueError` is raised:: >>> v = VersionPredicate('p1.p2.p3.p4(>=1.0, <=1.3a1, !=1.2zb3)') Traceback (most recent call last): ... ValueError: invalid version number '1.2zb3' It the module or package name given does not conform to what's allowed as a legal module or package name, `ValueError` is raised:: >>> v = VersionPredicate('foo-bar') Traceback (most recent call last): ... ValueError: expected parenthesized list: '-bar' >>> v = VersionPredicate('foo bar (12.21)') Traceback (most recent call last): ... ValueError: expected parenthesized list: 'bar (12.21)' """ def __init__(self, versionPredicateStr): """Parse a version predicate string. """ # Fields: # name: package name # pred: list of (comparison string, StrictVersion) versionPredicateStr = versionPredicateStr.strip() if not versionPredicateStr: raise ValueError("empty package restriction") match = re_validPackage.match(versionPredicateStr) if not match: raise ValueError("bad package name in %r" % versionPredicateStr) self.name, paren = match.groups() paren = paren.strip() if paren: match = re_paren.match(paren) if not match: raise ValueError("expected parenthesized list: %r" % paren) str = match.groups()[0] self.pred = [splitUp(aPred) for aPred in str.split(",")] if not self.pred: raise ValueError("empty parenthesized list in %r" % versionPredicateStr) else: self.pred = [] def __str__(self): if self.pred: seq = [cond + " " + str(ver) for cond, ver in self.pred] return self.name + " (" + ", ".join(seq) + ")" else: return self.name def satisfied_by(self, version): """True if version is compatible with all the predicates in self. The parameter version must be acceptable to the StrictVersion constructor. It may be either a string or StrictVersion. """ for cond, ver in self.pred: if not compmap[cond](version, ver): return False return True _provision_rx = None def split_provision(value): """Return the name and optional version number of a provision. The version number, if given, will be returned as a `StrictVersion` instance, otherwise it will be `None`. >>> split_provision('mypkg') ('mypkg', None) >>> split_provision(' mypkg( 1.2 ) ') ('mypkg', StrictVersion ('1.2')) """ global _provision_rx if _provision_rx is None: _provision_rx = re.compile( r"([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)(?:\s*\(\s*([^)\s]+)\s*\))?$", re.ASCII) value = value.strip() m = _provision_rx.match(value) if not m: raise ValueError("illegal provides specification: %r" % value) ver = m.group(2) or None if ver: ver = distutils.version.StrictVersion(ver) return m.group(1), ver PKH]F9.:.:>python3.10/site-packages/setuptools/_distutils/bcppcompiler.pynu["""distutils.bcppcompiler Contains BorlandCCompiler, an implementation of the abstract CCompiler class for the Borland C++ compiler. """ # This implementation by Lyle Johnson, based on the original msvccompiler.py # module and using the directions originally published by Gordon Williams. # XXX looks like there's a LOT of overlap between these two classes: # someone should sit down and factor out the common code as # WindowsCCompiler! --GPW import os from distutils.errors import \ DistutilsExecError, \ CompileError, LibError, LinkError, UnknownFileError from distutils.ccompiler import \ CCompiler, gen_preprocess_options from distutils.file_util import write_file from distutils.dep_util import newer from distutils import log class BCPPCompiler(CCompiler) : """Concrete class that implements an interface to the Borland C/C++ compiler, as defined by the CCompiler abstract class. """ compiler_type = 'bcpp' # Just set this so CCompiler's constructor doesn't barf. We currently # don't use the 'set_executables()' bureaucracy provided by CCompiler, # as it really isn't necessary for this sort of single-compiler class. # Would be nice to have a consistent interface with UnixCCompiler, # though, so it's worth thinking about. executables = {} # Private class data (need to distinguish C from C++ source for compiler) _c_extensions = ['.c'] _cpp_extensions = ['.cc', '.cpp', '.cxx'] # Needed for the filename generation methods provided by the # base class, CCompiler. src_extensions = _c_extensions + _cpp_extensions obj_extension = '.obj' static_lib_extension = '.lib' shared_lib_extension = '.dll' static_lib_format = shared_lib_format = '%s%s' exe_extension = '.exe' def __init__ (self, verbose=0, dry_run=0, force=0): CCompiler.__init__ (self, verbose, dry_run, force) # These executables are assumed to all be in the path. # Borland doesn't seem to use any special registry settings to # indicate their installation locations. self.cc = "bcc32.exe" self.linker = "ilink32.exe" self.lib = "tlib.exe" self.preprocess_options = None self.compile_options = ['/tWM', '/O2', '/q', '/g0'] self.compile_options_debug = ['/tWM', '/Od', '/q', '/g0'] self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x'] self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x'] self.ldflags_static = [] self.ldflags_exe = ['/Gn', '/q', '/x'] self.ldflags_exe_debug = ['/Gn', '/q', '/x','/r'] # -- Worker methods ------------------------------------------------ def compile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): macros, objects, extra_postargs, pp_opts, build = \ self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs) compile_opts = extra_preargs or [] compile_opts.append ('-c') if debug: compile_opts.extend (self.compile_options_debug) else: compile_opts.extend (self.compile_options) for obj in objects: try: src, ext = build[obj] except KeyError: continue # XXX why do the normpath here? src = os.path.normpath(src) obj = os.path.normpath(obj) # XXX _setup_compile() did a mkpath() too but before the normpath. # Is it possible to skip the normpath? self.mkpath(os.path.dirname(obj)) if ext == '.res': # This is already a binary file -- skip it. continue # the 'for' loop if ext == '.rc': # This needs to be compiled to a .res file -- do it now. try: self.spawn (["brcc32", "-fo", obj, src]) except DistutilsExecError as msg: raise CompileError(msg) continue # the 'for' loop # The next two are both for the real compiler. if ext in self._c_extensions: input_opt = "" elif ext in self._cpp_extensions: input_opt = "-P" else: # Unknown file type -- no extra options. The compiler # will probably fail, but let it just in case this is a # file the compiler recognizes even if we don't. input_opt = "" output_opt = "-o" + obj # Compiler command line syntax is: "bcc32 [options] file(s)". # Note that the source file names must appear at the end of # the command line. try: self.spawn ([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + extra_postargs + [src]) except DistutilsExecError as msg: raise CompileError(msg) return objects # compile () def create_static_lib (self, objects, output_libname, output_dir=None, debug=0, target_lang=None): (objects, output_dir) = self._fix_object_args (objects, output_dir) output_filename = \ self.library_filename (output_libname, output_dir=output_dir) if self._need_link (objects, output_filename): lib_args = [output_filename, '/u'] + objects if debug: pass # XXX what goes here? try: self.spawn ([self.lib] + lib_args) except DistutilsExecError as msg: raise LibError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) # create_static_lib () def link (self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): # XXX this ignores 'build_temp'! should follow the lead of # msvccompiler.py (objects, output_dir) = self._fix_object_args (objects, output_dir) (libraries, library_dirs, runtime_library_dirs) = \ self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) if runtime_library_dirs: log.warn("I don't know what to do with 'runtime_library_dirs': %s", str(runtime_library_dirs)) if output_dir is not None: output_filename = os.path.join (output_dir, output_filename) if self._need_link (objects, output_filename): # Figure out linker args based on type of target. if target_desc == CCompiler.EXECUTABLE: startup_obj = 'c0w32' if debug: ld_args = self.ldflags_exe_debug[:] else: ld_args = self.ldflags_exe[:] else: startup_obj = 'c0d32' if debug: ld_args = self.ldflags_shared_debug[:] else: ld_args = self.ldflags_shared[:] # Create a temporary exports file for use by the linker if export_symbols is None: def_file = '' else: head, tail = os.path.split (output_filename) modname, ext = os.path.splitext (tail) temp_dir = os.path.dirname(objects[0]) # preserve tree structure def_file = os.path.join (temp_dir, '%s.def' % modname) contents = ['EXPORTS'] for sym in (export_symbols or []): contents.append(' %s=_%s' % (sym, sym)) self.execute(write_file, (def_file, contents), "writing %s" % def_file) # Borland C++ has problems with '/' in paths objects2 = map(os.path.normpath, objects) # split objects in .obj and .res files # Borland C++ needs them at different positions in the command line objects = [startup_obj] resources = [] for file in objects2: (base, ext) = os.path.splitext(os.path.normcase(file)) if ext == '.res': resources.append(file) else: objects.append(file) for l in library_dirs: ld_args.append("/L%s" % os.path.normpath(l)) ld_args.append("/L.") # we sometimes use relative paths # list of object files ld_args.extend(objects) # XXX the command-line syntax for Borland C++ is a bit wonky; # certain filenames are jammed together in one big string, but # comma-delimited. This doesn't mesh too well with the # Unix-centric attitude (with a DOS/Windows quoting hack) of # 'spawn()', so constructing the argument list is a bit # awkward. Note that doing the obvious thing and jamming all # the filenames and commas into one argument would be wrong, # because 'spawn()' would quote any filenames with spaces in # them. Arghghh!. Apparently it works fine as coded... # name of dll/exe file ld_args.extend([',',output_filename]) # no map file and start libraries ld_args.append(',,') for lib in libraries: # see if we find it and if there is a bcpp specific lib # (xxx_bcpp.lib) libfile = self.find_library_file(library_dirs, lib, debug) if libfile is None: ld_args.append(lib) # probably a BCPP internal library -- don't warn else: # full name which prefers bcpp_xxx.lib over xxx.lib ld_args.append(libfile) # some default libraries ld_args.append ('import32') ld_args.append ('cw32mt') # def file for export symbols ld_args.extend([',',def_file]) # add resource files ld_args.append(',') ld_args.extend(resources) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath (os.path.dirname (output_filename)) try: self.spawn ([self.linker] + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) # link () # -- Miscellaneous methods ----------------------------------------- def find_library_file (self, dirs, lib, debug=0): # List of effective library names to try, in order of preference: # xxx_bcpp.lib is better than xxx.lib # and xxx_d.lib is better than xxx.lib if debug is set # # The "_bcpp" suffix is to handle a Python installation for people # with multiple compilers (primarily Distutils hackers, I suspect # ;-). The idea is they'd have one static library for each # compiler they care about, since (almost?) every Windows compiler # seems to have a different format for static libraries. if debug: dlib = (lib + "_d") try_names = (dlib + "_bcpp", lib + "_bcpp", dlib, lib) else: try_names = (lib + "_bcpp", lib) for dir in dirs: for name in try_names: libfile = os.path.join(dir, self.library_filename(name)) if os.path.exists(libfile): return libfile else: # Oops, didn't find it in *any* of 'dirs' return None # overwrite the one from CCompiler to support rc and res-files def object_filenames (self, source_filenames, strip_dir=0, output_dir=''): if output_dir is None: output_dir = '' obj_names = [] for src_name in source_filenames: # use normcase to make sure '.rc' is really '.rc' and not '.RC' (base, ext) = os.path.splitext (os.path.normcase(src_name)) if ext not in (self.src_extensions + ['.rc','.res']): raise UnknownFileError("unknown file type '%s' (from '%s')" % \ (ext, src_name)) if strip_dir: base = os.path.basename (base) if ext == '.res': # these can go unchanged obj_names.append (os.path.join (output_dir, base + ext)) elif ext == '.rc': # these need to be compiled to .res-files obj_names.append (os.path.join (output_dir, base + '.res')) else: obj_names.append (os.path.join (output_dir, base + self.obj_extension)) return obj_names # object_filenames () def preprocess (self, source, output_file=None, macros=None, include_dirs=None, extra_preargs=None, extra_postargs=None): (_, macros, include_dirs) = \ self._fix_compile_args(None, macros, include_dirs) pp_opts = gen_preprocess_options(macros, include_dirs) pp_args = ['cpp32.exe'] + pp_opts if output_file is not None: pp_args.append('-o' + output_file) if extra_preargs: pp_args[:0] = extra_preargs if extra_postargs: pp_args.extend(extra_postargs) pp_args.append(source) # We need to preprocess: either we're being forced to, or the # source file is newer than the target (or the target doesn't # exist). if self.force or output_file is None or newer(source, output_file): if output_file: self.mkpath(os.path.dirname(output_file)) try: self.spawn(pp_args) except DistutilsExecError as msg: print(msg) raise CompileError(msg) # preprocess() PKH]k"# :python3.10/site-packages/setuptools/_distutils/dep_util.pynu["""distutils.dep_util Utility functions for simple, timestamp-based dependency of files and groups of files; also, function based entirely on such timestamp dependency analysis.""" import os from distutils.errors import DistutilsFileError def newer (source, target): """Return true if 'source' exists and is more recently modified than 'target', or if 'source' exists and 'target' doesn't. Return false if both exist and 'target' is the same age or younger than 'source'. Raise DistutilsFileError if 'source' does not exist. """ if not os.path.exists(source): raise DistutilsFileError("file '%s' does not exist" % os.path.abspath(source)) if not os.path.exists(target): return 1 from stat import ST_MTIME mtime1 = os.stat(source)[ST_MTIME] mtime2 = os.stat(target)[ST_MTIME] return mtime1 > mtime2 # newer () def newer_pairwise (sources, targets): """Walk two filename lists in parallel, testing if each source is newer than its corresponding target. Return a pair of lists (sources, targets) where source is newer than target, according to the semantics of 'newer()'. """ if len(sources) != len(targets): raise ValueError("'sources' and 'targets' must be same length") # build a pair of lists (sources, targets) where source is newer n_sources = [] n_targets = [] for i in range(len(sources)): if newer(sources[i], targets[i]): n_sources.append(sources[i]) n_targets.append(targets[i]) return (n_sources, n_targets) # newer_pairwise () def newer_group (sources, target, missing='error'): """Return true if 'target' is out-of-date with respect to any file listed in 'sources'. In other words, if 'target' exists and is newer than every file in 'sources', return false; otherwise return true. 'missing' controls what we do when a source file is missing; the default ("error") is to blow up with an OSError from inside 'stat()'; if it is "ignore", we silently drop any missing source files; if it is "newer", any missing source files make us assume that 'target' is out-of-date (this is handy in "dry-run" mode: it'll make you pretend to carry out commands that wouldn't work because inputs are missing, but that doesn't matter because you're not actually going to run the commands). """ # If the target doesn't even exist, then it's definitely out-of-date. if not os.path.exists(target): return 1 # Otherwise we have to find out the hard way: if *any* source file # is more recent than 'target', then 'target' is out-of-date and # we can immediately return true. If we fall through to the end # of the loop, then 'target' is up-to-date and we return false. from stat import ST_MTIME target_mtime = os.stat(target)[ST_MTIME] for source in sources: if not os.path.exists(source): if missing == 'error': # blow up when we stat() the file pass elif missing == 'ignore': # missing source dropped from continue # target's dependency list elif missing == 'newer': # missing source means target is return 1 # out-of-date source_mtime = os.stat(source)[ST_MTIME] if source_mtime > target_mtime: return 1 else: return 0 # newer_group () PKH]۟FF5python3.10/site-packages/setuptools/_distutils/cmd.pynu["""distutils.cmd Provides the Command class, the base class for the command classes in the distutils.command package. """ import sys, os, re from distutils.errors import DistutilsOptionError from distutils import util, dir_util, file_util, archive_util, dep_util from distutils import log class Command: """Abstract base class for defining command classes, the "worker bees" of the Distutils. A useful analogy for command classes is to think of them as subroutines with local variables called "options". The options are "declared" in 'initialize_options()' and "defined" (given their final values, aka "finalized") in 'finalize_options()', both of which must be defined by every command class. The distinction between the two is necessary because option values might come from the outside world (command line, config file, ...), and any options dependent on other options must be computed *after* these outside influences have been processed -- hence 'finalize_options()'. The "body" of the subroutine, where it does all its work based on the values of its options, is the 'run()' method, which must also be implemented by every command class. """ # 'sub_commands' formalizes the notion of a "family" of commands, # eg. "install" as the parent with sub-commands "install_lib", # "install_headers", etc. The parent of a family of commands # defines 'sub_commands' as a class attribute; it's a list of # (command_name : string, predicate : unbound_method | string | None) # tuples, where 'predicate' is a method of the parent command that # determines whether the corresponding command is applicable in the # current situation. (Eg. we "install_headers" is only applicable if # we have any C header files to install.) If 'predicate' is None, # that command is always applicable. # # 'sub_commands' is usually defined at the *end* of a class, because # predicates can be unbound methods, so they must already have been # defined. The canonical example is the "install" command. sub_commands = [] # -- Creation/initialization methods ------------------------------- def __init__(self, dist): """Create and initialize a new Command object. Most importantly, invokes the 'initialize_options()' method, which is the real initializer and depends on the actual command being instantiated. """ # late import because of mutual dependence between these classes from distutils.dist import Distribution if not isinstance(dist, Distribution): raise TypeError("dist must be a Distribution instance") if self.__class__ is Command: raise RuntimeError("Command is an abstract class") self.distribution = dist self.initialize_options() # Per-command versions of the global flags, so that the user can # customize Distutils' behaviour command-by-command and let some # commands fall back on the Distribution's behaviour. None means # "not defined, check self.distribution's copy", while 0 or 1 mean # false and true (duh). Note that this means figuring out the real # value of each flag is a touch complicated -- hence "self._dry_run" # will be handled by __getattr__, below. # XXX This needs to be fixed. self._dry_run = None # verbose is largely ignored, but needs to be set for # backwards compatibility (I think)? self.verbose = dist.verbose # Some commands define a 'self.force' option to ignore file # timestamps, but methods defined *here* assume that # 'self.force' exists for all commands. So define it here # just to be safe. self.force = None # The 'help' flag is just used for command-line parsing, so # none of that complicated bureaucracy is needed. self.help = 0 # 'finalized' records whether or not 'finalize_options()' has been # called. 'finalize_options()' itself should not pay attention to # this flag: it is the business of 'ensure_finalized()', which # always calls 'finalize_options()', to respect/update it. self.finalized = 0 # XXX A more explicit way to customize dry_run would be better. def __getattr__(self, attr): if attr == 'dry_run': myval = getattr(self, "_" + attr) if myval is None: return getattr(self.distribution, attr) else: return myval else: raise AttributeError(attr) def ensure_finalized(self): if not self.finalized: self.finalize_options() self.finalized = 1 # Subclasses must define: # initialize_options() # provide default values for all options; may be customized by # setup script, by options from config file(s), or by command-line # options # finalize_options() # decide on the final values for all options; this is called # after all possible intervention from the outside world # (command-line, option file, etc.) has been processed # run() # run the command: do whatever it is we're here to do, # controlled by the command's various option values def initialize_options(self): """Set default values for all the options that this command supports. Note that these defaults may be overridden by other commands, by the setup script, by config files, or by the command-line. Thus, this is not the place to code dependencies between options; generally, 'initialize_options()' implementations are just a bunch of "self.foo = None" assignments. This method must be implemented by all command classes. """ raise RuntimeError("abstract method -- subclass %s must override" % self.__class__) def finalize_options(self): """Set final values for all the options that this command supports. This is always called as late as possible, ie. after any option assignments from the command-line or from other commands have been done. Thus, this is the place to code option dependencies: if 'foo' depends on 'bar', then it is safe to set 'foo' from 'bar' as long as 'foo' still has the same value it was assigned in 'initialize_options()'. This method must be implemented by all command classes. """ raise RuntimeError("abstract method -- subclass %s must override" % self.__class__) def dump_options(self, header=None, indent=""): from distutils.fancy_getopt import longopt_xlate if header is None: header = "command options for '%s':" % self.get_command_name() self.announce(indent + header, level=log.INFO) indent = indent + " " for (option, _, _) in self.user_options: option = option.translate(longopt_xlate) if option[-1] == "=": option = option[:-1] value = getattr(self, option) self.announce(indent + "%s = %s" % (option, value), level=log.INFO) def run(self): """A command's raison d'etre: carry out the action it exists to perform, controlled by the options initialized in 'initialize_options()', customized by other commands, the setup script, the command-line, and config files, and finalized in 'finalize_options()'. All terminal output and filesystem interaction should be done by 'run()'. This method must be implemented by all command classes. """ raise RuntimeError("abstract method -- subclass %s must override" % self.__class__) def announce(self, msg, level=1): """If the current verbosity level is of greater than or equal to 'level' print 'msg' to stdout. """ log.log(level, msg) def debug_print(self, msg): """Print 'msg' to stdout if the global DEBUG (taken from the DISTUTILS_DEBUG environment variable) flag is true. """ from distutils.debug import DEBUG if DEBUG: print(msg) sys.stdout.flush() # -- Option validation methods ------------------------------------- # (these are very handy in writing the 'finalize_options()' method) # # NB. the general philosophy here is to ensure that a particular option # value meets certain type and value constraints. If not, we try to # force it into conformance (eg. if we expect a list but have a string, # split the string on comma and/or whitespace). If we can't force the # option into conformance, raise DistutilsOptionError. Thus, command # classes need do nothing more than (eg.) # self.ensure_string_list('foo') # and they can be guaranteed that thereafter, self.foo will be # a list of strings. def _ensure_stringlike(self, option, what, default=None): val = getattr(self, option) if val is None: setattr(self, option, default) return default elif not isinstance(val, str): raise DistutilsOptionError("'%s' must be a %s (got `%s`)" % (option, what, val)) return val def ensure_string(self, option, default=None): """Ensure that 'option' is a string; if not defined, set it to 'default'. """ self._ensure_stringlike(option, "string", default) def ensure_string_list(self, option): r"""Ensure that 'option' is a list of strings. If 'option' is currently a string, we split it either on /,\s*/ or /\s+/, so "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become ["foo", "bar", "baz"]. """ val = getattr(self, option) if val is None: return elif isinstance(val, str): setattr(self, option, re.split(r',\s*|\s+', val)) else: if isinstance(val, list): ok = all(isinstance(v, str) for v in val) else: ok = False if not ok: raise DistutilsOptionError( "'%s' must be a list of strings (got %r)" % (option, val)) def _ensure_tested_string(self, option, tester, what, error_fmt, default=None): val = self._ensure_stringlike(option, what, default) if val is not None and not tester(val): raise DistutilsOptionError(("error in '%s' option: " + error_fmt) % (option, val)) def ensure_filename(self, option): """Ensure that 'option' is the name of an existing file.""" self._ensure_tested_string(option, os.path.isfile, "filename", "'%s' does not exist or is not a file") def ensure_dirname(self, option): self._ensure_tested_string(option, os.path.isdir, "directory name", "'%s' does not exist or is not a directory") # -- Convenience methods for commands ------------------------------ def get_command_name(self): if hasattr(self, 'command_name'): return self.command_name else: return self.__class__.__name__ def set_undefined_options(self, src_cmd, *option_pairs): """Set the values of any "undefined" options from corresponding option values in some other command object. "Undefined" here means "is None", which is the convention used to indicate that an option has not been changed between 'initialize_options()' and 'finalize_options()'. Usually called from 'finalize_options()' for options that depend on some other command rather than another option of the same command. 'src_cmd' is the other command from which option values will be taken (a command object will be created for it if necessary); the remaining arguments are '(src_option,dst_option)' tuples which mean "take the value of 'src_option' in the 'src_cmd' command object, and copy it to 'dst_option' in the current command object". """ # Option_pairs: list of (src_option, dst_option) tuples src_cmd_obj = self.distribution.get_command_obj(src_cmd) src_cmd_obj.ensure_finalized() for (src_option, dst_option) in option_pairs: if getattr(self, dst_option) is None: setattr(self, dst_option, getattr(src_cmd_obj, src_option)) def get_finalized_command(self, command, create=1): """Wrapper around Distribution's 'get_command_obj()' method: find (create if necessary and 'create' is true) the command object for 'command', call its 'ensure_finalized()' method, and return the finalized command object. """ cmd_obj = self.distribution.get_command_obj(command, create) cmd_obj.ensure_finalized() return cmd_obj # XXX rename to 'get_reinitialized_command()'? (should do the # same in dist.py, if so) def reinitialize_command(self, command, reinit_subcommands=0): return self.distribution.reinitialize_command(command, reinit_subcommands) def run_command(self, command): """Run some other command: uses the 'run_command()' method of Distribution, which creates and finalizes the command object if necessary and then invokes its 'run()' method. """ self.distribution.run_command(command) def get_sub_commands(self): """Determine the sub-commands that are relevant in the current distribution (ie., that need to be run). This is based on the 'sub_commands' class attribute: each tuple in that list may include a method that we call to determine if the subcommand needs to be run for the current distribution. Return a list of command names. """ commands = [] for (cmd_name, method) in self.sub_commands: if method is None or method(self): commands.append(cmd_name) return commands # -- External world manipulation ----------------------------------- def warn(self, msg): log.warn("warning: %s: %s\n", self.get_command_name(), msg) def execute(self, func, args, msg=None, level=1): util.execute(func, args, msg, dry_run=self.dry_run) def mkpath(self, name, mode=0o777): dir_util.mkpath(name, mode, dry_run=self.dry_run) def copy_file(self, infile, outfile, preserve_mode=1, preserve_times=1, link=None, level=1): """Copy a file respecting verbose, dry-run and force flags. (The former two default to whatever is in the Distribution object, and the latter defaults to false for commands that don't define it.)""" return file_util.copy_file(infile, outfile, preserve_mode, preserve_times, not self.force, link, dry_run=self.dry_run) def copy_tree(self, infile, outfile, preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1): """Copy an entire directory tree respecting verbose, dry-run, and force flags. """ return dir_util.copy_tree(infile, outfile, preserve_mode, preserve_times, preserve_symlinks, not self.force, dry_run=self.dry_run) def move_file (self, src, dst, level=1): """Move a file respecting dry-run flag.""" return file_util.move_file(src, dst, dry_run=self.dry_run) def spawn(self, cmd, search_path=1, level=1): """Spawn an external command respecting dry-run flag.""" from distutils.spawn import spawn spawn(cmd, search_path, dry_run=self.dry_run) def make_archive(self, base_name, format, root_dir=None, base_dir=None, owner=None, group=None): return archive_util.make_archive(base_name, format, root_dir, base_dir, dry_run=self.dry_run, owner=owner, group=group) def make_file(self, infiles, outfile, func, args, exec_msg=None, skip_msg=None, level=1): """Special case of 'execute()' for operations that process one or more input files and generate one output file. Works just like 'execute()', except the operation is skipped and a different message printed if 'outfile' already exists and is newer than all files listed in 'infiles'. If the command defined 'self.force', and it is true, then the command is unconditionally run -- does no timestamp checks. """ if skip_msg is None: skip_msg = "skipping %s (inputs unchanged)" % outfile # Allow 'infiles' to be a single string if isinstance(infiles, str): infiles = (infiles,) elif not isinstance(infiles, (list, tuple)): raise TypeError( "'infiles' must be a string, or a list or tuple of strings") if exec_msg is None: exec_msg = "generating %s from %s" % (outfile, ', '.join(infiles)) # If 'outfile' must be regenerated (either because it doesn't # exist, is out-of-date, or the 'force' flag is true) then # perform the action that presumably regenerates it if self.force or dep_util.newer_group(infiles, outfile): self.execute(func, args, exec_msg, level) # Otherwise, print the "skip" message else: log.debug(skip_msg) PKH]$Fq8python3.10/site-packages/setuptools/_distutils/config.pynu["""distutils.pypirc Provides the PyPIRCCommand class, the base class for the command classes that uses .pypirc in the distutils.command package. """ import os from configparser import RawConfigParser from distutils.cmd import Command DEFAULT_PYPIRC = """\ [distutils] index-servers = pypi [pypi] username:%s password:%s """ class PyPIRCCommand(Command): """Base command that knows how to handle the .pypirc file """ DEFAULT_REPOSITORY = 'https://upload.pypi.org/legacy/' DEFAULT_REALM = 'pypi' repository = None realm = None user_options = [ ('repository=', 'r', "url of repository [default: %s]" % \ DEFAULT_REPOSITORY), ('show-response', None, 'display full response text from server')] boolean_options = ['show-response'] def _get_rc_file(self): """Returns rc file path.""" return os.path.join(os.path.expanduser('~'), '.pypirc') def _store_pypirc(self, username, password): """Creates a default .pypirc file.""" rc = self._get_rc_file() with os.fdopen(os.open(rc, os.O_CREAT | os.O_WRONLY, 0o600), 'w') as f: f.write(DEFAULT_PYPIRC % (username, password)) def _read_pypirc(self): """Reads the .pypirc file.""" rc = self._get_rc_file() if os.path.exists(rc): self.announce('Using PyPI login from %s' % rc) repository = self.repository or self.DEFAULT_REPOSITORY config = RawConfigParser() config.read(rc) sections = config.sections() if 'distutils' in sections: # let's get the list of servers index_servers = config.get('distutils', 'index-servers') _servers = [server.strip() for server in index_servers.split('\n') if server.strip() != ''] if _servers == []: # nothing set, let's try to get the default pypi if 'pypi' in sections: _servers = ['pypi'] else: # the file is not properly defined, returning # an empty dict return {} for server in _servers: current = {'server': server} current['username'] = config.get(server, 'username') # optional params for key, default in (('repository', self.DEFAULT_REPOSITORY), ('realm', self.DEFAULT_REALM), ('password', None)): if config.has_option(server, key): current[key] = config.get(server, key) else: current[key] = default # work around people having "repository" for the "pypi" # section of their config set to the HTTP (rather than # HTTPS) URL if (server == 'pypi' and repository in (self.DEFAULT_REPOSITORY, 'pypi')): current['repository'] = self.DEFAULT_REPOSITORY return current if (current['server'] == repository or current['repository'] == repository): return current elif 'server-login' in sections: # old format server = 'server-login' if config.has_option(server, 'repository'): repository = config.get(server, 'repository') else: repository = self.DEFAULT_REPOSITORY return {'username': config.get(server, 'username'), 'password': config.get(server, 'password'), 'repository': repository, 'server': server, 'realm': self.DEFAULT_REALM} return {} def _read_pypi_response(self, response): """Read and decode a PyPI HTTP response.""" import cgi content_type = response.getheader('content-type', 'text/plain') encoding = cgi.parse_header(content_type)[1].get('charset', 'ascii') return response.read().decode(encoding) def initialize_options(self): """Initialize options.""" self.repository = None self.realm = None self.show_response = 0 def finalize_options(self): """Finalizes options.""" if self.repository is None: self.repository = self.DEFAULT_REPOSITORY if self.realm is None: self.realm = self.DEFAULT_REALM PKH]Q800;python3.10/site-packages/setuptools/_distutils/text_file.pynu["""text_file provides the TextFile class, which gives an interface to text files that (optionally) takes care of stripping comments, ignoring blank lines, and joining lines with backslashes.""" import sys, io class TextFile: """Provides a file-like object that takes care of all the things you commonly want to do when processing a text file that has some line-by-line syntax: strip comments (as long as "#" is your comment character), skip blank lines, join adjacent lines by escaping the newline (ie. backslash at end of line), strip leading and/or trailing whitespace. All of these are optional and independently controllable. Provides a 'warn()' method so you can generate warning messages that report physical line number, even if the logical line in question spans multiple physical lines. Also provides 'unreadline()' for implementing line-at-a-time lookahead. Constructor is called as: TextFile (filename=None, file=None, **options) It bombs (RuntimeError) if both 'filename' and 'file' are None; 'filename' should be a string, and 'file' a file object (or something that provides 'readline()' and 'close()' methods). It is recommended that you supply at least 'filename', so that TextFile can include it in warning messages. If 'file' is not supplied, TextFile creates its own using 'io.open()'. The options are all boolean, and affect the value returned by 'readline()': strip_comments [default: true] strip from "#" to end-of-line, as well as any whitespace leading up to the "#" -- unless it is escaped by a backslash lstrip_ws [default: false] strip leading whitespace from each line before returning it rstrip_ws [default: true] strip trailing whitespace (including line terminator!) from each line before returning it skip_blanks [default: true} skip lines that are empty *after* stripping comments and whitespace. (If both lstrip_ws and rstrip_ws are false, then some lines may consist of solely whitespace: these will *not* be skipped, even if 'skip_blanks' is true.) join_lines [default: false] if a backslash is the last non-newline character on a line after stripping comments and whitespace, join the following line to it to form one "logical line"; if N consecutive lines end with a backslash, then N+1 physical lines will be joined to form one logical line. collapse_join [default: false] strip leading whitespace from lines that are joined to their predecessor; only matters if (join_lines and not lstrip_ws) errors [default: 'strict'] error handler used to decode the file content Note that since 'rstrip_ws' can strip the trailing newline, the semantics of 'readline()' must differ from those of the builtin file object's 'readline()' method! In particular, 'readline()' returns None for end-of-file: an empty string might just be a blank line (or an all-whitespace line), if 'rstrip_ws' is true but 'skip_blanks' is not.""" default_options = { 'strip_comments': 1, 'skip_blanks': 1, 'lstrip_ws': 0, 'rstrip_ws': 1, 'join_lines': 0, 'collapse_join': 0, 'errors': 'strict', } def __init__(self, filename=None, file=None, **options): """Construct a new TextFile object. At least one of 'filename' (a string) and 'file' (a file-like object) must be supplied. They keyword argument options are described above and affect the values returned by 'readline()'.""" if filename is None and file is None: raise RuntimeError("you must supply either or both of 'filename' and 'file'") # set values for all options -- either from client option hash # or fallback to default_options for opt in self.default_options.keys(): if opt in options: setattr(self, opt, options[opt]) else: setattr(self, opt, self.default_options[opt]) # sanity check client option hash for opt in options.keys(): if opt not in self.default_options: raise KeyError("invalid TextFile option '%s'" % opt) if file is None: self.open(filename) else: self.filename = filename self.file = file self.current_line = 0 # assuming that file is at BOF! # 'linebuf' is a stack of lines that will be emptied before we # actually read from the file; it's only populated by an # 'unreadline()' operation self.linebuf = [] def open(self, filename): """Open a new file named 'filename'. This overrides both the 'filename' and 'file' arguments to the constructor.""" self.filename = filename self.file = io.open(self.filename, 'r', errors=self.errors) self.current_line = 0 def close(self): """Close the current file and forget everything we know about it (filename, current line number).""" file = self.file self.file = None self.filename = None self.current_line = None file.close() def gen_error(self, msg, line=None): outmsg = [] if line is None: line = self.current_line outmsg.append(self.filename + ", ") if isinstance(line, (list, tuple)): outmsg.append("lines %d-%d: " % tuple(line)) else: outmsg.append("line %d: " % line) outmsg.append(str(msg)) return "".join(outmsg) def error(self, msg, line=None): raise ValueError("error: " + self.gen_error(msg, line)) def warn(self, msg, line=None): """Print (to stderr) a warning message tied to the current logical line in the current file. If the current logical line in the file spans multiple physical lines, the warning refers to the whole range, eg. "lines 3-5". If 'line' supplied, it overrides the current line number; it may be a list or tuple to indicate a range of physical lines, or an integer for a single physical line.""" sys.stderr.write("warning: " + self.gen_error(msg, line) + "\n") def readline(self): """Read and return a single logical line from the current file (or from an internal buffer if lines have previously been "unread" with 'unreadline()'). If the 'join_lines' option is true, this may involve reading multiple physical lines concatenated into a single string. Updates the current line number, so calling 'warn()' after 'readline()' emits a warning about the physical line(s) just read. Returns None on end-of-file, since the empty string can occur if 'rstrip_ws' is true but 'strip_blanks' is not.""" # If any "unread" lines waiting in 'linebuf', return the top # one. (We don't actually buffer read-ahead data -- lines only # get put in 'linebuf' if the client explicitly does an # 'unreadline()'. if self.linebuf: line = self.linebuf[-1] del self.linebuf[-1] return line buildup_line = '' while True: # read the line, make it None if EOF line = self.file.readline() if line == '': line = None if self.strip_comments and line: # Look for the first "#" in the line. If none, never # mind. If we find one and it's the first character, or # is not preceded by "\", then it starts a comment -- # strip the comment, strip whitespace before it, and # carry on. Otherwise, it's just an escaped "#", so # unescape it (and any other escaped "#"'s that might be # lurking in there) and otherwise leave the line alone. pos = line.find("#") if pos == -1: # no "#" -- no comments pass # It's definitely a comment -- either "#" is the first # character, or it's elsewhere and unescaped. elif pos == 0 or line[pos-1] != "\\": # Have to preserve the trailing newline, because it's # the job of a later step (rstrip_ws) to remove it -- # and if rstrip_ws is false, we'd better preserve it! # (NB. this means that if the final line is all comment # and has no trailing newline, we will think that it's # EOF; I think that's OK.) eol = (line[-1] == '\n') and '\n' or '' line = line[0:pos] + eol # If all that's left is whitespace, then skip line # *now*, before we try to join it to 'buildup_line' -- # that way constructs like # hello \\ # # comment that should be ignored # there # result in "hello there". if line.strip() == "": continue else: # it's an escaped "#" line = line.replace("\\#", "#") # did previous line end with a backslash? then accumulate if self.join_lines and buildup_line: # oops: end of file if line is None: self.warn("continuation line immediately precedes " "end-of-file") return buildup_line if self.collapse_join: line = line.lstrip() line = buildup_line + line # careful: pay attention to line number when incrementing it if isinstance(self.current_line, list): self.current_line[1] = self.current_line[1] + 1 else: self.current_line = [self.current_line, self.current_line + 1] # just an ordinary line, read it as usual else: if line is None: # eof return None # still have to be careful about incrementing the line number! if isinstance(self.current_line, list): self.current_line = self.current_line[1] + 1 else: self.current_line = self.current_line + 1 # strip whitespace however the client wants (leading and # trailing, or one or the other, or neither) if self.lstrip_ws and self.rstrip_ws: line = line.strip() elif self.lstrip_ws: line = line.lstrip() elif self.rstrip_ws: line = line.rstrip() # blank line (whether we rstrip'ed or not)? skip to next line # if appropriate if (line == '' or line == '\n') and self.skip_blanks: continue if self.join_lines: if line[-1] == '\\': buildup_line = line[:-1] continue if line[-2:] == '\\\n': buildup_line = line[0:-2] + '\n' continue # well, I guess there's some actual content there: return it return line def readlines(self): """Read and return the list of all logical lines remaining in the current file.""" lines = [] while True: line = self.readline() if line is None: return lines lines.append(line) def unreadline(self, line): """Push 'line' (a string) onto an internal buffer that will be checked by future 'readline()' calls. Handy for implementing a parser with line-at-a-time lookahead.""" self.linebuf.append(line) PKH]MQMQ?python3.10/site-packages/setuptools/_distutils/_msvccompiler.pynu["""distutils._msvccompiler Contains MSVCCompiler, an implementation of the abstract CCompiler class for Microsoft Visual Studio 2015. The module is compatible with VS 2015 and later. You can find legacy support for older versions in distutils.msvc9compiler and distutils.msvccompiler. """ # Written by Perry Stoll # hacked by Robin Becker and Thomas Heller to do a better job of # finding DevStudio (through the registry) # ported to VS 2005 and VS 2008 by Christian Heimes # ported to VS 2015 by Steve Dower import os import subprocess import contextlib import warnings import unittest.mock with contextlib.suppress(ImportError): import winreg from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ CompileError, LibError, LinkError from distutils.ccompiler import CCompiler, gen_lib_options from distutils import log from distutils.util import get_platform from itertools import count def _find_vc2015(): try: key = winreg.OpenKeyEx( winreg.HKEY_LOCAL_MACHINE, r"Software\Microsoft\VisualStudio\SxS\VC7", access=winreg.KEY_READ | winreg.KEY_WOW64_32KEY ) except OSError: log.debug("Visual C++ is not registered") return None, None best_version = 0 best_dir = None with key: for i in count(): try: v, vc_dir, vt = winreg.EnumValue(key, i) except OSError: break if v and vt == winreg.REG_SZ and os.path.isdir(vc_dir): try: version = int(float(v)) except (ValueError, TypeError): continue if version >= 14 and version > best_version: best_version, best_dir = version, vc_dir return best_version, best_dir def _find_vc2017(): """Returns "15, path" based on the result of invoking vswhere.exe If no install is found, returns "None, None" The version is returned to avoid unnecessarily changing the function result. It may be ignored when the path is not None. If vswhere.exe is not available, by definition, VS 2017 is not installed. """ root = os.environ.get("ProgramFiles(x86)") or os.environ.get("ProgramFiles") if not root: return None, None try: path = subprocess.check_output([ os.path.join(root, "Microsoft Visual Studio", "Installer", "vswhere.exe"), "-latest", "-prerelease", "-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", "-property", "installationPath", "-products", "*", ], encoding="mbcs", errors="strict").strip() except (subprocess.CalledProcessError, OSError, UnicodeDecodeError): return None, None path = os.path.join(path, "VC", "Auxiliary", "Build") if os.path.isdir(path): return 15, path return None, None PLAT_SPEC_TO_RUNTIME = { 'x86' : 'x86', 'x86_amd64' : 'x64', 'x86_arm' : 'arm', 'x86_arm64' : 'arm64' } def _find_vcvarsall(plat_spec): # bpo-38597: Removed vcruntime return value _, best_dir = _find_vc2017() if not best_dir: best_version, best_dir = _find_vc2015() if not best_dir: log.debug("No suitable Visual C++ version found") return None, None vcvarsall = os.path.join(best_dir, "vcvarsall.bat") if not os.path.isfile(vcvarsall): log.debug("%s cannot be found", vcvarsall) return None, None return vcvarsall, None def _get_vc_env(plat_spec): if os.getenv("DISTUTILS_USE_SDK"): return { key.lower(): value for key, value in os.environ.items() } vcvarsall, _ = _find_vcvarsall(plat_spec) if not vcvarsall: raise DistutilsPlatformError("Unable to find vcvarsall.bat") try: out = subprocess.check_output( 'cmd /u /c "{}" {} && set'.format(vcvarsall, plat_spec), stderr=subprocess.STDOUT, ).decode('utf-16le', errors='replace') except subprocess.CalledProcessError as exc: log.error(exc.output) raise DistutilsPlatformError("Error executing {}" .format(exc.cmd)) env = { key.lower(): value for key, _, value in (line.partition('=') for line in out.splitlines()) if key and value } return env def _find_exe(exe, paths=None): """Return path to an MSVC executable program. Tries to find the program in several places: first, one of the MSVC program search paths from the registry; next, the directories in the PATH environment variable. If any of those work, return an absolute path that is known to exist. If none of them work, just return the original program name, 'exe'. """ if not paths: paths = os.getenv('path').split(os.pathsep) for p in paths: fn = os.path.join(os.path.abspath(p), exe) if os.path.isfile(fn): return fn return exe # A map keyed by get_platform() return values to values accepted by # 'vcvarsall.bat'. Always cross-compile from x86 to work with the # lighter-weight MSVC installs that do not include native 64-bit tools. PLAT_TO_VCVARS = { 'win32' : 'x86', 'win-amd64' : 'x86_amd64', 'win-arm32' : 'x86_arm', 'win-arm64' : 'x86_arm64' } class MSVCCompiler(CCompiler) : """Concrete class that implements an interface to Microsoft Visual C++, as defined by the CCompiler abstract class.""" compiler_type = 'msvc' # Just set this so CCompiler's constructor doesn't barf. We currently # don't use the 'set_executables()' bureaucracy provided by CCompiler, # as it really isn't necessary for this sort of single-compiler class. # Would be nice to have a consistent interface with UnixCCompiler, # though, so it's worth thinking about. executables = {} # Private class data (need to distinguish C from C++ source for compiler) _c_extensions = ['.c'] _cpp_extensions = ['.cc', '.cpp', '.cxx'] _rc_extensions = ['.rc'] _mc_extensions = ['.mc'] # Needed for the filename generation methods provided by the # base class, CCompiler. src_extensions = (_c_extensions + _cpp_extensions + _rc_extensions + _mc_extensions) res_extension = '.res' obj_extension = '.obj' static_lib_extension = '.lib' shared_lib_extension = '.dll' static_lib_format = shared_lib_format = '%s%s' exe_extension = '.exe' def __init__(self, verbose=0, dry_run=0, force=0): CCompiler.__init__ (self, verbose, dry_run, force) # target platform (.plat_name is consistent with 'bdist') self.plat_name = None self.initialized = False def initialize(self, plat_name=None): # multi-init means we would need to check platform same each time... assert not self.initialized, "don't init multiple times" if plat_name is None: plat_name = get_platform() # sanity check for platforms to prevent obscure errors later. if plat_name not in PLAT_TO_VCVARS: raise DistutilsPlatformError("--plat-name must be one of {}" .format(tuple(PLAT_TO_VCVARS))) # Get the vcvarsall.bat spec for the requested platform. plat_spec = PLAT_TO_VCVARS[plat_name] vc_env = _get_vc_env(plat_spec) if not vc_env: raise DistutilsPlatformError("Unable to find a compatible " "Visual Studio installation.") self._paths = vc_env.get('path', '') paths = self._paths.split(os.pathsep) self.cc = _find_exe("cl.exe", paths) self.linker = _find_exe("link.exe", paths) self.lib = _find_exe("lib.exe", paths) self.rc = _find_exe("rc.exe", paths) # resource compiler self.mc = _find_exe("mc.exe", paths) # message compiler self.mt = _find_exe("mt.exe", paths) # message compiler for dir in vc_env.get('include', '').split(os.pathsep): if dir: self.add_include_dir(dir.rstrip(os.sep)) for dir in vc_env.get('lib', '').split(os.pathsep): if dir: self.add_library_dir(dir.rstrip(os.sep)) self.preprocess_options = None # bpo-38597: Always compile with dynamic linking # Future releases of Python 3.x will include all past # versions of vcruntime*.dll for compatibility. self.compile_options = [ '/nologo', '/O2', '/W3', '/GL', '/DNDEBUG', '/MD' ] self.compile_options_debug = [ '/nologo', '/Od', '/MDd', '/Zi', '/W3', '/D_DEBUG' ] ldflags = [ '/nologo', '/INCREMENTAL:NO', '/LTCG' ] ldflags_debug = [ '/nologo', '/INCREMENTAL:NO', '/LTCG', '/DEBUG:FULL' ] self.ldflags_exe = [*ldflags, '/MANIFEST:EMBED,ID=1'] self.ldflags_exe_debug = [*ldflags_debug, '/MANIFEST:EMBED,ID=1'] self.ldflags_shared = [*ldflags, '/DLL', '/MANIFEST:EMBED,ID=2', '/MANIFESTUAC:NO'] self.ldflags_shared_debug = [*ldflags_debug, '/DLL', '/MANIFEST:EMBED,ID=2', '/MANIFESTUAC:NO'] self.ldflags_static = [*ldflags] self.ldflags_static_debug = [*ldflags_debug] self._ldflags = { (CCompiler.EXECUTABLE, None): self.ldflags_exe, (CCompiler.EXECUTABLE, False): self.ldflags_exe, (CCompiler.EXECUTABLE, True): self.ldflags_exe_debug, (CCompiler.SHARED_OBJECT, None): self.ldflags_shared, (CCompiler.SHARED_OBJECT, False): self.ldflags_shared, (CCompiler.SHARED_OBJECT, True): self.ldflags_shared_debug, (CCompiler.SHARED_LIBRARY, None): self.ldflags_static, (CCompiler.SHARED_LIBRARY, False): self.ldflags_static, (CCompiler.SHARED_LIBRARY, True): self.ldflags_static_debug, } self.initialized = True # -- Worker methods ------------------------------------------------ def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): ext_map = { **{ext: self.obj_extension for ext in self.src_extensions}, **{ext: self.res_extension for ext in self._rc_extensions + self._mc_extensions}, } output_dir = output_dir or '' def make_out_path(p): base, ext = os.path.splitext(p) if strip_dir: base = os.path.basename(base) else: _, base = os.path.splitdrive(base) if base.startswith((os.path.sep, os.path.altsep)): base = base[1:] try: # XXX: This may produce absurdly long paths. We should check # the length of the result and trim base until we fit within # 260 characters. return os.path.join(output_dir, base + ext_map[ext]) except LookupError: # Better to raise an exception instead of silently continuing # and later complain about sources and targets having # different lengths raise CompileError("Don't know how to compile {}".format(p)) return list(map(make_out_path, source_filenames)) def compile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): if not self.initialized: self.initialize() compile_info = self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs) macros, objects, extra_postargs, pp_opts, build = compile_info compile_opts = extra_preargs or [] compile_opts.append('/c') if debug: compile_opts.extend(self.compile_options_debug) else: compile_opts.extend(self.compile_options) add_cpp_opts = False for obj in objects: try: src, ext = build[obj] except KeyError: continue if debug: # pass the full pathname to MSVC in debug mode, # this allows the debugger to find the source file # without asking the user to browse for it src = os.path.abspath(src) if ext in self._c_extensions: input_opt = "/Tc" + src elif ext in self._cpp_extensions: input_opt = "/Tp" + src add_cpp_opts = True elif ext in self._rc_extensions: # compile .RC to .RES file input_opt = src output_opt = "/fo" + obj try: self.spawn([self.rc] + pp_opts + [output_opt, input_opt]) except DistutilsExecError as msg: raise CompileError(msg) continue elif ext in self._mc_extensions: # Compile .MC to .RC file to .RES file. # * '-h dir' specifies the directory for the # generated include file # * '-r dir' specifies the target directory of the # generated RC file and the binary message resource # it includes # # For now (since there are no options to change this), # we use the source-directory for the include file and # the build directory for the RC file and message # resources. This works at least for win32all. h_dir = os.path.dirname(src) rc_dir = os.path.dirname(obj) try: # first compile .MC to .RC and .H file self.spawn([self.mc, '-h', h_dir, '-r', rc_dir, src]) base, _ = os.path.splitext(os.path.basename (src)) rc_file = os.path.join(rc_dir, base + '.rc') # then compile .RC to .RES file self.spawn([self.rc, "/fo" + obj, rc_file]) except DistutilsExecError as msg: raise CompileError(msg) continue else: # how to handle this file? raise CompileError("Don't know how to compile {} to {}" .format(src, obj)) args = [self.cc] + compile_opts + pp_opts if add_cpp_opts: args.append('/EHsc') args.append(input_opt) args.append("/Fo" + obj) args.extend(extra_postargs) try: self.spawn(args) except DistutilsExecError as msg: raise CompileError(msg) return objects def create_static_lib(self, objects, output_libname, output_dir=None, debug=0, target_lang=None): if not self.initialized: self.initialize() objects, output_dir = self._fix_object_args(objects, output_dir) output_filename = self.library_filename(output_libname, output_dir=output_dir) if self._need_link(objects, output_filename): lib_args = objects + ['/OUT:' + output_filename] if debug: pass # XXX what goes here? try: log.debug('Executing "%s" %s', self.lib, ' '.join(lib_args)) self.spawn([self.lib] + lib_args) except DistutilsExecError as msg: raise LibError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): if not self.initialized: self.initialize() objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args if runtime_library_dirs: self.warn("I don't know what to do with 'runtime_library_dirs': " + str(runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ldflags = self._ldflags[target_desc, debug] export_opts = ["/EXPORT:" + sym for sym in (export_symbols or [])] ld_args = (ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]) # The MSVC linker generates .lib and .exp files, which cannot be # suppressed by any linker switches. The .lib files may even be # needed! Make sure they are generated in the temporary build # directory. Since they have different names for debug and release # builds, they can go into the same directory. build_temp = os.path.dirname(objects[0]) if export_symbols is not None: (dll_name, dll_ext) = os.path.splitext( os.path.basename(output_filename)) implib_file = os.path.join( build_temp, self.library_filename(dll_name)) ld_args.append ('/IMPLIB:' + implib_file) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) output_dir = os.path.dirname(os.path.abspath(output_filename)) self.mkpath(output_dir) try: log.debug('Executing "%s" %s', self.linker, ' '.join(ld_args)) self.spawn([self.linker] + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) def spawn(self, cmd): env = dict(os.environ, PATH=self._paths) with self._fallback_spawn(cmd, env) as fallback: return super().spawn(cmd, env=env) return fallback.value @contextlib.contextmanager def _fallback_spawn(self, cmd, env): """ Discovered in pypa/distutils#15, some tools monkeypatch the compiler, so the 'env' kwarg causes a TypeError. Detect this condition and restore the legacy, unsafe behavior. """ bag = type('Bag', (), {})() try: yield bag except TypeError as exc: if "unexpected keyword argument 'env'" not in str(exc): raise else: return warnings.warn( "Fallback spawn triggered. Please update distutils monkeypatch.") with unittest.mock.patch('os.environ', env): bag.value = super().spawn(cmd) # -- Miscellaneous methods ----------------------------------------- # These are all used by the 'gen_lib_options() function, in # ccompiler.py. def library_dir_option(self, dir): return "/LIBPATH:" + dir def runtime_library_dir_option(self, dir): raise DistutilsPlatformError( "don't know how to set runtime library search path for MSVC") def library_option(self, lib): return self.library_filename(lib) def find_library_file(self, dirs, lib, debug=0): # Prefer a debugging library if found (and requested), but deal # with it if we don't have one. if debug: try_names = [lib + "_d", lib] else: try_names = [lib] for dir in dirs: for name in try_names: libfile = os.path.join(dir, self.library_filename(name)) if os.path.isfile(libfile): return libfile else: # Oops, didn't find it in *any* of 'dirs' return None PKH]B:python3.10/site-packages/setuptools/_distutils/__init__.pynu["""distutils The main package for the Python Module Distribution Utilities. Normally used from a setup script as from distutils.core import setup setup (...) """ import sys __version__ = sys.version[:sys.version.index(' ')] local = True PKH]%_4_4:python3.10/site-packages/setuptools/_distutils/filelist.pynu["""distutils.filelist Provides the FileList class, used for poking about the filesystem and building lists of files. """ import os import re import fnmatch import functools from distutils.util import convert_path from distutils.errors import DistutilsTemplateError, DistutilsInternalError from distutils import log class FileList: """A list of files built by on exploring the filesystem and filtered by applying various patterns to what we find there. Instance attributes: dir directory from which files will be taken -- only used if 'allfiles' not supplied to constructor files list of filenames currently being built/filtered/manipulated allfiles complete list of files under consideration (ie. without any filtering applied) """ def __init__(self, warn=None, debug_print=None): # ignore argument to FileList, but keep them for backwards # compatibility self.allfiles = None self.files = [] def set_allfiles(self, allfiles): self.allfiles = allfiles def findall(self, dir=os.curdir): self.allfiles = findall(dir) def debug_print(self, msg): """Print 'msg' to stdout if the global DEBUG (taken from the DISTUTILS_DEBUG environment variable) flag is true. """ from distutils.debug import DEBUG if DEBUG: print(msg) # Collection methods def append(self, item): self.files.append(item) def extend(self, items): self.files.extend(items) def sort(self): # Not a strict lexical sort! sortable_files = sorted(map(os.path.split, self.files)) self.files = [] for sort_tuple in sortable_files: self.files.append(os.path.join(*sort_tuple)) # Other miscellaneous utility methods def remove_duplicates(self): # Assumes list has been sorted! for i in range(len(self.files) - 1, 0, -1): if self.files[i] == self.files[i - 1]: del self.files[i] # "File template" methods def _parse_template_line(self, line): words = line.split() action = words[0] patterns = dir = dir_pattern = None if action in ('include', 'exclude', 'global-include', 'global-exclude'): if len(words) < 2: raise DistutilsTemplateError( "'%s' expects ..." % action) patterns = [convert_path(w) for w in words[1:]] elif action in ('recursive-include', 'recursive-exclude'): if len(words) < 3: raise DistutilsTemplateError( "'%s' expects ..." % action) dir = convert_path(words[1]) patterns = [convert_path(w) for w in words[2:]] elif action in ('graft', 'prune'): if len(words) != 2: raise DistutilsTemplateError( "'%s' expects a single " % action) dir_pattern = convert_path(words[1]) else: raise DistutilsTemplateError("unknown action '%s'" % action) return (action, patterns, dir, dir_pattern) def process_template_line(self, line): # Parse the line: split it up, make sure the right number of words # is there, and return the relevant words. 'action' is always # defined: it's the first word of the line. Which of the other # three are defined depends on the action; it'll be either # patterns, (dir and patterns), or (dir_pattern). (action, patterns, dir, dir_pattern) = self._parse_template_line(line) # OK, now we know that the action is valid and we have the # right number of words on the line for that action -- so we # can proceed with minimal error-checking. if action == 'include': self.debug_print("include " + ' '.join(patterns)) for pattern in patterns: if not self.include_pattern(pattern, anchor=1): log.warn("warning: no files found matching '%s'", pattern) elif action == 'exclude': self.debug_print("exclude " + ' '.join(patterns)) for pattern in patterns: if not self.exclude_pattern(pattern, anchor=1): log.warn(("warning: no previously-included files " "found matching '%s'"), pattern) elif action == 'global-include': self.debug_print("global-include " + ' '.join(patterns)) for pattern in patterns: if not self.include_pattern(pattern, anchor=0): log.warn(("warning: no files found matching '%s' " "anywhere in distribution"), pattern) elif action == 'global-exclude': self.debug_print("global-exclude " + ' '.join(patterns)) for pattern in patterns: if not self.exclude_pattern(pattern, anchor=0): log.warn(("warning: no previously-included files matching " "'%s' found anywhere in distribution"), pattern) elif action == 'recursive-include': self.debug_print("recursive-include %s %s" % (dir, ' '.join(patterns))) for pattern in patterns: if not self.include_pattern(pattern, prefix=dir): msg = ( "warning: no files found matching '%s' " "under directory '%s'" ) log.warn(msg, pattern, dir) elif action == 'recursive-exclude': self.debug_print("recursive-exclude %s %s" % (dir, ' '.join(patterns))) for pattern in patterns: if not self.exclude_pattern(pattern, prefix=dir): log.warn(("warning: no previously-included files matching " "'%s' found under directory '%s'"), pattern, dir) elif action == 'graft': self.debug_print("graft " + dir_pattern) if not self.include_pattern(None, prefix=dir_pattern): log.warn("warning: no directories found matching '%s'", dir_pattern) elif action == 'prune': self.debug_print("prune " + dir_pattern) if not self.exclude_pattern(None, prefix=dir_pattern): log.warn(("no previously-included directories found " "matching '%s'"), dir_pattern) else: raise DistutilsInternalError( "this cannot happen: invalid action '%s'" % action) # Filtering/selection methods def include_pattern(self, pattern, anchor=1, prefix=None, is_regex=0): """Select strings (presumably filenames) from 'self.files' that match 'pattern', a Unix-style wildcard (glob) pattern. Patterns are not quite the same as implemented by the 'fnmatch' module: '*' and '?' match non-special characters, where "special" is platform- dependent: slash on Unix; colon, slash, and backslash on DOS/Windows; and colon on Mac OS. If 'anchor' is true (the default), then the pattern match is more stringent: "*.py" will match "foo.py" but not "foo/bar.py". If 'anchor' is false, both of these will match. If 'prefix' is supplied, then only filenames starting with 'prefix' (itself a pattern) and ending with 'pattern', with anything in between them, will match. 'anchor' is ignored in this case. If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and 'pattern' is assumed to be either a string containing a regex or a regex object -- no translation is done, the regex is just compiled and used as-is. Selected strings will be added to self.files. Return True if files are found, False otherwise. """ # XXX docstring lying about what the special chars are? files_found = False pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) self.debug_print("include_pattern: applying regex r'%s'" % pattern_re.pattern) # delayed loading of allfiles list if self.allfiles is None: self.findall() for name in self.allfiles: if pattern_re.search(name): self.debug_print(" adding " + name) self.files.append(name) files_found = True return files_found def exclude_pattern( self, pattern, anchor=1, prefix=None, is_regex=0): """Remove strings (presumably filenames) from 'files' that match 'pattern'. Other parameters are the same as for 'include_pattern()', above. The list 'self.files' is modified in place. Return True if files are found, False otherwise. """ files_found = False pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) self.debug_print("exclude_pattern: applying regex r'%s'" % pattern_re.pattern) for i in range(len(self.files)-1, -1, -1): if pattern_re.search(self.files[i]): self.debug_print(" removing " + self.files[i]) del self.files[i] files_found = True return files_found # Utility functions def _find_all_simple(path): """ Find all files under 'path' """ all_unique = _UniqueDirs.filter(os.walk(path, followlinks=True)) results = ( os.path.join(base, file) for base, dirs, files in all_unique for file in files ) return filter(os.path.isfile, results) class _UniqueDirs(set): """ Exclude previously-seen dirs from walk results, avoiding infinite recursion. Ref https://bugs.python.org/issue44497. """ def __call__(self, walk_item): """ Given an item from an os.walk result, determine if the item represents a unique dir for this instance and if not, prevent further traversal. """ base, dirs, files = walk_item stat = os.stat(base) candidate = stat.st_dev, stat.st_ino found = candidate in self if found: del dirs[:] self.add(candidate) return not found @classmethod def filter(cls, items): return filter(cls(), items) def findall(dir=os.curdir): """ Find all files under 'dir' and return the list of full filenames. Unless dir is '.', return full filenames with dir prepended. """ files = _find_all_simple(dir) if dir == os.curdir: make_rel = functools.partial(os.path.relpath, start=dir) files = map(make_rel, files) return list(files) def glob_to_re(pattern): """Translate a shell-like glob pattern to a regular expression; return a string containing the regex. Differs from 'fnmatch.translate()' in that '*' does not match "special characters" (which are platform-specific). """ pattern_re = fnmatch.translate(pattern) # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, # and by extension they shouldn't match such "special characters" under # any OS. So change all non-escaped dots in the RE to match any # character except the special characters (currently: just os.sep). sep = os.sep if os.sep == '\\': # we're using a regex to manipulate a regex, so we need # to escape the backslash twice sep = r'\\\\' escaped = r'\1[^%s]' % sep pattern_re = re.sub(r'((?s CPKH]eg g 6python3.10/site-packages/setuptools/extern/__init__.pynu[import importlib.util import sys class VendorImporter: """ A PEP 302 meta path importer for finding optionally-vendored or otherwise naturally-installed packages from root_name. """ def __init__(self, root_name, vendored_names=(), vendor_pkg=None): self.root_name = root_name self.vendored_names = set(vendored_names) self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor') @property def search_path(self): """ Search first the vendor package then as a natural package. """ yield self.vendor_pkg + '.' yield '' def _module_matches_namespace(self, fullname): """Figure out if the target module is vendored.""" root, base, target = fullname.partition(self.root_name + '.') return not root and any(map(target.startswith, self.vendored_names)) def load_module(self, fullname): """ Iterate over the search path to locate and load fullname. """ root, base, target = fullname.partition(self.root_name + '.') for prefix in self.search_path: try: extant = prefix + target __import__(extant) mod = sys.modules[extant] sys.modules[fullname] = mod return mod except ImportError: pass else: raise ImportError( "The '{target}' package is required; " "normally this is bundled with this package so if you get " "this warning, consult the packager of your " "distribution.".format(**locals()) ) def create_module(self, spec): return self.load_module(spec.name) def exec_module(self, module): pass def find_spec(self, fullname, path=None, target=None): """Return a module spec for vendored names.""" return ( importlib.util.spec_from_loader(fullname, self) if self._module_matches_namespace(fullname) else None ) def install(self): """ Install this importer into sys.meta_path if not already present. """ if self not in sys.meta_path: sys.meta_path.append(self) names = 'packaging', 'pyparsing', 'ordered_set', 'more_itertools', VendorImporter(__name__, names, 'setuptools._vendor').install() PKH]T^ΛΛ4python3.10/site-packages/setuptools/package_index.pynu["""PyPI and direct package downloading""" import sys import os import re import io import shutil import socket import base64 import hashlib import itertools import warnings import configparser import html import http.client import urllib.parse import urllib.request import urllib.error from functools import wraps import setuptools from pkg_resources import ( CHECKOUT_DIST, Distribution, BINARY_DIST, normalize_path, SOURCE_DIST, Environment, find_distributions, safe_name, safe_version, to_filename, Requirement, DEVELOP_DIST, EGG_DIST, ) from distutils import log from distutils.errors import DistutilsError from fnmatch import translate from setuptools.wheel import Wheel from setuptools.extern.more_itertools import unique_everseen EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.+!]+)$') HREF = re.compile(r"""href\s*=\s*['"]?([^'"> ]+)""", re.I) PYPI_MD5 = re.compile( r'([^<]+)\n\s+\(md5\)' ) URL_SCHEME = re.compile('([-+.a-z0-9]{2,}):', re.I).match EXTENSIONS = ".tar.gz .tar.bz2 .tar .zip .tgz".split() __all__ = [ 'PackageIndex', 'distros_for_url', 'parse_bdist_wininst', 'interpret_distro_name', ] _SOCKET_TIMEOUT = 15 _tmpl = "setuptools/{setuptools.__version__} Python-urllib/{py_major}" user_agent = _tmpl.format( py_major='{}.{}'.format(*sys.version_info), setuptools=setuptools) def parse_requirement_arg(spec): try: return Requirement.parse(spec) except ValueError as e: raise DistutilsError( "Not a URL, existing file, or requirement spec: %r" % (spec,) ) from e def parse_bdist_wininst(name): """Return (base,pyversion) or (None,None) for possible .exe name""" lower = name.lower() base, py_ver, plat = None, None, None if lower.endswith('.exe'): if lower.endswith('.win32.exe'): base = name[:-10] plat = 'win32' elif lower.startswith('.win32-py', -16): py_ver = name[-7:-4] base = name[:-16] plat = 'win32' elif lower.endswith('.win-amd64.exe'): base = name[:-14] plat = 'win-amd64' elif lower.startswith('.win-amd64-py', -20): py_ver = name[-7:-4] base = name[:-20] plat = 'win-amd64' return base, py_ver, plat def egg_info_for_url(url): parts = urllib.parse.urlparse(url) scheme, server, path, parameters, query, fragment = parts base = urllib.parse.unquote(path.split('/')[-1]) if server == 'sourceforge.net' and base == 'download': # XXX Yuck base = urllib.parse.unquote(path.split('/')[-2]) if '#' in base: base, fragment = base.split('#', 1) return base, fragment def distros_for_url(url, metadata=None): """Yield egg or source distribution objects that might be found at a URL""" base, fragment = egg_info_for_url(url) for dist in distros_for_location(url, base, metadata): yield dist if fragment: match = EGG_FRAGMENT.match(fragment) if match: for dist in interpret_distro_name( url, match.group(1), metadata, precedence=CHECKOUT_DIST ): yield dist def distros_for_location(location, basename, metadata=None): """Yield egg or source distribution objects based on basename""" if basename.endswith('.egg.zip'): basename = basename[:-4] # strip the .zip if basename.endswith('.egg') and '-' in basename: # only one, unambiguous interpretation return [Distribution.from_location(location, basename, metadata)] if basename.endswith('.whl') and '-' in basename: wheel = Wheel(basename) if not wheel.is_compatible(): return [] return [Distribution( location=location, project_name=wheel.project_name, version=wheel.version, # Increase priority over eggs. precedence=EGG_DIST + 1, )] if basename.endswith('.exe'): win_base, py_ver, platform = parse_bdist_wininst(basename) if win_base is not None: return interpret_distro_name( location, win_base, metadata, py_ver, BINARY_DIST, platform ) # Try source distro extensions (.zip, .tgz, etc.) # for ext in EXTENSIONS: if basename.endswith(ext): basename = basename[:-len(ext)] return interpret_distro_name(location, basename, metadata) return [] # no extension matched def distros_for_filename(filename, metadata=None): """Yield possible egg or source distribution objects based on a filename""" return distros_for_location( normalize_path(filename), os.path.basename(filename), metadata ) def interpret_distro_name( location, basename, metadata, py_version=None, precedence=SOURCE_DIST, platform=None ): """Generate alternative interpretations of a source distro name Note: if `location` is a filesystem filename, you should call ``pkg_resources.normalize_path()`` on it before passing it to this routine! """ # Generate alternative interpretations of a source distro name # Because some packages are ambiguous as to name/versions split # e.g. "adns-python-1.1.0", "egenix-mx-commercial", etc. # So, we generate each possible interpretation (e.g. "adns, python-1.1.0" # "adns-python, 1.1.0", and "adns-python-1.1.0, no version"). In practice, # the spurious interpretations should be ignored, because in the event # there's also an "adns" package, the spurious "python-1.1.0" version will # compare lower than any numeric version number, and is therefore unlikely # to match a request for it. It's still a potential problem, though, and # in the long run PyPI and the distutils should go for "safe" names and # versions in distribution archive names (sdist and bdist). parts = basename.split('-') if not py_version and any(re.match(r'py\d\.\d$', p) for p in parts[2:]): # it is a bdist_dumb, not an sdist -- bail out return for p in range(1, len(parts) + 1): yield Distribution( location, metadata, '-'.join(parts[:p]), '-'.join(parts[p:]), py_version=py_version, precedence=precedence, platform=platform ) def unique_values(func): """ Wrap a function returning an iterable such that the resulting iterable only ever yields unique items. """ @wraps(func) def wrapper(*args, **kwargs): return unique_everseen(func(*args, **kwargs)) return wrapper REL = re.compile(r"""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I) # this line is here to fix emacs' cruddy broken syntax highlighting @unique_values def find_external_links(url, page): """Find rel="homepage" and rel="download" links in `page`, yielding URLs""" for match in REL.finditer(page): tag, rel = match.groups() rels = set(map(str.strip, rel.lower().split(','))) if 'homepage' in rels or 'download' in rels: for match in HREF.finditer(tag): yield urllib.parse.urljoin(url, htmldecode(match.group(1))) for tag in ("Home Page", "Download URL"): pos = page.find(tag) if pos != -1: match = HREF.search(page, pos) if match: yield urllib.parse.urljoin(url, htmldecode(match.group(1))) class ContentChecker: """ A null content checker that defines the interface for checking content """ def feed(self, block): """ Feed a block of data to the hash. """ return def is_valid(self): """ Check the hash. Return False if validation fails. """ return True def report(self, reporter, template): """ Call reporter with information about the checker (hash name) substituted into the template. """ return class HashChecker(ContentChecker): pattern = re.compile( r'(?Psha1|sha224|sha384|sha256|sha512|md5)=' r'(?P[a-f0-9]+)' ) def __init__(self, hash_name, expected): self.hash_name = hash_name self.hash = hashlib.new(hash_name) self.expected = expected @classmethod def from_url(cls, url): "Construct a (possibly null) ContentChecker from a URL" fragment = urllib.parse.urlparse(url)[-1] if not fragment: return ContentChecker() match = cls.pattern.search(fragment) if not match: return ContentChecker() return cls(**match.groupdict()) def feed(self, block): self.hash.update(block) def is_valid(self): return self.hash.hexdigest() == self.expected def report(self, reporter, template): msg = template % self.hash_name return reporter(msg) class PackageIndex(Environment): """A distribution index that scans web pages for download URLs""" def __init__( self, index_url="https://pypi.org/simple/", hosts=('*',), ca_bundle=None, verify_ssl=True, *args, **kw ): Environment.__init__(self, *args, **kw) self.index_url = index_url + "/" [:not index_url.endswith('/')] self.scanned_urls = {} self.fetched_urls = {} self.package_pages = {} self.allows = re.compile('|'.join(map(translate, hosts))).match self.to_scan = [] self.opener = urllib.request.urlopen # FIXME: 'PackageIndex.process_url' is too complex (14) def process_url(self, url, retrieve=False): # noqa: C901 """Evaluate a URL as a possible download, and maybe retrieve it""" if url in self.scanned_urls and not retrieve: return self.scanned_urls[url] = True if not URL_SCHEME(url): self.process_filename(url) return else: dists = list(distros_for_url(url)) if dists: if not self.url_ok(url): return self.debug("Found link: %s", url) if dists or not retrieve or url in self.fetched_urls: list(map(self.add, dists)) return # don't need the actual page if not self.url_ok(url): self.fetched_urls[url] = True return self.info("Reading %s", url) self.fetched_urls[url] = True # prevent multiple fetch attempts tmpl = "Download error on %s: %%s -- Some packages may not be found!" f = self.open_url(url, tmpl % url) if f is None: return if isinstance(f, urllib.error.HTTPError) and f.code == 401: self.info("Authentication error: %s" % f.msg) self.fetched_urls[f.url] = True if 'html' not in f.headers.get('content-type', '').lower(): f.close() # not html, we can't process it return base = f.url # handle redirects page = f.read() if not isinstance(page, str): # In Python 3 and got bytes but want str. if isinstance(f, urllib.error.HTTPError): # Errors have no charset, assume latin1: charset = 'latin-1' else: charset = f.headers.get_param('charset') or 'latin-1' page = page.decode(charset, "ignore") f.close() for match in HREF.finditer(page): link = urllib.parse.urljoin(base, htmldecode(match.group(1))) self.process_url(link) if url.startswith(self.index_url) and getattr(f, 'code', None) != 404: page = self.process_index(url, page) def process_filename(self, fn, nested=False): # process filenames or directories if not os.path.exists(fn): self.warn("Not found: %s", fn) return if os.path.isdir(fn) and not nested: path = os.path.realpath(fn) for item in os.listdir(path): self.process_filename(os.path.join(path, item), True) dists = distros_for_filename(fn) if dists: self.debug("Found: %s", fn) list(map(self.add, dists)) def url_ok(self, url, fatal=False): s = URL_SCHEME(url) is_file = s and s.group(1).lower() == 'file' if is_file or self.allows(urllib.parse.urlparse(url)[1]): return True msg = ( "\nNote: Bypassing %s (disallowed host; see " "http://bit.ly/2hrImnY for details).\n") if fatal: raise DistutilsError(msg % url) else: self.warn(msg, url) def scan_egg_links(self, search_path): dirs = filter(os.path.isdir, search_path) egg_links = ( (path, entry) for path in dirs for entry in os.listdir(path) if entry.endswith('.egg-link') ) list(itertools.starmap(self.scan_egg_link, egg_links)) def scan_egg_link(self, path, entry): with open(os.path.join(path, entry)) as raw_lines: # filter non-empty lines lines = list(filter(None, map(str.strip, raw_lines))) if len(lines) != 2: # format is not recognized; punt return egg_path, setup_path = lines for dist in find_distributions(os.path.join(path, egg_path)): dist.location = os.path.join(path, *lines) dist.precedence = SOURCE_DIST self.add(dist) def _scan(self, link): # Process a URL to see if it's for a package page NO_MATCH_SENTINEL = None, None if not link.startswith(self.index_url): return NO_MATCH_SENTINEL parts = list(map( urllib.parse.unquote, link[len(self.index_url):].split('/') )) if len(parts) != 2 or '#' in parts[1]: return NO_MATCH_SENTINEL # it's a package page, sanitize and index it pkg = safe_name(parts[0]) ver = safe_version(parts[1]) self.package_pages.setdefault(pkg.lower(), {})[link] = True return to_filename(pkg), to_filename(ver) def process_index(self, url, page): """Process the contents of a PyPI page""" # process an index page into the package-page index for match in HREF.finditer(page): try: self._scan(urllib.parse.urljoin(url, htmldecode(match.group(1)))) except ValueError: pass pkg, ver = self._scan(url) # ensure this page is in the page index if not pkg: return "" # no sense double-scanning non-package pages # process individual package page for new_url in find_external_links(url, page): # Process the found URL base, frag = egg_info_for_url(new_url) if base.endswith('.py') and not frag: if ver: new_url += '#egg=%s-%s' % (pkg, ver) else: self.need_version_info(url) self.scan_url(new_url) return PYPI_MD5.sub( lambda m: '%s' % m.group(1, 3, 2), page ) def need_version_info(self, url): self.scan_all( "Page at %s links to .py file(s) without version info; an index " "scan is required.", url ) def scan_all(self, msg=None, *args): if self.index_url not in self.fetched_urls: if msg: self.warn(msg, *args) self.info( "Scanning index of all packages (this may take a while)" ) self.scan_url(self.index_url) def find_packages(self, requirement): self.scan_url(self.index_url + requirement.unsafe_name + '/') if not self.package_pages.get(requirement.key): # Fall back to safe version of the name self.scan_url(self.index_url + requirement.project_name + '/') if not self.package_pages.get(requirement.key): # We couldn't find the target package, so search the index page too self.not_found_in_index(requirement) for url in list(self.package_pages.get(requirement.key, ())): # scan each page that might be related to the desired package self.scan_url(url) def obtain(self, requirement, installer=None): self.prescan() self.find_packages(requirement) for dist in self[requirement.key]: if dist in requirement: return dist self.debug("%s does not match %s", requirement, dist) return super(PackageIndex, self).obtain(requirement, installer) def check_hash(self, checker, filename, tfp): """ checker is a ContentChecker """ checker.report( self.debug, "Validating %%s checksum for %s" % filename) if not checker.is_valid(): tfp.close() os.unlink(filename) raise DistutilsError( "%s validation failed for %s; " "possible download problem?" % (checker.hash.name, os.path.basename(filename)) ) def add_find_links(self, urls): """Add `urls` to the list that will be prescanned for searches""" for url in urls: if ( self.to_scan is None # if we have already "gone online" or not URL_SCHEME(url) # or it's a local file/directory or url.startswith('file:') or list(distros_for_url(url)) # or a direct package link ): # then go ahead and process it now self.scan_url(url) else: # otherwise, defer retrieval till later self.to_scan.append(url) def prescan(self): """Scan urls scheduled for prescanning (e.g. --find-links)""" if self.to_scan: list(map(self.scan_url, self.to_scan)) self.to_scan = None # from now on, go ahead and process immediately def not_found_in_index(self, requirement): if self[requirement.key]: # we've seen at least one distro meth, msg = self.info, "Couldn't retrieve index page for %r" else: # no distros seen for this name, might be misspelled meth, msg = ( self.warn, "Couldn't find index page for %r (maybe misspelled?)") meth(msg, requirement.unsafe_name) self.scan_all() def download(self, spec, tmpdir): """Locate and/or download `spec` to `tmpdir`, returning a local path `spec` may be a ``Requirement`` object, or a string containing a URL, an existing local filename, or a project/version requirement spec (i.e. the string form of a ``Requirement`` object). If it is the URL of a .py file with an unambiguous ``#egg=name-version`` tag (i.e., one that escapes ``-`` as ``_`` throughout), a trivial ``setup.py`` is automatically created alongside the downloaded file. If `spec` is a ``Requirement`` object or a string containing a project/version requirement spec, this method returns the location of a matching distribution (possibly after downloading it to `tmpdir`). If `spec` is a locally existing file or directory name, it is simply returned unchanged. If `spec` is a URL, it is downloaded to a subpath of `tmpdir`, and the local filename is returned. Various errors may be raised if a problem occurs during downloading. """ if not isinstance(spec, Requirement): scheme = URL_SCHEME(spec) if scheme: # It's a url, download it to tmpdir found = self._download_url(scheme.group(1), spec, tmpdir) base, fragment = egg_info_for_url(spec) if base.endswith('.py'): found = self.gen_setup(found, fragment, tmpdir) return found elif os.path.exists(spec): # Existing file or directory, just return it return spec else: spec = parse_requirement_arg(spec) return getattr(self.fetch_distribution(spec, tmpdir), 'location', None) def fetch_distribution( # noqa: C901 # is too complex (14) # FIXME self, requirement, tmpdir, force_scan=False, source=False, develop_ok=False, local_index=None): """Obtain a distribution suitable for fulfilling `requirement` `requirement` must be a ``pkg_resources.Requirement`` instance. If necessary, or if the `force_scan` flag is set, the requirement is searched for in the (online) package index as well as the locally installed packages. If a distribution matching `requirement` is found, the returned distribution's ``location`` is the value you would have gotten from calling the ``download()`` method with the matching distribution's URL or filename. If no matching distribution is found, ``None`` is returned. If the `source` flag is set, only source distributions and source checkout links will be considered. Unless the `develop_ok` flag is set, development and system eggs (i.e., those using the ``.egg-info`` format) will be ignored. """ # process a Requirement self.info("Searching for %s", requirement) skipped = {} dist = None def find(req, env=None): if env is None: env = self # Find a matching distribution; may be called more than once for dist in env[req.key]: if dist.precedence == DEVELOP_DIST and not develop_ok: if dist not in skipped: self.warn( "Skipping development or system egg: %s", dist, ) skipped[dist] = 1 continue test = ( dist in req and (dist.precedence <= SOURCE_DIST or not source) ) if test: loc = self.download(dist.location, tmpdir) dist.download_location = loc if os.path.exists(dist.download_location): return dist if force_scan: self.prescan() self.find_packages(requirement) dist = find(requirement) if not dist and local_index is not None: dist = find(requirement, local_index) if dist is None: if self.to_scan is not None: self.prescan() dist = find(requirement) if dist is None and not force_scan: self.find_packages(requirement) dist = find(requirement) if dist is None: self.warn( "No local packages or working download links found for %s%s", (source and "a source distribution of " or ""), requirement, ) else: self.info("Best match: %s", dist) return dist.clone(location=dist.download_location) def fetch(self, requirement, tmpdir, force_scan=False, source=False): """Obtain a file suitable for fulfilling `requirement` DEPRECATED; use the ``fetch_distribution()`` method now instead. For backward compatibility, this routine is identical but returns the ``location`` of the downloaded distribution instead of a distribution object. """ dist = self.fetch_distribution(requirement, tmpdir, force_scan, source) if dist is not None: return dist.location return None def gen_setup(self, filename, fragment, tmpdir): match = EGG_FRAGMENT.match(fragment) dists = match and [ d for d in interpret_distro_name(filename, match.group(1), None) if d.version ] or [] if len(dists) == 1: # unambiguous ``#egg`` fragment basename = os.path.basename(filename) # Make sure the file has been downloaded to the temp dir. if os.path.dirname(filename) != tmpdir: dst = os.path.join(tmpdir, basename) from setuptools.command.easy_install import samefile if not samefile(filename, dst): shutil.copy2(filename, dst) filename = dst with open(os.path.join(tmpdir, 'setup.py'), 'w') as file: file.write( "from setuptools import setup\n" "setup(name=%r, version=%r, py_modules=[%r])\n" % ( dists[0].project_name, dists[0].version, os.path.splitext(basename)[0] ) ) return filename elif match: raise DistutilsError( "Can't unambiguously interpret project/version identifier %r; " "any dashes in the name or version should be escaped using " "underscores. %r" % (fragment, dists) ) else: raise DistutilsError( "Can't process plain .py files without an '#egg=name-version'" " suffix to enable automatic setup script generation." ) dl_blocksize = 8192 def _download_to(self, url, filename): self.info("Downloading %s", url) # Download the file fp = None try: checker = HashChecker.from_url(url) fp = self.open_url(url) if isinstance(fp, urllib.error.HTTPError): raise DistutilsError( "Can't download %s: %s %s" % (url, fp.code, fp.msg) ) headers = fp.info() blocknum = 0 bs = self.dl_blocksize size = -1 if "content-length" in headers: # Some servers return multiple Content-Length headers :( sizes = headers.get_all('Content-Length') size = max(map(int, sizes)) self.reporthook(url, filename, blocknum, bs, size) with open(filename, 'wb') as tfp: while True: block = fp.read(bs) if block: checker.feed(block) tfp.write(block) blocknum += 1 self.reporthook(url, filename, blocknum, bs, size) else: break self.check_hash(checker, filename, tfp) return headers finally: if fp: fp.close() def reporthook(self, url, filename, blocknum, blksize, size): pass # no-op # FIXME: def open_url(self, url, warning=None): # noqa: C901 # is too complex (12) if url.startswith('file:'): return local_open(url) try: return open_with_auth(url, self.opener) except (ValueError, http.client.InvalidURL) as v: msg = ' '.join([str(arg) for arg in v.args]) if warning: self.warn(warning, msg) else: raise DistutilsError('%s %s' % (url, msg)) from v except urllib.error.HTTPError as v: return v except urllib.error.URLError as v: if warning: self.warn(warning, v.reason) else: raise DistutilsError("Download error for %s: %s" % (url, v.reason)) from v except http.client.BadStatusLine as v: if warning: self.warn(warning, v.line) else: raise DistutilsError( '%s returned a bad status line. The server might be ' 'down, %s' % (url, v.line) ) from v except (http.client.HTTPException, socket.error) as v: if warning: self.warn(warning, v) else: raise DistutilsError("Download error for %s: %s" % (url, v)) from v def _download_url(self, scheme, url, tmpdir): # Determine download filename # name, fragment = egg_info_for_url(url) if name: while '..' in name: name = name.replace('..', '.').replace('\\', '_') else: name = "__downloaded__" # default if URL has no path contents if name.endswith('.egg.zip'): name = name[:-4] # strip the extra .zip before download filename = os.path.join(tmpdir, name) # Download the file # if scheme == 'svn' or scheme.startswith('svn+'): return self._download_svn(url, filename) elif scheme == 'git' or scheme.startswith('git+'): return self._download_git(url, filename) elif scheme.startswith('hg+'): return self._download_hg(url, filename) elif scheme == 'file': return urllib.request.url2pathname(urllib.parse.urlparse(url)[2]) else: self.url_ok(url, True) # raises error if not allowed return self._attempt_download(url, filename) def scan_url(self, url): self.process_url(url, True) def _attempt_download(self, url, filename): headers = self._download_to(url, filename) if 'html' in headers.get('content-type', '').lower(): return self._download_html(url, headers, filename) else: return filename def _download_html(self, url, headers, filename): file = open(filename) for line in file: if line.strip(): # Check for a subversion index page if re.search(r'([^- ]+ - )?Revision \d+:', line): # it's a subversion index page: file.close() os.unlink(filename) return self._download_svn(url, filename) break # not an index page file.close() os.unlink(filename) raise DistutilsError("Unexpected HTML page found at " + url) def _download_svn(self, url, filename): warnings.warn("SVN download support is deprecated", UserWarning) url = url.split('#', 1)[0] # remove any fragment for svn's sake creds = '' if url.lower().startswith('svn:') and '@' in url: scheme, netloc, path, p, q, f = urllib.parse.urlparse(url) if not netloc and path.startswith('//') and '/' in path[2:]: netloc, path = path[2:].split('/', 1) auth, host = _splituser(netloc) if auth: if ':' in auth: user, pw = auth.split(':', 1) creds = " --username=%s --password=%s" % (user, pw) else: creds = " --username=" + auth netloc = host parts = scheme, netloc, url, p, q, f url = urllib.parse.urlunparse(parts) self.info("Doing subversion checkout from %s to %s", url, filename) os.system("svn checkout%s -q %s %s" % (creds, url, filename)) return filename @staticmethod def _vcs_split_rev_from_url(url, pop_prefix=False): scheme, netloc, path, query, frag = urllib.parse.urlsplit(url) scheme = scheme.split('+', 1)[-1] # Some fragment identification fails path = path.split('#', 1)[0] rev = None if '@' in path: path, rev = path.rsplit('@', 1) # Also, discard fragment url = urllib.parse.urlunsplit((scheme, netloc, path, query, '')) return url, rev def _download_git(self, url, filename): filename = filename.split('#', 1)[0] url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) self.info("Doing git clone from %s to %s", url, filename) os.system("git clone --quiet %s %s" % (url, filename)) if rev is not None: self.info("Checking out %s", rev) os.system("git -C %s checkout --quiet %s" % ( filename, rev, )) return filename def _download_hg(self, url, filename): filename = filename.split('#', 1)[0] url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) self.info("Doing hg clone from %s to %s", url, filename) os.system("hg clone --quiet %s %s" % (url, filename)) if rev is not None: self.info("Updating to %s", rev) os.system("hg --cwd %s up -C -r %s -q" % ( filename, rev, )) return filename def debug(self, msg, *args): log.debug(msg, *args) def info(self, msg, *args): log.info(msg, *args) def warn(self, msg, *args): log.warn(msg, *args) # This pattern matches a character entity reference (a decimal numeric # references, a hexadecimal numeric reference, or a named reference). entity_sub = re.compile(r'&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?').sub def decode_entity(match): what = match.group(0) return html.unescape(what) def htmldecode(text): """ Decode HTML entities in the given text. >>> htmldecode( ... 'https://../package_name-0.1.2.tar.gz' ... '?tokena=A&tokenb=B">package_name-0.1.2.tar.gz') 'https://../package_name-0.1.2.tar.gz?tokena=A&tokenb=B">package_name-0.1.2.tar.gz' """ return entity_sub(decode_entity, text) def socket_timeout(timeout=15): def _socket_timeout(func): def _socket_timeout(*args, **kwargs): old_timeout = socket.getdefaulttimeout() socket.setdefaulttimeout(timeout) try: return func(*args, **kwargs) finally: socket.setdefaulttimeout(old_timeout) return _socket_timeout return _socket_timeout def _encode_auth(auth): """ Encode auth from a URL suitable for an HTTP header. >>> str(_encode_auth('username%3Apassword')) 'dXNlcm5hbWU6cGFzc3dvcmQ=' Long auth strings should not cause a newline to be inserted. >>> long_auth = 'username:' + 'password'*10 >>> chr(10) in str(_encode_auth(long_auth)) False """ auth_s = urllib.parse.unquote(auth) # convert to bytes auth_bytes = auth_s.encode() encoded_bytes = base64.b64encode(auth_bytes) # convert back to a string encoded = encoded_bytes.decode() # strip the trailing carriage return return encoded.replace('\n', '') class Credential: """ A username/password pair. Use like a namedtuple. """ def __init__(self, username, password): self.username = username self.password = password def __iter__(self): yield self.username yield self.password def __str__(self): return '%(username)s:%(password)s' % vars(self) class PyPIConfig(configparser.RawConfigParser): def __init__(self): """ Load from ~/.pypirc """ defaults = dict.fromkeys(['username', 'password', 'repository'], '') configparser.RawConfigParser.__init__(self, defaults) rc = os.path.join(os.path.expanduser('~'), '.pypirc') if os.path.exists(rc): self.read(rc) @property def creds_by_repository(self): sections_with_repositories = [ section for section in self.sections() if self.get(section, 'repository').strip() ] return dict(map(self._get_repo_cred, sections_with_repositories)) def _get_repo_cred(self, section): repo = self.get(section, 'repository').strip() return repo, Credential( self.get(section, 'username').strip(), self.get(section, 'password').strip(), ) def find_credential(self, url): """ If the URL indicated appears to be a repository defined in this config, return the credential for that repository. """ for repository, cred in self.creds_by_repository.items(): if url.startswith(repository): return cred def open_with_auth(url, opener=urllib.request.urlopen): """Open a urllib2 request, handling HTTP authentication""" parsed = urllib.parse.urlparse(url) scheme, netloc, path, params, query, frag = parsed # Double scheme does not raise on macOS as revealed by a # failing test. We would expect "nonnumeric port". Refs #20. if netloc.endswith(':'): raise http.client.InvalidURL("nonnumeric port: ''") if scheme in ('http', 'https'): auth, address = _splituser(netloc) else: auth = None if not auth: cred = PyPIConfig().find_credential(url) if cred: auth = str(cred) info = cred.username, url log.info('Authenticating as %s for %s (from .pypirc)', *info) if auth: auth = "Basic " + _encode_auth(auth) parts = scheme, address, path, params, query, frag new_url = urllib.parse.urlunparse(parts) request = urllib.request.Request(new_url) request.add_header("Authorization", auth) else: request = urllib.request.Request(url) request.add_header('User-Agent', user_agent) fp = opener(request) if auth: # Put authentication info back into request URL if same host, # so that links found on the page will work s2, h2, path2, param2, query2, frag2 = urllib.parse.urlparse(fp.url) if s2 == scheme and h2 == address: parts = s2, netloc, path2, param2, query2, frag2 fp.url = urllib.parse.urlunparse(parts) return fp # copy of urllib.parse._splituser from Python 3.8 def _splituser(host): """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" user, delim, host = host.rpartition('@') return (user if delim else None), host # adding a timeout to avoid freezing package_index open_with_auth = socket_timeout(_SOCKET_TIMEOUT)(open_with_auth) def fix_sf_url(url): return url # backward compatibility def local_open(url): """Read a local path, with special support for directories""" scheme, server, path, param, query, frag = urllib.parse.urlparse(url) filename = urllib.request.url2pathname(path) if os.path.isfile(filename): return urllib.request.urlopen(url) elif path.endswith('/') and os.path.isdir(filename): files = [] for f in os.listdir(filename): filepath = os.path.join(filename, f) if f == 'index.html': with open(filepath, 'r') as fp: body = fp.read() break elif os.path.isdir(filepath): f += '/' files.append('<a href="{name}">{name}</a>'.format(name=f)) else: tmpl = ( "<html><head><title>{url}" "{files}") body = tmpl.format(url=url, files='\n'.join(files)) status, message = 200, "OK" else: status, message, body = 404, "Path not found", "Not found" headers = {'content-type': 'text/html'} body_stream = io.StringIO(body) return urllib.error.HTTPError(url, status, message, headers, body_stream) PKH]+Jε/python3.10/site-packages/setuptools/dep_util.pynu[from distutils.dep_util import newer_group # yes, this is was almost entirely copy-pasted from # 'newer_pairwise()', this is just another convenience # function. def newer_pairwise_group(sources_groups, targets): """Walk both arguments in parallel, testing if each source group is newer than its corresponding target. Returns a pair of lists (sources_groups, targets) where sources is newer than target, according to the semantics of 'newer_group()'. """ if len(sources_groups) != len(targets): raise ValueError( "'sources_group' and 'targets' must be the same length") # build a pair of lists (sources_groups, targets) where source is newer n_sources = [] n_targets = [] for i in range(len(sources_groups)): if newer_group(sources_groups[i], targets[i]): n_sources.append(sources_groups[i]) n_targets.append(targets[i]) return n_sources, n_targets PKH]_ 0python3.10/site-packages/setuptools/installer.pynu[import glob import os import subprocess import sys import tempfile from distutils import log from distutils.errors import DistutilsError import pkg_resources from setuptools.wheel import Wheel def _fixup_find_links(find_links): """Ensure find-links option end-up being a list of strings.""" if isinstance(find_links, str): return find_links.split() assert isinstance(find_links, (tuple, list)) return find_links def fetch_build_egg(dist, req): # noqa: C901 # is too complex (16) # FIXME """Fetch an egg needed for building. Use pip/wheel to fetch/build a wheel.""" # Warn if wheel is not available try: pkg_resources.get_distribution('wheel') except pkg_resources.DistributionNotFound: dist.announce('WARNING: The wheel package is not available.', log.WARN) # Ignore environment markers; if supplied, it is required. req = strip_marker(req) # Take easy_install options into account, but do not override relevant # pip environment variables (like PIP_INDEX_URL or PIP_QUIET); they'll # take precedence. opts = dist.get_option_dict('easy_install') if 'allow_hosts' in opts: raise DistutilsError('the `allow-hosts` option is not supported ' 'when using pip to install requirements.') quiet = 'PIP_QUIET' not in os.environ and 'PIP_VERBOSE' not in os.environ if 'PIP_INDEX_URL' in os.environ: index_url = None elif 'index_url' in opts: index_url = opts['index_url'][1] else: index_url = None find_links = ( _fixup_find_links(opts['find_links'][1])[:] if 'find_links' in opts else [] ) if dist.dependency_links: find_links.extend(dist.dependency_links) eggs_dir = os.path.realpath(dist.get_egg_cache_dir()) environment = pkg_resources.Environment() for egg_dist in pkg_resources.find_distributions(eggs_dir): if egg_dist in req and environment.can_add(egg_dist): return egg_dist with tempfile.TemporaryDirectory() as tmpdir: cmd = [ sys.executable, '-m', 'pip', '--disable-pip-version-check', 'wheel', '--no-deps', '-w', tmpdir, ] if quiet: cmd.append('--quiet') if index_url is not None: cmd.extend(('--index-url', index_url)) for link in find_links or []: cmd.extend(('--find-links', link)) # If requirement is a PEP 508 direct URL, directly pass # the URL to pip, as `req @ url` does not work on the # command line. cmd.append(req.url or str(req)) try: subprocess.check_call(cmd) except subprocess.CalledProcessError as e: raise DistutilsError(str(e)) from e wheel = Wheel(glob.glob(os.path.join(tmpdir, '*.whl'))[0]) dist_location = os.path.join(eggs_dir, wheel.egg_name()) wheel.install_as_egg(dist_location) dist_metadata = pkg_resources.PathMetadata( dist_location, os.path.join(dist_location, 'EGG-INFO')) dist = pkg_resources.Distribution.from_filename( dist_location, metadata=dist_metadata) return dist def strip_marker(req): """ Return a new requirement without the environment marker to avoid calling pip with something like `babel; extra == "i18n"`, which would always be ignored. """ # create a copy to avoid mutating the input req = pkg_resources.Requirement.parse(str(req)) req.marker = None return req PKH]l< SZSZ-python3.10/site-packages/setuptools/config.pynu[import ast import io import os import sys import warnings import functools import importlib from collections import defaultdict from functools import partial from functools import wraps from glob import iglob import contextlib from distutils.errors import DistutilsOptionError, DistutilsFileError from setuptools.extern.packaging.version import LegacyVersion, parse from setuptools.extern.packaging.specifiers import SpecifierSet class StaticModule: """ Attempt to load the module by the name """ def __init__(self, name): spec = importlib.util.find_spec(name) with open(spec.origin) as strm: src = strm.read() module = ast.parse(src) vars(self).update(locals()) del self.self def __getattr__(self, attr): try: return next( ast.literal_eval(statement.value) for statement in self.module.body if isinstance(statement, ast.Assign) for target in statement.targets if isinstance(target, ast.Name) and target.id == attr ) except Exception as e: raise AttributeError( "{self.name} has no attribute {attr}".format(**locals()) ) from e @contextlib.contextmanager def patch_path(path): """ Add path to front of sys.path for the duration of the context. """ try: sys.path.insert(0, path) yield finally: sys.path.remove(path) def read_configuration(filepath, find_others=False, ignore_option_errors=False): """Read given configuration file and returns options from it as a dict. :param str|unicode filepath: Path to configuration file to get options from. :param bool find_others: Whether to search for other configuration files which could be on in various places. :param bool ignore_option_errors: Whether to silently ignore options, values of which could not be resolved (e.g. due to exceptions in directives such as file:, attr:, etc.). If False exceptions are propagated as expected. :rtype: dict """ from setuptools.dist import Distribution, _Distribution filepath = os.path.abspath(filepath) if not os.path.isfile(filepath): raise DistutilsFileError('Configuration file %s does not exist.' % filepath) current_directory = os.getcwd() os.chdir(os.path.dirname(filepath)) try: dist = Distribution() filenames = dist.find_config_files() if find_others else [] if filepath not in filenames: filenames.append(filepath) _Distribution.parse_config_files(dist, filenames=filenames) handlers = parse_configuration( dist, dist.command_options, ignore_option_errors=ignore_option_errors ) finally: os.chdir(current_directory) return configuration_to_dict(handlers) def _get_option(target_obj, key): """ Given a target object and option key, get that option from the target object, either through a get_{key} method or from an attribute directly. """ getter_name = 'get_{key}'.format(**locals()) by_attribute = functools.partial(getattr, target_obj, key) getter = getattr(target_obj, getter_name, by_attribute) return getter() def configuration_to_dict(handlers): """Returns configuration data gathered by given handlers as a dict. :param list[ConfigHandler] handlers: Handlers list, usually from parse_configuration() :rtype: dict """ config_dict = defaultdict(dict) for handler in handlers: for option in handler.set_options: value = _get_option(handler.target_obj, option) config_dict[handler.section_prefix][option] = value return config_dict def parse_configuration(distribution, command_options, ignore_option_errors=False): """Performs additional parsing of configuration options for a distribution. Returns a list of used option handlers. :param Distribution distribution: :param dict command_options: :param bool ignore_option_errors: Whether to silently ignore options, values of which could not be resolved (e.g. due to exceptions in directives such as file:, attr:, etc.). If False exceptions are propagated as expected. :rtype: list """ options = ConfigOptionsHandler(distribution, command_options, ignore_option_errors) options.parse() meta = ConfigMetadataHandler( distribution.metadata, command_options, ignore_option_errors, distribution.package_dir, ) meta.parse() return meta, options class ConfigHandler: """Handles metadata supplied in configuration files.""" section_prefix = None """Prefix for config sections handled by this handler. Must be provided by class heirs. """ aliases = {} """Options aliases. For compatibility with various packages. E.g.: d2to1 and pbr. Note: `-` in keys is replaced with `_` by config parser. """ def __init__(self, target_obj, options, ignore_option_errors=False): sections = {} section_prefix = self.section_prefix for section_name, section_options in options.items(): if not section_name.startswith(section_prefix): continue section_name = section_name.replace(section_prefix, '').strip('.') sections[section_name] = section_options self.ignore_option_errors = ignore_option_errors self.target_obj = target_obj self.sections = sections self.set_options = [] @property def parsers(self): """Metadata item name to parser function mapping.""" raise NotImplementedError( '%s must provide .parsers property' % self.__class__.__name__ ) def __setitem__(self, option_name, value): unknown = tuple() target_obj = self.target_obj # Translate alias into real name. option_name = self.aliases.get(option_name, option_name) current_value = getattr(target_obj, option_name, unknown) if current_value is unknown: raise KeyError(option_name) if current_value: # Already inhabited. Skipping. return skip_option = False parser = self.parsers.get(option_name) if parser: try: value = parser(value) except Exception: skip_option = True if not self.ignore_option_errors: raise if skip_option: return setter = getattr(target_obj, 'set_%s' % option_name, None) if setter is None: setattr(target_obj, option_name, value) else: setter(value) self.set_options.append(option_name) @classmethod def _parse_list(cls, value, separator=','): """Represents value as a list. Value is split either by separator (defaults to comma) or by lines. :param value: :param separator: List items separator character. :rtype: list """ if isinstance(value, list): # _get_parser_compound case return value if '\n' in value: value = value.splitlines() else: value = value.split(separator) return [chunk.strip() for chunk in value if chunk.strip()] @classmethod def _parse_list_glob(cls, value, separator=','): """Equivalent to _parse_list() but expands any glob patterns using glob(). However, unlike with glob() calls, the results remain relative paths. :param value: :param separator: List items separator character. :rtype: list """ glob_characters = ('*', '?', '[', ']', '{', '}') values = cls._parse_list(value, separator=separator) expanded_values = [] for value in values: # Has globby characters? if any(char in value for char in glob_characters): # then expand the glob pattern while keeping paths *relative*: expanded_values.extend(sorted( os.path.relpath(path, os.getcwd()) for path in iglob(os.path.abspath(value)))) else: # take the value as-is: expanded_values.append(value) return expanded_values @classmethod def _parse_dict(cls, value): """Represents value as a dict. :param value: :rtype: dict """ separator = '=' result = {} for line in cls._parse_list(value): key, sep, val = line.partition(separator) if sep != separator: raise DistutilsOptionError( 'Unable to parse option value to dict: %s' % value ) result[key.strip()] = val.strip() return result @classmethod def _parse_bool(cls, value): """Represents value as boolean. :param value: :rtype: bool """ value = value.lower() return value in ('1', 'true', 'yes') @classmethod def _exclude_files_parser(cls, key): """Returns a parser function to make sure field inputs are not files. Parses a value after getting the key so error messages are more informative. :param key: :rtype: callable """ def parser(value): exclude_directive = 'file:' if value.startswith(exclude_directive): raise ValueError( 'Only strings are accepted for the {0} field, ' 'files are not accepted'.format(key) ) return value return parser @classmethod def _parse_file(cls, value): """Represents value as a string, allowing including text from nearest files using `file:` directive. Directive is sandboxed and won't reach anything outside directory with setup.py. Examples: file: README.rst, CHANGELOG.md, src/file.txt :param str value: :rtype: str """ include_directive = 'file:' if not isinstance(value, str): return value if not value.startswith(include_directive): return value spec = value[len(include_directive) :] filepaths = (os.path.abspath(path.strip()) for path in spec.split(',')) return '\n'.join( cls._read_file(path) for path in filepaths if (cls._assert_local(path) or True) and os.path.isfile(path) ) @staticmethod def _assert_local(filepath): if not filepath.startswith(os.getcwd()): raise DistutilsOptionError('`file:` directive can not access %s' % filepath) @staticmethod def _read_file(filepath): with io.open(filepath, encoding='utf-8') as f: return f.read() @classmethod def _parse_attr(cls, value, package_dir=None): """Represents value as a module attribute. Examples: attr: package.attr attr: package.module.attr :param str value: :rtype: str """ attr_directive = 'attr:' if not value.startswith(attr_directive): return value attrs_path = value.replace(attr_directive, '').strip().split('.') attr_name = attrs_path.pop() module_name = '.'.join(attrs_path) module_name = module_name or '__init__' parent_path = os.getcwd() if package_dir: if attrs_path[0] in package_dir: # A custom path was specified for the module we want to import custom_path = package_dir[attrs_path[0]] parts = custom_path.rsplit('/', 1) if len(parts) > 1: parent_path = os.path.join(os.getcwd(), parts[0]) module_name = parts[1] else: module_name = custom_path elif '' in package_dir: # A custom parent directory was specified for all root modules parent_path = os.path.join(os.getcwd(), package_dir['']) with patch_path(parent_path): try: # attempt to load value statically return getattr(StaticModule(module_name), attr_name) except Exception: # fallback to simple import module = importlib.import_module(module_name) return getattr(module, attr_name) @classmethod def _get_parser_compound(cls, *parse_methods): """Returns parser function to represents value as a list. Parses a value applying given methods one after another. :param parse_methods: :rtype: callable """ def parse(value): parsed = value for method in parse_methods: parsed = method(parsed) return parsed return parse @classmethod def _parse_section_to_dict(cls, section_options, values_parser=None): """Parses section options into a dictionary. Optionally applies a given parser to values. :param dict section_options: :param callable values_parser: :rtype: dict """ value = {} values_parser = values_parser or (lambda val: val) for key, (_, val) in section_options.items(): value[key] = values_parser(val) return value def parse_section(self, section_options): """Parses configuration file section. :param dict section_options: """ for (name, (_, value)) in section_options.items(): try: self[name] = value except KeyError: pass # Keep silent for a new option may appear anytime. def parse(self): """Parses configuration file items from one or more related sections. """ for section_name, section_options in self.sections.items(): method_postfix = '' if section_name: # [section.option] variant method_postfix = '_%s' % section_name section_parser_method = getattr( self, # Dots in section names are translated into dunderscores. ('parse_section%s' % method_postfix).replace('.', '__'), None, ) if section_parser_method is None: raise DistutilsOptionError( 'Unsupported distribution option section: [%s.%s]' % (self.section_prefix, section_name) ) section_parser_method(section_options) def _deprecated_config_handler(self, func, msg, warning_class): """this function will wrap around parameters that are deprecated :param msg: deprecation message :param warning_class: class of warning exception to be raised :param func: function to be wrapped around """ @wraps(func) def config_handler(*args, **kwargs): warnings.warn(msg, warning_class) return func(*args, **kwargs) return config_handler class ConfigMetadataHandler(ConfigHandler): section_prefix = 'metadata' aliases = { 'home_page': 'url', 'summary': 'description', 'classifier': 'classifiers', 'platform': 'platforms', } strict_mode = False """We need to keep it loose, to be partially compatible with `pbr` and `d2to1` packages which also uses `metadata` section. """ def __init__( self, target_obj, options, ignore_option_errors=False, package_dir=None ): super(ConfigMetadataHandler, self).__init__( target_obj, options, ignore_option_errors ) self.package_dir = package_dir @property def parsers(self): """Metadata item name to parser function mapping.""" parse_list = self._parse_list parse_file = self._parse_file parse_dict = self._parse_dict exclude_files_parser = self._exclude_files_parser return { 'platforms': parse_list, 'keywords': parse_list, 'provides': parse_list, 'requires': self._deprecated_config_handler( parse_list, "The requires parameter is deprecated, please use " "install_requires for runtime dependencies.", DeprecationWarning, ), 'obsoletes': parse_list, 'classifiers': self._get_parser_compound(parse_file, parse_list), 'license': exclude_files_parser('license'), 'license_file': self._deprecated_config_handler( exclude_files_parser('license_file'), "The license_file parameter is deprecated, " "use license_files instead.", DeprecationWarning, ), 'license_files': parse_list, 'description': parse_file, 'long_description': parse_file, 'version': self._parse_version, 'project_urls': parse_dict, } def _parse_version(self, value): """Parses `version` option value. :param value: :rtype: str """ version = self._parse_file(value) if version != value: version = version.strip() # Be strict about versions loaded from file because it's easy to # accidentally include newlines and other unintended content if isinstance(parse(version), LegacyVersion): tmpl = ( 'Version loaded from {value} does not ' 'comply with PEP 440: {version}' ) raise DistutilsOptionError(tmpl.format(**locals())) return version version = self._parse_attr(value, self.package_dir) if callable(version): version = version() if not isinstance(version, str): if hasattr(version, '__iter__'): version = '.'.join(map(str, version)) else: version = '%s' % version return version class ConfigOptionsHandler(ConfigHandler): section_prefix = 'options' @property def parsers(self): """Metadata item name to parser function mapping.""" parse_list = self._parse_list parse_list_semicolon = partial(self._parse_list, separator=';') parse_bool = self._parse_bool parse_dict = self._parse_dict parse_cmdclass = self._parse_cmdclass return { 'zip_safe': parse_bool, 'include_package_data': parse_bool, 'package_dir': parse_dict, 'scripts': parse_list, 'eager_resources': parse_list, 'dependency_links': parse_list, 'namespace_packages': parse_list, 'install_requires': parse_list_semicolon, 'setup_requires': parse_list_semicolon, 'tests_require': parse_list_semicolon, 'packages': self._parse_packages, 'entry_points': self._parse_file, 'py_modules': parse_list, 'python_requires': SpecifierSet, 'cmdclass': parse_cmdclass, } def _parse_cmdclass(self, value): def resolve_class(qualified_class_name): idx = qualified_class_name.rfind('.') class_name = qualified_class_name[idx + 1 :] pkg_name = qualified_class_name[:idx] module = __import__(pkg_name) return getattr(module, class_name) return {k: resolve_class(v) for k, v in self._parse_dict(value).items()} def _parse_packages(self, value): """Parses `packages` option value. :param value: :rtype: list """ find_directives = ['find:', 'find_namespace:'] trimmed_value = value.strip() if trimmed_value not in find_directives: return self._parse_list(value) findns = trimmed_value == find_directives[1] # Read function arguments from a dedicated section. find_kwargs = self.parse_section_packages__find( self.sections.get('packages.find', {}) ) if findns: from setuptools import find_namespace_packages as find_packages else: from setuptools import find_packages return find_packages(**find_kwargs) def parse_section_packages__find(self, section_options): """Parses `packages.find` configuration file section. To be used in conjunction with _parse_packages(). :param dict section_options: """ section_data = self._parse_section_to_dict(section_options, self._parse_list) valid_keys = ['where', 'include', 'exclude'] find_kwargs = dict( [(k, v) for k, v in section_data.items() if k in valid_keys and v] ) where = find_kwargs.get('where') if where is not None: find_kwargs['where'] = where[0] # cast list to single val return find_kwargs def parse_section_entry_points(self, section_options): """Parses `entry_points` configuration file section. :param dict section_options: """ parsed = self._parse_section_to_dict(section_options, self._parse_list) self['entry_points'] = parsed def _parse_package_data(self, section_options): parsed = self._parse_section_to_dict(section_options, self._parse_list) root = parsed.get('*') if root: parsed[''] = root del parsed['*'] return parsed def parse_section_package_data(self, section_options): """Parses `package_data` configuration file section. :param dict section_options: """ self['package_data'] = self._parse_package_data(section_options) def parse_section_exclude_package_data(self, section_options): """Parses `exclude_package_data` configuration file section. :param dict section_options: """ self['exclude_package_data'] = self._parse_package_data(section_options) def parse_section_extras_require(self, section_options): """Parses `extras_require` configuration file section. :param dict section_options: """ parse_list = partial(self._parse_list, separator=';') self['extras_require'] = self._parse_section_to_dict( section_options, parse_list ) def parse_section_data_files(self, section_options): """Parses `data_files` configuration file section. :param dict section_options: """ parsed = self._parse_section_to_dict(section_options, self._parse_list_glob) self['data_files'] = [(k, v) for k, v in parsed.items()] PKH]T+4python3.10/site-packages/setuptools/unicode_utils.pynu[import unicodedata import sys # HFS Plus uses decomposed UTF-8 def decompose(path): if isinstance(path, str): return unicodedata.normalize('NFD', path) try: path = path.decode('utf-8') path = unicodedata.normalize('NFD', path) path = path.encode('utf-8') except UnicodeError: pass # Not UTF-8 return path def filesys_decode(path): """ Ensure that the given path is decoded, NONE when no expected encoding works """ if isinstance(path, str): return path fs_enc = sys.getfilesystemencoding() or 'utf-8' candidates = fs_enc, 'utf-8' for enc in candidates: try: return path.decode(enc) except UnicodeDecodeError: continue def try_encode(string, enc): "turn unicode encoding into a functional routine" try: return string.encode(enc) except UnicodeEncodeError: return None PKH]_/python3.10/site-packages/setuptools/__init__.pynu["""Extensions to the 'distutils' for large or complex distributions""" from fnmatch import fnmatchcase import functools import os import re import warnings import _distutils_hack.override # noqa: F401 import distutils.core from distutils.errors import DistutilsOptionError from distutils.util import convert_path from ._deprecation_warning import SetuptoolsDeprecationWarning import setuptools.version from setuptools.extension import Extension from setuptools.dist import Distribution from setuptools.depends import Require from . import monkey __all__ = [ 'setup', 'Distribution', 'Command', 'Extension', 'Require', 'SetuptoolsDeprecationWarning', 'find_packages', 'find_namespace_packages', ] __version__ = setuptools.version.__version__ bootstrap_install_from = None class PackageFinder: """ Generate a list of all Python packages found within a directory """ @classmethod def find(cls, where='.', exclude=(), include=('*',)): """Return a list all Python packages found within directory 'where' 'where' is the root directory which will be searched for packages. It should be supplied as a "cross-platform" (i.e. URL-style) path; it will be converted to the appropriate local path syntax. 'exclude' is a sequence of package names to exclude; '*' can be used as a wildcard in the names, such that 'foo.*' will exclude all subpackages of 'foo' (but not 'foo' itself). 'include' is a sequence of package names to include. If it's specified, only the named packages will be included. If it's not specified, all found packages will be included. 'include' can contain shell style wildcard patterns just like 'exclude'. """ return list( cls._find_packages_iter( convert_path(where), cls._build_filter('ez_setup', '*__pycache__', *exclude), cls._build_filter(*include), ) ) @classmethod def _find_packages_iter(cls, where, exclude, include): """ All the packages found in 'where' that pass the 'include' filter, but not the 'exclude' filter. """ for root, dirs, files in os.walk(where, followlinks=True): # Copy dirs to iterate over it, then empty dirs. all_dirs = dirs[:] dirs[:] = [] for dir in all_dirs: full_path = os.path.join(root, dir) rel_path = os.path.relpath(full_path, where) package = rel_path.replace(os.path.sep, '.') # Skip directory trees that are not valid packages if '.' in dir or not cls._looks_like_package(full_path): continue # Should this package be included? if include(package) and not exclude(package): yield package # Keep searching subdirectories, as there may be more packages # down there, even if the parent was excluded. dirs.append(dir) @staticmethod def _looks_like_package(path): """Does a directory look like a package?""" return os.path.isfile(os.path.join(path, '__init__.py')) @staticmethod def _build_filter(*patterns): """ Given a list of patterns, return a callable that will be true only if the input matches at least one of the patterns. """ return lambda name: any(fnmatchcase(name, pat=pat) for pat in patterns) class PEP420PackageFinder(PackageFinder): @staticmethod def _looks_like_package(path): return True find_packages = PackageFinder.find find_namespace_packages = PEP420PackageFinder.find def _install_setup_requires(attrs): # Note: do not use `setuptools.Distribution` directly, as # our PEP 517 backend patch `distutils.core.Distribution`. class MinimalDistribution(distutils.core.Distribution): """ A minimal version of a distribution for supporting the fetch_build_eggs interface. """ def __init__(self, attrs): _incl = 'dependency_links', 'setup_requires' filtered = {k: attrs[k] for k in set(_incl) & set(attrs)} distutils.core.Distribution.__init__(self, filtered) def finalize_options(self): """ Disable finalize_options to avoid building the working set. Ref #2158. """ dist = MinimalDistribution(attrs) # Honor setup.cfg's options. dist.parse_config_files(ignore_option_errors=True) if dist.setup_requires: warnings.warn( "setup_requires is deprecated. Supply build " "dependencies using PEP 517 pyproject.toml build-requires.", SetuptoolsDeprecationWarning, ) dist.fetch_build_eggs(dist.setup_requires) def setup(**attrs): # Make sure we have any requirements needed to interpret 'attrs'. _install_setup_requires(attrs) return distutils.core.setup(**attrs) setup.__doc__ = distutils.core.setup.__doc__ _Command = monkey.get_unpatched(distutils.core.Command) class Command(_Command): __doc__ = _Command.__doc__ command_consumes_arguments = False def __init__(self, dist, **kw): """ Construct the command for dist, updating vars(self) with any keyword parameters. """ _Command.__init__(self, dist) vars(self).update(kw) def _ensure_stringlike(self, option, what, default=None): val = getattr(self, option) if val is None: setattr(self, option, default) return default elif not isinstance(val, str): raise DistutilsOptionError( "'%s' must be a %s (got `%s`)" % (option, what, val) ) return val def ensure_string_list(self, option): r"""Ensure that 'option' is a list of strings. If 'option' is currently a string, we split it either on /,\s*/ or /\s+/, so "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become ["foo", "bar", "baz"]. """ val = getattr(self, option) if val is None: return elif isinstance(val, str): setattr(self, option, re.split(r',\s*|\s+', val)) else: if isinstance(val, list): ok = all(isinstance(v, str) for v in val) else: ok = False if not ok: raise DistutilsOptionError( "'%s' must be a list of strings (got %r)" % (option, val) ) def reinitialize_command(self, command, reinit_subcommands=0, **kw): cmd = _Command.reinitialize_command(self, command, reinit_subcommands) vars(cmd).update(kw) return cmd def _find_all_simple(path): """ Find all files under 'path' """ results = ( os.path.join(base, file) for base, dirs, files in os.walk(path, followlinks=True) for file in files ) return filter(os.path.isfile, results) def findall(dir=os.curdir): """ Find all files under 'dir' and return the list of full filenames. Unless dir is '.', return full filenames with dir prepended. """ files = _find_all_simple(dir) if dir == os.curdir: make_rel = functools.partial(os.path.relpath, start=dir) files = map(make_rel, files) return list(files) class sic(str): """Treat this string as-is (https://en.wikipedia.org/wiki/Sic)""" # Apply monkey patches monkey.patch_all() PKH]UU??Spython3.10/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-310.pycnu[o Xai;@szdZddlZddlmZz ddlmZmZWney'ddlmZmZYnwe dZ dZ ddZ Gdd d eeZ dS) z An OrderedSet is a custom MutableSet that remembers its order, so that every entry has an index that can be looked up. Based on a recipe originally posted to ActiveState Recipes by Raymond Hettiger, and released under the MIT license. N)deque) MutableSetSequencez3.1cCs"t|dot|t ot|t S)a  Are we being asked to look up a list of things, instead of a single thing? We check for the `__iter__` attribute so that this can cover types that don't have to be known by this module, such as NumPy arrays. Strings, however, should be considered as atomic values to look up, not iterables. The same goes for tuples, since they are immutable and therefore valid entries. We don't need to check for the Python 2 `unicode` type, because it doesn't have an `__iter__` attribute anyway. __iter__)hasattr isinstancestrtuple)objr /builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/ordered_set.py is_iterables   r c@seZdZdZd;ddZddZddZd d Zd d Zd dZ ddZ ddZ e Z ddZ ddZeZeZddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3d4Zd5d6Z d7d8Z!d9d:Z"dS)< OrderedSetz An OrderedSet is a custom MutableSet that remembers its order, so that every entry has an index that can be looked up. Example: >>> OrderedSet([1, 1, 2, 3, 2]) OrderedSet([1, 2, 3]) NcCs$g|_i|_|dur||O}dSdSN)itemsmap)selfiterabler r r __init__4s  zOrderedSet.__init__cC t|jS)z Returns the number of unique elements in the ordered set Example: >>> len(OrderedSet([])) 0 >>> len(OrderedSet([1, 2])) 2 )lenrrr r r __len__: zOrderedSet.__len__csvt|tr |tkr St|rfdd|DSt|ds$t|tr5j|}t|tr3|S|St d|)aQ Get the item at a given index. If `index` is a slice, you will get back that slice of items, as a new OrderedSet. If `index` is a list or a similar iterable, you'll get a list of items corresponding to those indices. This is similar to NumPy's "fancy indexing". The result is not an OrderedSet because you may ask for duplicate indices, and the number of elements returned should be the number of elements asked for. Example: >>> oset = OrderedSet([1, 2, 3]) >>> oset[1] 2 csg|]}j|qSr )r).0irr r [z*OrderedSet.__getitem__.. __index__z+Don't know how to index an OrderedSet by %r) rslice SLICE_ALLcopyr rrlist __class__ TypeError)rindexresultr rr __getitem__Fs    zOrderedSet.__getitem__cCs ||S)z Return a shallow copy of this object. Example: >>> this = OrderedSet([1, 2, 3]) >>> other = this.copy() >>> this == other True >>> this is other False )r#rr r r r!es zOrderedSet.copycCst|dkrdSt|S)Nrr)rr"rr r r __getstate__ss zOrderedSet.__getstate__cCs$|dkr |gdS||dS)Nr)r)rstater r r __setstate__szOrderedSet.__setstate__cCs ||jvS)z Test if the item is in this ordered set Example: >>> 1 in OrderedSet([1, 3, 2]) True >>> 5 in OrderedSet([1, 3, 2]) False )rrkeyr r r __contains__rzOrderedSet.__contains__cCs0||jvrt|j|j|<|j||j|S)aE Add `key` as an item to this OrderedSet, then return its index. If `key` is already in the OrderedSet, return the index it already had. Example: >>> oset = OrderedSet() >>> oset.append(3) 0 >>> print(oset) OrderedSet([3]) )rrrappendr+r r r adds   zOrderedSet.addcCs>d}z |D]}||}qW|Stytdt|w)a< Update the set with the given iterable sequence, then return the index of the last element inserted. Example: >>> oset = OrderedSet([1, 2, 3]) >>> oset.update([3, 1, 5, 1, 4]) 4 >>> print(oset) OrderedSet([1, 2, 3, 5, 4]) Nz(Argument needs to be an iterable, got %s)r/r$ ValueErrortype)rsequenceZ item_indexitemr r r updates    zOrderedSet.updatecs$t|r fdd|DSj|S)aH Get the index of a given entry, raising an IndexError if it's not present. `key` can be an iterable of entries that is not a string, in which case this returns a list of indices. Example: >>> oset = OrderedSet([1, 2, 3]) >>> oset.index(2) 1 csg|]}|qSr )r%)rsubkeyrr r rrz$OrderedSet.index..)r rr+r rr r%s  zOrderedSet.indexcCs,|jstd|jd}|jd=|j|=|S)z Remove and return the last element from the set. Raises KeyError if the set is empty. Example: >>> oset = OrderedSet([1, 2, 3]) >>> oset.pop() 3 z Set is empty)rKeyErrorr)relemr r r pops   zOrderedSet.popcCsT||vr&|j|}|j|=|j|=|jD]\}}||kr%|d|j|<qdSdS)a Remove an element. Do not raise an exception if absent. The MutableSet mixin uses this to implement the .remove() method, which *does* raise an error when asked to remove a non-existent item. Example: >>> oset = OrderedSet([1, 2, 3]) >>> oset.discard(2) >>> print(oset) OrderedSet([1, 3]) >>> oset.discard(2) >>> print(oset) OrderedSet([1, 3]) N)rr)rr,rkvr r r discards zOrderedSet.discardcCs|jdd=|jdS)z8 Remove all items from this OrderedSet. N)rrclearrr r r r>s zOrderedSet.clearcCr)zb Example: >>> list(iter(OrderedSet([1, 2, 3]))) [1, 2, 3] )iterrrr r r r zOrderedSet.__iter__cCr)zf Example: >>> list(reversed(OrderedSet([1, 2, 3]))) [3, 2, 1] )reversedrrr r r __reversed__ r@zOrderedSet.__reversed__cCs&|s d|jjfSd|jjt|fS)Nz%s()z%s(%r))r#__name__r"rr r r __repr__szOrderedSet.__repr__cCsLt|ttfrt|t|kSzt|}Wn tyYdSwt||kS)a Returns true if the containers have the same items. If `other` is a Sequence, then order is checked, otherwise it is ignored. Example: >>> oset = OrderedSet([1, 3, 2]) >>> oset == [1, 3, 2] True >>> oset == [1, 2, 3] False >>> oset == [2, 3] False >>> oset == OrderedSet([3, 2, 1]) False F)rrrr"setr$)rotherZ other_as_setr r r __eq__s   zOrderedSet.__eq__cGs<t|tr|jnt}ttt|g|}tj|}||S)a Combines all unique items. Each items order is defined by its first appearance. Example: >>> oset = OrderedSet.union(OrderedSet([3, 1, 4, 1, 5]), [1, 3], [2, 0]) >>> print(oset) OrderedSet([3, 1, 4, 5, 2, 0]) >>> oset.union([8, 9]) OrderedSet([3, 1, 4, 5, 2, 0, 8, 9]) >>> oset | {10} OrderedSet([3, 1, 4, 5, 2, 0, 10]) )rrr#rr"itchain from_iterable)rsetsclsZ containersrr r r union6s zOrderedSet.unioncCs ||Sr) intersectionrrFr r r __and__Is zOrderedSet.__and__csNt|tr|jnt}|r!tjtt|fdd|D}||S|}||S)a Returns elements in common between all sets. Order is defined only by the first set. Example: >>> oset = OrderedSet.intersection(OrderedSet([0, 1, 2, 3]), [1, 2, 3]) >>> print(oset) OrderedSet([1, 2, 3]) >>> oset.intersection([2, 4, 5], [1, 2, 3, 4]) OrderedSet([2]) >>> oset.intersection() OrderedSet([1, 2, 3]) c3s|] }|vr|VqdSrr rr3commonr r ^z*OrderedSet.intersection..)rrr#rErNrrrKrLrr rRr rNMszOrderedSet.intersectioncs@|j}|rtjtt|fdd|D}||S|}||S)a Returns all elements that are in this set but not the others. Example: >>> OrderedSet([1, 2, 3]).difference(OrderedSet([2])) OrderedSet([1, 3]) >>> OrderedSet([1, 2, 3]).difference(OrderedSet([2]), OrderedSet([3])) OrderedSet([1]) >>> OrderedSet([1, 2, 3]) - OrderedSet([2]) OrderedSet([1, 3]) >>> OrderedSet([1, 2, 3]).difference() OrderedSet([1, 2, 3]) c3s|] }|vr|VqdSrr rQrFr r rTtrUz(OrderedSet.difference..)r#rErMrrVr rWr differencecszOrderedSet.differencecs*t|tkr dStfdd|DS)a7 Report whether another set contains this set. Example: >>> OrderedSet([1, 2, 3]).issubset({1, 2}) False >>> OrderedSet([1, 2, 3]).issubset({1, 2, 3, 4}) True >>> OrderedSet([1, 2, 3]).issubset({1, 4, 3, 5}) False Fc3|]}|vVqdSrr rQrWr r rTz&OrderedSet.issubset..rallrOr rWr issubsety zOrderedSet.issubsetcs*tt|kr dStfdd|DS)a= Report whether this set contains another set. Example: >>> OrderedSet([1, 2]).issuperset([1, 2, 3]) False >>> OrderedSet([1, 2, 3, 4]).issuperset({1, 2, 3}) True >>> OrderedSet([1, 4, 3, 5]).issuperset({1, 2, 3}) False Fc3rYrr rQrr r rTrZz(OrderedSet.issuperset..r[rOr rr issupersetr^zOrderedSet.issupersetcCs:t|tr|jnt}|||}|||}||S)a Return the symmetric difference of two OrderedSets as a new set. That is, the new set will contain all elements that are in exactly one of the sets. Their order will be preserved, with elements from `self` preceding elements from `other`. Example: >>> this = OrderedSet([1, 4, 3, 5, 7]) >>> other = OrderedSet([9, 7, 1, 3, 2]) >>> this.symmetric_difference(other) OrderedSet([4, 5, 9, 2]) )rrr#rXrM)rrFrLZdiff1Zdiff2r r r symmetric_differences zOrderedSet.symmetric_differencecCs||_ddt|D|_dS)zt Replace the 'items' list of this OrderedSet with a new one, updating self.map accordingly. cSsi|]\}}||qSr r )ridxr3r r r rz,OrderedSet._update_items..N)r enumerater)rrr r r _update_itemsszOrderedSet._update_itemscs:t|D]}t|Oq|fdd|jDdS)a Update this OrderedSet to remove items from one or more other sets. Example: >>> this = OrderedSet([1, 2, 3]) >>> this.difference_update(OrderedSet([2, 4])) >>> print(this) OrderedSet([1, 3]) >>> this = OrderedSet([1, 2, 3, 4, 5]) >>> this.difference_update(OrderedSet([2, 4]), OrderedSet([1, 4, 6])) >>> print(this) OrderedSet([3, 5]) cg|]}|vr|qSr r rQitems_to_remover r rz0OrderedSet.difference_update..NrErdr)rrKrFr rfr difference_updateszOrderedSet.difference_updatecs&t|fdd|jDdS)a^ Update this OrderedSet to keep only items in another set, preserving their order in this set. Example: >>> this = OrderedSet([1, 4, 3, 5, 7]) >>> other = OrderedSet([9, 7, 1, 3, 2]) >>> this.intersection_update(other) >>> print(this) OrderedSet([1, 3, 7]) csg|]}|vr|qSr r rQrWr r rrhz2OrderedSet.intersection_update..NrirOr rWr intersection_updates zOrderedSet.intersection_updatecs<fdd|D}t|fddjD|dS)a Update this OrderedSet to remove items from another set, then add items from the other set that were not present in this set. Example: >>> this = OrderedSet([1, 4, 3, 5, 7]) >>> other = OrderedSet([9, 7, 1, 3, 2]) >>> this.symmetric_difference_update(other) >>> print(this) OrderedSet([4, 5, 9, 2]) crer r rQrr r rrhz:OrderedSet.symmetric_difference_update..crer r rQrfr r rrhNri)rrFZ items_to_addr )rgrr symmetric_difference_updates  z&OrderedSet.symmetric_difference_updater)#rC __module__ __qualname____doc__rrr'r!r(r*r-r/r.r4r%Zget_locZ get_indexerr9r=r>rrBrDrGrMrPrNrXr]r_r`rdrjrkrlr r r r r*sB     r)ro itertoolsrH collectionsrcollections.abcrr ImportErrorrr __version__r rr r r r s  PKH]wAPpython3.10/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-310.pycnu[o Xai@sdS)Nrrr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/__init__.pysPKH] Qpython3.10/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-310.pycnu[o Xaix @s dZdZdZdZddlZddlmZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlmZzddlmZWneySddlmZYnwzdd lmZdd lmZWneywdd l mZdd l mZYnwzdd l mZWneyzdd lmZWn eydZYnwYnwgd Zee jdd Zedd kZ e re j!Z"e#Z$e%Z&e#Z'e(e)e*e+e,ee-e.e/e0e1g Z2n)e j3Z"e4Z5ddZ'gZ2ddl6Z6d7D]Z8z e29e:e6e8Wqe;yYqweGddde?Z@ejAejBZCdZDeDdZEeCeDZFe%dZGdHddejIDZJGdddeKZLGdd d eLZMGd!d"d"eLZNGd#d$d$eNZOGd%d&d&eKZPGd'd(d(e?ZQGd)d*d*e?ZReSeRd+d,ZTd-d.ZUd/d0ZVd1d2ZWd3d4ZXd5d6ZYd7d8ZZ dd:d;Z[Gdd?d?e\Z]Gd@dAdAe]Z^GdBdCdCe]Z_GdDdEdEe]Z`e`Zae`e\_bGdFdGdGe]ZcGdHdIdIe`ZdGdJdKdKecZeGdLdMdMe]ZfGdNdOdOe]ZgGdPdQdQe]ZhGdRdSdSe]ZiGdTdUdUe]ZjGdVdWdWe]ZkGdXdYdYe]ZlGdZd[d[elZmGd\d]d]elZnGd^d_d_elZoGd`dadaelZpGdbdcdcelZqGdddedeelZrGdfdgdgelZsGdhdidie\ZtGdjdkdketZuGdldmdmetZvGdndodoetZwGdpdqdqetZxGdrdsdse\ZyGdtdudueyZzGdvdwdweyZ{GdxdydyeyZ|Gdzd{d{e|Z}Gd|d}d}e|Z~Gd~dde?ZeZGdddeyZGdddeyZGdddeyZGdddeZGdddeyZGdddeZGdddeZGdddeZGdddeZGddde?ZddZdddZdddZddZddZddZddZdddZddZdddZddZddZe^dZendZeodZepdZeqdZegeGdd9dddZehdddZehdddZeeBeBejdddBZeeedeZe`deddee}eeBddZddĄZddƄZddȄZddʄZdd̄ZeddZ eddZ ddЄZdd҄ZddԄZddքZe?e_ddd؄Ze@Ze?e_e?e_edكedڃfdd܄ZeZ eehd݃ddߡZeehdddZeehd݃dehddBdZeeadedZdddefddZdddZedZedZeegeCeFdd\ZZeed7dZehddHeàġddZddZeehdddZ ehddZ ehdɡdZehddZ eehddeBdZ eZ ehddZ ee}egeJddeegde`deoϡdZeeeeBdddZ GdddZeӐd krhedd Zedd ZegeCeFd Zee֐d ddeZeee׃dZؐdeBZee֐d ddeZeeeڃdZeԐdeِdeeېdZeܠݐdejޠݐdejߠݐdejݐdddlZej᠝eejejݐddSdS(a pyparsing module - Classes and methods to define and execute parsing grammars ============================================================================= The pyparsing module is an alternative approach to creating and executing simple grammars, vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you don't need to learn a new syntax for defining grammars or matching expressions - the parsing module provides a library of classes that you use to construct the grammar directly in Python. Here is a program to parse "Hello, World!" (or any greeting of the form C{", !"}), built up using L{Word}, L{Literal}, and L{And} elements (L{'+'} operator gives L{And} expressions, strings are auto-converted to L{Literal} expressions):: from pyparsing import Word, alphas # define grammar of a greeting greet = Word(alphas) + "," + Word(alphas) + "!" hello = "Hello, World!" print (hello, "->", greet.parseString(hello)) The program outputs the following:: Hello, World! -> ['Hello', ',', 'World', '!'] The Python representation of the grammar is quite readable, owing to the self-explanatory class names, and the use of '+', '|' and '^' operators. The L{ParseResults} object returned from L{ParserElement.parseString} can be accessed as a nested list, a dictionary, or an object with named attributes. The pyparsing module handles some of the problems that are typically vexing when writing text parsers: - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) - quoted strings - embedded comments Getting Started - ----------------- Visit the classes L{ParserElement} and L{ParseResults} to see the base classes that most other pyparsing classes inherit from. Use the docstrings for examples of how to: - construct literal match expressions from L{Literal} and L{CaselessLiteral} classes - construct character word-group expressions using the L{Word} class - see how to create repetitive expressions using L{ZeroOrMore} and L{OneOrMore} classes - use L{'+'}, L{'|'}, L{'^'}, and L{'&'} operators to combine simple expressions into more complex ones - associate names with your parsed results using L{ParserElement.setResultsName} - find some helpful expression short-cuts like L{delimitedList} and L{oneOf} - find more useful common expressions in the L{pyparsing_common} namespace class z2.2.1z18 Sep 2018 00:49 UTCz*Paul McGuire N)ref)datetime)RLock)Iterable)MutableMapping) OrderedDict)iAndCaselessKeywordCaselessLiteral CharsNotInCombineDictEachEmpty FollowedByForward GoToColumnGroupKeywordLineEnd LineStartLiteral MatchFirstNoMatchNotAny OneOrMoreOnlyOnceOptionalOrParseBaseExceptionParseElementEnhanceParseExceptionParseExpressionParseFatalException ParseResultsParseSyntaxException ParserElement QuotedStringRecursiveGrammarExceptionRegexSkipTo StringEnd StringStartSuppressTokenTokenConverterWhiteWordWordEnd WordStart ZeroOrMore alphanumsalphas alphas8bit anyCloseTag anyOpenTag cStyleCommentcolcommaSeparatedListcommonHTMLEntity countedArraycppStyleCommentdblQuotedStringdblSlashComment delimitedListdictOfdowncaseTokensemptyhexnums htmlCommentjavaStyleCommentlinelineEnd lineStartlineno makeHTMLTags makeXMLTagsmatchOnlyAtColmatchPreviousExprmatchPreviousLiteral nestedExprnullDebugActionnumsoneOfopAssocoperatorPrecedence printablespunc8bitpythonStyleComment quotedString removeQuotesreplaceHTMLEntity replaceWith restOfLinesglQuotedStringsrange stringEnd stringStarttraceParseAction unicodeString upcaseTokens withAttribute indentedBlockoriginalTextForungroup infixNotation locatedExpr withClass CloseMatchtokenMappyparsing_commoncCs`t|tr|Szt|WSty/t|td}td}|dd| |YSw)aDrop-in replacement for str(obj) that tries to be Unicode friendly. It first tries str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It then < returns the unicode object | encodes it with the default encoding | ... >. xmlcharrefreplacez&#\d+;cSs$dtt|dddddS)Nz\ur)hexinttry/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/pyparsing.py$z_ustr..) isinstanceunicodestrUnicodeEncodeErrorencodesysgetdefaultencodingr)setParseActiontransformString)objretZ xmlcharrefryryrz_ustrs   rz6sum len sorted reversed list tuple set any all min maxccs|]}|VqdSNry).0yryryrz srcCs:d}dddD}t||D] \}}|||}q|S)z/Escape &, <, >, ", ', etc. in a string of data.z&><"'css|] }d|dVqdS)&;Nry)rsryryrzrz_xml_escape..zamp gt lt quot apos)splitzipreplace)data from_symbols to_symbolsfrom_to_ryryrz _xml_escapes rc@s eZdZdS) _ConstantsN)__name__ __module__ __qualname__ryryryrzrsr 0123456789Z ABCDEFabcdef\ccs|] }|tjvr|VqdSr)string whitespacercryryrzrc@sPeZdZdZdddZeddZdd Zd d Zd d Z dddZ ddZ dS)rz7base exception class for all parsing runtime exceptionsrNcCs>||_|dur||_d|_n||_||_||_|||f|_dSNr)locmsgpstr parserElementargs)selfrrrelemryryrz__init__szParseBaseException.__init__cCs||j|j|j|jS)z internal factory method to simplify creating one type of ParseException from another - avoids having __init__ signature conflicts among subclasses )rrrr)clsperyryrz_from_exceptionsz"ParseBaseException._from_exceptioncCsJ|dkr t|j|jS|dvrt|j|jS|dkr!t|j|jSt|)zsupported attributes by name are: - lineno - returns the line number of the exception text - col - returns the column number of the exception text - line - returns the line containing the exception text rL)r;columnrI)rLrrr;rIAttributeError)ranameryryrz __getattr__szParseBaseException.__getattr__cCsd|j|j|j|jfS)Nz"%s (at char %d), (line:%d, col:%d))rrrLrrryryrz__str__szParseBaseException.__str__cCt|Srrrryryrz__repr__zParseBaseException.__repr__>!} ('-' operator) indicates that parsing is to stop immediately because an unbacktrackable syntax error has been foundNrryryryrzr%sr%c@ eZdZdZddZddZdS)r(zZexception thrown by L{ParserElement.validate} if the grammar could be improperly recursivecCs ||_dSrparseElementTracerparseElementListryryrzr4 z"RecursiveGrammarException.__init__cCs d|jS)NzRecursiveGrammarException: %srrryryrzr7rz!RecursiveGrammarException.__str__N)rrrrrrryryryrzr(2s r(c@s,eZdZddZddZddZddZd S) _ParseResultsWithOffsetcCs||f|_dSrtup)rp1p2ryryrzr;z _ParseResultsWithOffset.__init__cC |j|Srrriryryrz __getitem__=rz#_ParseResultsWithOffset.__getitem__cCst|jdSNr)reprrrryryrzr?rz _ParseResultsWithOffset.__repr__cCs|jd|f|_dSrrrryryrz setOffsetArz!_ParseResultsWithOffset.setOffsetN)rrrrrrrryryryrzr:s  rc@seZdZdZd[ddZddddefddZdd Zefd d Zd d Z ddZ ddZ ddZ e Z ddZddZddZddZddZerPeZ eZ eZneZ eZ eZ ddZd d!Zd"d#Zd$d%Zd&d'Zd\d(d)Zd*d+Zd,d-Zd.d/Zd0d1Z d2d3Z!d4d5Z"d6d7Z#d8d9Z$d:d;Z%d} - see L{ParserElement.setResultsName}) Example:: integer = Word(nums) date_str = (integer.setResultsName("year") + '/' + integer.setResultsName("month") + '/' + integer.setResultsName("day")) # equivalent form: # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") # parseString returns a ParseResults object result = date_str.parseString("1999/12/31") def test(s, fn=repr): print("%s -> %s" % (s, fn(eval(s)))) test("list(result)") test("result[0]") test("result['month']") test("result.day") test("'month' in result") test("'minutes' in result") test("result.dump()", str) prints:: list(result) -> ['1999', '/', '12', '/', '31'] result[0] -> '1999' result['month'] -> '12' result.day -> '31' 'month' in result -> True 'minutes' in result -> False result.dump() -> ['1999', '/', '12', '/', '31'] - day: 31 - month: 12 - year: 1999 NTcCs"t||r|St|}d|_|SNT)r}object__new___ParseResults__doinit)rtoklistnameasListmodalretobjryryrzrks  zParseResults.__new__c Csb|jr;d|_d|_d|_i|_||_||_|durg}||tr(|dd|_n||tr3t||_n|g|_t |_ |dur|r|sHd|j|<||t rQt |}||_||t dttfre|ddgfvs||trm|g}|r||tr~t|d||<n tt|dd||<|||_dSz |d||<WdStttfy|||<YdSwdSdSdS)NFrr)r_ParseResults__name_ParseResults__parent_ParseResults__accumNames_ParseResults__asList_ParseResults__modallist_ParseResults__toklist_generatorTypedict_ParseResults__tokdictrvrr basestringr$rcopyKeyError TypeError IndexError)rrrrrr}ryryrzrtsH      "  zParseResults.__init__cCsLt|ttfr |j|S||jvr|j|ddStdd|j|DS)NrtrcSsg|]}|dqSrryrvryryrz z,ParseResults.__getitem__..)r}rvslicerrrr$rryryrzrs   zParseResults.__getitem__cCs||tr|j|t|g|j|<|d}n"||ttfr'||j|<|}n|j|tt|dg|j|<|}||trFt||_ dSdSr) rrgetrrvrrr$wkrefr)rkrr}subryryrz __setitem__s   " zParseResults.__setitem__c Cst|ttfrXt|j}|j|=t|tr$|dkr||7}t||d}tt||}||j D]\}}|D]}t |D]\}\}} t || | |k||<qBq.rrryrrz _itervalueszParseResults._itervaluescr)Nc3s|] }||fVqdSrryrrryrzrrz*ParseResults._iteritems..r!rryrrz _iteritemsr#zParseResults._iteritemscC t|S)zVReturns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).)rrrryryrzkeys zParseResults.keyscCr%)zXReturns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).)r itervaluesrryryrzvaluesr'zParseResults.valuescCr%)zfReturns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).)r iteritemsrryryrzrr'zParseResults.itemscCr)zSince keys() returns an iterator, this method is helpful in bypassing code that looks for the existence of any defined results names.)boolrrryryrzhaskeyss zParseResults.haskeyscOs|sdg}|D]\}}|dkr|d|f}q td|t|dts1t|dks1|d|vr>|d}||}||=|S|d}|S)a Removes and returns item at specified index (default=C{last}). Supports both C{list} and C{dict} semantics for C{pop()}. If passed no argument or an integer argument, it will use C{list} semantics and pop tokens from the list of parsed tokens. If passed a non-integer argument (most likely a string), it will use C{dict} semantics and pop the corresponding value from any defined results names. A second default return value argument is supported, just as in C{dict.pop()}. Example:: def remove_first(tokens): tokens.pop(0) print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] label = Word(alphas) patt = label("LABEL") + OneOrMore(Word(nums)) print(patt.parseString("AAB 123 321").dump()) # Use pop() in a parse action to remove named result (note that corresponding value is not # removed from list form of results) def remove_LABEL(tokens): tokens.pop("LABEL") return tokens patt.addParseAction(remove_LABEL) print(patt.parseString("AAB 123 321").dump()) prints:: ['AAB', '123', '321'] - LABEL: AAB ['AAB', '123', '321'] rtdefaultrz-pop() got an unexpected keyword argument '%s'r)rrr}rvr)rrkwargsrrindexr defaultvalueryryrzpops"   zParseResults.popcCs||vr||S|S)ai Returns named result matching the given key, or if there is no such name, then returns the given C{defaultValue} or C{None} if no C{defaultValue} is specified. Similar to C{dict.get()}. Example:: integer = Word(nums) date_str = integer("year") + '/' + integer("month") + '/' + integer("day") result = date_str.parseString("1999/12/31") print(result.get("year")) # -> '1999' print(result.get("hour", "not specified")) # -> 'not specified' print(result.get("hour")) # -> None ry)rkey defaultValueryryrzr3szParseResults.getcCsR|j|||jD]\}}t|D]\}\}}t||||k||<qq dS)a Inserts new element at location index in the list of parsed tokens. Similar to C{list.insert()}. Example:: print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] # use a parse action to insert the parse location in the front of the parsed results def insert_locn(locn, tokens): tokens.insert(0, locn) print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] N)rinsertrrrr)rr/insStrrr rr rryryrzr4Is zParseResults.insertcCs|j|dS)a Add single element to end of ParseResults list of elements. Example:: print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] # use a parse action to compute the sum of the parsed integers, and add it to the end def append_sum(tokens): tokens.append(sum(map(int, tokens))) print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] N)rappend)ritemryryrzr6] zParseResults.appendcCs&t|tr ||7}dS|j|dS)a Add sequence of elements to end of ParseResults list of elements. Example:: patt = OneOrMore(Word(alphas)) # use a parse action to append the reverse of the matched strings, to make a palindrome def make_palindrome(tokens): tokens.extend(reversed([t[::-1] for t in tokens])) return ''.join(tokens) print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' N)r}r$rextend)ritemseqryryrzr9ks zParseResults.extendcCs|jdd=|jdS)z7 Clear all elements and results names. N)rrclearrryryrzr;}s zParseResults.clearcCs z||WStyYdSwr)rrrr$rrryryrzrs   zParseResults.__getattr__cCs|}||7}|Srr)rotherrryryrz__add__szParseResults.__add__cs|jr5t|jfdd|j}fdd|D}|D]\}}|||<t|dtr4t||d_q|j|j7_|j |j|S)Ncs|dkrS|Srry)a)offsetryrzr{rz'ParseResults.__iadd__..c s4g|]\}}|D]}|t|d|dfqqSrr)rrrvlistr) addoffsetryrzrs  z)ParseResults.__iadd__..r) rrrrr}r$rrrupdate)rr> otheritemsotherdictitemsrrry)rErArz__iadd__s     zParseResults.__iadd__cCs"t|tr |dkr |S||Sr)r}rvrrr>ryryrz__radd__szParseResults.__radd__cCsdt|jt|jfS)Nz(%s, %s))rrrrryryrzrzParseResults.__repr__cCsdddd|jDdS)N[, css*|]}t|tr t|nt|VqdSr)r}r$rrrrryryrzrs(z'ParseResults.__str__..])rrrryryrzrszParseResults.__str__rcCsLg}|jD]}|r|r||t|tr||7}q|t|q|Sr)rr6r}r$ _asStringListr)rsepoutr7ryryrzrQs   zParseResults._asStringListcCsdd|jDS)a Returns the parse results as a nested list of matching tokens, all converted to strings. Example:: patt = OneOrMore(Word(alphas)) result = patt.parseString("sldkj lsdkj sldkj") # even though the result prints in string-like form, it is actually a pyparsing ParseResults print(type(result), result) # -> ['sldkj', 'lsdkj', 'sldkj'] # Use asList() to create an actual list result_list = result.asList() print(type(result_list), result_list) # -> ['sldkj', 'lsdkj', 'sldkj'] cSs"g|] }t|tr |n|qSry)r}r$r)rresryryrzrs"z'ParseResults.asList..rrryryrzrszParseResults.asListcs6tr|j}n|j}fddtfdd|DS)a Returns the named parse results as a nested dictionary. Example:: integer = Word(nums) date_str = integer("year") + '/' + integer("month") + '/' + integer("day") result = date_str.parseString('12/31/1999') print(type(result), repr(result)) # -> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) result_dict = result.asDict() print(type(result_dict), repr(result_dict)) # -> {'day': '1999', 'year': '12', 'month': '31'} # even though a ParseResults supports dict-like access, sometime you just need to have a dict import json print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} cs0t|tr|r |Sfdd|DS|S)Ncsg|]}|qSryryrtoItemryrzrrz7ParseResults.asDict..toItem..)r}r$r,asDict)rrUryrzrVs z#ParseResults.asDict..toItemc3s |] \}}||fVqdSrryrrrrUryrzrz&ParseResults.asDict..)PY_3rr*r)ritem_fnryrUrzrWs   zParseResults.asDictcCs8t|j}|j|_|j|_|j|j|j|_|S)zA Returns a new copy of a C{ParseResults} object. )r$rrrrrrFrrrryryrzrs  zParseResults.copyFc CsFd}g}tdd|jD}|d}|sd}d}d}d} |dur%|} n|jr+|j} | s3|r1dSd} |||d| d g7}t|jD]S\} } t| trp| |vr`|| || |oY|du||g7}qA|| d|oi|du||g7}qAd} | |vrz|| } | s|rqAd} t t | } |||d| d | d | d g 7}qA|||d | d g7}d |S) z (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.  css*|]\}}|D] }|d|fVqqdSrNryrCryryrzrs  z%ParseResults.asXML.. rNITEM<>.z %s%s- %s: r_rcs|]}t|tVqdSr)r}r$)rvvryryrzrz %s%s[%d]: %s%s%sr) r6rrr,sortedrr}r$dumpranyrr) rrgdepthfullrSNLrrrrruryryrzrxgs.     4, zParseResults.dumpcOs tj|g|Ri|dS)a Pretty-printer for parsed results as a list, using the C{pprint} module. Accepts additional positional or keyword args as defined for the C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint}) Example:: ident = Word(alphas, alphanums) num = Word(nums) func = Forward() term = ident | num | Group('(' + func + ')') func <<= ident + Group(Optional(delimitedList(term))) result = func.parseString("fna a,b,(fnb c,d,200),100") result.pprint(width=40) prints:: ['fna', ['a', 'b', ['(', 'fnb', ['c', 'd', '200'], ')'], '100']] N)pprintrrrr.ryryrzr}s zParseResults.pprintcCs.|j|j|jdur|pd|j|jffSr)rrrrrrrryryrz __getstate__szParseResults.__getstate__cCsP|d|_|d\|_}}|_i|_|j||dur#t||_dSd|_dSr)rrrrrFrr)rstaterr inAccumNamesryryrz __setstate__s   zParseResults.__setstate__cCs|j|j|j|jfSr)rrrrrryryrz__getnewargs__rzParseResults.__getnewargs__cCstt|t|Sr)rrrr&rryryrzrrLzParseResults.__dir__)NNTTrr)NFrT)rrT)4rrrrrr}rrrrrrr __nonzero__rrrr"r$rZr&r)rrr(r*r,r1rr4r6r9r;rr?rIrKrrrQrrWrrdrprsrxr}rrrrryryryrzr$Dst & '   4  # = %- r$cCsF|}d|krt|krnn ||ddkrdS||dd|S)aReturns current column within a string, counting newlines as line separators. The first column is number 1. Note: the default parsing behavior is to expand tabs in the input string before starting the parsing process. See L{I{ParserElement.parseString}} for more information on parsing strings containing C{}s, and suggested methods to maintain a consistent view of the parsed string, the parse location, and line and column positions within the parsed string. rrr])rrfind)rstrgrryryrzr;s Br;cCs|dd|dS)aReturns current line number within a string, counting newlines as line separators. The first line is number 1. Note: the default parsing behavior is to expand tabs in the input string before starting the parsing process. See L{I{ParserElement.parseString}} for more information on parsing strings containing C{}s, and suggested methods to maintain a consistent view of the parsed string, the parse location, and line and column positions within the parsed string. r]rr)count)rrryryrzrLs rLcCsB|dd|}|d|}|dkr||d|S||ddS)zfReturns the line of text containing loc within a string, counting newlines as line separators. r]rrN)rfind)rrlastCRnextCRryryrzrIs  rIcCs8tdt|dt|dt||t||fdS)NzMatch z at loc z(%d,%d))printrrLr;)instringrexprryryrz_defaultStartDebugActions8rcCs$tdt|dt|dS)NzMatched z -> )rrrr)rstartlocendlocrtoksryryrz_defaultSuccessDebugActions$rcCstdt|dS)NzException raised:)rr)rrrexcryryrz_defaultExceptionDebugActionrrcGdS)zG'Do-nothing' debug action, to suppress debugging output during parsing.Nry)rryryrzrSsrSrscstvr fddSdgdgtdddkr#ddd}dd d ntj}tjd }|dd d }|d|d|ffdd}d}z tdtdj}Wn tybt}Ynw||_|S)Ncs|Srryrlrx)funcryrzr{z_trim_arity..rFrs)rqcSs8tdkrdnd}tj| |dd|}|ddgS)N)rqrrrlimitrs)system_version traceback extract_stack)rrA frame_summaryryryrzrsz"_trim_arity..extract_stackcSs$tj||d}|d}|ddgS)Nrrtrs)r extract_tb)tbrframesrryryrzrsz_trim_arity..extract_tbrrtrc s z|dd}dd<|WStyJdrztd}|dddddks4W~n~wdkrIdd7<Yqw)NrrTrtrsr)rrexc_info)rrrr foundArityrrmaxargspa_call_line_synthryrzwrapper-s&   z_trim_arity..wrapperzr __class__r) singleArgBuiltinsrrrrgetattrr Exceptionr)rrr LINE_DIFF this_liner func_nameryrrz _trim_aritys.      rcseZdZdZdZdZeddZeddZddd Z d d Z d d Z dddZ dddZ ddZddZddZddZddZddZddd Zd!d"Zdd#d$Zd%d&Zd'd(ZGd)d*d*eZed+urpGd,d-d-eZnGd.d-d-eZiZeZd/d/gZ dd0d1Z!eZ"ed2d3Z#dZ$edd5d6Z%dd7d8Z&e'dfd9d:Z(d;d<Z)e'fd=d>Z*e'dfd?d@Z+dAdBZ,dCdDZ-dEdFZ.dGdHZ/dIdJZ0dKdLZ1dMdNZ2dOdPZ3dQdRZ4dSdTZ5dUdVZ6dWdXZ7dYdZZ8dd[d\Z9d]d^Z:d_d`Z;dadbZdgdhZ?ddidjZ@dkdlZAdmdnZBdodpZCdqdrZDgfdsdtZEddudvZFfdwdxZGdydzZHd{d|ZId}d~ZJddZKdddZLdddZMZNS)r&z)Abstract base level parser element class.z FcC |t_dS)a Overrides the default whitespace chars Example:: # default whitespace chars are space, and newline OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] # change to just treat newline as significant ParserElement.setDefaultWhitespaceChars(" \t") OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] N)r&DEFAULT_WHITE_CHARScharsryryrzsetDefaultWhitespaceCharsTs z'ParserElement.setDefaultWhitespaceCharscCr)a Set class to be used for inclusion of string literals into a parser. Example:: # default literal class used is Literal integer = Word(nums) date_str = integer("year") + '/' + integer("month") + '/' + integer("day") date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] # change to Suppress ParserElement.inlineLiteralsUsing(Suppress) date_str = integer("year") + '/' + integer("month") + '/' + integer("day") date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] N)r&_literalStringClass)rryryrzinlineLiteralsUsingcs z!ParserElement.inlineLiteralsUsingcCst|_d|_d|_d|_||_d|_tj|_ d|_ d|_ d|_ t|_ d|_d|_d|_d|_d|_d|_d|_d|_d|_dS)NTFr)NNN)r parseAction failActionstrRepr resultsName saveAsListskipWhitespacer&r whiteCharscopyDefaultWhiteCharsmayReturnEmptykeepTabs ignoreExprsdebug streamlined mayIndexErrorerrmsg modalResults debugActionsre callPreparse callDuringTry)rsavelistryryrzrxs( zParserElement.__init__cCs<t|}|jdd|_|jdd|_|jrtj|_|S)a$ Make a copy of this C{ParserElement}. Useful for defining different parse actions for the same parsing pattern, using copies of the original parse element. Example:: integer = Word(nums).setParseAction(lambda toks: int(toks[0])) integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K") integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) prints:: [5120, 100, 655360, 268435456] Equivalent form of C{expr.copy()} is just C{expr()}:: integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") N)rrrrr&rr)rcpyryryrzrs zParserElement.copycCs*||_d|j|_t|dr|j|j_|S)af Define name for this expression, makes debugging and exception messages clearer. Example:: Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) Expected exception)rrrrrr<ryryrzsetNames    zParserElement.setNamecCs4|}|dr|dd}d}||_| |_|S)aP Define name for referencing matching tokens as a nested attribute of the returned parse results. NOTE: this returns a *copy* of the original C{ParserElement} object; this is so that the client can define a basic element, such as an integer, and reference it in multiple places with different names. You can also set results names using the abbreviated syntax, C{expr("name")} in place of C{expr.setResultsName("name")} - see L{I{__call__}<__call__>}. Example:: date_str = (integer.setResultsName("year") + '/' + integer.setResultsName("month") + '/' + integer.setResultsName("day")) # equivalent form: date_str = integer("year") + '/' + integer("month") + '/' + integer("day") *NrtT)rendswithrr)rrlistAllMatchesnewselfryryrzsetResultsNames  zParserElement.setResultsNameTcsB|r|jdfdd }|_||_|St|jdr|jj|_|S)zMethod to invoke the Python pdb debugger when this element is about to be parsed. Set C{breakFlag} to True to enable, False to disable. Tcsddl}|||||Sr)pdb set_trace)rr doActions callPreParser _parseMethodryrzbreakersz'ParserElement.setBreak..breaker_originalParseMethodNTT)_parserr)r breakFlagrryrrzsetBreaks zParserElement.setBreakcOs&tttt||_|dd|_|S)a Define one or more actions to perform when successfully matching parse element definition. Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)}, C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: - s = the original string being parsed (see note below) - loc = the location of the matching substring - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object If the functions in fns modify the tokens, they can return them as the return value from fn, and the modified list of tokens will replace the original. Otherwise, fn does not need to return any value. Optional keyword arguments: - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing Note: the default parsing behavior is to expand tabs in the input string before starting the parsing process. See L{I{parseString}} for more information on parsing strings containing C{}s, and suggested methods to maintain a consistent view of the parsed string, the parse location, and line and column positions within the parsed string. Example:: integer = Word(nums) date_str = integer + '/' + integer + '/' + integer date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] # use parse action to convert to ints at parse time integer = Word(nums).setParseAction(lambda toks: int(toks[0])) date_str = integer + '/' + integer + '/' + integer # note that integer fields are now ints, not strings date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] rF)rmaprrrrrfnsr.ryryrzrs"zParserElement.setParseActioncOs4|jtttt|7_|jp|dd|_|S)z Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}}. See examples in L{I{copy}}. rF)rrrrrrrryryrzaddParseActionszParserElement.addParseActioncs^|dd|ddrtnt|D]fdd}|j|q|jp+|dd|_|S)aAdd a boolean predicate function to expression's list of parse actions. See L{I{setParseAction}} for function call signatures. Unlike C{setParseAction}, functions passed to C{addCondition} need to return boolean success/fail of the condition. Optional keyword arguments: - message = define a custom message to be used in the raised exception - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException Example:: integer = Word(nums).setParseAction(lambda toks: int(toks[0])) year_int = integer.copy() year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") date_str = year_int + '/' + integer + '/' + integer result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) messagezfailed user-defined conditionfatalFcs$tt|||s||dSr)r+rrexc_typefnrryrzpa&s z&ParserElement.addCondition..par)rr#r!rr6r)rrr.rryrrz addConditions zParserElement.addConditioncCs ||_|S)a Define action to perform if parsing fails at this expression. Fail acton fn is a callable function that takes the arguments C{fn(s,loc,expr,err)} where: - s = string being parsed - loc = location where expression match was attempted and failed - expr = the parse expression that failed - err = the exception thrown The function returns no value. It may throw C{L{ParseFatalException}} if it is desired to stop parsing immediately.)r)rrryryrz setFailAction-s zParserElement.setFailActionc CsJd}|r#d}|jD]}z |||\}}d}q ty Yq w|s|SNTF)rrr!)rrr exprsFoundedummyryryrz_skipIgnorables:s   zParserElement._skipIgnorablescCsZ|jr |||}|jr+|j}t|}||kr+|||vr+|d7}||kr+|||vs|SNr)rrrrr)rrrwtinstrlenryryrzpreParseGs zParserElement.preParsecCs|gfSrryrrrrryryrz parseImplSrzParserElement.parseImplcCs|Srryrrr tokenlistryryrz postParseVzParserElement.postParsec Cs|j}|s|jrm|jdr|jd||||r"|jr"|||}n|}|}zz ||||\}}WntyCt|t||j |wWnft yl} z|jdr\|jd|||| |jrg||||| d} ~ ww|ry|jry|||}n|}|}|j s|t|krz ||||\}}Wntyt|t||j |w||||\}}| |||}t ||j|j|jd} |jr3|s|jr3|rz$|jD]} | ||| }|durt ||j|jot|t tf|jd} qWnCt y } z|jdr|jd|||| d} ~ ww|jD]!} | ||| }|dur1t ||j|jo,t|t tf|jd} q|rG|jdrG|jd||||| || fS)Nrrs)rrr)rrrrrrrr!rrrrrr$rrrrrr}r) rrrrr debuggingpreloc tokensStarttokenserr retTokensrryryrz _parseNoCacheZs              zParserElement._parseNoCachecCs6z |j||dddWStyt|||j|w)NF)rr)rr#r!rrrrryryrztryParses  zParserElement.tryParsec Cs,z |||WdSttfyYdSw)NFT)r r!rr ryryrz canParseNexts zParserElement.canParseNextc@eZdZddZdS)zParserElement._UnboundedCachecs~it|_fdd}fdd}fdd}fdd}t|||_t|||_t|||_t|||_dS) Nc |Srrrr2cache not_in_cacheryrzr z3ParserElement._UnboundedCache.__init__..getcs ||<dSrryrr2r rryrzsetrz3ParserElement._UnboundedCache.__init__..setc dSrr;rrryrzr;rz5ParserElement._UnboundedCache.__init__..clearctSrrrrryrz cache_lenrz9ParserElement._UnboundedCache.__init__..cache_len)rrtypes MethodTyperrr;r)rrrr;rryrrzrs    z&ParserElement._UnboundedCache.__init__Nrrrrryryryrz_UnboundedCache rNc@r )ParserElement._FifoCachecst|_tfdd}fdd}fdd}fdd}t|||_t|||_t|||_t|||_dS) Ncr rrrrryrzrr.ParserElement._FifoCache.__init__..getcsJ||<tkr#zdWn tyYnwtks dSdSNF)rpopitemrr)rsizeryrzrs  .ParserElement._FifoCache.__init__..setcrrrrrryrzr;r0ParserElement._FifoCache.__init__..clearcrrrrrryrzrr4ParserElement._FifoCache.__init__..cache_len) rr _OrderedDictrrrrr;rrr%rrr;rry)rrr%rzrs   !ParserElement._FifoCache.__init__Nrryryryrz _FifoCacher r,c@r )r!cst|_itgfdd}fdd}fdd}fdd}t|||_t|||_t|||_t|||_ dS) Ncr rrrrryrzrrr"cs>||<tkrdtks |dSr)rr1popleftr6r)rkey_fifor%ryrzrs   r&csdSrrr)rr.ryrzr;s r'crrrrrryrzrrr() rr collectionsdequerrrrr;rr*ry)rr.rr%rzrs   r+Nrryryryrzr,r rc Csd\}}|||||f}tjqtj}||} | |jur^tj|d7<z |||||} WntyF} z ||| j | j d} ~ ww||| d| d f| WdStj|d7<t | t rn| | d| d fWdS1swYdS)NrBrr)r&packrat_cache_lock packrat_cacherrpackrat_cache_statsrrrrrrr}r) rrrrrHITMISSlookuprr rryryrz _parseCaches,   $zParserElement._parseCachecCs(tjdgttjtjdd<dSr)r&r2r;rr3ryryryrz resetCaches zParserElement.resetCachecCs<tjsdt_|durtt_nt|t_tjt_dSdS)aEnables "packrat" parsing, which adds memoizing to the parsing logic. Repeated parse attempts at the same string location (which happens often in many complex grammars) can immediately return a cached value, instead of re-executing parsing/validating code. Memoizing is done of both valid results and parsing exceptions. Parameters: - cache_size_limit - (default=C{128}) - if an integer value is provided will limit the size of the packrat cache; if None is passed, then the cache size will be unbounded; if 0 is passed, the cache will be effectively disabled. This speedup may break existing programs that use parse actions that have side-effects. For this reason, packrat parsing is disabled when you first import pyparsing. To activate the packrat feature, your program must call the class method C{ParserElement.enablePackrat()}. If your program uses C{psyco} to "compile as you go", you must call C{enablePackrat} before calling C{psyco.full()}. If you do not do this, Python will crash. For best results, call C{enablePackrat()} immediately after importing pyparsing. Example:: import pyparsing pyparsing.ParserElement.enablePackrat() TN)r&_packratEnabledrr2r,r7r)cache_size_limitryryrz enablePackrat%s   zParserElement.enablePackratc Cst|js ||jD]}|q|js|}z"||d\}}|r<|||}t t }|||W|SW|St yP}ztj rJ|d}~ww)aC Execute the parse expression with the given string. This is the main interface to the client code, once the complete expression has been built. If you want the grammar to require that the entire input string be successfully parsed, then set C{parseAll} to True (equivalent to ending the grammar with C{L{StringEnd()}}). Note: C{parseString} implicitly calls C{expandtabs()} on the input string, in order to report proper column numbers in parse actions. If the input string contains tabs and the grammar uses parse actions that use the C{loc} argument to index into the string being parsed, you can ensure you have a consistent view of the input string by: - calling C{parseWithTabs} on your grammar before calling C{parseString} (see L{I{parseWithTabs}}) - define your parse action using the full C{(s,loc,toks)} signature, and reference the input string using the parse action's C{s} argument - explicitly expand the tabs in your input string before calling C{parseString} Example:: Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text rN) r&r8r streamlinerr expandtabsrrrr+rverbose_stacktrace)rrparseAllrrrserryryrz parseStringHs,     zParserElement.parseStringc csD|js||jD]}|q |jst|}t|}d}|j}|j}t d} zb||kr| |krz|||} ||| dd\} } Wn t yS| d}Yn)w| |krx| d7} | | | fV|ru|||} | |krp| }n |d7}n| }n| d}||kr| |ks6WdSWdSWdSWdSt y}zt j r|d}~ww)a Scan the input string for expression matches. Each match will return the matching tokens, start location, and end location. May be called with optional C{maxMatches} argument, to clip scanning after 'n' matches are found. If C{overlap} is specified, then overlapping matches will be reported. Note that the start and end locations are reported relative to the string being parsed. See L{I{parseString}} for more information on parsing strings with embedded tabs. Example:: source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" print(source) for tokens,start,end in Word(alphas).scanString(source): print(' '*start + '^'*(end-start)) print(' '*start + tokens[0]) prints:: sldjf123lsdjjkf345sldkjf879lkjsfd987 ^^^^^ sldjf ^^^^^^^ lsdjjkf ^^^^^^ sldkjf ^^^^^^ lkjsfd rFrrN)rr=rrrr>rrrr&r8r!rr?)rr maxMatchesoverlaprrr preparseFnparseFnmatchesrnextLocrnextlocrryryrz scanStringzsL         (zParserElement.scanStringc Csg}d}d|_zN||D]-\}}}|||||r8t|tr)||7}nt|tr3||7}n|||}q |||ddd|D}dtt t |WSt yg}zt j ra|d}~ww)af Extension to C{L{scanString}}, to modify matching text with modified tokens that may be returned from a parse action. To use C{transformString}, define a grammar and attach a parse action to it that modifies the returned token list. Invoking C{transformString()} on a target string will then scan for matches, and replace the matched text patterns according to the logic in the parse action. C{transformString()} returns the resulting transformed string. Example:: wd = Word(alphas) wd.setParseAction(lambda toks: toks[0].title()) print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) Prints:: Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. rTNcSsg|]}|r|qSryry)roryryrzrrz1ParserElement.transformString..r)rrKr6r}r$rrrrr_flattenrr&r?)rrrSlastErxrrrryryrzrs,    zParserElement.transformStringc CsBztdd|||DWSty }ztjr|d}~ww)a Another extension to C{L{scanString}}, simplifying the access to the tokens found to match the given parse expression. May be called with optional C{maxMatches} argument, to clip searching after 'n' matches are found. Example:: # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters cap_word = Word(alphas.upper(), alphas.lower()) print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) # the sum() builtin can be used to merge results into a single ParseResults object print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) prints:: [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] cSsg|]\}}}|qSryry)rrxrrryryrzrz.ParserElement.searchString..N)r$rKrr&r?)rrrDrryryrz searchStringszParserElement.searchStringc csVd}d}|j||dD]\}}}|||V|r|dV|}q ||dVdS)a[ Generator method to split a string using the given expression as a separator. May be called with optional C{maxsplit} argument, to limit the number of splits; and the optional C{includeSeparators} argument (default=C{False}), if the separating matching text should be included in the split results. Example:: punc = oneOf(list(".,;:/-!?")) print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) prints:: ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] r)rDN)rK) rrmaxsplitincludeSeparatorssplitslastrxrrryryrzrs  zParserElement.splitcCFt|tr t|}t|tstjdt|tdddSt||gS)a Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement converts them to L{Literal}s by default. Example:: greet = Word(alphas) + "," + Word(alphas) + "!" hello = "Hello, World!" print (hello, "->", greet.parseString(hello)) Prints:: Hello, World! -> ['Hello', ',', 'World', '!'] 4Cannot combine element of type %s with ParserElementrs stacklevelN) r}rr&rwarningswarnr SyntaxWarningrrJryryrzr?s   zParserElement.__add__cCsBt|tr t|}t|tstjdt|tdddS||S)z] Implementation of + operator when left operand is not a C{L{ParserElement}} rVrsrWNr}rr&rrYrZrr[rJryryrzrK1   zParserElement.__radd__cCsJt|tr t|}t|tstjdt|tdddS|t |S)zQ Implementation of - operator, returns C{L{And}} with error stop rVrsrWN) r}rr&rrYrZrr[r _ErrorStoprJryryrz__sub__=s   zParserElement.__sub__cCsBt|tr t|}t|tstjdt|tdddS||S)z] Implementation of - operator when left operand is not a C{L{ParserElement}} rVrsrWNr\rJryryrz__rsub__Ir]zParserElement.__rsub__cst|tr |d}}npt|trt|ddd}|ddur$d|df}t|dtrO|ddurO|ddkr;tS|ddkrEtS|dtSt|dtrft|dtrf|\}}||8}ntdt|dt|dtdt||dkrtd|dkrtd ||krdkrtd |rÇfd d |r|dkr|}|Stg||}|S|}|S|dkrˈ}|Stg|}|S) a Implementation of * operator, allows use of C{expr * 3} in place of C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples may also include C{None} as in: - C{expr*(n,None)} or C{expr*(n,)} is equivalent to C{expr*n + L{ZeroOrMore}(expr)} (read as "at least n instances of C{expr}") - C{expr*(None,n)} is equivalent to C{expr*(0,n)} (read as "0 to n instances of C{expr}") - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} Note that C{expr*(None,n)} does not raise an exception if more than n exprs exist in the input stream; that is, C{expr*(None,n)} does not enforce a maximum number of expr occurrences. If this behavior is desired, then write C{expr*(None,n) + ~expr} r)NNNrsrz7cannot multiply 'ParserElement' and ('%s','%s') objectsz0cannot multiply 'ParserElement' and '%s' objectsz/cannot multiply ParserElement by negative valuez@second tuple value must be greater or equal to first tuple valuez+cannot multiply ParserElement by 0 or (0,0)cs$|dkrt|dStSr)rnmakeOptionalListrryrzrdsz/ParserElement.__mul__..makeOptionalList) r}rvtupler4rrr ValueErrorr)rr> minElements optElementsrryrcrz__mul__UsN          zParserElement.__mul__cCs ||Sr)rirJryryrz__rmul__rzParserElement.__rmul__cCrU)zI Implementation of | operator - returns C{L{MatchFirst}} rVrsrWN) r}rr&rrYrZrr[rrJryryrz__or__    zParserElement.__or__cCsBt|tr t|}t|tstjdt|tdddS||BS)z] Implementation of | operator when left operand is not a C{L{ParserElement}} rVrsrWNr\rJryryrz__ror__r]zParserElement.__ror__cCrU)zA Implementation of ^ operator - returns C{L{Or}} rVrsrWN) r}rr&rrYrZrr[rrJryryrz__xor__rlzParserElement.__xor__cCsBt|tr t|}t|tstjdt|tdddS||AS)z] Implementation of ^ operator when left operand is not a C{L{ParserElement}} rVrsrWNr\rJryryrz__rxor__r]zParserElement.__rxor__cCrU)zC Implementation of & operator - returns C{L{Each}} rVrsrWN) r}rr&rrYrZrr[rrJryryrz__and__rlzParserElement.__and__cCsBt|tr t|}t|tstjdt|tdddS||@S)z] Implementation of & operator when left operand is not a C{L{ParserElement}} rVrsrWNr\rJryryrz__rand__r]zParserElement.__rand__cCr)zE Implementation of ~ operator - returns C{L{NotAny}} )rrryryrz __invert__szParserElement.__invert__cCs|dur ||S|S)a  Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}. If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be passed as C{True}. If C{name} is omitted, same as calling C{L{copy}}. Example:: # these are equivalent userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") N)rrr<ryryrz__call__s zParserElement.__call__cCr)z Suppresses the output of this C{ParserElement}; useful to keep punctuation from cluttering up returned output. )r-rryryrzsuppressszParserElement.suppresscC d|_|S)a Disables the skipping of whitespace before matching the characters in the C{ParserElement}'s defined pattern. This is normally only used internally by the pyparsing module, but may be needed in some whitespace-sensitive grammars. FrrryryrzleaveWhitespacezParserElement.leaveWhitespacecCsd|_||_d|_|S)z8 Overrides the default whitespace chars TF)rrr)rrryryrzsetWhitespaceChars sz ParserElement.setWhitespaceCharscCru)z Overrides default behavior to expand C{}s to spaces before parsing the input string. Must be called before C{parseString} when the input grammar contains elements that match C{} characters. T)rrryryrz parseWithTabsrxzParserElement.parseWithTabscCsNt|tr t|}t|tr||jvr|j||S|jt||S)a Define expression to be ignored (e.g., comments) while doing pattern matching; may be called repeatedly, to define multiple comment or other ignorable patterns. Example:: patt = OneOrMore(Word(alphas)) patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] patt.ignore(cStyleComment) patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] )r}rr-rr6rrJryryrzignores    zParserElement.ignorecCs"|pt|pt|p tf|_d|_|S)zT Enable display of debugging messages while doing pattern matching. T)rrrrr)r startAction successActionexceptionActionryryrzsetDebugActions6s zParserElement.setDebugActionscCs |r |ttt|Sd|_|S)a Enable display of debugging messages while doing pattern matching. Set C{flag} to True to enable, False to disable. Example:: wd = Word(alphas).setName("alphaword") integer = Word(nums).setName("numword") term = wd | integer # turn on debugging for wd wd.setDebug() OneOrMore(term).parseString("abc 123 xyz 890") prints:: Match alphaword at loc 0(1,1) Matched alphaword -> ['abc'] Match alphaword at loc 3(1,4) Exception raised:Expected alphaword (at char 4), (line:1, col:5) Match alphaword at loc 7(1,8) Matched alphaword -> ['xyz'] Match alphaword at loc 11(1,12) Exception raised:Expected alphaword (at char 12), (line:1, col:13) Match alphaword at loc 15(1,16) Exception raised:Expected alphaword (at char 15), (line:1, col:16) The output shown is that produced by the default debug actions - custom debug actions can be specified using L{setDebugActions}. Prior to attempting to match the C{wd} expression, the debugging message C{"Match at loc (,)"} is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"} message is shown. Also note the use of L{setName} to assign a human-readable name to the expression, which makes debugging and exception messages easier to understand - for instance, the default name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}. F)rrrrr)rflagryryrzsetDebug@s #zParserElement.setDebugcCs|jSr)rrryryrzrizParserElement.__str__cCrrrrryryrzrlrzParserElement.__repr__cCsd|_d|_|Sr)rrrryryrzr=oszParserElement.streamlinecCsdSrryrryryrzcheckRecursiontrzParserElement.checkRecursioncCs|gdS)zj Check defined expressions for valid structure, check for infinite recursive definitions. N)r)r validateTraceryryrzvalidatewszParserElement.validatec Csz|}Wn"ty(t|d }|}Wdn1s!wYYnwz|||WStyB}ztjr<|d}~ww)z Execute the parse expression on the given file or filename. If a filename is specified (instead of a file object), the entire file is opened, read, and closed before parsing. rN)readropenrBrr&r?)rfile_or_filenamer@ file_contentsfrryryrz parseFile}s     zParserElement.parseFilecsDt|tr||upt|t|kSt|tr||Stt||kSr)r}r&varsrrHsuperrJrryrz__eq__s   zParserElement.__eq__cC ||k SrryrJryryrz__ne__rzParserElement.__ne__cCs tt|Sr)hashidrryryrz__hash__rzParserElement.__hash__cC||kSrryrJryryrz__req__rzParserElement.__req__cCrrryrJryryrz__rne__rzParserElement.__rne__cCs.z |jt||dWdStyYdSw)a Method for quick testing of a parser against a test string. Good for simple inline microtests of sub expressions while building up larger parser. Parameters: - testString - to test against this expression for a match - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests Example:: expr = Word(nums) assert expr.matches("100") r@TF)rBrr)r testStringr@ryryrzrHs   zParserElement.matches#c Cst|trtttj|}t|trt|}g}g}d} |D]} |dur.| | ds2|r8| s8| | q"| s;q"d || g} g}z| dd} |j | |d} | | j|d| o_| } Wnuty} zIt| trpdnd }d| vr| t| j| | d t| j| d d |n | d | jd || d t| | o|} | } WYd} ~ n%d} ~ wty}z| dt|| o|} |} WYd}~nd}~ww|r|r| d td | | | | fq"| |fS)a3 Execute the parse expression on a series of test strings, showing each test, the parsed results or where the parse failed. Quick and easy way to run a parse expression against a list of sample strings. Parameters: - tests - a list of separate test strings, or a multiline string of test strings - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests - comment - (default=C{'#'}) - expression for indicating embedded comments in the test string; pass None to disable comment filtering - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline; if False, only dump nested list - printResults - (default=C{True}) prints test output to stdout - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing Returns: a (success, results) tuple, where success indicates that all tests succeeded (or failed if C{failureTests} is True), and the results contain a list of lines of each test's output Example:: number_expr = pyparsing_common.number.copy() result = number_expr.runTests(''' # unsigned integer 100 # negative integer -100 # float with scientific notation 6.02e23 # integer with scientific notation 1e-12 ''') print("Success" if result[0] else "Failed!") result = number_expr.runTests(''' # stray character 100Z # missing leading digit before '.' -.100 # too many '.' 3.14.159 ''', failureTests=True) print("Success" if result[0] else "Failed!") prints:: # unsigned integer 100 [100] # negative integer -100 [-100] # float with scientific notation 6.02e23 [6.02e+23] # integer with scientific notation 1e-12 [1e-12] Success # stray character 100Z ^ FAIL: Expected end of text (at char 3), (line:1, col:4) # missing leading digit before '.' -.100 ^ FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) # too many '.' 3.14.159 ^ FAIL: Expected end of text (at char 4), (line:1, col:5) Success Each test string must be on a single line. If you want to test a string that spans multiple lines, create a test like this:: expr.runTest(r"this is a test\n of strings that spans \n 3 lines") (Note that this is a raw string literal, you must include the leading 'r'.) TNFr]\nr)r{z(FATAL)r r^zFAIL: zFAIL-EXCEPTION: )r}rrrrrrstrip splitlinesrrHr6rrrBrxrr#rIrr;rr)rtestsr@commentfullDump printResults failureTests allResultscommentssuccessrxrSresultrrrryryrzrunTestssT W   $ zParserElement.runTestsFTr)r9r)TrTTF)Orrrrrr? staticmethodrrrrrrrrrrrrrrrrr r rrr)r,r2rr1r3r7rr8r:r<rB_MAX_INTrKrrPrr?rKr_r`rirjrkrmrnrorprqrrrsrtrwryrzr{rrrrr=rrrrrrrrrHr __classcell__ryryrrzr&Os     &    G    "2G +   D          )    r&c eZdZdZfddZZS)r.zT Abstract C{ParserElement} subclass, for defining atomic matching patterns. cstt|jdddSNFr)rr.rrrryrzr@ r#zToken.__init__rrrrrrryryrrzr.< r.cr)rz, An empty token, will always match. cs$tt|d|_d|_d|_dS)NrTF)rrrrrrrrryrzrH s zEmpty.__init__rryryrrzrD rrc*eZdZdZfddZdddZZS)rz( A token that will never match. cs*tt|d|_d|_d|_d|_dS)NrTFzUnmatchable token)rrrrrrrrrryrzrS s  zNoMatch.__init__TcCst|||j|r)r!rrryryrzrZ szNoMatch.parseImplrrrrrrrrryryrrzrO s rcr)ra Token to exactly match a specified string. Example:: Literal('blah').parseString('blah') # -> ['blah'] Literal('blah').parseString('blahfooblah') # -> ['blah'] Literal('blah').parseString('bla') # -> Exception: Expected "blah" For case-insensitive matching, use L{CaselessLiteral}. For keyword matching (force word break before and after the matched string), use L{Keyword} or L{CaselessKeyword}. cstt|||_t||_z|d|_Wnty*tj dt ddt |_ Ynwdt |j|_d|j|_d|_d|_dS)Nrz2null string passed to Literal; use Empty() insteadrsrW"%s"rF)rrrmatchrmatchLenfirstMatchCharrrYrZr[rrrrrrrr matchStringrryrzrl s     zLiteral.__init__TcCsF|||jkr|jdks||j|r||j|jfSt|||j|r)rr startswithrr!rrryryrzr szLiteral.parseImplrrryryrrzr^ s rcsLeZdZdZedZdfdd Zddd Zfd d Ze d d Z Z S)ra\ Token to exactly match a specified string as a keyword, that is, it must be immediately followed by a non-keyword character. Compare with C{L{Literal}}: - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}. - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} Accepts two optional constructor arguments in addition to the keyword string: - C{identChars} is a string of characters that would be valid identifier characters, defaulting to all alphanumerics + "_" and "$" - C{caseless} allows case-insensitive matching, default is C{False}. Example:: Keyword("start").parseString("start") # -> ['start'] Keyword("start").parseString("starting") # -> Exception For case-insensitive matching, use L{CaselessKeyword}. _$NFcstt||durtj}||_t||_z|d|_Wnty.t j dt ddYnwd|j|_ d|j |_ d|_d|_||_|rO||_|}t||_dS)Nrz2null string passed to Keyword; use Empty() insteadrsrWrrF)rrrDEFAULT_KEYWORD_CHARSrrrrrrYrZr[rrrrcaselessupper caselessmatchr identChars)rrrrrryrzr s*      zKeyword.__init__TcCs|jr>||||j|jkr=|t||jks&|||j|jvr=|dks5||d|jvr=||j|jfSn;|||jkry|jdksQ||j|ry|t||jksd|||j|jvry|dksq||d|jvry||j|jfSt |||j |r) rrrrrrrrrr!rrryryrzr s*&zKeyword.parseImplcstt|}tj|_|Sr)rrrrr)rrrryrzr sz Keyword.copycCr)z,Overrides the default Keyword chars N)rrrryryrzsetDefaultKeywordChars s zKeyword.setDefaultKeywordCharsr#r) rrrrr5rrrrrrrryryrrzr s  rcr)r al Token to match a specified string, ignoring case of letters. Note: the matched results will always be in the case of the given match string, NOT the case of the input text. Example:: OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] (Contrast with example for L{CaselessKeyword}.) cs6tt||||_d|j|_d|j|_dS)Nz'%s'r)rr rr returnStringrrrrryrzr s zCaselessLiteral.__init__TcCs<||||j|jkr||j|jfSt|||j|r)rrrrr!rrryryrzr szCaselessLiteral.parseImplrrryryrrzr s r c,eZdZdZdfdd Zd ddZZS) r z Caseless version of L{Keyword}. Example:: OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] (Contrast with example for L{CaselessLiteral}.) Ncstt|j||dddS)NTr)rr r)rrrrryrzr szCaselessKeyword.__init__TcCsf||||j|jkr+|t||jks#|||j|jvr+||j|jfSt|||j|r)rrrrrrr!rrryryrzr s*zCaselessKeyword.parseImplrrrryryrrzr sr cr) rnax A variation on L{Literal} which matches "close" matches, that is, strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters: - C{match_string} - string to be matched - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match The results from a successful parse will contain the matched text from the input string and the following named results: - C{mismatches} - a list of the positions within the match_string where mismatches were found - C{original} - the original match_string used to compare against the input string If C{mismatches} is an empty list, then the match was an exact match. Example:: patt = CloseMatch("ATCATCGAATGGA") patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) # exact match patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) # close match allowing up to 2 mismatches patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) rcsBtt|||_||_||_d|j|jf|_d|_d|_dS)Nz&Expected %r (with up to %d mismatches)F) rrnrr match_string maxMismatchesrrr)rrrrryrzr s zCloseMatch.__init__TcCs|}t|}|t|j}||kr[|j}d}g} |j} tt||||jD]\}} | \} } | | kr@| |t| | kr@nq'|d}t|||g}|j|d<| |d<||fSt|||j|)Nrroriginal mismatches) rrrrrr6r$r!r)rrrrstartrmaxlocrmatch_stringlocrrs_msrcmatresultsryryrzr s*    zCloseMatch.parseImpl)rrrryryrrzrn s rncs8eZdZdZd fdd Zdd d Zfd d ZZS)r1a Token for matching words composed of allowed character sets. Defined with string containing all allowed initial characters, an optional string containing allowed body characters (if omitted, defaults to the initial character set), and an optional minimum, maximum, and/or exact length. The default value for C{min} is 1 (a minimum value < 1 is not valid); the default values for C{max} and C{exact} are 0, meaning no maximum or exact length restriction. An optional C{excludeChars} parameter can list characters that might be found in the input C{bodyChars} string; useful to define a word of all printables except for one or two characters, for instance. L{srange} is useful for defining custom character set strings for defining C{Word} expressions, using range notation from regular expression character sets. A common mistake is to use C{Word} to match a specific literal string, as in C{Word("Address")}. Remember that C{Word} uses the string argument to define I{sets} of matchable characters. This expression would match "Add", "AAA", "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. To match an exact literal string, use L{Literal} or L{Keyword}. pyparsing includes helper strings for building Words: - L{alphas} - L{nums} - L{alphanums} - L{hexnums} - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) - L{printables} (any non-whitespace character) Example:: # a word composed of digits integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) # a word with a leading capital, and zero or more lowercase capital_word = Word(alphas.upper(), alphas.lower()) # hostnames are alphanumeric, with leading alpha, and '-' hostname = Word(alphas, alphanums+'-') # roman numeral (not a strict parser, accepts invalid mix of characters) roman = Word("IVXLCDM") # any string of non-whitespace characters, except for ',' csv_value = Word(printables, excludeChars=",") NrrFcstt|r#dfdd|D}|r#dfdd|D}||_t||_|r6||_t||_n||_t||_|dk|_ |dkrKt d||_ |dkrV||_ nt |_ |dkrc||_ ||_ t||_d|j|_d |_||_d |j|jvr|dkr|dkr|dkr|j|jkrd t|j|_n#t|jdkrd t|jt|jf|_n d t|jt|jf|_|jrd|jd|_z t|j|_WdStyd|_YdSwdSdSdSdS)Nrc3|] }|vr|VqdSrryr excludeCharsryrzr` rz Word.__init__..c3rrryrrryrzrb rrrzZcannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permittedrFrz[%s]+z%s[%s]*z [%s][%s]*z\b)rr1rr initCharsOrigr initChars bodyCharsOrig bodyChars maxSpecifiedrfminLenmaxLenrrrrr asKeyword_escapeRegexRangeCharsreStringrrescapecompiler)rrrminmaxexactrrrrrzr] s`      (    z Word.__init__Tc CsF|jr|j||}|st|||j||}||fS|||jvr-t|||j||}|d7}t|}|j}||j }t ||}||kr\|||vr\|d7}||kr\|||vsNd} |||j krgd} |j rv||krv|||vrvd} |j r|dkr||d|vs||kr|||vrd} | rt|||j|||||fS)NrFTr)rrr!rendgrouprrrrrrrr) rrrrrrr bodycharsrthrowExceptionryryrzr s8   ,zWord.parseImplcsxztt|WStyYnw|jdur9dd}|j|jkr1d||j||jf|_|jSd||j|_|jS)NcSs t|dkr|dddS|S)N...rrryryrz charsAsStr s z Word.__str__..charsAsStrz W:(%s,%s)zW:(%s))rr1rrrrr)rrrryrzr s   z Word.__str__)NrrrFNrrrrrrrrrryryrrzr1. s . 6#r1csFeZdZdZeedZd fdd Zd ddZ fd d Z Z S) r)a Token for matching strings that match a given regular expression. Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. If the given regex contains named groups (defined using C{(?P...)}), these will be preserved as named parse results. Example:: realnum = Regex(r"[+-]?\d+\.\d*") date = Regex(r'(?P\d{4})-(?P\d\d?)-(?P\d\d?)') # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") z[A-Z]rcstt|t|tr?|stjdtdd||_||_ zt |j|j |_ |j|_ Wn,t jy>tjd|tddwt|tjrT||_ t||_|_ ||_ ntdt||_d|j|_d|_d|_d S) zThe parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags.z0null string passed to Regex; use Empty() insteadrsrW$invalid pattern (%s) passed to RegexzCRegex may only be constructed with a string or a compiled RE objectrFTN)rr)rr}rrYrZr[patternflagsrrr sre_constantserrorcompiledREtyperrfrrrrr)rrrrryrzr s8       zRegex.__init__TcCs`|j||}|st|||j||}|}t|}|r,|D]}||||<q#||fSr)rrr!rr groupdictr$r)rrrrrdrrryryrzr s zRegex.parseImplcsDztt|WStyYnw|jdurdt|j|_|jS)NzRe:(%s))rr)rrrrrrrryrzr s  z Regex.__str__rr) rrrrrrrrrrrrryryrrzr) s   " r)cs8eZdZdZd fdd Zd ddZfd d ZZS) r'a Token for matching strings that are delimited by quoting characters. Defined with the following parameters: - quoteChar - string of one or more characters defining the quote delimiting string - escChar - character to escape quotes, typically backslash (default=C{None}) - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None}) - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True}) Example:: qs = QuotedString('"') print(qs.searchString('lsjdf "This is the quote" sldjf')) complex_qs = QuotedString('{{', endQuoteChar='}}') print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) sql_qs = QuotedString('"', escQuote='""') print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) prints:: [['This is the quote']] [['This is the "quote"']] [['This is the quote with "embedded" quotes']] NFTc s>tt|}|stjdtddt|dur|}n|}|s0tjdtddt|_t |_ |d_ |_ t |_ |_|_|_|_|rttjtjB_dtjtj d|durnt|podf_nd_dtjtj d|durt|pdf_t j d krjd d fd d tt j d ddDd7_|rÈjdt|7_|rڈjdt|7_tjd_jdtj 7_ztjj_j_Wntjy tjdjtddwt _!dj!_"d_#d_$dS)Nz$quoteChar cannot be the empty stringrsrWz'endQuoteChar cannot be the empty stringrz %s(?:[^%s%s]rz%s(?:[^%s\n\r%s]rz|(?:z)|(?:c3s6|]}dtjd|tj|fVqdS)z%s[^%s]N)rr endQuoteCharrrOrryrzrX s  z(QuotedString.__init__..rt)z|(?:%s)z|(?:%s.)z(.)z)*%srrFT)%rr'rrrYrZr[ SyntaxError quoteCharr quoteCharLenfirstQuoteCharrendQuoteCharLenescCharescQuoteunquoteResultsconvertWhitespaceEscapesr MULTILINEDOTALLrrrrrrescCharReplacePatternrrrrrrrrr)rrrr multilinerrrrrrzr/ s|            zQuotedString.__init__c Cs|||jkr|j||pd}|st|||j||}|}|jrf||j|j }t |t rfd|vrP|j rPddddd}| D] \}}|||}qE|jr[t|jd|}|jrf||j|j}||fS)N\ r]  )\trz\fz\rz\g<1>)rrrr!rrrrrrr}rrrrrrrrr) rrrrrrws_mapwslitwscharryryrzrp s*  zQuotedString.parseImplcsFztt|WStyYnw|jdur d|j|jf|_|jS)Nz.quoted string, starting with %s ending with %s)rr'rrrrrrrryrzr s  zQuotedString.__str__)NNFTNTrrryryrrzr' s  A#r'cs8eZdZdZd fdd Zd ddZfd d ZZS) r a Token for matching words composed of characters I{not} in a given set (will include whitespace in matched characters if not listed in the provided exclusion set - see example). Defined with string containing all disallowed characters, and an optional minimum, maximum, and/or exact length. The default value for C{min} is 1 (a minimum value < 1 is not valid); the default values for C{max} and C{exact} are 0, meaning no maximum or exact length restriction. Example:: # define a comma-separated-value as anything that is not a ',' csv_value = CharsNotIn(',') print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) prints:: ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] rrcstt|d|_||_|dkrtd||_|dkr ||_nt|_|dkr-||_||_t ||_ d|j |_ |jdk|_ d|_ dS)NFrzfcannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permittedrr)rr rrnotCharsrfrrrrrrrr)rr rrrrryrzr s     zCharsNotIn.__init__TcCs|||jvrt|||j||}|d7}|j}t||jt|}||kr:|||vr:|d7}||kr:|||vs,|||jkrIt|||j|||||fSr)r r!rrrrr)rrrrrnotcharsmaxlenryryrzr s  zCharsNotIn.parseImplcshztt|WStyYnw|jdur1t|jdkr+d|jdd|_|jSd|j|_|jS)Nrz !W:(%s...)z!W:(%s))rr rrrrr rrryrzr s   zCharsNotIn.__str__)rrrrrryryrrzr s  r cs<eZdZdZddddddZdfd d ZdddZZS)r0a Special matching class for matching whitespace. Normally, whitespace is ignored by pyparsing grammars. This class is included when some whitespace structures are significant. Define with a string containing the whitespace characters to be matched; default is C{" \t\r\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, as defined for the C{L{Word}} class. zzzzz)rrr]rr rrcstt|_dfddjDdddjD_d_dj_ |_ |dkr:|_ nt _ |dkrI|_ |_ dSdS)Nrc3s|] }|jvr|VqdSr) matchWhiterrryrzr rz!White.__init__..css|]}tj|VqdSr)r0 whiteStrsrryryrzr rvTrr) rr0rrryrrrrrrrr)rwsrrrrrrzr s   zWhite.__init__TcCs|||jvrt|||j||}|d7}||j}t|t|}||kr;|||jvr;|d7}||kr;|||jvs,|||jkrJt|||j|||||fSr)rr!rrrrr)rrrrrrryryrzr s zWhite.parseImpl)rrrrr)rrrrrrrrryryrrzr0 sr0ceZdZfddZZS)_PositionTokencs(tt||jj|_d|_d|_dSr)rrrrrrrrrrryrzr   z_PositionToken.__init__rrrrrryryrrzr rcs2eZdZdZfddZddZd ddZZS) rzb Token to advance to a specific column of input text; useful for tabular report scraping. cstt|||_dSr)rrrr;)rcolnorryrzr$  zGoToColumn.__init__cCs~t|||jkr=t|}|jr|||}||kr=||r=t|||jkr=|d7}||kr=||r=t|||jks'|Sr)r;rrrisspace)rrrrryryrzr( s $$zGoToColumn.preParseTcCsDt||}||jkrt||d|||j|}|||}||fS)NzText not in expected columnr;r!)rrrrthiscolnewlocrryryrzr1 s   zGoToColumn.parseImplr)rrrrrrrrryryrrzr s   rcr)ra Matches if current position is at the beginning of a line within the parse string Example:: test = ''' AAA this line AAA and this line AAA but not this one B AAA and definitely not this one ''' for t in (LineStart() + 'AAA' + restOfLine).searchString(test): print(t) Prints:: ['AAA', ' this line'] ['AAA', ' and this line'] ctt|d|_dS)NzExpected start of line)rrrrrrryrzrO rzLineStart.__init__TcCs&t||dkr |gfSt|||j|r)r;r!rrryryrzrS szLineStart.parseImplrrryryrrzr: s rcr)rzU Matches if current position is at the end of a line within the parse string cs,tt||tjddd|_dS)Nr]rzExpected end of line)rrrryr&rrrrrryrzr\ s zLineEnd.__init__TcCs\|t|kr||dkr|ddfSt|||j||t|kr&|dgfSt|||j|)Nr]rrr!rrryryrzra s     zLineEnd.parseImplrrryryrrzrX s rcr)r,zM Matches if current position is at the beginning of the parse string cr)NzExpected start of text)rr,rrrrryrzrp rzStringStart.__init__TcCs0|dkr|||dkrt|||j||gfSr)rr!rrryryrzrt szStringStart.parseImplrrryryrrzr,l  r,cr)r+zG Matches if current position is at the end of the parse string cr)NzExpected end of text)rr+rrrrryrzr rzStringEnd.__init__TcCsX|t|krt|||j||t|kr|dgfS|t|kr$|gfSt|||j|rr rryryrzr s    zStringEnd.parseImplrrryryrrzr+{ r!r+c.eZdZdZeffdd ZdddZZS)r3ap Matches if the current position is at the beginning of a Word, and is not preceded by any character in a given set of C{wordChars} (default=C{printables}). To emulate the C{} behavior of regular expressions, use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of the string being parsed, or at the beginning of a line. cs"tt|t||_d|_dS)NzNot at the start of a word)rr3rr wordCharsrrr#rryrzr s  zWordStart.__init__TcCs@|dkr||d|jvs|||jvrt|||j||gfSr)r#r!rrryryrzr s zWordStart.parseImplrrrrrrXrrrryryrrzr3 sr3cr")r2aZ Matches if the current position is at the end of a Word, and is not followed by any character in a given set of C{wordChars} (default=C{printables}). To emulate the C{} behavior of regular expressions, use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of the string being parsed, or at the end of a line. cs(tt|t||_d|_d|_dS)NFzNot at the end of a word)rr2rrr#rrr$rryrzr rzWordEnd.__init__TcCsPt|}|dkr$||kr$|||jvs||d|jvr$t|||j||gfSr)rr#r!r)rrrrrryryrzr s zWordEnd.parseImplrr%ryryrrzr2 sr2cseZdZdZdfdd ZddZddZd d Zfd d Zfd dZ fddZ dfdd Z gfddZ fddZ ZS)r"z^ Abstract subclass of ParserElement, for combining and post-processing parsed tokens. Fcstt||t|trt|}t|trt|g|_ n3t|t r.F)rr"rr}rrrr&rexprsrallrrrrr&rrryrzr s         zParseExpression.__init__cCrr)r&rryryrzr rzParseExpression.__getitem__cCs|j|d|_|Sr)r&r6rrJryryrzr6 s zParseExpression.appendcCs0d|_dd|jD|_|jD]}|q|S)z~Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on all contained expressions.FcSg|]}|qSryr=rrryryrzr rz3ParseExpression.leaveWhitespace..)rr&rw)rrryryrzrw s   zParseExpression.leaveWhitespacecstt|tr"||jvr tt|||jD] }||jdq|Stt|||jD] }||jdq-|Sr)r}r-rrr"r{r&)rr>rrryrzr{     zParseExpression.ignorecsLztt|WStyYnw|jdur#d|jjt|jf|_|jSNz%s:(%s)) rr"rrrrrrr&rrryrzr s  zParseExpression.__str__cs tt||jD]}|q t|jdkr|jd}t||jrO|jsO|jdurO|j sO|jdd|jdg|_d|_ |j |j O_ |j |j O_ |jd}t||jr|js|jdur|j s|jdd|jdd|_d|_ |j |j O_ |j |j O_ dt ||_|S)Nrsrrrtr)rr"r=r&rr}rrrrrrrrr)rrr>rryrzr= s8        zParseExpression.streamlinecstt|||}|Sr)rr"r)rrrrrryrzr szParseExpression.setResultsNamecCs6|dd|g}|jD]}||q |gdSr)r&rr)rrtmprryryrzr   zParseExpression.validatecs$tt|}dd|jD|_|S)NcSr)ryr=r*ryryrzr% rz(ParseExpression.copy..)rr"rr&r\rryrzr# szParseExpression.copyr)rrrrrrr6rwr{rr=rrrrryryrrzr" s " r"csTeZdZdZGdddeZdfdd ZdddZd d Zd d Z d dZ Z S)ra  Requires all given C{ParseExpression}s to be found in the given order. Expressions may be separated by whitespace. May be constructed using the C{'+'} operator. May also be constructed using the C{'-'} operator, which will suppress backtracking. Example:: integer = Word(nums) name_expr = OneOrMore(Word(alphas)) expr = And([integer("id"),name_expr("name"),integer("age")]) # more easily written as: expr = integer("id") + name_expr("name") + integer("age") cr)zAnd._ErrorStopcs*ttj|j|i|d|_|dS)N-)rrr^rrrwr~rryrzr9 s zAnd._ErrorStop.__init__rryryrrzr^8 rr^TcsRtt|||tdd|jD|_||jdj|jdj|_d|_ dS)Ncs|]}|jVqdSrrr*ryryrzr@ zAnd.__init__..rT) rrrr'r&rryrrrr(rryrzr> s  z And.__init__c Cs|jdj|||dd\}}d}|jddD]W}t|tjr"d}q|r[z ||||\}}Wn4ty7tyJ}zd|_t|d}~wt yZt|t ||j |w||||\}}|sj| rn||7}q||fS)NrFrCrT) r&rr}rr^r%r __traceback__rrrrr,) rrrr resultlist errorStopr exprtokensrryryrzrE s.     z And.parseImplcCt|tr t|}||Srr}rr&rr6rJryryrzrI^    z And.__iadd__cCs8|dd|g}|jD] }|||jsdSq dSr)r&rrrrsubRecCheckListrryryrzrc s  zAnd.checkRecursioncC@t|dr|jS|jdurdddd|jDd|_|jS)Nr{rcs|]}t|VqdSrrr*ryryrzro r zAnd.__str__..}rrrrr&rryryrzrj   z And.__str__r) rrrrrr^rrrIrrrryryrrzr( s rcDeZdZdZdfdd ZdddZdd Zd d Zd d ZZ S)ra Requires that at least one C{ParseExpression} is found. If two expressions match, the expression that matches the longest string will be used. May be constructed using the C{'^'} operator. Example:: # construct Or using '^' operator number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) print(number.searchString("123 3.1416 789")) prints:: [['123'], ['3.1416'], ['789']] Fc<tt||||jrtdd|jD|_dSd|_dS)Ncsr0rr1r*ryryrzr r2zOr.__init__..T)rrrr&ryrr(rryrzr  z Or.__init__Tc CsDd}d}g}|jD]M}z|||}Wn;ty2} zd| _| j|kr(| }| j}WYd} ~ q d} ~ wtyNt||krLt|t||j|}t|}Yq w|||fq |r|j ddd|D]-\} }z | |||WSty} zd| _| j|kr| }| j}WYd} ~ qcd} ~ ww|dur|j|_ |t||d|)NrtcSs |d Srry)xryryrzr{ rzOr.parseImpl..)r2 no defined alternatives to match) r&r r!r3rrrrr6sortrr) rrrr maxExcLoc maxExceptionrHrloc2r_ryryrzr sF      z Or.parseImplcCr7rr8rJryryrz__ixor__ r9z Or.__ixor__cCr<)Nrr=z ^ csr>rrr*ryryrzr r zOr.__str__..r?r@rryryrzr rAz Or.__str__cC,|dd|g}|jD]}||q dSrr&rr:ryryrzr   zOr.checkRecursionrr) rrrrrrrLrrrryryrrzrt s & rcrB)ra Requires that at least one C{ParseExpression} is found. If two expressions match, the first one listed is the one that will match. May be constructed using the C{'|'} operator. Example:: # construct MatchFirst using '|' operator # watch the order of expressions to match number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] # put more selective expression first number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] FcrC)Ncsr0rr1r*ryryrzr r2z&MatchFirst.__init__..T)rrrr&ryrr(rryrzr rDzMatchFirst.__init__Tc Csd}d}|jD]F}z ||||}|WSty1}z|j|kr'|}|j}WYd}~qd}~wtyMt||krKt|t||j|}t|}Yqw|durX|j|_|t||d|)NrtrF)r&rr!rrrrr) rrrrrHrIrrrryryrzr s*     zMatchFirst.parseImplcCr7rr8rJryryrz__ior__ r9zMatchFirst.__ior__cCr<)Nrr= | csr>rrr*ryryrzr r z%MatchFirst.__str__..r?r@rryryrzr rAzMatchFirst.__str__cCrMrrNr:ryryrzrrOzMatchFirst.checkRecursionrr) rrrrrrrPrrrryryrrzr s  rcs<eZdZdZd fdd Zd ddZddZd d ZZS) ram Requires all given C{ParseExpression}s to be found, but in any order. Expressions may be separated by whitespace. May be constructed using the C{'&'} operator. Example:: color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") integer = Word(nums) shape_attr = "shape:" + shape_type("shape") posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") color_attr = "color:" + color("color") size_attr = "size:" + integer("size") # use Each (using operator '&') to accept attributes in any order # (shape and posn are required, color and size are optional) shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) shape_spec.runTests(''' shape: SQUARE color: BLACK posn: 100, 120 shape: CIRCLE size: 50 color: BLUE posn: 50,80 color:GREEN size:20 shape:TRIANGLE posn:20,40 ''' ) prints:: shape: SQUARE color: BLACK posn: 100, 120 ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] - color: BLACK - posn: ['100', ',', '120'] - x: 100 - y: 120 - shape: SQUARE shape: CIRCLE size: 50 color: BLUE posn: 50,80 ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] - color: BLUE - posn: ['50', ',', '80'] - x: 50 - y: 80 - shape: CIRCLE - size: 50 color: GREEN size: 20 shape: TRIANGLE posn: 20,40 ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] - color: GREEN - posn: ['20', ',', '40'] - x: 20 - y: 40 - shape: TRIANGLE - size: 20 Tcs8tt|||tdd|jD|_d|_d|_dS)Ncsr0rr1r*ryryrzr?r2z Each.__init__..T)rrrr'r&rrinitExprGroupsr(rryrzr=s z Each.__init__c s|jrItdd|jD|_dd|jD}dd|jD}|||_dd|jD|_dd|jD|_dd|jD|_|j|j7_d |_|}|jdd}|jddg}d } | r||j|j} g} | D]8} z| ||}Wnt y| | Yqmw| |j t | | | |vr| | qm| vr | qmt| t| krd } | s_|rd d d|D} t ||d | |fdd|jD7}g}|D]} | |||\}}| |qt|tg}||fS)Ncss(|]}t|trt|j|fVqdSr)r}rrrr*ryryrzrEs&z!Each.parseImpl..cSg|] }t|tr|jqSryr}rrr*ryryrzrFz"Each.parseImpl..cSs g|] }|jrt|ts|qSry)rr}rr*ryryrzrG cSrSry)r}r4rr*ryryrzrIrUcSrSry)r}rrr*ryryrzrJrUcSs g|] }t|tttfs|qSry)r}rr4rr*ryryrzrKrVFTrNcsr>rrr*ryryrzrfr z*Missing one or more required elements (%s)cs$g|]}t|tr|jvr|qSryrTr*tmpOptryrzrjr|)rRrr&opt1map optionalsmultioptionals multirequiredrequiredr r!r6rrremoverrrsumr$)rrrropt1opt2tmpLoctmpReqd matchOrder keepMatchingtmpExprsfailedrmissingr4r finalResultsryrWrzrCsV     zEach.parseImplcCr<)Nrr=z & csr>rrr*ryryrzryr zEach.__str__..r?r@rryryrzrtrAz Each.__str__cCrMrrNr:ryryrzr}rOzEach.checkRecursionr) rrrrrrrrrryryrrzrs 5 1 rcsleZdZdZdfdd ZdddZdd Zfd d Zfd d ZddZ gfddZ fddZ Z S)r za Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens. Fcstt||t|tr ttjtrt|}ntt |}||_ d|_ |durM|j |_ |j |_ ||j|j|_|j|_|j|_|j|jdSdSr)rr rr}r issubclassr&rr.rrrrrryrrrrrr9rrrrryrzrs     zParseElementEnhance.__init__TcCs.|jdur|jj|||ddStd||j|)NFrCr)rrr!rrryryrzrs zParseElementEnhance.parseImplcCs*d|_|j|_|jdur|j|Sr#)rrrrwrryryrzrws    z#ParseElementEnhance.leaveWhitespacecstt|tr"||jvr tt|||jdur |j|jd|Stt|||jdur8|j|jd|Sr)r}r-rrr r{rrJrryrzr{r+zParseElementEnhance.ignorecs&tt||jdur|j|Sr)rr r=rrrryrzr=s  zParseElementEnhance.streamlinecCsF||vr t||g|dd|g}|jdur!|j|dSdSr)r(rr)rrr;ryryrzrs  z"ParseElementEnhance.checkRecursioncCs6|dd|g}|jdur|j||gdSrrrrrrr-ryryrzrr.zParseElementEnhance.validatecsVztt|WStyYnw|jdur(|jdur(d|jjt|jf|_|jSr,) rr rrrrrrrrrryrzrs zParseElementEnhance.__str__rr) rrrrrrrwr{r=rrrrryryrrzr s    r cr)ra Lookahead matching of the given parse expression. C{FollowedBy} does I{not} advance the parsing position within the input string, it only verifies that the specified parse expression matches at the current position. C{FollowedBy} always returns a null token list. Example:: # use FollowedBy to match a label only if it is followed by a ':' data_word = Word(alphas) label = data_word + FollowedBy(':') attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() prints:: [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] ctt||d|_dSr)rrrrrrrryrzr zFollowedBy.__init__TcCs|j|||gfSr)rr rryryrzrszFollowedBy.parseImplrrryryrrzrs rcs2eZdZdZfddZd ddZddZZS) ra Lookahead to disallow matching with the given parse expression. C{NotAny} does I{not} advance the parsing position within the input string, it only verifies that the specified parse expression does I{not} match at the current position. Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny} always returns a null token list. May be constructed using the '~' operator. Example:: cs0tt||d|_d|_dt|j|_dS)NFTzFound unwanted token, )rrrrrrrrrorryrzrszNotAny.__init__TcCs&|j||rt|||j||gfSr)rr r!rrryryrzrszNotAny.parseImplcC4t|dr|jS|jdurdt|jd|_|jS)Nrz~{r?rrrrrrryryrzr  zNotAny.__str__rrryryrrzrs  rcs(eZdZdfdd ZdddZZS) _MultipleMatchNcsLtt||d|_|}t|trt|}|dur!||_dSd|_dSr) rrtrrr}rr&r not_ender)rrstopOnenderrryrzr s   z_MultipleMatch.__init__Tc Cs|jj}|j}|jdu}|r|jj}|r|||||||dd\}}z*|j } |r1|||| r9|||} n|} ||| |\}} | sI| rM|| 7}q*ttfy[Y||fSwNFrC) rrrrur rr,r!r) rrrrself_expr_parseself_skip_ignorables check_ender try_not_enderrhasIgnoreExprsr tmptokensryryrzrs0       z_MultipleMatch.parseImplrr)rrrrrrryryrrzrt srtc@seZdZdZddZdS)ra Repetition of one or more of the given expression. Parameters: - expr - expression that must match one or more times - stopOn - (default=C{None}) - expression for a terminating sentinel (only required if the sentinel would ordinarily match the repetition expression) Example:: data_word = Word(alphas) label = data_word + FollowedBy(':') attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) text = "shape: SQUARE posn: upper left color: BLACK" OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] # use stopOn attribute for OneOrMore to avoid reading label string as part of the data attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] # could also be written as (attr_expr * (1,)).parseString(text).pprint() cCrq)Nrr=z}...rrrryryrzrJrszOneOrMore.__str__N)rrrrrryryryrzr0s rcs8eZdZdZd fdd Zd fdd Zdd ZZS) r4aw Optional repetition of zero or more of the given expression. Parameters: - expr - expression that must match zero or more times - stopOn - (default=C{None}) - expression for a terminating sentinel (only required if the sentinel would ordinarily match the repetition expression) Example: similar to L{OneOrMore} Ncstt|j||dd|_dS)N)rvT)rr4rr)rrrvrryrzr_s zZeroOrMore.__init__Tc s6z tt||||WSttfy|gfYSwr)rr4rr!rrrryrzrcs  zZeroOrMore.parseImplcCrq)NrrM]...rrrryryrzrirszZeroOrMore.__str__rrrryryrrzr4Ss  r4c@s eZdZddZeZddZdS) _NullTokencCrr#ryrryryrzrsrz_NullToken.__bool__cCrrryrryryrzrvrz_NullToken.__str__N)rrrrrrryryryrzrrs rcs6eZdZdZeffdd Zd ddZddZZS) raa Optional matching of the given expression. Parameters: - expr - expression that must match zero or more times - default (optional) - value to be returned if the optional expression is not found. Example:: # US postal code can be a 5-digit zip, plus optional 4-digit qualifier zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) zip.runTests(''' # traditional ZIP code 12345 # ZIP+4 form 12101-0001 # invalid ZIP 98765- ''') prints:: # traditional ZIP code 12345 ['12345'] # ZIP+4 form 12101-0001 ['12101-0001'] # invalid ZIP 98765- ^ FAIL: Expected end of text (at char 5), (line:1, col:6) cs.tt|j|dd|jj|_||_d|_dS)NFrT)rrrrrr3r)rrr-rryrzrs  zOptional.__init__Tc Csz|jj|||dd\}}W||fSttfyG|jtur6|jjr1t|jg}|j||jj<n|jg}ng}Y||fSY||fSY||fSwrx)rrr!rr3_optionalNotMatchedrr$)rrrrrryryrzrs     zOptional.parseImplcCrq)NrrMrPrrrryryrzrrszOptional.__str__r) rrrrrrrrrryryrrzrzs " rcs,eZdZdZd fdd Zd ddZZS) r*a Token for skipping over all undefined text until the matched expression is found. Parameters: - expr - target expression marking the end of the data to be skipped - include - (default=C{False}) if True, the target expression is also parsed (the skipped text and target expression are returned as a 2-element list). - ignore - (default=C{None}) used to define grammars (typically quoted strings and comments) that might contain false matches to the target expression - failOn - (default=C{None}) define expressions that are not allowed to be included in the skipped test; if found before the target expression is found, the SkipTo is not a match Example:: report = ''' Outstanding Issues Report - 1 Jan 2000 # | Severity | Description | Days Open -----+----------+-------------------------------------------+----------- 101 | Critical | Intermittent system crash | 6 94 | Cosmetic | Spelling error on Login ('log|n') | 14 79 | Minor | System slow when running too many reports | 47 ''' integer = Word(nums) SEP = Suppress('|') # use SkipTo to simply match everything up until the next SEP # - ignore quoted strings, so that a '|' character inside a quoted string does not match # - parse action will call token.strip() for each matched token, i.e., the description body string_data = SkipTo(SEP, ignore=quotedString) string_data.setParseAction(tokenMap(str.strip)) ticket_expr = (integer("issue_num") + SEP + string_data("sev") + SEP + string_data("desc") + SEP + integer("days_open")) for tkt in ticket_expr.searchString(report): print tkt.dump() prints:: ['101', 'Critical', 'Intermittent system crash', '6'] - days_open: 6 - desc: Intermittent system crash - issue_num: 101 - sev: Critical ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] - days_open: 14 - desc: Spelling error on Login ('log|n') - issue_num: 94 - sev: Cosmetic ['79', 'Minor', 'System slow when running too many reports', '47'] - days_open: 47 - desc: System slow when running too many reports - issue_num: 79 - sev: Minor FNcs`tt||||_d|_d|_||_d|_t|t r#t ||_ n||_ dt |j|_dS)NTFzNo match found for )rr*r ignoreExprrr includeMatchrr}rr&rfailOnrrr)rr>includer{rrryrzrs zSkipTo.__init__Tc Cs$|}t|}|j}|jj}|jdur|jjnd}|jdur!|jjnd} |} | |kri|dur3||| r3n>| durJ z| || } Wn tyHYnwq8z ||| dddWntt fyc| d7} Ynwn | |ks)t|||j || }|||} t | } |j r||||dd\}} | | 7} || fS)NrF)rrrC) rrrrr rr rr!rrr$r)rrrrrrr expr_parseself_failOn_canParseNextself_ignoreExpr_tryParsetmplocskiptext skipresultrryryrzrsD    zSkipTo.parseImpl)FNNrrryryrrzr*s6 r*csbeZdZdZdfdd ZddZddZd d Zd d Zgfd dZ ddZ fddZ Z S)raK Forward declaration of an expression to be defined later - used for recursive grammars, such as algebraic infix notation. When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. Note: take care when assigning to C{Forward} not to overlook precedence of operators. Specifically, '|' has a lower precedence than '<<', so that:: fwdExpr << a | b | c will actually be evaluated as:: (fwdExpr << a) | b | c thereby leaving b and c out as parseable alternatives. It is recommended that you explicitly group the values inserted into the C{Forward}:: fwdExpr << (a | b | c) Converting to use the '<<=' operator instead will avoid this problem. See L{ParseResults.pprint} for an example of a recursive parser created using C{Forward}. Ncstt|j|dddSr)rrrrJrryrzr@rLzForward.__init__cCsjt|tr t|}||_d|_|jj|_|jj|_||jj |jj |_ |jj |_ |j |jj |Sr)r}rr&rrrrrryrrrrr9rJryryrz __lshift__Cs      zForward.__lshift__cCs||>SrryrJryryrz __ilshift__PrzForward.__ilshift__cCrur#rvrryryrzrwSszForward.leaveWhitespacecCs$|jsd|_|jdur|j|Sr)rrr=rryryrzr=Ws   zForward.streamlinecCs>||vr|dd|g}|jdur|j||gdSrrlrmryryrzr^s   zForward.validatecCst|dr|jS|jjdS)Nrz: ...)rrrrZ _revertClass_ForwardNoRecurserr)r retStringryryrzres  zForward.__str__cs*|jdur tt|St}||K}|Sr)rrrrr\rryrzrvs z Forward.copyr) rrrrrrrrwr=rrrrryryrrzr-s  rc@r )rcCr)Nrryrryryrzrrz_ForwardNoRecurse.__str__N)rrrrryryryrzr~r rcs"eZdZdZdfdd ZZS)r/zQ Abstract subclass of C{ParseExpression}, for converting parsed results. Fcrnr#)rr/rrrkrryrzrrpzTokenConverter.__init__rrryryrrzr/sr/cs6eZdZdZd fdd ZfddZdd ZZS) r a Converter to concatenate all matching tokens to a single string. By default, the matching patterns must also be contiguous in the input string; this can be disabled by specifying C{'adjacent=False'} in the constructor. Example:: real = Word(nums) + '.' + Word(nums) print(real.parseString('3.1416')) # -> ['3', '.', '1416'] # will also erroneously match the following print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] real = Combine(Word(nums) + '.' + Word(nums)) print(real.parseString('3.1416')) # -> ['3.1416'] # no match when there are internal spaces print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) rTcs8tt|||r|||_d|_||_d|_dSr)rr rrwadjacentr joinStringr)rrrrrryrzrs zCombine.__init__cs*|jr t|||Stt|||Sr)rr&r{rr rJrryrzr{s  zCombine.ignorecCsL|}|dd=|td||jg|jd7}|jr$|r$|gS|S)Nr)r)rr$rrQrrrr,)rrrrretToksryryrzrs  "zCombine.postParse)rT)rrrrrr{rrryryrrzr s  r c(eZdZdZfddZddZZS)ra Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions. Example:: ident = Word(alphas) num = Word(nums) term = ident | num func = ident + Optional(delimitedList(term)) print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100'] func = ident + Group(Optional(delimitedList(term))) print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']] crnr)rrrrrorryrzrrpzGroup.__init__cCs|gSrryrryryrzrrzGroup.postParserrrrrrrryryrrzrs rcr)r aW Converter to return a repetitive expression as a list, but also as a dictionary. Each element can also be referenced using the first token in the expression as its key. Useful for tabular report scraping when the first column can be used as a item key. Example:: data_word = Word(alphas) label = data_word + FollowedBy(':') attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) text = "shape: SQUARE posn: upper left color: light blue texture: burlap" attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) # print attributes as plain groups print(OneOrMore(attr_expr).parseString(text).dump()) # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names result = Dict(OneOrMore(Group(attr_expr))).parseString(text) print(result.dump()) # access named fields as dict entries, or output as dict print(result['shape']) print(result.asDict()) prints:: ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] - color: light blue - posn: upper left - shape: SQUARE - texture: burlap SQUARE {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} See more examples at L{ParseResults} of accessing fields by results name. crnr)rr rrrorryrzrrpz Dict.__init__cCst|D]h\}}t|dkrq|d}t|tr t|d}t|dkr.td|||<qt|dkrEt|dtsEt|d|||<q|}|d=t|dks[t|trc| rct||||<qt|d|||<q|j rs|gS|S)Nrrrrs) rrr}rvrrrr$rr,r)rrrrrtokikey dictvalueryryrzrs$   zDict.postParserryryrrzr s #r c@r)r-aV Converter for ignoring the results of a parsed expression. Example:: source = "a, b, c,d" wd = Word(alphas) wd_list1 = wd + ZeroOrMore(',' + wd) print(wd_list1.parseString(source)) # often, delimiters that are useful during parsing are just in the # way afterward - use Suppress to keep them out of the parsed output wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) print(wd_list2.parseString(source)) prints:: ['a', ',', 'b', ',', 'c', ',', 'd'] ['a', 'b', 'c', 'd'] (See also L{delimitedList}.) cCsgSrryrryryrzrrzSuppress.postParsecCs|Srryrryryrzrt"rzSuppress.suppressN)rrrrrrtryryryrzr- s r-c@s(eZdZdZddZddZddZdS) rzI Wrapper for parse actions, to ensure they are only called once. cCst||_d|_dSr#)rcallablecalled)r methodCallryryrzr*s  zOnlyOnce.__init__cCs*|js||||}d|_|St||d)NTr)rrr!)rrrrxrryryrzrs-s  zOnlyOnce.__call__cCs d|_dSr#)rrryryrzreset3rzOnlyOnce.resetN)rrrrrrsrryryryrzr&s  rcs8tfdd}zj|_W|StyY|Sw)at Decorator for debugging parse actions. When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".} When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised. Example:: wd = Word(alphas) @traceParseAction def remove_duplicate_chars(tokens): return ''.join(sorted(set(''.join(tokens)))) wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) print(wds.parseString("slkdjs sld sldd sdlf sdljf")) prints:: >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) <>entering %s(line: '%s', %d, %r) z<.z)rrr)rrryrrzrd6s   rd,FcCs\t|dt|dt|d}|r!t|t|||S|tt|||S)a Helper to define a delimited list of expressions - the delimiter defaults to ','. By default, the list elements and delimiters can have intervening whitespace, and comments, but this can be overridden by passing C{combine=True} in the constructor. If C{combine} is set to C{True}, the matching tokens are returned as a single token string, with the delimiters included; otherwise, the matching tokens are returned as a list of tokens, with the delimiters suppressed. Example:: delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc'] delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] z [rr)rr r4rr-)rdelimcombinedlNameryryrzrBbs$ rBcsjtfdd}|durttdd}n|}|d|j|dd|d td S) a: Helper to define a counted list of expressions. This helper defines a pattern of the form:: integer expr expr expr... where the leading integer tells how many expr expressions follow. The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value. Example:: countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] # in this parser, the leading integer value is given in binary, # '10' indicating that 2 values are in the array binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] cs.|d}|rttg|ptt>gSr)rrrE)rrrxrb arrayExprrryrzcountFieldParseActions"z+countedArray..countFieldParseActionNcSs t|dSr)rvrwryryrzr{ zcountedArray..arrayLenTrz(len) r)rr1rTrrrrr)rintExprrryrrzr>us r>cCs6g}|D]}t|tr|t|q||q|Sr)r}rr9rMr6)LrrryryrzrMs   rMcs6tfdd}|j|dddt|S)a* Helper to define an expression that is indirectly defined from the tokens matched in a previous expression, that is, it looks for a 'repeat' of a previous expression. For example:: first = Word(nums) second = matchPreviousLiteral(first) matchExpr = first + ":" + second will match C{"1:1"}, but not C{"1:2"}. Because this matches a previous literal, will also match the leading C{"1:1"} in C{"1:10"}. If this is not desired, use C{matchPreviousExpr}. Do I{not} use with packrat parsing enabled. csT|r#t|dkr|d>dSt|}tdd|D>dSt>dS)Nrrcsr>r)rrttryryrzrr zDmatchPreviousLiteral..copyTokenToRepeater..)rrMrrr)rrrxtflatrepryrzcopyTokenToRepeaters   z1matchPreviousLiteral..copyTokenToRepeaterTr(prev) )rrrr)rrryrrzrQs   rQcsFt|}|Kfdd}|j|dddt|S)aS Helper to define an expression that is indirectly defined from the tokens matched in a previous expression, that is, it looks for a 'repeat' of a previous expression. For example:: first = Word(nums) second = matchPreviousExpr(first) matchExpr = first + ":" + second will match C{"1:1"}, but not C{"1:2"}. Because this matches by expressions, will I{not} match the leading C{"1:1"} in C{"1:10"}; the expressions are evaluated first, and then compared, so C{"1"} is compared with C{"10"}. Do I{not} use with packrat parsing enabled. cs*t|fdd}j|dddS)Ncs$t|}|krtddddS)Nrr)rMrr!)rrrx theseTokens matchTokensryrzmustMatchTheseTokenss  zLmatchPreviousExpr..copyTokenToRepeater..mustMatchTheseTokensTr)rMrr)rrrxrrrrzrs  z.matchPreviousExpr..copyTokenToRepeaterTrr)rrrrr)re2rryrrzrPs rPcCs:dD] }||t|}q|dd}|dd}t|S)Nz\^-]r]rrr )r_bslashr)rrryryrzrs   rTc s|r dd}dd}tn dd}dd}tg}t|tr#|}nt|tr-t|}ntjdt dd|s:t Sd }|t |d kr||}t ||d d D](\}} || |rd|||d =n||| rz|||d =| || | }nqR|d 7}|t |d ksD|s|rz3t |t d |krtd d dd|Dd|WStddd|Dd|WStytjdt ddYnwtfdd|Dd|S)a Helper to quickly define a set of alternative Literals, and makes sure to do longest-first testing when there is a conflict, regardless of the input order, but returns a C{L{MatchFirst}} for best performance. Parameters: - strs - a string of space-delimited literals, or a collection of string literals - caseless - (default=C{False}) - treat all literals as caseless - useRegex - (default=C{True}) - as an optimization, will generate a Regex object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or if creating a C{Regex} raises an exception) Example:: comp_oper = oneOf("< = > <= >= !=") var = Word(alphas) number = Word(nums) term = var | number comparison_expr = term + comp_oper + term print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) prints:: [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] cSs||kSr)rr@bryryrzr{zoneOf..cSs||Sr)rrrryryrzr{scSrrryrryryrzr{rcSs ||Sr)rrryryrzr{rz6Invalid argument to oneOf, expected string or iterablersrWrrNrz[%s]csr>r)rrsymryryrzrr zoneOf..rQ|css|]}t|VqdSr)rrrryryrzrrvz7Exception creating Regex for oneOf, building MatchFirstc3|]}|VqdSrryrparseElementClassryrzr$r )r rr}rrrrrYrZr[rrrr4rr)rrr) strsruseRegexisequalmaskssymbolsrcurr r>ryrrzrUsV       *&  "rUcCsttt||S)a Helper to easily and clearly define a dictionary by specifying the respective patterns for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens in the proper order. The key pattern can include delimiting markers or punctuation, as long as they are suppressed, thereby leaving the significant key text. The value pattern can include named results, so that the C{Dict} results can include named token fields. Example:: text = "shape: SQUARE posn: upper left color: light blue texture: burlap" attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) print(OneOrMore(attr_expr).parseString(text).dump()) attr_label = label attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) # similar to Dict, but simpler call format result = dictOf(attr_label, attr_value).parseString(text) print(result.dump()) print(result['shape']) print(result.shape) # object attribute access works too print(result.asDict()) prints:: [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] - color: light blue - posn: upper left - shape: SQUARE - texture: burlap SQUARE SQUARE {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} )r r4r)r2r ryryrzrC&s!rCcCs^tdd}|}d|_|d||d}|r dd}ndd}|||j|_|S) a Helper to return the original, untokenized text for a given expression. Useful to restore the parsed fields of an HTML start tag into the raw tag text itself, or to revert separate tokens with intervening whitespace back to the original matching input text. By default, returns astring containing the original parsed text. If the optional C{asString} argument is passed as C{False}, then the return value is a C{L{ParseResults}} containing any results names that were originally matched, and a single token containing the original matched text from the input string. So if the expression passed to C{L{originalTextFor}} contains expressions with defined results names, you must set C{asString} to C{False} if you want to preserve those results name values. Example:: src = "this is test bold text normal text " for tag in ("b","i"): opener,closer = makeHTMLTags(tag) patt = originalTextFor(opener + SkipTo(closer) + closer) print(patt.searchString(src)[0]) prints:: [' bold text '] ['text'] cS|Srry)rrrxryryrzr{az!originalTextFor..F_original_start _original_endcSs||j|jSr)rrrryryrzr{frcSs&||d|dg|dd<dS)Nrr)r1rryryrz extractTexths&z$originalTextFor..extractText)rrrrr)rasString locMarker endlocMarker matchExprrryryrzriIs  ricCst|ddS)zp Helper to undo pyparsing's default grouping of And expressions, even if all but one are non-empty. cSs|dSrryrwryryrzr{srzungroup..)r/r)rryryrzrjnsrjcCs4tdd}t|d|d|dS)a Helper to decorate a returned token with its starting and ending locations in the input string. This helper adds the following results names: - locn_start = location where matched expression begins - locn_end = location where matched expression ends - value = the actual parsed results Be careful if the input text contains C{} characters, you may want to call C{L{ParserElement.parseWithTabs}} Example:: wd = Word(alphas) for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): print(match) prints:: [[0, 'ljsdf', 5]] [[8, 'lksdjjf', 15]] [[18, 'lkkjj', 23]] cSrrryrryryrzr{rzlocatedExpr.. locn_startr locn_end)rrrrrw)rlocatorryryrzrlus$rlrErKrJrcrbz\[]-*.$+^?()~ rcCs |ddSrryrryryrzr{rr{z\\0?[xX][0-9a-fA-F]+cCstt|dddS)Nrz\0x)unichrrvlstriprryryrzr{z \\0[0-7]+cCstt|ddddS)Nrr)rrvrryryrzr{sz\]r/rMrnegatebodyrPcs@ddzdfddt|jDWStyYdSw)a Helper to easily define string ranges for use in Word construction. Borrows syntax from regexp '[]' string range definitions:: srange("[0-9]") -> "0123456789" srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" The input string must be enclosed in []'s, and the returned string is the expanded character set joined into a single string. The values enclosed in the []'s may be: - a single character - an escaped character with a leading backslash (such as C{\-} or C{\]}) - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) (C{\0x##} is also supported for backwards compatibility) - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character) - a range of any of the above, separated by a dash (C{'a-z'}, etc.) - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.) cSs<t|ts|Sdddtt|dt|ddDS)Nrcsr>r)rrryryrzrr z+srange....rr)r}r$rrord)pryryrzr{s<zsrange..rc3rrry)rpart _expandedryrzrr zsrange..)r_reBracketExprrBrrrryrrzras " racfdd}|S)zt Helper method for defining parse actions that require matching at a specific column in the input text. cs"t||krt||ddS)Nzmatched token not at column %dr)rlocnrraryrz verifyColsz!matchOnlyAtCol..verifyColry)rbrryrarzrOs rOcs fddS)a Helper method for common parse actions that simply return a literal value. Especially useful when used with C{L{transformString}()}. Example:: num = Word(nums).setParseAction(lambda toks: int(toks[0])) na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) term = na | num OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] csgSrryrreplStrryrzr{szreplaceWith..ryrryrrzr^s r^cCs|dddS)a Helper parse action for removing quotation marks from parsed quoted strings. Example:: # by default, quotation marks are included in parsed results quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] # use removeQuotes to strip quotation marks from parsed results quotedString.setParseAction(removeQuotes) quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] rrrtryrryryrzr\r8r\csLfdd}z tdtdj}Wn ty t}Ynw||_|S)aG Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional args are passed, they are forwarded to the given function as additional arguments after the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the parsed data to an integer using base 16. Example (compare the last to example in L{ParserElement.transformString}:: hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) hex_ints.runTests(''' 00 11 22 aa FF 0a 0d 1a ''') upperword = Word(alphas).setParseAction(tokenMap(str.upper)) OneOrMore(upperword).runTests(''' my kingdom for a horse ''') wd = Word(alphas).setParseAction(tokenMap(str.title)) OneOrMore(wd).setParseAction(' '.join).runTests(''' now is the winter of our discontent made glorious summer by this sun of york ''') prints:: 00 11 22 aa FF 0a 0d 1a [0, 17, 34, 170, 255, 10, 13, 26] my kingdom for a horse ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] now is the winter of our discontent made glorious summer by this sun of york ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] csfdd|DS)Ncsg|] }|gRqSryry)rtoknrrryrzrrUz(tokenMap..pa..ryrrryrzrrztokenMap..parr)rrrr)rrrrryrrzros    rocC t|Srrrrwryryrzr{rcCrrrlowerrwryryrzr{rc Cst|tr|}t|| d}n|j}tttd}|rLt t }t d|dt t t|t d|tddgdd  d d t d }nCd ddtD}t t t|B}t d|dt t t| ttt d|tddgdd  dd t d }ttd|d }|dd |ddd|}|dd |ddd|}||_||_||fS)zRInternal helper to construct opening and closing tag expressions, given a tag namerz_-:ratag=/Fr-rEcS |ddkSNrrryrryryrzr{rz_makeTags..rbrcss|] }|dvr|VqdS)rbNryrryryrzrrz_makeTags..cSrrryrryryrzr{rrcr:rz<%s>rz)r}rrrr1r6r5r@rrr\r-r r4rrrrrXr[rDr _Lrtitlerrr)tagStrxmlresname tagAttrName tagAttrValueopenTagZprintablesLessRAbrackcloseTagryryrz _makeTags s> ..rcC t|dS)a  Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. Example:: text = 'More info at the pyparsing wiki page' # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple a,a_end = makeHTMLTags("A") link_expr = a + SkipTo(a_end)("link_text") + a_end for link in link_expr.searchString(text): # attributes in the tag (like "href" shown here) are also accessible as named results print(link.link_text, '->', link.href) prints:: pyparsing -> http://pyparsing.wikispaces.com FrrryryrzrM(s rMcCr)z Helper to construct opening and closing tag expressions for XML, given a tag name. Matches tags only in the given upper/lower case. Example: similar to L{makeHTMLTags} TrrryryrzrN;s rNcs8|r |ddn|ddDfdd}|S)a< Helper to create a validating parse action to be used with start tags created with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag with a required attribute value, to avoid false matches on common tags such as C{} or C{
}. Call C{withAttribute} with a series of attribute names and values. Specify the list of filter attributes names and values as: - keyword arguments, as in C{(align="right")}, or - as an explicit dict with C{**} operator, when an attribute name is also a Python reserved word, as in C{**{"class":"Customer", "align":"right"}} - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) For attribute names with a namespace prefix, you must use the second form. Attribute names are matched insensitive to upper/lower case. If just testing for C{class} (with or without a namespace), use C{L{withClass}}. To verify that the attribute exists, but without specifying a value, pass C{withAttribute.ANY_VALUE} as the value. Example:: html = '''
Some text
1 4 0 1 0
1,3 2,3 1,1
this has no type
''' div,div_end = makeHTMLTags("div") # only match div tag having a type attribute with value "grid" div_grid = div().setParseAction(withAttribute(type="grid")) grid_expr = div_grid + SkipTo(div | div_end)("body") for grid_header in grid_expr.searchString(html): print(grid_header.body) # construct a match with any div tag having a type attribute, regardless of the value div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) div_expr = div_any_type + SkipTo(div | div_end)("body") for div_header in div_expr.searchString(html): print(div_header.body) prints:: 1 4 0 1 0 1 4 0 1 0 1,3 2,3 1,1 NcSsg|]\}}||fqSryryrXryryrzrzrz!withAttribute..csZD](\}}||vrt||d||tjkr*|||kr*t||d||||fqdS)Nzno matching attribute z+attribute '%s' has value '%s', must be '%s')r!rg ANY_VALUE)rrrattrName attrValueattrsryrzr{s  zwithAttribute..pa)r)rattrDictrryrrzrgDs 2 rgcCs"|rd|nd}tdi||iS)a Simplified version of C{L{withAttribute}} when matching on a div class - made difficult because C{class} is a reserved word in Python. Example:: html = '''
Some text
1 4 0 1 0
1,3 2,3 1,1
this <div> has no class
''' div,div_end = makeHTMLTags("div") div_grid = div().setParseAction(withClass("grid")) grid_expr = div_grid + SkipTo(div | div_end)("body") for grid_header in grid_expr.searchString(html): print(grid_header.body) div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) div_expr = div_any_type + SkipTo(div | div_end)("body") for div_header in div_expr.searchString(html): print(div_header.body) prints:: 1 4 0 1 0 1 4 0 1 0 1,3 2,3 1,1 z%s:classclassNry)rg) classname namespace classattrryryrzrms rm(rcCst}||||B}t|D]-\}}|ddd\}} } } | dkr(d|nd|} | dkrB|dus:t|dkr>td|\} }t| }| tjkr| d kr`t||t|t |}n| dkr|dur{t|||t|t ||}nt||t|t |}n| dkrt|| |||t|| |||}nutd | tj kr| d krt |t st |}t|j |t||}nP| dkr|durt|||t|t ||}n5t||t|t |}n&| dkrt|| |||t|| |||}ntd td | r2t | ttfr-|j| n|| ||| |BK}|}q||K}|S) aD Helper method for constructing grammars of expressions made up of operators working in a precedence hierarchy. Operators may be unary or binary, left- or right-associative. Parse actions can also be attached to operator expressions. The generated parser will also recognize the use of parentheses to override operator precedences (see example below). Note: if you define a deep operator list, you may see performance issues when using infixNotation. See L{ParserElement.enablePackrat} for a mechanism to potentially improve your parser performance. Parameters: - baseExpr - expression representing the most basic element for the nested - opList - list of tuples, one for each operator precedence level in the expression grammar; each tuple is of the form (opExpr, numTerms, rightLeftAssoc, parseAction), where: - opExpr is the pyparsing expression for the operator; may also be a string, which will be converted to a Literal; if numTerms is 3, opExpr is a tuple of two expressions, for the two operators separating the 3 terms - numTerms is the number of terms for this operator (must be 1, 2, or 3) - rightLeftAssoc is the indicator whether the operator is right or left associative, using the pyparsing-defined constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. - parseAction is the parse action to be associated with expressions matching this operator expression (the parse action tuple member may be omitted); if the parse action is passed a tuple or list of functions, this is equivalent to calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) Example:: # simple example of four-function arithmetic with ints and variable names integer = pyparsing_common.signed_integer varname = pyparsing_common.identifier arith_expr = infixNotation(integer | varname, [ ('-', 1, opAssoc.RIGHT), (oneOf('* /'), 2, opAssoc.LEFT), (oneOf('+ -'), 2, opAssoc.LEFT), ]) arith_expr.runTests(''' 5+3*6 (5+3)*6 -2--11 ''', fullDump=False) prints:: 5+3*6 [[5, '+', [3, '*', 6]]] (5+3)*6 [[[5, '+', 3], '*', 6]] -2--11 [[['-', 2], '-', ['-', 11]]] rNrrqz%s termz %s%s termrsz@if numterms=3, opExpr must be a tuple or list of two expressionsrz6operator must be unary (1), binary (2), or ternary (3)z2operator must indicate right or left associativity)rrrrfrrVLEFTrrrRIGHTr}rrrerr)baseExpropListlparrparrlastExprroperDefopExprarityrightLeftAssocrtermNameopExpr1opExpr2thisExprrryryrzrksZ=  &  &   rkz4"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*"z string enclosed in double quotesz4'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*'z string enclosed in single quotesz*quotedString using single or double quotesuzunicode string literalcCs||krtd|durt|trt|trt|dkrQt|dkrQ|dur>tt|t||tjdd dd}nTt t||tj dd}nA|durstt|t |t |ttjdd dd}nttt |t |ttjdd d d}ntd t }|dur|tt|t||B|Bt|K}n|tt|t||Bt|K}|d ||f|S) a~ Helper method for defining nested lists enclosed in opening and closing delimiters ("(" and ")" are the default). Parameters: - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression - content - expression for items within the nested lists (default=C{None}) - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) If an expression is not provided for the content argument, the nested expression will capture all whitespace-delimited content between delimiters as a list of separate values. Use the C{ignoreExpr} argument to define expressions that may contain opening or closing characters that should not be treated as opening or closing characters for nesting, such as quotedString or a comment expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. The default is L{quotedString}, but if no expressions are to be ignored, then pass C{None} for this argument. Example:: data_type = oneOf("void int short long char float double") decl_data_type = Combine(data_type + Optional(Word('*'))) ident = Word(alphas+'_', alphanums+'_') number = pyparsing_common.number arg = Group(decl_data_type + ident) LPAR,RPAR = map(Suppress, "()") code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) c_function = (decl_data_type("type") + ident("name") + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + code_body("body")) c_function.ignore(cStyleComment) source_code = ''' int is_odd(int x) { return (x%2); } int dec_to_hex(char hchar) { if (hchar >= '0' && hchar <= '9') { return (ord(hchar)-ord('0')); } else { return (10+ord(hchar)-ord('A')); } } ''' for func in c_function.searchString(source_code): print("%(name)s (%(type)s) args: %(args)s" % func) prints:: is_odd (int) args: [['int', 'x']] dec_to_hex (int) args: [['char', 'hchar']] z.opening and closing strings cannot be the sameNrrcS |dSrrrwryryrzr{grznestedExpr..cSr!rr"rwryryrzr{jrcSr!rr"rwryryrzr{prcSr!rr"rwryryrzr{trzOopening and closing arguments must be strings if no content expression is givenznested %s%s expression)rfr}rrr rr r&rrrErrrrr-r4r)openerclosercontentrrryryrzrR%sH:      *$rRc sfdd}fdd}fdd}ttd}tt|d}t|d }t|d } |rStt||t|t|t|| } ntt|t|t|t|} | t t| d S) a Helper method for defining space-delimited indentation blocks, such as those used to define block statements in Python source code. Parameters: - blockStatementExpr - expression defining syntax of statement that is repeated within the indented block - indentStack - list created by caller to manage indentation stack (multiple statementWithIndentedBlock expressions within a single grammar should share a common indentStack) - indent - boolean indicating whether block must be indented beyond the the current level; set to False for block of left-most statements (default=C{True}) A valid block must contain at least one C{blockStatement}. Example:: data = ''' def A(z): A1 B = 100 G = A2 A2 A3 B def BB(a,b,c): BB1 def BBA(): bba1 bba2 bba3 C D def spam(x,y): def eggs(z): pass ''' indentStack = [1] stmt = Forward() identifier = Word(alphas, alphanums) funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") func_body = indentedBlock(stmt, indentStack) funcDef = Group( funcDecl + func_body ) rvalue = Forward() funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") rvalue << (funcCall | identifier | Word(nums)) assignment = Group(identifier + "=" + rvalue) stmt << ( funcDef | assignment | identifier ) module_body = OneOrMore(stmt) parseTree = module_body.parseString(data) parseTree.pprint() prints:: [['def', 'A', ['(', 'z', ')'], ':', [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], 'B', ['def', 'BB', ['(', 'a', 'b', 'c', ')'], ':', [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], 'C', 'D', ['def', 'spam', ['(', 'x', 'y', ')'], ':', [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] csN|t|krdSt||}|dkr%|dkrt||dt||ddS)Nrtzillegal nestingznot a peer entry)rr;r#r!rrrxcurCol indentStackryrzcheckPeerIndents     z&indentedBlock..checkPeerIndentcs0t||}|dkr|dSt||d)Nrtznot a subentry)r;r6r!r&r(ryrzcheckSubIndents   z%indentedBlock..checkSubIndentcsN|t|krdSt||}r|dkr|dks!t||ddS)Nrtrznot an unindent)rr;r!r1r&r(ryrz checkUnindents    z$indentedBlock..checkUnindentz INDENTrUNINDENTzindented block) rrryrtrrrrrr{r) blockStatementExprr)rgr*r+r,r|r-PEERUNDENTsmExprryr(rzrhs( N   rhz#[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]z[\0xa1-\0xbf\0xd7\0xf7]z_:zany tagzgt lt amp nbsp quot aposz><& "'z &(?Prz);zcommon HTML entitycCs t|jS)zRHelper parser action to replace common HTML entities with their special characters)_htmlEntityMaprentityrwryryrzr]r'r]z/\*(?:[^*]|\*(?!/))*z*/zC style commentzz HTML commentz.*z rest of linez//(?:\\\n|[^\n])*z // commentzC++ style commentz#.*zPython style commentr commaItemrr<c@seZdZdZeeZ eeZ e e  d eZ e e d eedZ ed d eZ e ede e dZ ed d eeeed eB d Z eeed  d eZ ed d eZ eeBeBZ ed d eZ e eded dZ ed dZ ed dZ!e!de!d dZ"ee!de!ddee!de!d dZ#e#$dd d e  d!Z%e&e"e%Be#B d" d"Z' ed# d$Z( e)d=d&d'Z*e)d>d)d*Z+ed+ d,Z, ed- d.Z- ed/ d0Z. e/e0BZ1e)d1d2Z2e&e3e4d3e5e e6d3d4ee7d5 d6Z8e9ee:;e8Bd7d8 d9Z< e)ed:d Z= e)ed;d Z>d}, L{reals}, L{scientific notation}) - common L{programming identifiers} - network addresses (L{MAC}, L{IPv4}, L{IPv6}) - ISO8601 L{dates} and L{datetime} - L{UUID} - L{comma-separated list} Parse actions: - C{L{convertToInteger}} - C{L{convertToFloat}} - C{L{convertToDate}} - C{L{convertToDatetime}} - C{L{stripHTMLTags}} - C{L{upcaseTokens}} - C{L{downcaseTokens}} Example:: pyparsing_common.number.runTests(''' # any int or real number, returned as the appropriate type 100 -100 +100 3.14159 6.02e23 1e-12 ''') pyparsing_common.fnumber.runTests(''' # any int or real number, returned as float 100 -100 +100 3.14159 6.02e23 1e-12 ''') pyparsing_common.hex_integer.runTests(''' # hex numbers 100 FF ''') pyparsing_common.fraction.runTests(''' # fractions 1/2 -3/4 ''') pyparsing_common.mixed_integer.runTests(''' # mixed fractions 1 1/2 -3/4 1-3/4 ''') import uuid pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) pyparsing_common.uuid.runTests(''' # uuid 12345678-1234-5678-1234-567812345678 ''') prints:: # any int or real number, returned as the appropriate type 100 [100] -100 [-100] +100 [100] 3.14159 [3.14159] 6.02e23 [6.02e+23] 1e-12 [1e-12] # any int or real number, returned as float 100 [100.0] -100 [-100.0] +100 [100.0] 3.14159 [3.14159] 6.02e23 [6.02e+23] 1e-12 [1e-12] # hex numbers 100 [256] FF [255] # fractions 1/2 [0.5] -3/4 [-0.75] # mixed fractions 1 [1] 1/2 [0.5] -3/4 [-0.75] 1-3/4 [1.75] # uuid 12345678-1234-5678-1234-567812345678 [UUID('12345678-1234-5678-1234-567812345678')] integerz hex integerrz[+-]?\d+zsigned integerrfractioncCs|d|dS)Nrrtryrwryryrzr{rzpyparsing_common.r/z"fraction or mixed integer-fractionz [+-]?\d+\.\d*z real numberz+[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)z$real number with scientific notationz[+-]?\d+\.?\d*([eE][+-]?\d+)?fnumberrK identifierzK(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}z IPv4 addressz[0-9a-fA-F]{1,4} hex_integerrzfull IPv6 address)rrz::zshort IPv6 addresscCstdd|DdkS)Ncss |] }tj|rdVqdSr^)rp _ipv6_partrHrryryrzrrYz,pyparsing_common...r)r_rwryryrzr{rOz::ffff:zmixed IPv6 addressz IPv6 addressz:[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}z MAC address%Y-%m-%dcr)a Helper to create a parse action for converting parsed date string to Python datetime.date Params - - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) Example:: date_expr = pyparsing_common.iso8601_date.copy() date_expr.setParseAction(pyparsing_common.convertToDate()) print(date_expr.parseString("1999-12-31")) prints:: [datetime.date(1999, 12, 31)] c s@z t|dWSty}zt||t|d}~wwr)rstrptimedaterfr!rrrrxvefmtryrzcvt_fns z.pyparsing_common.convertToDate..cvt_fnryrDrEryrCrz convertToDate zpyparsing_common.convertToDate%Y-%m-%dT%H:%M:%S.%fcr)a Helper to create a parse action for converting parsed datetime string to Python datetime.datetime Params - - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) Example:: dt_expr = pyparsing_common.iso8601_datetime.copy() dt_expr.setParseAction(pyparsing_common.convertToDatetime()) print(dt_expr.parseString("1999-12-31T23:59:59.999")) prints:: [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] c s<z t|dWSty}zt||t|d}~wwr)rr?rfr!rrArCryrzrEs z2pyparsing_common.convertToDatetime..cvt_fnryrFryrCrzconvertToDatetimerHz"pyparsing_common.convertToDatetimez7(?P\d{4})(?:-(?P\d\d)(?:-(?P\d\d))?)?z ISO8601 datez(?P\d{4})-(?P\d\d)-(?P\d\d)[T ](?P\d\d):(?P\d\d)(:(?P\d\d(\.\d*)?)?)?(?PZ|[+-]\d\d:?\d\d)?zISO8601 datetimez2[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}UUIDcCstj|dS)a Parse action to remove HTML tags from web page HTML source Example:: # strip HTML links from normal text text = 'More info at the
pyparsing wiki page' td,td_end = makeHTMLTags("TD") table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page' r)rp_html_stripperr)rrrryryrz stripHTMLTagss zpyparsing_common.stripHTMLTagsrrr5r6rrzcomma separated listcCrrrrwryryrzr{"rcCrrrrwryryrzr{%rN)r>)rI)?rrrrrorvconvertToIntegerfloatconvertToFloatr1rTrrr7rFr;r)signed_integerr8rrrt mixed_integerr_realsci_realr=numberr9r6r5r: ipv4_addressr=_full_ipv6_address_short_ipv6_addressr_mixed_ipv6_addressr ipv6_address mac_addressrrGrJ iso8601_dateiso8601_datetimeuuidr9r8rLrMrrrrXr0 _commasepitemrBr[rcomma_separated_listrfrDryryryrzrps"" 2      rp__main__selectfromrr)rcolumnsrZtablescommandaK # '*' as column list and dotted table name select * from SYS.XYZZY # caseless match on "SELECT", and casts back to "select" SELECT * from XYZZY, ABC # list of column names, and mixed case SELECT keyword Select AA,BB,CC from Sys.dual # multiple tables Select A, B, C from Sys.dual, Table2 # invalid SELECT keyword - should fail Xelect A, B, C from Sys.dual # incomplete command - should fail Select # invalid column name - should fail Select ^^^ frox Sys.dual z] 100 -100 +100 3.14159 6.02e23 1e-12 z 100 FF z6 12345678-1234-5678-1234-567812345678 )rs)rFr)FTrr)r __version____versionTime__ __author__rweakrefrrrrrYrrr/r}rrr_threadr ImportError threadingcollections.abcrrrr)Z ordereddict__all__re version_inforrZmaxsizerrrchrrrr_rrwreversedrrryr'rrrZmaxintxranger __builtin__rfnamer6rrrrrrrascii_uppercaseascii_lowercaser6rTrFr5rr printablerXrrr!r#r%r(rr$registerr;rLrIrrrrSrr&r.rrrrrrr r rnr1r)r'r r0rrrrr,r+r3r2r"rrrrr rrrtrr4rrrr*rrr/r rr r-rrdrBr>rMrQrPrrUrCrirjrlrrErKrJrcrbr _escapedPunc_escapedHexChar_escapedOctChar _singleChar _charRangerrrarOr^r\rorfrDrrMrNrgrrmrVrrrkrWr@r`r[rerRrhr7rYr9r8rrr3r&r=r]r:rGrwr_rAr?rHrZr=r_r<rprZ selectTokenZ fromTokenidentZ columnNameZcolumnNameListZ columnSpecZ tableNameZ tableNameListZ simpleSQLrrUr9r;r^rKryryryrzs4            8      @v &A= I G3pLOD|M &#@sQ,A ,   I #%     0  ,  ? #p   Zr   "    "   PKH]lfFfF^python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/recipes.cpython-310.pycnu[o Xai?@sdZddlZddlmZddlmZmZmZmZm Z m Z m Z m Z m Z mZddlZddlmZmZmZgdZddZdDd d Zd d ZdEd dZdEddZddZefddZddZeZddZddZ ddZ!dEddZ"dd Z#zdd!lm$Z%Wn e&ye#Z$Yn wd"d#Z$e#je$_dEd$d%Z'd&d'Z(d(d)Z)d*d+Z*dEd,d-Z+dEd.d/Z,dEd0d1Z-dFd2d3Z.d4d5d6d7Z/dEd8d9Z0d:d;Z1dd?Z3d@dAZ4dBdCZ5dS)GaImported from the recipes section of the itertools documentation. All functions taken from the recipes section of the itertools library docs [1]_. Some backward-compatible usability improvements have been made. .. [1] http://docs.python.org/library/itertools.html#recipes N)deque) chain combinationscountcyclegroupbyislicerepeatstarmaptee zip_longest) randrangesamplechoice) all_equalconsumeconvolve dotproduct first_trueflattengrouper iter_exceptncyclesnthnth_combinationpadnonepad_nonepairwise partitionpowersetprependquantify#random_combination_with_replacementrandom_combinationrandom_permutationrandom_product repeatfunc roundrobintabulatetailtakeunique_everseenunique_justseencCtt||S)zReturn first *n* items of the iterable as a list. >>> take(3, range(10)) [0, 1, 2] If there are fewer than *n* items in the iterable, all of them are returned. >>> take(10, range(3)) [0, 1, 2] )listrniterabler2/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/recipes.pyr*<s r*cCst|t|S)aReturn an iterator over the results of ``func(start)``, ``func(start + 1)``, ``func(start + 2)``... *func* should be a function that accepts one integer argument. If *start* is not specified it defaults to 0. It will be incremented each time the iterator is advanced. >>> square = lambda x: x ** 2 >>> iterator = tabulate(square, -3) >>> take(4, iterator) [9, 4, 1, 0] )mapr)functionstartr2r2r3r(Lsr(cCstt||dS)zReturn an iterator over the last *n* items of *iterable*. >>> t = tail(3, 'ABCDEFG') >>> list(t) ['E', 'F', 'G'] maxlen)iterrr/r2r2r3r)^sr)cCs.|dur t|dddStt|||ddS)aXAdvance *iterable* by *n* steps. If *n* is ``None``, consume it entirely. Efficiently exhausts an iterator without returning values. Defaults to consuming the whole iterator, but an optional second argument may be provided to limit consumption. >>> i = (x for x in range(10)) >>> next(i) 0 >>> consume(i, 3) >>> next(i) 4 >>> consume(i) >>> next(i) Traceback (most recent call last): File "", line 1, in StopIteration If the iterator has fewer items remaining than the provided limit, the whole iterator will be consumed. >>> i = (x for x in range(3)) >>> consume(i, 5) >>> next(i) Traceback (most recent call last): File "", line 1, in StopIteration Nrr7)rnextr)iteratorr0r2r2r3ris rcCstt||d|S)zReturns the nth item or a default value. >>> l = range(10) >>> nth(l, 3) 3 >>> nth(l, 20, "zebra") 'zebra' N)r:r)r1r0defaultr2r2r3rs rcCst|}t|dot|d S)z Returns ``True`` if all the elements are equal to each other. >>> all_equal('aaaa') True >>> all_equal('aaab') False TF)rr:)r1gr2r2r3rs rcCr-)zcReturn the how many times the predicate is true. >>> quantify([True, False, True]) 2 )sumr4)r1predr2r2r3r!sr!cCst|tdS)aReturns the sequence of elements and then returns ``None`` indefinitely. >>> take(5, pad_none(range(3))) [0, 1, 2, None, None] Useful for emulating the behavior of the built-in :func:`map` function. See also :func:`padded`. N)rr r1r2r2r3rs rcCsttt||S)zvReturns the sequence elements *n* times >>> list(ncycles(["a", "b"], 3)) ['a', 'b', 'a', 'b', 'a', 'b'] )r from_iterabler tuple)r1r0r2r2r3rsrcCstttj||S)zcReturns the dot product of the two iterables. >>> dotproduct([10, 10], [20, 20]) 400 )r>r4operatormul)Zvec1Zvec2r2r2r3rsrcCs t|S)zReturn an iterator flattening one level of nesting in a list of lists. >>> list(flatten([[0, 1], [2, 3]])) [0, 1, 2, 3] See also :func:`collapse`, which can flatten multiple levels of nesting. )rrA)Z listOfListsr2r2r3rs rcGs&|dur t|t|St|t||S)aGCall *func* with *args* repeatedly, returning an iterable over the results. If *times* is specified, the iterable will terminate after that many repetitions: >>> from operator import add >>> times = 4 >>> args = 3, 5 >>> list(repeatfunc(add, times, *args)) [8, 8, 8, 8] If *times* is ``None`` the iterable will not terminate: >>> from random import randrange >>> times = None >>> args = 1, 11 >>> take(6, repeatfunc(randrange, times, *args)) # doctest:+SKIP [2, 4, 8, 1, 8, 4] N)r r )functimesargsr2r2r3r&sr&ccs,t|\}}t|dt||EdHdS)zReturns an iterator of paired items, overlapping, from the original >>> take(4, pairwise(count())) [(0, 1), (1, 2), (2, 3), (3, 4)] On Python 3.10 and above, this is an alias for :func:`itertools.pairwise`. N)r r:zip)r1abr2r2r3 _pairwises rK)rccst|EdHdSN)itertools_pairwiser@r2r2r3rsrcCs<t|trtdt||}}t|g|}t|d|iS)zCollect data into fixed-length chunks or blocks. >>> list(grouper('ABCDEFG', 3, 'x')) [('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')] z+grouper expects iterable as first parameter fillvalue) isinstanceintwarningswarnDeprecationWarningr9r )r1r0rNrGr2r2r3rs  rcgslt|}tdd|D}|r4z |D]}|VqWnty/|d8}tt||}Ynw|sdSdS)aJYields an item from each iterable, alternating between them. >>> list(roundrobin('ABC', 'D', 'EF')) ['A', 'D', 'E', 'B', 'F', 'C'] This function produces the same output as :func:`interleave_longest`, but may perform better for some inputs (in particular when the number of iterables is small). css|]}t|jVqdSrL)r9__next__).0itr2r2r3 9zroundrobin..N)lenr StopIterationr) iterablespendingZnextsr:r2r2r3r',s    r'csFdurtfdd|D}t|\}}dd|Ddd|DfS)a Returns a 2-tuple of iterables derived from the input iterable. The first yields the items that have ``pred(item) == False``. The second yields the items that have ``pred(item) == True``. >>> is_odd = lambda x: x % 2 != 0 >>> iterable = range(10) >>> even_items, odd_items = partition(is_odd, iterable) >>> list(even_items), list(odd_items) ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9]) If *pred* is None, :func:`bool` is used. >>> iterable = [0, 1, False, True, '', ' '] >>> false_items, true_items = partition(None, iterable) >>> list(false_items), list(true_items) ([0, False, ''], [1, True, ' ']) Nc3s|] }||fVqdSrLr2)rUxr?r2r3rWZzpartition..css|] \}}|s|VqdSrLr2rUZcondr^r2r2r3rW]r`css|] \}}|r|VqdSrLr2rar2r2r3rW^r`)boolr )r?r1Z evaluationst1t2r2r_r3rCs   rcs,t|tfddttdDS)aYields all possible subsets of the iterable. >>> list(powerset([1, 2, 3])) [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] :func:`powerset` will operate on iterables that aren't :class:`set` instances, so repeated elements in the input will produce repeated elements in the output. Use :func:`unique_everseen` on the input to avoid generating duplicates: >>> seq = [1, 1, 0] >>> list(powerset(seq)) [(), (1,), (1,), (0,), (1, 1), (1, 0), (1, 0), (1, 1, 0)] >>> from more_itertools import unique_everseen >>> list(powerset(unique_everseen(seq))) [(), (1,), (0,), (1, 0)] c3s|]}t|VqdSrL)r)rUrsr2r3rWvrXzpowerset..rY)r.rrArangerZr@r2rfr3rbs$rc cst}|j}g}|j}|du}|D]+}|r||n|}z ||vr(|||VWqty=||vr;|||VYqwdS)a Yield unique elements, preserving order. >>> list(unique_everseen('AAAABBBCCDAABBB')) ['A', 'B', 'C', 'D'] >>> list(unique_everseen('ABBCcAD', str.lower)) ['A', 'B', 'C', 'D'] Sequences with a mix of hashable and unhashable items can be used. The function will be slower (i.e., `O(n^2)`) for unhashable items. Remember that ``list`` objects are unhashable - you can use the *key* parameter to transform the list to a tuple (which is hashable) to avoid a slowdown. >>> iterable = ([1, 2], [2, 3], [1, 2]) >>> list(unique_everseen(iterable)) # Slow [[1, 2], [2, 3]] >>> list(unique_everseen(iterable, key=tuple)) # Faster [[1, 2], [2, 3]] Similary, you may want to convert unhashable ``set`` objects with ``key=frozenset``. For ``dict`` objects, ``key=lambda x: frozenset(x.items())`` can be used. N)setaddappend TypeError) r1keyZseensetZ seenset_addZseenlistZ seenlist_addZuse_keyelementkr2r2r3r+ys( r+cCsttttdt||S)zYields elements in order, ignoring serial duplicates >>> list(unique_justseen('AAAABBBCCDAABBB')) ['A', 'B', 'C', 'D', 'A', 'B'] >>> list(unique_justseen('ABBCcAD', str.lower)) ['A', 'B', 'C', 'A', 'D'] rY)r4r:rC itemgetterr)r1rmr2r2r3r,s r,ccs4z|dur |V |Vq |yYdSw)aXYields results from a function repeatedly until an exception is raised. Converts a call-until-exception interface to an iterator interface. Like ``iter(func, sentinel)``, but uses an exception instead of a sentinel to end the loop. >>> l = [0, 1, 2] >>> list(iter_except(l.pop, IndexError)) [2, 1, 0] Nr2)rE exceptionfirstr2r2r3rs  rcCstt|||S)a Returns the first true value in the iterable. If no true value is found, returns *default* If *pred* is not None, returns the first item for which ``pred(item) == True`` . >>> first_true(range(10)) 1 >>> first_true(range(10), pred=lambda x: x > 5) 6 >>> first_true(range(10), default='missing', pred=lambda x: x > 9) 'missing' )r:filter)r1r<r?r2r2r3rsrrY)r cGs$dd|D|}tdd|DS)aDraw an item at random from each of the input iterables. >>> random_product('abc', range(4), 'XYZ') # doctest:+SKIP ('c', 3, 'Z') If *repeat* is provided as a keyword argument, that many items will be drawn from each iterable. >>> random_product('abcd', range(4), repeat=2) # doctest:+SKIP ('a', 2, 'd', 3) This equivalent to taking a random selection from ``itertools.product(*args, **kwarg)``. cSsg|]}t|qSr2rBrUpoolr2r2r3 sz"random_product..css|]}t|VqdSrL)rrur2r2r3rWz!random_product..rt)r rGpoolsr2r2r3r%sr%cCs*t|}|dur t|n|}tt||S)abReturn a random *r* length permutation of the elements in *iterable*. If *r* is not specified or is ``None``, then *r* defaults to the length of *iterable*. >>> random_permutation(range(5)) # doctest:+SKIP (3, 4, 0, 1, 2) This equivalent to taking a random selection from ``itertools.permutations(iterable, r)``. N)rBrZr)r1rervr2r2r3r$s r$cs8t|t}ttt||}tfdd|DS)zReturn a random *r* length subsequence of the elements in *iterable*. >>> random_combination(range(5), 3) # doctest:+SKIP (2, 3, 4) This equivalent to taking a random selection from ``itertools.combinations(iterable, r)``. c3|]}|VqdSrLr2rUirvr2r3rWrxz%random_combination..)rBrZsortedrrh)r1rer0indicesr2r}r3r#s r#cs@t|ttfddt|D}tfdd|DS)aSReturn a random *r* length subsequence of elements in *iterable*, allowing individual elements to be repeated. >>> random_combination_with_replacement(range(3), 5) # doctest:+SKIP (0, 0, 1, 2, 2) This equivalent to taking a random selection from ``itertools.combinations_with_replacement(iterable, r)``. c3s|]}tVqdSrL)r r{)r0r2r3rWrxz6random_combination_with_replacement..c3rzrLr2r{r}r2r3rWrx)rBrZr~rh)r1rerr2)r0rvr3r"s r"c Cst|}t|}|dks||krtd}t|||}td|dD] }|||||}q"|dkr7||7}|dks?||krAtg}|ry||||d|d}}}||krn||8}|||||d}}||ksY||d||sEt|S)aEquivalent to ``list(combinations(iterable, r))[index]``. The subsequences of *iterable* that are of length *r* can be ordered lexicographically. :func:`nth_combination` computes the subsequence at sort position *index* directly, without computing the previous subsequences. >>> nth_combination(range(5), 3, 5) (0, 3, 4) ``ValueError`` will be raised If *r* is negative or greater than the length of *iterable*. ``IndexError`` will be raised if the given *index* is invalid. rrY)rBrZ ValueErrorminrh IndexErrorrk) r1reindexrvr0cror|resultr2r2r3r"s, rcCs t|g|S)aYield *value*, followed by the elements in *iterator*. >>> value = '0' >>> iterator = ['1', '2', '3'] >>> list(prepend(value, iterator)) ['0', '1', '2', '3'] To prepend multiple values, see :func:`itertools.chain` or :func:`value_chain`. )r)valuer;r2r2r3r Ls r ccsjt|ddd}t|}tdg|d|}t|td|dD]}||tttj ||Vq!dS)aBConvolve the iterable *signal* with the iterable *kernel*. >>> signal = (1, 2, 3, 4, 5) >>> kernel = [3, 2, 1] >>> list(convolve(signal, kernel)) [3, 8, 14, 20, 26, 14, 5] Note: the input arguments are not interchangeable, as the *kernel* is immediately consumed and stored. Nrrr7rY) rBrZrrr rkr>r4rCrD)signalZkernelr0Zwindowr^r2r2r3r[s  r)rrL)NN)6__doc__rQ collectionsr itertoolsrrrrrrr r r r rCrandomr rr__all__r*r(r)rrrrbr!rrrrrr&rKrrM ImportErrorrr'rrr+r,rrr%r$r#r"rr rr2r2r2r3sV 0 !  (        -  * PKH]DBB_python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/__init__.cpython-310.pycnu[o XaiR@sddlTddlTdZdS))*z8.8.0N)moreZrecipes __version__rr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__init__.pysPKH]{yحح[python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/more.cpython-310.pycnu[o Xai@sddlZddlmZmZmZmZddlmZddlm Z ddl m Z m Z m Z ddlmZmZmZmZddlmZmZmZmZmZmZmZmZmZmZmZmZddl m!Z!m"Z"m#Z#m$Z$dd l%m&Z&m'Z'dd l(m(Z(m)Z)m*Z*dd l+m,Z,m-Z-m.Z.m/Z/m0Z0dd l1m2Z2m3Z3dd l4m5Z5ddl6m7Z7m8Z8m9Z9m:Z:m;Z;mZ?dddZ@e?fddZAe?fddZBe?fddZCGdddZDddZEddZFd d!ZGd"d#ZHd$d%ZIdd&d'ZJdd(d)ZKdd*d+ZLd,d-ZMdd.d/ZNd0d1ZOdd2d3ZPGd4d5d5ZQdd6d7ZRd8d9ZSd:d;ZTddd?ZVdd@dAZWddCdDZXddEdFZYddGdHZZddIdJZ[dKdLZ\ddMdNZ]ddOdPZ^dQdRZ_ddTdUZ`GdVdWdWeaZbdXdYZcdZd[Zdddd\d]d^Zedd`daZfdbdcZgdddeZheiejffdfdgZkddhdiZlddjdkZmGdldmdmejejnZoddndoZpdpdqZqerdfdrdsZsdtduZtdvdwZudxdyZvGdzd{d{Zwd|d}Zxd~dZyddfddZze.fddddZ{GdddeZ|GdddZ}GdddZ~erfddZddZd_ddZdddZerdfddZdddZddZdddZGdddZdddZddZddZddZddZddZddZdddZdddZGdddeZGdddZddZdddZddZddZddZddZdd„ZddĄZGddƄdƃZdS)N)Counter defaultdictdequeabc)Sequence)ThreadPoolExecutor)partialreducewraps)mergeheapify heapreplaceheappop) chaincompresscountcycle dropwhilegroupbyislicerepeatstarmap takewhiletee zip_longest)exp factorialfloorlog)EmptyQueue)random randrangeuniform) itemgettermulsubgtlt) hexversionmaxsize) monotonic)consumeflattenpairwisepowersettakeunique_everseen)S AbortThreadadjacentalways_iterablealways_reversiblebucket callback_iterchunkedcircular_shiftscollapsecollateconsecutive_groupsconsumer countable count_cycle mark_ends differencedistinct_combinationsdistinct_permutations distributedivide exactly_n filter_exceptfirstgroupby_transformileninterleave_longest interleave intersperseislice_extendediterateichunked is_sortedlastlocatelstripmake_decorator map_except map_reduce nth_or_lastnth_permutation nth_product numeric_rangeoneonlypadded partitionsset_partitionspeekable repeat_lastreplacerlocaterstrip run_lengthsampleseekable SequenceView side_effectsliced sort_togethersplit_at split_after split_before split_when split_intospystaggerstrip substringssubstrings_indexes time_limitedunique_to_eachunzipwindowed with_iterUnequalIterablesError zip_equal zip_offsetwindowed_complete all_unique value_chain product_indexcombination_indexpermutation_indexFcs6tttt|g|rfdd}t|SS)aJBreak *iterable* into lists of length *n*: >>> list(chunked([1, 2, 3, 4, 5, 6], 3)) [[1, 2, 3], [4, 5, 6]] By the default, the last yielded list will have fewer than *n* elements if the length of *iterable* is not divisible by *n*: >>> list(chunked([1, 2, 3, 4, 5, 6, 7, 8], 3)) [[1, 2, 3], [4, 5, 6], [7, 8]] To use a fill-in value instead, see the :func:`grouper` recipe. If the length of *iterable* is not divisible by *n* and *strict* is ``True``, then ``ValueError`` will be raised before the last list is yielded. c3*D]}t|krtd|VqdS)Nziterable is not divisible by n.len ValueError)chunkiteratorn/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/more.pyret  zchunked..ret)iterrr1)iterablerstrictrrrrr9s  r9c CsJztt|WSty$}z|turtd||WYd}~Sd}~ww)aReturn the first item of *iterable*, or *default* if *iterable* is empty. >>> first([0, 1, 2, 3]) 0 >>> first([], 'some default') 'some default' If *default* is not provided and there are no items in the iterable, raise ``ValueError``. :func:`first` is useful when you have a generator of expensive-to-retrieve values and want any arbitrary one. It is marginally shorter than ``next(iter(iterable), default)``. zKfirst() was called on an empty iterable, and no default value was provided.N)nextr StopIteration_markerr)rdefaulterrrrIsrIc Cstz#t|tr |dWSt|drtdkrtt|WSt|dddWSttt fy9|t ur5t d|YSw)aReturn the last item of *iterable*, or *default* if *iterable* is empty. >>> last([0, 1, 2, 3]) 3 >>> last([], 'some default') 'some default' If *default* is not provided and there are no items in the iterable, raise ``ValueError``. __reversed__ir,maxlenzDlast() was called on an empty iterable, and no default was provided.) isinstancerhasattrr)rreversedr IndexError TypeErrorrrr)rrrrrrSs  rScCstt||d|dS)agReturn the nth or the last item of *iterable*, or *default* if *iterable* is empty. >>> nth_or_last([0, 1, 2, 3], 2) 2 >>> nth_or_last([0, 1], 2) 1 >>> nth_or_last([], 0, 'some default') 'some default' If *default* is not provided and there are no items in the iterable, raise ``ValueError``. r,r)rSr)rrrrrrrYsrYc@sTeZdZdZddZddZddZefdd Zd d Z d d Z ddZ ddZ dS)rbaWrap an iterator to allow lookahead and prepending elements. Call :meth:`peek` on the result to get the value that will be returned by :func:`next`. This won't advance the iterator: >>> p = peekable(['a', 'b']) >>> p.peek() 'a' >>> next(p) 'a' Pass :meth:`peek` a default value to return that instead of raising ``StopIteration`` when the iterator is exhausted. >>> p = peekable([]) >>> p.peek('hi') 'hi' peekables also offer a :meth:`prepend` method, which "inserts" items at the head of the iterable: >>> p = peekable([1, 2, 3]) >>> p.prepend(10, 11, 12) >>> next(p) 10 >>> p.peek() 11 >>> list(p) [11, 12, 1, 2, 3] peekables can be indexed. Index 0 is the item that will be returned by :func:`next`, index 1 is the item after that, and so on: The values up to the given index will be cached. >>> p = peekable(['a', 'b', 'c', 'd']) >>> p[0] 'a' >>> p[1] 'b' >>> next(p) 'a' Negative indexes are supported, but be aware that they will cache the remaining items in the source iterator, which may require significant storage. To check whether a peekable is exhausted, check its truth value: >>> p = peekable(['a', 'b']) >>> if p: # peekable has items ... list(p) ['a', 'b'] >>> if not p: # peekable is exhausted ... list(p) [] cCst||_t|_dSN)r_itr_cacheselfrrrr__init__%s  zpeekable.__init__cC|Srrrrrr__iter__)zpeekable.__iter__cC$z|WdStyYdSwNFTpeekrrrrr__bool__,   zpeekable.__bool__cCsH|jsz |jt|jWnty|tur|YSw|jdS)zReturn the item that will be next returned from ``next()``. Return ``default`` if there are no items left. If ``default`` is not provided, raise ``StopIteration``. r)rappendrrrr)rrrrrr3s  z peekable.peekcGs|jt|dS)aStack up items to be the next ones returned from ``next()`` or ``self.peek()``. The items will be returned in first in, first out order:: >>> p = peekable([1, 2, 3]) >>> p.prepend(10, 11, 12) >>> next(p) 10 >>> list(p) [11, 12, 1, 2, 3] It is possible, by prepending items, to "resurrect" a peekable that previously raised ``StopIteration``. >>> p = peekable([]) >>> next(p) Traceback (most recent call last): ... StopIteration >>> p.prepend(1) >>> next(p) 1 >>> next(p) Traceback (most recent call last): ... StopIteration N)r extendleftr)ritemsrrrprependCszpeekable.prependcCs|jr|jSt|jSr)rpopleftrrrrrr__next__bs  zpeekable.__next__cCs|jdurdn|j}|dkr#|jdurdn|j}|jdurtn|j}n |dkr?|jdur.dn|j}|jdur;t dn|j}ntd|dksK|dkrS|j|jntt ||dt}t |j}||krr|jt |j||t |j|S)Nr,rrzslice step cannot be zero) stepstartstopr*rrextendrminmaxrrlist)rindexrrrr cache_lenrrr _get_slicehs zpeekable._get_slicecCsdt|tr ||St|j}|dkr|j|jn||kr-|jt|j|d||j|SNrr,)rslicerrrrrr)rrrrrr __getitem__s    zpeekable.__getitem__N) __name__ __module__ __qualname____doc__rrrrrrrrrrrrrrbs:  rbcOstdtt|i|S)aReturn a sorted merge of the items from each of several already-sorted *iterables*. >>> list(collate('ACDZ', 'AZ', 'JKL')) ['A', 'A', 'C', 'D', 'J', 'K', 'L', 'Z', 'Z'] Works lazily, keeping only the next value from each iterable in memory. Use :func:`collate` to, for example, perform a n-way mergesort of items that don't fit in memory. If a *key* function is specified, the iterables will be sorted according to its result: >>> key = lambda s: int(s) # Sort by numeric value, not by string >>> list(collate(['1', '10'], ['2', '11'], key=key)) ['1', '2', '10', '11'] If the *iterables* are sorted in descending order, set *reverse* to ``True``: >>> list(collate([5, 3, 1], [4, 2, 0], reverse=True)) [5, 4, 3, 2, 1, 0] If the elements of the passed-in iterables are out of order, you might get unexpected results. On Python 3.5+, this function is an alias for :func:`heapq.merge`. z>> @consumer ... def tally(): ... i = 0 ... while True: ... print('Thing number %s is %s.' % (i, (yield))) ... i += 1 ... >>> t = tally() >>> t.send('red') Thing number 0 is red. >>> t.send('fish') Thing number 1 is fish. Without the decorator, you would have to call ``next(t)`` before ``t.send()`` could be used. cs|i|}t||Sr)r)argsrgenfuncrrwrapperszconsumer..wrapper)r )rrrrrr>sr>cCs t}tt||ddt|S)zReturn the number of items in *iterable*. >>> ilen(x for x in range(1000000) if x % 3 == 0) 333334 This consumes the iterable, so handle with care. rr)rrzipr)rcounterrrrrKs rKccs |V||}q)zReturn ``start``, ``func(start)``, ``func(func(start))``, ... >>> from itertools import islice >>> list(islice(iterate(lambda x: 2*x, 1), 10)) [1, 2, 4, 8, 16, 32, 64, 128, 256, 512] r)rrrrrrPs rPccs6|}|EdHWddS1swYdS)a:Wrap an iterable in a ``with`` statement, so it closes once exhausted. For example, this will close the file when the iterator is exhausted:: upper_lines = (line.upper() for line in with_iter(open('foo'))) Any context manager which returns an iterable is a candidate for ``with_iter``. Nr)Zcontext_managerrrrrr|s "r|c Csvt|}zt|}Wnty}z|ptd|d}~wwzt|}Wn ty.Y|Swd||}|p:t|)aReturn the first item from *iterable*, which is expected to contain only that item. Raise an exception if *iterable* is empty or has more than one item. :func:`one` is useful for ensuring that an iterable contains only one item. For example, it can be used to retrieve the result of a database query that is expected to return a single row. If *iterable* is empty, ``ValueError`` will be raised. You may specify a different exception with the *too_short* keyword: >>> it = [] >>> one(it) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... ValueError: too many items in iterable (expected 1)' >>> too_short = IndexError('too few items') >>> one(it, too_short=too_short) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... IndexError: too few items Similarly, if *iterable* contains more than one item, ``ValueError`` will be raised. You may specify a different exception with the *too_long* keyword: >>> it = ['too', 'many'] >>> one(it) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... ValueError: Expected exactly one item in iterable, but got 'too', 'many', and perhaps more. >>> too_long = RuntimeError >>> one(it, too_long=too_long) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... RuntimeError Note that :func:`one` attempts to advance *iterable* twice to ensure there is only one item. See :func:`spy` or :func:`peekable` to check iterable contents less destructively. z&too few items in iterable (expected 1)NLExpected exactly one item in iterable, but got {!r}, {!r}, and perhaps more.)rrrrformat)rZ too_shorttoo_longit first_valuer second_valuemsgrrrr]s&,     r]cstfdd}dd}t|}t||dur}d|kr"kr1nn |kr,||S|||St|r7dSdS) aYield successive distinct permutations of the elements in *iterable*. >>> sorted(distinct_permutations([1, 0, 1])) [(0, 1, 1), (1, 0, 1), (1, 1, 0)] Equivalent to ``set(permutations(iterable))``, except duplicates are not generated and thrown away. For larger input sequences this is much more efficient. Duplicate permutations arise when there are duplicated elements in the input iterable. The number of items returned is `n! / (x_1! * x_2! * ... * x_n!)`, where `n` is the total number of items input, and each `x_i` is the count of a distinct item in the input sequence. If *r* is given, only the *r*-length permutations are yielded. >>> sorted(distinct_permutations([1, 0, 1], r=2)) [(0, 1), (1, 0), (1, 1)] >>> sorted(distinct_permutations(range(3), r=2)) [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)] c3s t|VtdddD]}||||dkrnqdStd|dD] }||||kr4nq(||||||<||<|d|d||dd<q)NTrr,)tuplerange)Aijsizerr_full^s z$distinct_permutations.._fullc ss4|d|||d}}t|ddd}tt|} t|V|d}|D]}|||kr2n||}q(dS|D]}||||krT||||||<||<nq;|D]}||||krp||||||<||<nqW||d||d7}|d7}|d|||||d||d<|dd<q)Nr,r)rrr) rrheadtailZright_head_indexesZleft_tail_indexesZpivotrrrrr_partialvs4    2z'distinct_permutations.._partialNrr)r)sortedrr)rrrrrrrrrDEs 'rDcCsX|dkrtd|dkrttt||ddSt|g}t||}ttt||ddS)a6Intersperse filler element *e* among the items in *iterable*, leaving *n* items between each filler element. >>> list(intersperse('!', [1, 2, 3, 4, 5])) [1, '!', 2, '!', 3, '!', 4, '!', 5] >>> list(intersperse(None, [1, 2, 3, 4, 5], n=2)) [1, 2, None, 3, 4, None, 5] rz n must be > 0r,N)rrrMrr9r.)rrrZfillerchunksrrrrNs   rNcsFdd|D}tttt|fddDfdd|DS)aReturn the elements from each of the input iterables that aren't in the other input iterables. For example, suppose you have a set of packages, each with a set of dependencies:: {'pkg_1': {'A', 'B'}, 'pkg_2': {'B', 'C'}, 'pkg_3': {'B', 'D'}} If you remove one package, which dependencies can also be removed? If ``pkg_1`` is removed, then ``A`` is no longer necessary - it is not associated with ``pkg_2`` or ``pkg_3``. Similarly, ``C`` is only needed for ``pkg_2``, and ``D`` is only needed for ``pkg_3``:: >>> unique_to_each({'A', 'B'}, {'B', 'C'}, {'B', 'D'}) [['A'], ['C'], ['D']] If there are duplicates in one input iterable that aren't in the others they will be duplicated in the output. Input order is preserved:: >>> unique_to_each("mississippi", "missouri") [['p', 'p'], ['o', 'u', 'r']] It is assumed that the elements of each iterable are hashable. cSsg|]}t|qSr)r.0rrrr z"unique_to_each..csh|] }|dkr|qSr,r)relement)countsrr z!unique_to_each..csg|] }ttj|qSr)rfilter __contains__r)uniquesrrrr)rr from_iterablemapset)rpoolr)rrrrysryccs|dkr td|dkrtVdS|dkrtdt|d}|}t|j|D]}|d8}|s7|}t|Vq(t|}||krOtt|t|||VdSd|kr\t||krmndS||f|7}t|VdSdS)aMReturn a sliding window of width *n* over the given iterable. >>> all_windows = windowed([1, 2, 3, 4, 5], 3) >>> list(all_windows) [(1, 2, 3), (2, 3, 4), (3, 4, 5)] When the window is larger than the iterable, *fillvalue* is used in place of missing values: >>> list(windowed([1, 2, 3], 4)) [(1, 2, 3, None)] Each window will advance in increments of *step*: >>> list(windowed([1, 2, 3, 4, 5, 6], 3, fillvalue='!', step=2)) [(1, 2, 3), (3, 4, 5), (5, 6, '!')] To slide into the iterable's items, use :func:`chain` to add filler items to the left: >>> iterable = [1, 2, 3, 4] >>> n = 3 >>> padding = [None] * (n - 1) >>> list(windowed(chain(padding, iterable), 3)) [(None, None, 1), (None, 1, 2), (1, 2, 3), (2, 3, 4)] rn must be >= 0Nr,zstep must be >= 1r) rrrrrrrrr)seqr fillvaluerZwindowr_rrrrr{s.   r{ccsvg}t|D] }|||fVqt|}t|}td|dD]}t||dD] }||||Vq,q"dS)aFYield all of the substrings of *iterable*. >>> [''.join(s) for s in substrings('more')] ['m', 'o', 'r', 'e', 'mo', 'or', 're', 'mor', 'ore', 'more'] Note that non-string iterables can also be subdivided. >>> list(substrings([0, 1, 2])) [(0,), (1,), (2,), (0, 1), (1, 2), (0, 1, 2)] rr,N)rrrrr)rritem item_countrrrrrrvs   rvcs0tdtd}|rt|}fdd|DS)a@Yield all substrings and their positions in *seq* The items yielded will be a tuple of the form ``(substr, i, j)``, where ``substr == seq[i:j]``. This function only works for iterables that support slicing, such as ``str`` objects. >>> for item in substrings_indexes('more'): ... print(item) ('m', 0, 1) ('o', 1, 2) ('r', 2, 3) ('e', 3, 4) ('mo', 0, 2) ('or', 1, 3) ('re', 2, 4) ('mor', 0, 3) ('ore', 1, 4) ('more', 0, 4) Set *reverse* to ``True`` to yield the same items in the opposite order. r,c3sD|]}tt|dD]}||||||fVqqdSr,N)rr)rLrrrr Ns  z%substrings_indexes..)rrr)rreverserrrrrw1s  rwc@s:eZdZdZd ddZddZddZd d Zd d ZdS)r7aWrap *iterable* and return an object that buckets it iterable into child iterables based on a *key* function. >>> iterable = ['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'b3'] >>> s = bucket(iterable, key=lambda x: x[0]) # Bucket by 1st character >>> sorted(list(s)) # Get the keys ['a', 'b', 'c'] >>> a_iterable = s['a'] >>> next(a_iterable) 'a1' >>> next(a_iterable) 'a2' >>> list(s['b']) ['b1', 'b2', 'b3'] The original iterable will be advanced and its items will be cached until they are used by the child iterables. This may require significant storage. By default, attempting to select a bucket to which no items belong will exhaust the iterable and cache all values. If you specify a *validator* function, selected buckets will instead be checked against it. >>> from itertools import count >>> it = count(1, 2) # Infinite sequence of odd numbers >>> key = lambda x: x % 10 # Bucket by last digit >>> validator = lambda x: x in {1, 3, 5, 7, 9} # Odd digits only >>> s = bucket(it, key=key, validator=validator) >>> 2 in s False >>> list(s[2]) [] NcCs,t||_||_tt|_|pdd|_dS)NcSsdSNTrxrrr{z!bucket.__init__..)rr_keyrrr _validator)rrkey validatorrrrrws  zbucket.__init__cCsH||sdSzt||}Wn tyYdSw|j||dSr)rrrr appendleft)rvaluerrrrr}s  zbucket.__contains__ccs~ |j|r|j|Vn. zt|j}Wn ty"YdSw||}||kr0|Vn||r=|j||qq)z Helper to yield items from the parent iterator that match *value*. Items that don't match are stored in the local cache as they are encountered. TN)rrrrrr rr)rrr item_valuerrr _get_valuess$    zbucket._get_valuesccsF|jD]}||}||r|j||q|jEdHdSr)rr rrrkeys)rrrrrrrs   zbucket.__iter__cCs||s tdS||S)Nr)rrrrrrrrrs  zbucket.__getitem__r) rrrrrrrrrrrrrr7Ss #  r7cCs$t|}t||}|t||fS)aReturn a 2-tuple with a list containing the first *n* elements of *iterable*, and an iterator with the same items as *iterable*. This allows you to "look ahead" at the items in the iterable without advancing it. There is one item in the list by default: >>> iterable = 'abcdefg' >>> head, iterable = spy(iterable) >>> head ['a'] >>> list(iterable) ['a', 'b', 'c', 'd', 'e', 'f', 'g'] You may use unpacking to retrieve items instead of lists: >>> (head,), iterable = spy('abcdefg') >>> head 'a' >>> (first, second), iterable = spy('abcdefg', 2) >>> first 'a' >>> second 'b' The number of items requested can be larger than the number of items in the iterable: >>> iterable = [1, 2, 3, 4, 5] >>> head, iterable = spy(iterable, 10) >>> head [1, 2, 3, 4, 5] >>> list(iterable) [1, 2, 3, 4, 5] )rr1copyr)rrrrrrrrss% rscGstt|S)a4Return a new iterable yielding from each iterable in turn, until the shortest is exhausted. >>> list(interleave([1, 2, 3], [4, 5], [6, 7, 8])) [1, 4, 6, 2, 5, 7] For a version that doesn't terminate after the shortest iterable is exhausted, see :func:`interleave_longest`. )rrr)rrrrrMs rMcGs"tt|dti}dd|DS)asReturn a new iterable yielding from each iterable in turn, skipping any that are exhausted. >>> list(interleave_longest([1, 2, 3], [4, 5], [6, 7, 8])) [1, 4, 6, 2, 5, 7, 3, 8] This function produces the same output as :func:`roundrobin`, but may perform better for some inputs (in particular when the number of iterables is large). rcss|] }|tur|VqdSr)r)rr rrrrz%interleave_longest..)rrrr)rrrrrrLs rLc#s&fdd|dEdHdS)a>Flatten an iterable with multiple levels of nesting (e.g., a list of lists of tuples) into non-iterable types. >>> iterable = [(1, 2), ([3, 4], [[5], [6]])] >>> list(collapse(iterable)) [1, 2, 3, 4, 5, 6] Binary and text strings are not considered iterable and will not be collapsed. To avoid collapsing other types, specify *base_type*: >>> iterable = ['ab', ('cd', 'ef'), ['gh', 'ij']] >>> list(collapse(iterable, base_type=tuple)) ['ab', ('cd', 'ef'), 'gh', 'ij'] Specify *levels* to stop flattening after a certain level: >>> iterable = [('a', ['b']), ('c', ['d'])] >>> list(collapse(iterable)) # Fully flattened ['a', 'b', 'c', 'd'] >>> list(collapse(iterable, levels=1)) # Only one level flattened ['a', ['b'], 'c', ['d']] c3sdur |kst|ttfsdurt|r|VdSzt|}Wn ty1|VYdSw|D] }||dEdHq4dSNr,)rstrbytesrr)nodeleveltreechild base_typelevelswalkrrr#s    zcollapse..walkrNr)rr!r"rr rr;sr;ccsz5|dur ||dur|D] }|||Vqnt||D] }|||EdHqW|dur5|dSdS|dur?|ww)auInvoke *func* on each item in *iterable* (or on each *chunk_size* group of items) before yielding the item. `func` must be a function that takes a single argument. Its return value will be discarded. *before* and *after* are optional functions that take no arguments. They will be executed before iteration starts and after it ends, respectively. `side_effect` can be used for logging, updating progress bars, or anything that is not functionally "pure." Emitting a status message: >>> from more_itertools import consume >>> func = lambda item: print('Received {}'.format(item)) >>> consume(side_effect(func, range(2))) Received 0 Received 1 Operating on chunks of items: >>> pair_sums = [] >>> func = lambda chunk: pair_sums.append(sum(chunk)) >>> list(side_effect(func, [0, 1, 2, 3, 4, 5], 2)) [0, 1, 2, 3, 4, 5] >>> list(pair_sums) [1, 5, 9] Writing to a file-like object: >>> from io import StringIO >>> from more_itertools import consume >>> f = StringIO() >>> func = lambda x: print(x, file=f) >>> before = lambda: print(u'HEADER', file=f) >>> after = f.close >>> it = [u'a', u'b', u'c'] >>> consume(side_effect(func, it, before=before, after=after)) >>> f.closed True N)r9)rr chunk_sizebeforeafterrrrrrrk,s$,   rkcs@ttfddtdD|rfdd}t|SS)apYield slices of length *n* from the sequence *seq*. >>> list(sliced((1, 2, 3, 4, 5, 6), 3)) [(1, 2, 3), (4, 5, 6)] By the default, the last yielded slice will have fewer than *n* elements if the length of *seq* is not divisible by *n*: >>> list(sliced((1, 2, 3, 4, 5, 6, 7, 8), 3)) [(1, 2, 3), (4, 5, 6), (7, 8)] If the length of *seq* is not divisible by *n* and *strict* is ``True``, then ``ValueError`` will be raised before the last slice is yielded. This function will only work for iterables that support slicing. For non-sliceable iterables, see :func:`chunked`. c3s |] }||VqdSrrrr)rrrrr}zsliced..rc3r)Nzseq is not divisible by n.r)Z_slicerrrrrzsliced..ret)rrrr)rrrrr)rrrrrlis  rlrccs|dkr t|VdSg}t|}|D]'}||r6|V|r#|gV|dkr/t|VdSg}|d8}q||q|VdS)a<Yield lists of items from *iterable*, where each list is delimited by an item where callable *pred* returns ``True``. >>> list(split_at('abcdcba', lambda x: x == 'b')) [['a'], ['c', 'd', 'c'], ['a']] >>> list(split_at(range(10), lambda n: n % 2 == 1)) [[0], [2], [4], [6], [8], []] At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, then there is no limit on the number of splits: >>> list(split_at(range(10), lambda n: n % 2 == 1, maxsplit=2)) [[0], [2], [4, 5, 6, 7, 8, 9]] By default, the delimiting items are not included in the output. The include them, set *keep_separator* to ``True``. >>> list(split_at('abcdcba', lambda x: x == 'b', keep_separator=True)) [['a'], ['b'], ['c', 'd', 'c'], ['b'], ['a']] rNr,rrr)rpredmaxsplitZkeep_separatorbufrrrrrrns$     rnccs|dkr t|VdSg}t|}|D]%}||r4|r4|V|dkr.|gt|VdSg}|d8}||q|rA|VdSdS)a\Yield lists of items from *iterable*, where each list ends just before an item for which callable *pred* returns ``True``: >>> list(split_before('OneTwo', lambda s: s.isupper())) [['O', 'n', 'e'], ['T', 'w', 'o']] >>> list(split_before(range(10), lambda n: n % 3 == 0)) [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, then there is no limit on the number of splits: >>> list(split_before(range(10), lambda n: n % 3 == 0, maxsplit=2)) [[0, 1, 2], [3, 4, 5], [6, 7, 8, 9]] rNr,r)rr*r+r,rrrrrrps$    rpccs|dkr t|VdSg}t|}|D]"}||||r6|r6|V|dkr0t|VdSg}|d8}q|r>|VdSdS)a[Yield lists of items from *iterable*, where each list ends with an item where callable *pred* returns ``True``: >>> list(split_after('one1two2', lambda s: s.isdigit())) [['o', 'n', 'e', '1'], ['t', 'w', 'o', '2']] >>> list(split_after(range(10), lambda n: n % 3 == 0)) [[0], [1, 2, 3], [4, 5, 6], [7, 8, 9]] At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, then there is no limit on the number of splits: >>> list(split_after(range(10), lambda n: n % 3 == 0, maxsplit=2)) [[0], [1, 2, 3], [4, 5, 6, 7, 8, 9]] rNr,r)r-rrrros&     roccs|dkr t|VdSt|}zt|}Wn ty YdSw|g}|D]&}|||rE|V|dkr?|gt|VdSg}|d8}|||}q&|VdS)aSplit *iterable* into pieces based on the output of *pred*. *pred* should be a function that takes successive pairs of items and returns ``True`` if the iterable should be split in between them. For example, to find runs of increasing numbers, split the iterable when element ``i`` is larger than element ``i + 1``: >>> list(split_when([1, 2, 3, 3, 2, 5, 2, 4, 2], lambda x, y: x > y)) [[1, 2, 3, 3], [2, 5], [2, 4], [2]] At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, then there is no limit on the number of splits: >>> list(split_when([1, 2, 3, 3, 2, 5, 2, 4, 2], ... lambda x, y: x > y, maxsplit=2)) [[1, 2, 3, 3], [2, 5], [2, 4, 2]] rNr,)rrrrr)rr*r+rZcur_itemr,Z next_itemrrrrqs,      rqccs@t|}|D]}|durt|VdStt||VqdS)aYield a list of sequential items from *iterable* of length 'n' for each integer 'n' in *sizes*. >>> list(split_into([1,2,3,4,5,6], [1,2,3])) [[1], [2, 3], [4, 5, 6]] If the sum of *sizes* is smaller than the length of *iterable*, then the remaining items of *iterable* will not be returned. >>> list(split_into([1,2,3,4,5,6], [2,3])) [[1, 2], [3, 4, 5]] If the sum of *sizes* is larger than the length of *iterable*, fewer items will be returned in the iteration that overruns *iterable* and further lists will be empty: >>> list(split_into([1,2,3,4], [1,2,3,4])) [[1], [2, 3], [4], []] When a ``None`` object is encountered in *sizes*, the returned list will contain items up to the end of *iterable* the same way that itertools.slice does: >>> list(split_into([1,2,3,4,5,6,7,8,9,0], [2,3,None])) [[1, 2], [3, 4, 5], [6, 7, 8, 9, 0]] :func:`split_into` can be useful for grouping a series of items where the sizes of the groups are not uniform. An example would be where in a row from a table, multiple columns represent elements of the same feature (e.g. a point represented by x,y,z) but, the format is not the same for all columns. N)rrr)rsizesrrrrrrr+s# rrc cst|}|durt|t|EdHdS|dkrtdd}|D] }|V|d7}q!|r3|||n||}t|D]}|Vq;dS)aYield the elements from *iterable*, followed by *fillvalue*, such that at least *n* items are emitted. >>> list(padded([1, 2, 3], '?', 5)) [1, 2, 3, '?', '?'] If *next_multiple* is ``True``, *fillvalue* will be emitted until the number of items emitted is a multiple of *n*:: >>> list(padded([1, 2, 3, 4], n=3, next_multiple=True)) [1, 2, 3, 4, None, None] If *n* is ``None``, *fillvalue* will be emitted indefinitely. Nr,n must be at least 1r)rrrrr) rrrZ next_multiplerrr remainingrrrrr_Xs  r_ccs8t}|D]}|Vq|tur|n|}t|EdHdS)a"After the *iterable* is exhausted, keep yielding its last element. >>> list(islice(repeat_last(range(3)), 5)) [0, 1, 2, 2, 2] If the iterable is empty, yield *default* forever:: >>> list(islice(repeat_last(range(0), 42), 5)) [42, 42, 42, 42, 42] N)rr)rrrfinalrrrrcxs  rccs0dkrtdt|}fddt|DS)aDistribute the items from *iterable* among *n* smaller iterables. >>> group_1, group_2 = distribute(2, [1, 2, 3, 4, 5, 6]) >>> list(group_1) [1, 3, 5] >>> list(group_2) [2, 4, 6] If the length of *iterable* is not evenly divisible by *n*, then the length of the returned iterables will not be identical: >>> children = distribute(3, [1, 2, 3, 4, 5, 6, 7]) >>> [list(c) for c in children] [[1, 4, 7], [2, 5], [3, 6]] If the length of *iterable* is smaller than *n*, then the last returned iterables will be empty: >>> children = distribute(5, [1, 2, 3]) >>> [list(c) for c in children] [[1], [2], [3], [], []] This function uses :func:`itertools.tee` and may require significant storage. If you need the order items in the smaller iterables to match the original iterable, see :func:`divide`. r,r/csg|] \}}t||dqSr)r)rrrrrrrszdistribute..)rr enumerate)rrchildrenrr2rrEs rErrr,cCs t|t|}t||||dS)a[Yield tuples whose elements are offset from *iterable*. The amount by which the `i`-th item in each tuple is offset is given by the `i`-th item in *offsets*. >>> list(stagger([0, 1, 2, 3])) [(None, 0, 1), (0, 1, 2), (1, 2, 3)] >>> list(stagger(range(8), offsets=(0, 2, 4))) [(0, 2, 4), (1, 3, 5), (2, 4, 6), (3, 5, 7)] By default, the sequence will end when the final element of a tuple is the last item in the iterable. To continue until the first element of a tuple is the last item in the iterable, set *longest* to ``True``:: >>> list(stagger([0, 1, 2, 3], longest=True)) [(None, 0, 1), (0, 1, 2), (1, 2, 3), (2, 3, None), (3, None, None)] By default, ``None`` will be used to replace offsets beyond the end of the sequence. Specify *fillvalue* to use some other value. )offsetslongestr)rrr)rr6r7rr4rrrrtsrtcseZdZdfdd ZZS)r}Ncs*d}|dur |dj|7}t|dS)Nz Iterables have different lengthsz/: index 0 has length {}; index {} has length {})rsuperr)rdetailsr __class__rrrs zUnequalIterablesError.__init__r)rrrr __classcell__rrr:rr}sr}ccs8t|dtiD]}|D] }|turtq |VqdS)Nr)rrr})rZcombovalrrr_zip_equal_generatorsr>cGstdkr tdtz+t|d}t|dddD]\}}t|}||kr(nqt|WSt|||fdtyBt |YSw)a ``zip`` the input *iterables* together, but raise ``UnequalIterablesError`` if they aren't all the same length. >>> it_1 = range(3) >>> it_2 = iter('abc') >>> list(zip_equal(it_1, it_2)) [(0, 'a'), (1, 'b'), (2, 'c')] >>> it_1 = range(3) >>> it_2 = iter('abcd') >>> list(zip_equal(it_1, it_2)) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... more_itertools.more.UnequalIterablesError: Iterables have different lengths i zwzip_equal will be removed in a future version of more-itertools. Use the builtin zip function with strict=True instead.rr,N)r9) r)rrrrr3rr}rr>)rZ first_sizerrrrrrr~s"    r~)r7rcGst|t|kr tdg}t||D](\}}|dkr(|tt|| |q|dkr6|t||dq||q|rEt|d|iSt|S)aF``zip`` the input *iterables* together, but offset the `i`-th iterable by the `i`-th item in *offsets*. >>> list(zip_offset('0123', 'abcdef', offsets=(0, 1))) [('0', 'b'), ('1', 'c'), ('2', 'd'), ('3', 'e')] This can be used as a lightweight alternative to SciPy or pandas to analyze data sets in which some series have a lead or lag relationship. By default, the sequence will end when the shortest iterable is exhausted. To continue until the longest iterable is exhausted, set *longest* to ``True``. >>> list(zip_offset('0123', 'abcdef', offsets=(0, 1), longest=True)) [('0', 'b'), ('1', 'c'), ('2', 'd'), ('3', 'e'), (None, 'f')] By default, ``None`` will be used to replace offsets beyond the end of the sequence. Specify *fillvalue* to use some other value. z,Number of iterables and offsets didn't matchrNr)rrrrrrrr)r6r7rr staggeredrrrrrr s rrcsndur t|}n!t|}t|dkr|dfdd}n t|fdd}tttt|||dS)aReturn the input iterables sorted together, with *key_list* as the priority for sorting. All iterables are trimmed to the length of the shortest one. This can be used like the sorting function in a spreadsheet. If each iterable represents a column of data, the key list determines which columns are used for sorting. By default, all iterables are sorted using the ``0``-th iterable:: >>> iterables = [(4, 3, 2, 1), ('a', 'b', 'c', 'd')] >>> sort_together(iterables) [(1, 2, 3, 4), ('d', 'c', 'b', 'a')] Set a different key list to sort according to another iterable. Specifying multiple keys dictates how ties are broken:: >>> iterables = [(3, 1, 2), (0, 1, 0), ('c', 'b', 'a')] >>> sort_together(iterables, key_list=(1, 2)) [(2, 3, 1), (0, 0, 1), ('a', 'c', 'b')] To sort by a function of the elements of the iterable, pass a *key* function. Its arguments are the elements of the iterables corresponding to the key list:: >>> names = ('a', 'b', 'c') >>> lengths = (1, 2, 3) >>> widths = (5, 2, 1) >>> def area(length, width): ... return length * width >>> sort_together([names, lengths, widths], key_list=(1, 2), key=area) [('c', 'b', 'a'), (3, 2, 1), (1, 2, 5)] Set *reverse* to ``True`` to sort in descending order. >>> sort_together([(1, 2, 3), ('c', 'b', 'a')], reverse=True) [(3, 2, 1), ('a', 'b', 'c')] Nr,rcs |SrrZ zipped_items)r key_offsetrrr fs zsort_together..cs |SrrrA) get_key_itemsrrrr ks)rr)r$rrrr)rZkey_listrrZ key_argumentr)rCrrBrrm2s(  rmcsPtt|\}}|s dS|d}t|t|}ddtfddt|DS)aThe inverse of :func:`zip`, this function disaggregates the elements of the zipped *iterable*. The ``i``-th iterable contains the ``i``-th element from each element of the zipped iterable. The first element is used to to determine the length of the remaining elements. >>> iterable = [('a', 1), ('b', 2), ('c', 3), ('d', 4)] >>> letters, numbers = unzip(iterable) >>> list(letters) ['a', 'b', 'c', 'd'] >>> list(numbers) [1, 2, 3, 4] This is similar to using ``zip(*iterable)``, but it avoids reading *iterable* into memory. Note, however, that this function uses :func:`itertools.tee` and thus may require significant storage. rrcsfdd}|S)Ncsz|WStytwr)rr)objrrrgetters    z)unzip..itemgetter..getterr)rrFrrErr$s zunzip..itemgetterc3s"|] \}}t||VqdSrr)rrrr$rrr zunzip..)rsrrrrr3)rrrrrHrrztsrzc Cs|dkrtdz|ddWn tyt|}Ynw|}tt||\}}g}d}td|dD]}|}|||krA|dn|7}|t|||q4|S)aDivide the elements from *iterable* into *n* parts, maintaining order. >>> group_1, group_2 = divide(2, [1, 2, 3, 4, 5, 6]) >>> list(group_1) [1, 2, 3] >>> list(group_2) [4, 5, 6] If the length of *iterable* is not evenly divisible by *n*, then the length of the returned iterables will not be identical: >>> children = divide(3, [1, 2, 3, 4, 5, 6, 7]) >>> [list(c) for c in children] [[1, 2, 3], [4, 5], [6, 7]] If the length of the iterable is smaller than n, then the last returned iterables will be empty: >>> children = divide(5, [1, 2, 3]) >>> [list(c) for c in children] [[1], [2], [3], [], []] This function will exhaust the iterable before returning and may require significant storage. If order is not important, see :func:`distribute`, which does not first pull the iterable into memory. r,r/Nr)rrrdivmodrrrr) rrrqrrrrrrrrrFs   rFcCsT|durtdS|durt||rt|fSzt|WSty)t|fYSw)axIf *obj* is iterable, return an iterator over its items:: >>> obj = (1, 2, 3) >>> list(always_iterable(obj)) [1, 2, 3] If *obj* is not iterable, return a one-item iterable containing *obj*:: >>> obj = 1 >>> list(always_iterable(obj)) [1] If *obj* is ``None``, return an empty iterable: >>> obj = None >>> list(always_iterable(None)) [] By default, binary and text strings are not considered iterable:: >>> obj = 'foo' >>> list(always_iterable(obj)) ['foo'] If *base_type* is set, objects for which ``isinstance(obj, base_type)`` returns ``True`` won't be considered iterable. >>> obj = {'a': 1} >>> list(always_iterable(obj)) # Iterate over the dict's keys ['a'] >>> list(always_iterable(obj, base_type=dict)) # Treat dicts as a unit [{'a': 1}] Set *base_type* to ``None`` to avoid any special handling and treat objects Python considers iterable as iterable: >>> obj = 'foo' >>> list(always_iterable(obj, base_type=None)) ['f', 'o', 'o'] Nr)rrr)rDr!rrrr5s)   r5cCsZ|dkrtdt|\}}dg|}t|t|||}ttt|d|d}t||S)asReturn an iterable over `(bool, item)` tuples where the `item` is drawn from *iterable* and the `bool` indicates whether that item satisfies the *predicate* or is adjacent to an item that does. For example, to find whether items are adjacent to a ``3``:: >>> list(adjacent(lambda x: x == 3, range(6))) [(False, 0), (False, 1), (True, 2), (True, 3), (True, 4), (False, 5)] Set *distance* to change what counts as adjacent. For example, to find whether items are two places away from a ``3``: >>> list(adjacent(lambda x: x == 3, range(6), distance=2)) [(False, 0), (True, 1), (True, 2), (True, 3), (True, 4), (True, 5)] This is useful for contextualizing the results of a search function. For example, a code comparison tool might want to identify lines that have changed, but also surrounding lines to give the viewer of the diff context. The predicate function will only be called once for each item in the iterable. See also :func:`groupby_transform`, which can be used with this function to group ranges of items with the same `bool` value. rzdistance must be at least 0Frr,)rrrranyr{r) predicaterdistancei1i2paddingselectedZadjacent_to_selectedrrrr4 s   r4cs:t||}rfdd|D}rfdd|D}|S)aAn extension of :func:`itertools.groupby` that can apply transformations to the grouped data. * *keyfunc* is a function computing a key value for each item in *iterable* * *valuefunc* is a function that transforms the individual items from *iterable* after grouping * *reducefunc* is a function that transforms each group of items >>> iterable = 'aAAbBBcCC' >>> keyfunc = lambda k: k.upper() >>> valuefunc = lambda v: v.lower() >>> reducefunc = lambda g: ''.join(g) >>> list(groupby_transform(iterable, keyfunc, valuefunc, reducefunc)) [('A', 'aaa'), ('B', 'bbb'), ('C', 'ccc')] Each optional argument defaults to an identity function if not specified. :func:`groupby_transform` is useful when grouping elements of an iterable using a separate iterable as the key. To do this, :func:`zip` the iterables and pass a *keyfunc* that extracts the first element and a *valuefunc* that extracts the second element:: >>> from operator import itemgetter >>> keys = [0, 0, 1, 1, 1, 2, 2, 2, 3] >>> values = 'abcdefghi' >>> iterable = zip(keys, values) >>> grouper = groupby_transform(iterable, itemgetter(0), itemgetter(1)) >>> [(k, ''.join(g)) for k, g in grouper] [(0, 'ab'), (1, 'cde'), (2, 'fgh'), (3, 'i')] Note that the order of items in the iterable is significant. Only adjacent items are grouped together, so if you don't want any duplicate groups, you should sort the iterable by the key function. c3s"|] \}}|t|fVqdSrrGrkg) valuefuncrrrZrIz$groupby_transform..c3s |] \}}||fVqdSrrrS) reducefuncrrr\r(r)rkeyfuncrVrWrr)rWrVrrJ4s $rJc@seZdZdZeeddZddZddZddZ d d Z d d Z d dZ ddZ ddZddZddZddZddZddZddZdd Zd!S)"r\a<An extension of the built-in ``range()`` function whose arguments can be any orderable numeric type. With only *stop* specified, *start* defaults to ``0`` and *step* defaults to ``1``. The output items will match the type of *stop*: >>> list(numeric_range(3.5)) [0.0, 1.0, 2.0, 3.0] With only *start* and *stop* specified, *step* defaults to ``1``. The output items will match the type of *start*: >>> from decimal import Decimal >>> start = Decimal('2.1') >>> stop = Decimal('5.1') >>> list(numeric_range(start, stop)) [Decimal('2.1'), Decimal('3.1'), Decimal('4.1')] With *start*, *stop*, and *step* specified the output items will match the type of ``start + step``: >>> from fractions import Fraction >>> start = Fraction(1, 2) # Start at 1/2 >>> stop = Fraction(5, 2) # End at 5/2 >>> step = Fraction(1, 2) # Count by 1/2 >>> list(numeric_range(start, stop, step)) [Fraction(1, 2), Fraction(1, 1), Fraction(3, 2), Fraction(2, 1)] If *step* is zero, ``ValueError`` is raised. Negative steps are supported: >>> list(numeric_range(3, -1, -1.0)) [3.0, 2.0, 1.0, 0.0] Be aware of the limitations of floating point numbers; the representation of the yielded numbers may be surprising. ``datetime.datetime`` objects can be used for *start* and *stop*, if *step* is a ``datetime.timedelta`` object: >>> import datetime >>> start = datetime.datetime(2019, 1, 1) >>> stop = datetime.datetime(2019, 1, 3) >>> step = datetime.timedelta(days=1) >>> items = iter(numeric_range(start, stop, step)) >>> next(items) datetime.datetime(2019, 1, 1, 0, 0) >>> next(items) datetime.datetime(2019, 1, 2, 0, 0) rcGst|}|dkr |\|_t|jd|_t|j|jd|_n5|dkr6|\|_|_t|j|jd|_n|dkrC|\|_|_|_n|dkrNtd|td|t|jd|_|j|jkrgtd|j|jk|_ | dS)Nr,rrz2numeric_range expected at least 1 argument, got {}z2numeric_range expected at most 3 arguments, got {}z&numeric_range() arg 3 must not be zero) r_stoptype_start_steprr_zeror_growing _init_len)rrZargcrrrrs0   znumeric_range.__init__cCs|jr |j|jkS|j|jkSr)r`r]r[rrrrrs  znumeric_range.__bool__cCsx|jr|j|kr|jkrndS||j|j|jkSdS|j|kr+|jkr:ndS|j||j |jkSdSNF)r`r]r[r^r_)relemrrrrsznumeric_range.__contains__cCs^t|tr-t| }t| }|s|r|o|S|j|jko,|j|jko,|d|dkSdS)NrF)rr\boolr]r^ _get_by_index)rotherZ empty_selfZ empty_otherrrr__eq__s     znumeric_range.__eq__cCst|tr ||St|trc|jdur|jn|j|j}|jdus)|j|j kr-|j}n|j|jkr7|j }n||j}|j dusH|j |jkrL|j }n|j |j krW|j}n||j }t |||St d t|j)Nz8numeric range indices must be integers or slices, not {})rintrerrr^r_lenr]r[rr\rrr\r)rrrrrrrrrs&        znumeric_range.__getitem__cCs"|rt|j|d|jfS|jSNr)hashr]rer^ _EMPTY_HASHrrrr__hash__sznumeric_range.__hash__cs>fddtD}jrtttj|Stttj|S)Nc3s |] }j|jVqdSr)r]r^)rrrrrrr(z)numeric_range.__iter__..)rr`rrr'r[r()rvaluesrrrrsznumeric_range.__iter__cCs|jSr)rirrrr__len__sznumeric_range.__len__cCst|jr |j}|j}|j}n |j}|j}|j }||}||jkr%d|_dSt||\}}t|t||jk|_dSNr)r`r]r[r^r_rirJrh)rrrrrNrKrrrrras  znumeric_range._init_lencCst|j|j|jffSr)r\r]r[r^rrrr __reduce__ sznumeric_range.__reduce__cCsB|jdkrdt|jt|jSdt|jt|jt|jS)Nr,znumeric_range({}, {})znumeric_range({}, {}, {}))r^rreprr]r[rrrr__repr__s znumeric_range.__repr__cCs"tt|d|j|j|j Srj)rr\rer]r^rrrrrs znumeric_range.__reversed__cCs t||vSr)rhrrrrr!s znumeric_range.countcCs|jr&|j|kr|jkr%nn8t||j|j\}}||jkr%t|Sn#|j|kr2|jkrInnt|j||j \}}||jkrIt|Std|)Nz{} is not in numeric range) r`r]r[rJr^r_rhrr)rrrKrrrrr$s  znumeric_range.indexcCs<|dkr ||j7}|dks||jkrtd|j||jS)Nrz'numeric range object index out of range)rirr]r^)rrrrrre2s  znumeric_range._get_by_indexN)rrrrrkrrlrrrrgrrmrrorarqrsrrrrerrrrr\as$3   r\cs<ts tdS|durtnt|}fdd|DS)aCycle through the items from *iterable* up to *n* times, yielding the number of completed cycles along with each item. If *n* is omitted the process repeats indefinitely. >>> list(count_cycle('AB', 3)) [(0, 'A'), (0, 'B'), (1, 'A'), (1, 'B'), (2, 'A'), (2, 'B')] rNc3s"|] }D]}||fVqqdSrr)rrrrrrrGrIzcount_cycle..)rrrr)rrrrrtrr@:s  r@ccst|}zt|}Wn tyYdSwztD]}|}t|}|dkd|fVqWdSty?|dkd|fVYdSw)aHYield 3-tuples of the form ``(is_first, is_last, item)``. >>> list(mark_ends('ABC')) [(True, False, 'A'), (False, False, 'B'), (False, True, 'C')] Use this when looping over an iterable to take special action on its first and/or last items: >>> iterable = ['Header', 100, 200, 'Footer'] >>> total = 0 >>> for is_first, is_last, item in mark_ends(iterable): ... if is_first: ... continue # Skip the header ... if is_last: ... continue # Skip the footer ... total += item >>> print(total) 300 NrFT)rrrr)rrbrarrrrAJs     rAcCsJ|dur ttt||S|dkrtdt||td}ttt||S)aYield the index of each item in *iterable* for which *pred* returns ``True``. *pred* defaults to :func:`bool`, which will select truthy items: >>> list(locate([0, 1, 1, 0, 1, 0, 0])) [1, 2, 4] Set *pred* to a custom function to, e.g., find the indexes for a particular item. >>> list(locate(['a', 'b', 'c', 'b'], lambda x: x == 'b')) [1, 3] If *window_size* is given, then the *pred* function will be called with that many items. This enables searching for sub-sequences: >>> iterable = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3] >>> pred = lambda *args: args == (1, 2, 3) >>> list(locate(iterable, pred=pred, window_size=3)) [1, 5, 9] Use with :func:`seekable` to find indexes and then retrieve the associated items: >>> from itertools import count >>> from more_itertools import seekable >>> source = (3 * n + 1 if (n % 2) else n // 2 for n in count()) >>> it = seekable(source) >>> pred = lambda x: x > 100 >>> indexes = locate(it, pred=pred) >>> i = next(indexes) >>> it.seek(i) >>> next(it) 106 Nr,zwindow size must be at least 1r)rrrrr{rr)rr* window_sizerrrrrTos &rTcCs t||S)aYield the items from *iterable*, but strip any from the beginning for which *pred* returns ``True``. For example, to remove a set of items from the start of an iterable: >>> iterable = (None, False, None, 1, 2, None, 3, False, None) >>> pred = lambda x: x in {None, False, ''} >>> list(lstrip(iterable, pred)) [1, 2, None, 3, False, None] This function is analogous to to :func:`str.lstrip`, and is essentially an wrapper for :func:`itertools.dropwhile`. )rrr*rrrrUs rUccsHg}|j}|j}|D]}||r||q |EdH||Vq dS)aYield the items from *iterable*, but strip any from the end for which *pred* returns ``True``. For example, to remove a set of items from the end of an iterable: >>> iterable = (None, False, None, 1, 2, None, 3, False, None) >>> pred = lambda x: x in {None, False, ''} >>> list(rstrip(iterable, pred)) [None, False, None, 1, 2, None, 3] This function is analogous to :func:`str.rstrip`. N)rclear)rr*cacheZ cache_append cache_clearr rrrrfs  rfcCstt|||S)aYield the items from *iterable*, but strip any from the beginning and end for which *pred* returns ``True``. For example, to remove a set of items from both ends of an iterable: >>> iterable = (None, False, None, 1, 2, None, 3, False, None) >>> pred = lambda x: x in {None, False, ''} >>> list(strip(iterable, pred)) [1, 2, None, 3] This function is analogous to :func:`str.strip`. )rfrUryrrrrusruc@0eZdZdZddZddZddZdd Zd S) rOaAn extension of :func:`itertools.islice` that supports negative values for *stop*, *start*, and *step*. >>> iterable = iter('abcdefgh') >>> list(islice_extended(iterable, -4, -1)) ['e', 'f', 'g'] Slices with negative values require some caching of *iterable*, but this function takes care to minimize the amount of memory required. For example, you can use a negative step with an infinite iterator: >>> from itertools import count >>> list(islice_extended(count(), 110, 99, -2)) [110, 108, 106, 104, 102, 100] You can also use slice notation directly: >>> iterable = map(str, count()) >>> it = islice_extended(iterable)[10:20:2] >>> list(it) ['10', '12', '14', '16', '18'] cGs*t|}|rt|t||_dS||_dSr)r_islice_helperr _iterable)rrrrrrrrs zislice_extended.__init__cCrrrrrrrrrzislice_extended.__iter__cC t|jSr)rrrrrrr  zislice_extended.__next__cCs"t|tr tt|j|Std)Nz4islice_extended.__getitem__ argument must be a slice)rrrOr~rr)rrrrrr s zislice_extended.__getitem__N)rrrrrrrrrrrrrOs  rOccs|j}|j}|jdkrtd|jpd}|dkr|durdn|}|dkrstt|d| d}|r7|ddnd}t||d}|durG|}n|dkrQt||}nt||d}||} | dkrbdSt|d| |D]\} } | VqidS|dur|dkrt t|||dtt|| | d}t|D]\} } | } | |dkr| V| | qdSt||||EdHdS|durdn|}|dur |dkr | d} tt|d| d}|r|ddnd}|dkr||}}n t||dd}}t ||||D]\} } | VqdS|dur|d} t t|| | d|dkr%|}d} n|dur1d}|d} n d}||} | dkr>dSt t|| }||d|EdHdS)Nrz1step argument must be a non-zero integer or None.r,rr) rrrrrr3rrrrrrr)rsrrrr{len_iterrrrrrZ cached_itemmrrrr~ sv            r~cCs*zt|WStytt|YSw)aAn extension of :func:`reversed` that supports all iterables, not just those which implement the ``Reversible`` or ``Sequence`` protocols. >>> print(*always_reversible(x for x in range(3))) 2 1 0 If the iterable is already reversible, this function returns the result of :func:`reversed()`. If the iterable is not reversible, this function will cache the remaining items in the iterable and yield them in reverse order, which may require significant storage. )rrrrtrrrr6j s   r6cCrrrr rrrr | r r c#s8tt|fdddD] \}}ttd|Vq dS)aYield groups of consecutive items using :func:`itertools.groupby`. The *ordering* function determines whether two items are adjacent by returning their position. By default, the ordering function is the identity function. This is suitable for finding runs of numbers: >>> iterable = [1, 10, 11, 12, 20, 30, 31, 32, 33, 40] >>> for group in consecutive_groups(iterable): ... print(list(group)) [1] [10, 11, 12] [20] [30, 31, 32, 33] [40] For finding runs of adjacent letters, try using the :meth:`index` method of a string of letters: >>> from string import ascii_lowercase >>> iterable = 'abcdfgilmnop' >>> ordering = ascii_lowercase.index >>> for group in consecutive_groups(iterable, ordering): ... print(list(group)) ['a', 'b', 'c', 'd'] ['f', 'g'] ['i'] ['l', 'm', 'n', 'o', 'p'] Each group of consecutive items is an iterator that shares it source with *iterable*. When an an output group is advanced, the previous group is no longer available unless its elements are copied (e.g., into a ``list``). >>> iterable = [1, 2, 11, 12, 21, 22] >>> saved_groups = [] >>> for group in consecutive_groups(iterable): ... saved_groups.append(list(group)) # Copy group elements >>> saved_groups [[1, 2], [11, 12], [21, 22]] cs|d|dSrrr orderingrrr  rz$consecutive_groups..rr,N)rr3rr$)rrrTrUrrrr=| s *r=)initialcCsXt|\}}zt|g}Wn tytgYSw|dur!g}t|t|t||S)aThis function is the inverse of :func:`itertools.accumulate`. By default it will compute the first difference of *iterable* using :func:`operator.sub`: >>> from itertools import accumulate >>> iterable = accumulate([0, 1, 2, 3, 4]) # produces 0, 1, 3, 6, 10 >>> list(difference(iterable)) [0, 1, 2, 3, 4] *func* defaults to :func:`operator.sub`, but other functions can be specified. They will be applied as follows:: A, B, C, D, ... --> A, func(B, A), func(C, B), func(D, C), ... For example, to do progressive division: >>> iterable = [1, 2, 6, 24, 120] >>> func = lambda x, y: x // y >>> list(difference(iterable, func)) [1, 2, 3, 4, 5] If the *initial* keyword is set, the first element will be skipped when computing successive differences. >>> it = [10, 11, 13, 16] # from accumulate([1, 2, 3], initial=10) >>> list(difference(it, initial=10)) [1, 2, 3] N)rrrrrrr)rrrrvrurIrrrrB s   rBc@r}) rjaSReturn a read-only view of the sequence object *target*. :class:`SequenceView` objects are analogous to Python's built-in "dictionary view" types. They provide a dynamic view of a sequence's items, meaning that when the sequence updates, so does the view. >>> seq = ['0', '1', '2'] >>> view = SequenceView(seq) >>> view SequenceView(['0', '1', '2']) >>> seq.append('3') >>> view SequenceView(['0', '1', '2', '3']) Sequence views support indexing, slicing, and length queries. They act like the underlying sequence, except they don't allow assignment: >>> view[1] '1' >>> view[1:-1] ['1', '2'] >>> len(view) 4 Sequence views are useful as an alternative to copying, as they don't require (much) extra storage. cCst|tst||_dSr)rrr_target)rtargetrrrr s  zSequenceView.__init__cCs |j|Sr)r)rrrrrr rzSequenceView.__getitem__cCrr)rrrrrrro rzSequenceView.__len__cCsd|jjt|jS)Nz{}({}))rr;rrrrrrrrrs szSequenceView.__repr__N)rrrrrrrorsrrrrrj s  rjc@sNeZdZdZdddZddZddZd d Zefd d Z d dZ ddZ dS)ria Wrap an iterator to allow for seeking backward and forward. This progressively caches the items in the source iterable so they can be re-visited. Call :meth:`seek` with an index to seek to that position in the source iterable. To "reset" an iterator, seek to ``0``: >>> from itertools import count >>> it = seekable((str(n) for n in count())) >>> next(it), next(it), next(it) ('0', '1', '2') >>> it.seek(0) >>> next(it), next(it), next(it) ('0', '1', '2') >>> next(it) '3' You can also seek forward: >>> it = seekable((str(n) for n in range(20))) >>> it.seek(10) >>> next(it) '10' >>> it.seek(20) # Seeking past the end of the source isn't a problem >>> list(it) [] >>> it.seek(0) # Resetting works even after hitting the end >>> next(it), next(it), next(it) ('0', '1', '2') Call :meth:`peek` to look ahead one item without advancing the iterator: >>> it = seekable('1234') >>> it.peek() '1' >>> list(it) ['1', '2', '3', '4'] >>> it.peek(default='empty') 'empty' Before the iterator is at its end, calling :func:`bool` on it will return ``True``. After it will return ``False``: >>> it = seekable('5678') >>> bool(it) True >>> list(it) ['5', '6', '7', '8'] >>> bool(it) False You may view the contents of the cache with the :meth:`elements` method. That returns a :class:`SequenceView`, a view that updates automatically: >>> it = seekable((str(n) for n in range(10))) >>> next(it), next(it), next(it) ('0', '1', '2') >>> elements = it.elements() >>> elements SequenceView(['0', '1', '2']) >>> next(it) '3' >>> elements SequenceView(['0', '1', '2', '3']) By default, the cache grows as the source iterable progresses, so beware of wrapping very large or infinite iterables. Supply *maxlen* to limit the size of the cache (this of course limits how far back you can seek). >>> from itertools import count >>> it = seekable((str(n) for n in count()), maxlen=2) >>> next(it), next(it), next(it), next(it) ('0', '1', '2', '3') >>> list(it.elements()) ['2', '3'] >>> it.seek(0) >>> next(it), next(it), next(it), next(it) ('2', '3', '4', '5') >>> next(it) '6' NcCs0t||_|dur g|_ntg||_d|_dSr)r_sourcerr_index)rrrrrrrY s   zseekable.__init__cCrrrrrrrra rzseekable.__iter__cCs`|jdur#z|j|j}Wn tyd|_Yn w|jd7_|St|j}|j||Sr)rrrrrrrrrrrrd s     zseekable.__next__cCrrrrrrrrr rzseekable.__bool__cCsVzt|}Wnty|tur|YSw|jdur"t|j|_|jd8_|Sr)rrrrrr)rrZpeekedrrrry s    z seekable.peekcCrr)rjrrrrrelements rzseekable.elementscCs.||_|t|j}|dkrt||dSdSrp)rrrr-)rr remainderrrrseek s z seekable.seekr) rrrrrrrrrrrrrrrrri s U  ric@s(eZdZdZeddZeddZdS)rga :func:`run_length.encode` compresses an iterable with run-length encoding. It yields groups of repeated items with the count of how many times they were repeated: >>> uncompressed = 'abbcccdddd' >>> list(run_length.encode(uncompressed)) [('a', 1), ('b', 2), ('c', 3), ('d', 4)] :func:`run_length.decode` decompresses an iterable that was previously compressed with run-length encoding. It yields the items of the decompressed iterable: >>> compressed = [('a', 1), ('b', 2), ('c', 3), ('d', 4)] >>> list(run_length.decode(compressed)) ['a', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd', 'd'] cCsddt|DS)Ncss |] \}}|t|fVqdSr)rKrSrrrr r(z$run_length.encode..rXrtrrrencode szrun_length.encodecCstdd|DS)Ncss|] \}}t||VqdSr)r)rrTrrrrr z$run_length.decode..)rrrtrrrdecode szrun_length.decodeN)rrrr staticmethodrrrrrrrg s  rgcCstt|dt|||kS)aReturn ``True`` if exactly ``n`` items in the iterable are ``True`` according to the *predicate* function. >>> exactly_n([True, True, False], 2) True >>> exactly_n([True, True, False], 1) False >>> exactly_n([0, 1, 2, 3, 4, 5], 3, lambda x: x < 3) True The iterable will be advanced until ``n + 1`` truthy items are encountered, so avoid calling it on infinite iterables. r,)rr1r)rrrMrrrrG srGcCs$t|}tt|tt|t|S)zReturn a list of circular shifts of *iterable*. >>> circular_shifts(range(4)) [(0, 1, 2, 3), (1, 2, 3, 0), (2, 3, 0, 1), (3, 0, 1, 2)] )rr1rr{r)rlstrrrr: sr:csfdd}|S)aReturn a decorator version of *wrapping_func*, which is a function that modifies an iterable. *result_index* is the position in that function's signature where the iterable goes. This lets you use itertools on the "production end," i.e. at function definition. This can augment what the function returns without changing the function's code. For example, to produce a decorator version of :func:`chunked`: >>> from more_itertools import chunked >>> chunker = make_decorator(chunked, result_index=0) >>> @chunker(3) ... def iter_range(n): ... return iter(range(n)) ... >>> list(iter_range(9)) [[0, 1, 2], [3, 4, 5], [6, 7, 8]] To only allow truthy items to be returned: >>> truth_serum = make_decorator(filter, result_index=1) >>> @truth_serum(bool) ... def boolean_test(): ... return [0, 1, '', ' ', False, True] ... >>> list(boolean_test()) [1, ' ', True] The :func:`peekable` and :func:`seekable` wrappers make for practical decorators: >>> from more_itertools import peekable >>> peekable_function = make_decorator(peekable) >>> @peekable_function() ... def str_range(*args): ... return (str(x) for x in range(*args)) ... >>> it = str_range(1, 20, 2) >>> next(it), next(it), next(it) ('1', '3', '5') >>> it.peek() '7' >>> next(it) '7' csfdd}|S)Ncsfdd}|S)Ncs0|i|}t}|||iSr)rinsert)rrresultZwrapping_args_)f result_index wrapping_args wrapping_funcwrapping_kwargsrr inner_wrapper s zOmake_decorator..decorator..outer_wrapper..inner_wrapperr)rr)rrrr)rr outer_wrapper sz8make_decorator..decorator..outer_wrapperr)rrrrr)rrr decorator s z!make_decorator..decoratorr)rrrrrrrV s2 rVc Cst|durddn|}tt}|D]}||}||}|||q|dur5|D] \}}||||<q*d|_|S)aReturn a dictionary that maps the items in *iterable* to categories defined by *keyfunc*, transforms them with *valuefunc*, and then summarizes them by category with *reducefunc*. *valuefunc* defaults to the identity function if it is unspecified. If *reducefunc* is unspecified, no summarization takes place: >>> keyfunc = lambda x: x.upper() >>> result = map_reduce('abbccc', keyfunc) >>> sorted(result.items()) [('A', ['a']), ('B', ['b', 'b']), ('C', ['c', 'c', 'c'])] Specifying *valuefunc* transforms the categorized items: >>> keyfunc = lambda x: x.upper() >>> valuefunc = lambda x: 1 >>> result = map_reduce('abbccc', keyfunc, valuefunc) >>> sorted(result.items()) [('A', [1]), ('B', [1, 1]), ('C', [1, 1, 1])] Specifying *reducefunc* summarizes the categorized items: >>> keyfunc = lambda x: x.upper() >>> valuefunc = lambda x: 1 >>> reducefunc = sum >>> result = map_reduce('abbccc', keyfunc, valuefunc, reducefunc) >>> sorted(result.items()) [('A', 1), ('B', 2), ('C', 3)] You may want to filter the input iterable before applying the map/reduce procedure: >>> all_items = range(30) >>> items = [x for x in all_items if 10 <= x <= 20] # Filter >>> keyfunc = lambda x: x % 2 # Evens map to 0; odds to 1 >>> categories = map_reduce(items, keyfunc=keyfunc) >>> sorted(categories.items()) [(0, [10, 12, 14, 16, 18, 20]), (1, [11, 13, 15, 17, 19])] >>> summaries = map_reduce(items, keyfunc=keyfunc, reducefunc=sum) >>> sorted(summaries.items()) [(0, 90), (1, 75)] Note that all items in the iterable are gathered into a list before the summarization step, which may require significant storage. The returned object is a :obj:`collections.defaultdict` with the ``default_factory`` set to ``None``, such that it behaves like a normal dictionary. NcSrrrr rrrr < r zmap_reduce..)rrrrdefault_factory) rrYrVrWrrrrZ value_listrrrrX s3rXcsV|dur!zt|fddtt||DWSty Ynwttt|||S)aYield the index of each item in *iterable* for which *pred* returns ``True``, starting from the right and moving left. *pred* defaults to :func:`bool`, which will select truthy items: >>> list(rlocate([0, 1, 1, 0, 1, 0, 0])) # Truthy at 1, 2, and 4 [4, 2, 1] Set *pred* to a custom function to, e.g., find the indexes for a particular item: >>> iterable = iter('abcb') >>> pred = lambda x: x == 'b' >>> list(rlocate(iterable, pred)) [3, 1] If *window_size* is given, then the *pred* function will be called with that many items. This enables searching for sub-sequences: >>> iterable = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3] >>> pred = lambda *args: args == (1, 2, 3) >>> list(rlocate(iterable, pred=pred, window_size=3)) [9, 5, 1] Beware, this function won't return anything for infinite iterables. If *iterable* is reversible, ``rlocate`` will reverse it and search from the right. Otherwise, it will search from the left and return the results in reverse order. See :func:`locate` to for other example applications. Nc3s|] }|dVqdSrrr'rrrrp rzrlocate..)rrTrrr)rr*rxrrrreL s! rec cs|dkr tdt|}t|tg|d}t||}d}|D],}||r?|dus.||kr?|d7}|EdHt||dq |rL|dturL|dVq dS)aYYield the items from *iterable*, replacing the items for which *pred* returns ``True`` with the items from the iterable *substitutes*. >>> iterable = [1, 1, 0, 1, 1, 0, 1, 1] >>> pred = lambda x: x == 0 >>> substitutes = (2, 3) >>> list(replace(iterable, pred, substitutes)) [1, 1, 2, 3, 1, 1, 2, 3, 1, 1] If *count* is given, the number of replacements will be limited: >>> iterable = [1, 1, 0, 1, 1, 0, 1, 1, 0] >>> pred = lambda x: x == 0 >>> substitutes = [None] >>> list(replace(iterable, pred, substitutes, count=2)) [1, 1, None, 1, 1, None, 1, 1, 0] Use *window_size* to control the number of items passed as arguments to *pred*. This allows for locating and replacing subsequences. >>> iterable = [0, 1, 2, 5, 0, 1, 2, 5] >>> window_size = 3 >>> pred = lambda *args: args == (0, 1, 2) # 3 items passed to pred >>> substitutes = [3, 4] # Splice in these items >>> list(replace(iterable, pred, substitutes, window_size=window_size)) [3, 4, 5, 3, 4, 5] r,zwindow_size must be at least 1rN)rrrrr{r-) rr*Z substitutesrrxrZwindowsrwrrrrdw s$   rdc#sNt|t}ttd|D]}fddtd|||fDVqdS)a"Yield all possible order-preserving partitions of *iterable*. >>> iterable = 'abc' >>> for part in partitions(iterable): ... print([''.join(p) for p in part]) ['abc'] ['a', 'bc'] ['ab', 'c'] ['a', 'b', 'c'] This is unrelated to :func:`partition`. r,csg|] \}}||qSrr)rrrsequencerrr rzpartitions..r@N)rrr0rr)rrrrrrr` s &r`c#st|}t|}|dur|dkrtd||krdSfdd|dur9td|dD] }||EdHq,dS||EdHdS)a Yield the set partitions of *iterable* into *k* parts. Set partitions are not order-preserving. >>> iterable = 'abc' >>> for part in set_partitions(iterable, 2): ... print([''.join(p) for p in part]) ['a', 'bc'] ['ab', 'c'] ['b', 'ac'] If *k* is not given, every set partition is generated. >>> iterable = 'abc' >>> for part in set_partitions(iterable): ... print([''.join(p) for p in part]) ['abc'] ['a', 'bc'] ['ab', 'c'] ['b', 'ac'] ['a', 'b', 'c'] Nr,z6Can't partition in a negative or zero number of groupsc3st|}|dkr|gVdS||krdd|DVdS|^}}||dD] }|gg|Vq(||D]"}tt|D]}|d||g||g||ddVq?q7dS)Nr,cSsg|]}|gqSrr)rrrrrr szAset_partitions..set_partitions_helper..)rr)rrTrrMprset_partitions_helperrrr s 0z-set_partitions..set_partitions_helper)rrrr)rrTrrrrrra s  rac@(eZdZdZddZddZddZdS) rxa Yield items from *iterable* until *limit_seconds* have passed. If the time limit expires before all items have been yielded, the ``timed_out`` parameter will be set to ``True``. >>> from time import sleep >>> def generator(): ... yield 1 ... yield 2 ... sleep(0.2) ... yield 3 >>> iterable = time_limited(0.1, generator()) >>> list(iterable) [1, 2] >>> iterable.timed_out True Note that the time is checked before each item is yielded, and iteration stops if the time elapsed is greater than *limit_seconds*. If your time limit is 1 second, but it takes 2 seconds to generate the first item from the iterable, the function will run for 2 seconds and not yield anything. cCs2|dkrtd||_t||_t|_d|_dS)Nrzlimit_seconds must be positiveF)r limit_secondsrrr+ _start_time timed_out)rrrrrrr s   ztime_limited.__init__cCrrrrrrrr! rztime_limited.__iter__cCs*t|j}t|j|jkrd|_t|Sr)rrr+rrrrrrrrr$ s ztime_limited.__next__Nrrrrrrrrrrrrx s  rxcCsLt|}t||}zt|}Wn tyY|Swd||}|p%t|)a*If *iterable* has only one item, return it. If it has zero items, return *default*. If it has more than one item, raise the exception given by *too_long*, which is ``ValueError`` by default. >>> only([], default='missing') 'missing' >>> only([1]) 1 >>> only([1, 2]) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... ValueError: Expected exactly one item in iterable, but got 1, 2, and perhaps more.' >>> only([1, 2], too_long=TypeError) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... TypeError Note that :func:`only` attempts to advance *iterable* twice to ensure there is only one item. See :func:`spy` or :func:`peekable` to check iterable contents less destructively. r)rrrrr)rrrrrrrrrrr^- s    r^ccsNt|} t|t}|turdStt|g|\}}t||Vt||q)aBreak *iterable* into sub-iterables with *n* elements each. :func:`ichunked` is like :func:`chunked`, but it yields iterables instead of lists. If the sub-iterables are read in order, the elements of *iterable* won't be stored in memory. If they are read out of order, :func:`itertools.tee` is used to cache elements as necessary. >>> from itertools import count >>> all_chunks = ichunked(count(), 4) >>> c_1, c_2, c_3 = next(all_chunks), next(all_chunks), next(all_chunks) >>> list(c_2) # c_1's elements have been cached; c_3's haven't been [4, 5, 6, 7] >>> list(c_1) [0, 1, 2, 3] >>> list(c_3) [8, 9, 10, 11] TN)rrrrrrr-)rrsourcerrrrrrQV s   rQccs|dkr td|dkrdVdSt|}tt|tddg}dg|}d}|rtz t|d\}}WntyE||d8}Yq(w|||<|d|krVt|Vn|tt||dd|dtdd|d7}|s*dSdS)aBYield the distinct combinations of *r* items taken from *iterable*. >>> list(distinct_combinations([0, 0, 1], 2)) [(0, 0), (0, 1)] Equivalent to ``set(combinations(iterable))``, except duplicates are not generated and thrown away. For larger input sequences this is much more efficient. rzr must be non-negativerNr,rr) rrr2r3r$rrpopr)rrr generatorsZ current_comborZcur_idxrrrrrC{ s:      rCc gs6|D]}z||Wn |yYqw|VqdS)aYield the items from *iterable* for which the *validator* function does not raise one of the specified *exceptions*. *validator* is called for each item in *iterable*. It should be a function that accepts one argument and raises an exception if that item is not valid. >>> iterable = ['1', '2', 'three', '4', None] >>> list(filter_except(int, iterable, ValueError, TypeError)) ['1', '2', '4'] If an exception other than one given by *exceptions* is raised by *validator*, it is raised like normal. Nr)rr exceptionsrrrrrH s  rHc gs0|D]}z||VWq|yYqwdS)aTransform each item from *iterable* with *function* and yield the result, unless *function* raises one of the specified *exceptions*. *function* is called to transform each item in *iterable*. It should be a accept one argument. >>> iterable = ['1', '2', 'three', '4', None] >>> list(map_except(int, iterable, ValueError, TypeError)) [1, 2, 4] If an exception other than one given by *exceptions* is raised by *function*, it is raised like normal. Nr)functionrrrrrrrW s rWcCst||}ttt|}|ttttd|}t||D]*\}}||krL||t|<|ttt|9}|ttttd|d7}q"|Sr)r1rrr!rr3r")rrT reservoirWZ next_indexrrrrr_sample_unweighted s  "rc sdd|D}t|t||td\}}tt|}t||D]8\}}||krYd\}}t||} t| d} t| |} t| |fd\}}tt|}q%||8}q%fddt|DS)Ncss|] }tt|VqdSr)rr!)rweightrrrr rz#_sample_weighted..rr,csg|]}tdqSr)r)rrrrrr sz$_sample_weighted..) r1rr rr!rr#r r) rrTweightsZ weight_keysZsmallest_weight_keyrZweights_to_skiprrZt_wZr_2Z weight_keyrrr_sample_weighted s        rcCs:|dkrgSt|}|durt||St|}t|||S)afReturn a *k*-length list of elements chosen (without replacement) from the *iterable*. Like :func:`random.sample`, but works on iterables of unknown length. >>> iterable = range(100) >>> sample(iterable, 5) # doctest: +SKIP [81, 60, 96, 16, 4] An iterable with *weights* may also be given: >>> iterable = range(100) >>> weights = (i * i + 1 for i in range(100)) >>> sampled = sample(iterable, 5, weights=weights) # doctest: +SKIP [79, 67, 74, 66, 78] The algorithm can also be used to generate weighted random permutations. The relative weight of each item determines the probability that it appears late in the permutation. >>> data = "abcdefgh" >>> weights = range(1, len(data) + 1) >>> sample(data, k=len(data), weights=weights) # doctest: +SKIP ['c', 'a', 'b', 'e', 'g', 'd', 'h', 'f'] rN)rrr)rrTrrrrrh s  rhcCs6|rtnt}|dur |nt||}tt|t| S)aReturns ``True`` if the items of iterable are in sorted order, and ``False`` otherwise. *key* and *reverse* have the same meaning that they do in the built-in :func:`sorted` function. >>> is_sorted(['1', '2', '3', '4', '5'], key=int) True >>> is_sorted([5, 4, 3, 1, 2], reverse=True) False The function returns ``False`` after encountering the first out-of-order item. If there are no out-of-order items, the iterable is exhausted. N)r(r'rrLrr/)rrrcomparerrrrrR1 s rRc@s eZdZdS)r3N)rrrrrrrr3D sr3c@sZeZdZdZdddZddZdd Zd d Zd d Ze ddZ e ddZ ddZ dS)r8aConvert a function that uses callbacks to an iterator. Let *func* be a function that takes a `callback` keyword argument. For example: >>> def func(callback=None): ... for i, c in [(1, 'a'), (2, 'b'), (3, 'c')]: ... if callback: ... callback(i, c) ... return 4 Use ``with callback_iter(func)`` to get an iterator over the parameters that are delivered to the callback. >>> with callback_iter(func) as it: ... for args, kwargs in it: ... print(args) (1, 'a') (2, 'b') (3, 'c') The function will be called in a background thread. The ``done`` property indicates whether it has completed execution. >>> it.done True If it completes successfully, its return value will be available in the ``result`` property. >>> it.result 4 Notes: * If the function uses some keyword argument besides ``callback``, supply *callback_kwd*. * If it finished executing, but raised an exception, accessing the ``result`` property will raise the same exception. * If it hasn't finished executing, accessing the ``result`` property from within the ``with`` block will raise ``RuntimeError``. * If it hasn't finished executing, accessing the ``result`` property from outside the ``with`` block will raise a ``more_itertools.AbortThread`` exception. * Provide *wait_seconds* to adjust how frequently the it is polled for output. callback皙?cCs8||_||_d|_d|_||_tdd|_||_dS)NFr,) max_workers) _func _callback_kwd_aborted_future _wait_secondsr _executor_reader _iterator)rrZ callback_kwdZ wait_secondsrrrr{ s zcallback_iter.__init__cCrrrrrrr __enter__ rzcallback_iter.__enter__cCsd|_|jdSr)rrshutdown)rexc_type exc_value tracebackrrr__exit__ szcallback_iter.__exit__cCrrrrrrrr rzcallback_iter.__iter__cCrr)rrrrrrr rzcallback_iter.__next__cCs|jdurdS|jSrb)rdonerrrrr s  zcallback_iter.donecCs|jstd|jS)NzFunction has not yet completed)r RuntimeErrorrrrrrrr s zcallback_iter.resultc#stfdd}jjjfij|i_ z jjd}Wn ty-Ynw |Vj r;nqg} z }Wn tyNYn w | |q? |EdHdS)Ncs jrtd||fdS)Nzcanceled by user)rr3put)rrrKrrrr sz'callback_iter._reader..callbackT)timeout)r rsubmitrrrgetrr task_doner get_nowaitrjoin)rrrr0rrrr s>      zcallback_iter._readerN)rr) rrrrrrrrrpropertyrrrrrrrr8H s 2    r8ccs|dkr tdt|}t|}||krtdt||dD]}|d|}||||}|||d}|||fVq!dS)a Yield ``(beginning, middle, end)`` tuples, where: * Each ``middle`` has *n* items from *iterable* * Each ``beginning`` has the items before the ones in ``middle`` * Each ``end`` has the items after the ones in ``middle`` >>> iterable = range(7) >>> n = 3 >>> for beginning, middle, end in windowed_complete(iterable, n): ... print(beginning, middle, end) () (0, 1, 2) (3, 4, 5, 6) (0,) (1, 2, 3) (4, 5, 6) (0, 1) (2, 3, 4) (5, 6) (0, 1, 2) (3, 4, 5) (6,) (0, 1, 2, 3) (4, 5, 6) () Note that *n* must be at least 0 and most equal to the length of *iterable*. This function will exhaust the iterable and may require significant storage. rrzn must be <= len(seq)r,N)rrrr)rrrrrZ beginningZmiddleendrrrr s rc Csxt}|j}g}|j}|rt||n|D]%}z||vrWdS||Wqty9||vr3YdS||YqwdS)a Returns ``True`` if all the elements of *iterable* are unique (no two elements are equal). >>> all_unique('ABCB') False If a *key* function is specified, it will be used to make comparisons. >>> all_unique('ABCb') True >>> all_unique('ABCb', str.lower) False The function returns as soon as the first non-unique element is encountered. Iterables with a mix of hashable and unhashable items can be used, but the function will be slower for unhashable items. FT)raddrrr)rrZseensetZ seenset_addZseenlistZ seenlist_addrrrrr s   rcGstttt|}ttt|}tt|}|dkr||7}d|kr(|ks+ttg}t||D]\}}| |||||}q2tt|S)aEquivalent to ``list(product(*args))[index]``. The products of *args* can be ordered lexicographically. :func:`nth_product` computes the product at sort position *index* without computing the previous products. >>> nth_product(8, range(2), range(2), range(2), range(2)) (1, 0, 0, 0) ``IndexError`` will be raised if the given *index* is invalid. r) rrrrrr r%rrr)rrpoolsnscrrrrrrr[s    r[c Cs&t|}t|}|dus||kr|t|}}nd|kr#|ks&ttt|t||}|dkr8||7}d|krC|ksFtt|dkrMtSdg|}||kr^|t||n|}td|dD]#}t||\}} d||kr||krnn| |||<|dkrnqgtt|j |S)a'Equivalent to ``list(permutations(iterable, r))[index]``` The subsequences of *iterable* that are of length *r* where order is important can be ordered lexicographically. :func:`nth_permutation` computes the subsequence at sort position *index* directly, without computing the previous subsequences. >>> nth_permutation('ghijk', 2, 5) ('h', 'i') ``ValueError`` will be raised If *r* is negative or greater than the length of *iterable*. ``IndexError`` will be raised if the given *index* is invalid. Nrr,) rrrrrrrrJrr) rrrrrrrrKdrrrrrZ.s6  rZc gsL|D] }t|ttfr|Vqz|EdHWqty#|VYqwdS)aYield all arguments passed to the function in the same order in which they were passed. If an argument itself is iterable then iterate over its values. >>> list(value_chain(1, 2, 3, [4, 5, 6])) [1, 2, 3, 4, 5, 6] Binary and text strings are not considered iterable and are emitted as-is: >>> list(value_chain('12', '34', ['56', '78'])) ['12', '34', '56', '78'] Multiple levels of nesting are not flattened. N)rrrr)rrrrrr\s  rcGsVd}t||tdD]\}}|tus|turtdt|}|t|||}q |S)aEquivalent to ``list(product(*args)).index(element)`` The products of *args* can be ordered lexicographically. :func:`product_index` computes the first index of *element* without computing the previous products. >>> product_index([8, 2], range(10), range(5)) 42 ``ValueError`` will be raised if the given *element* isn't in the product of *args*. rrwz element is not a product of args)rrrrrr)rrrr rrrrrxs rc Cst|}t|d\}}|durdSg}t|}|D]\}}||kr5||t|d\}}|dur3n|}qtdt||dfd\}} d} tt|ddD]\} } || } | | krj| t| t| t| | 7} qNt|dt|dt||| S)aEquivalent to ``list(combinations(iterable, r)).index(element)`` The subsequences of *iterable* that are of length *r* can be ordered lexicographically. :func:`combination_index` computes the index of the first *element*, without computing the previous combinations. >>> combination_index('adf', 'abcdefg') 10 ``ValueError`` will be raised if the given *element* isn't one of the combinations of *iterable*. NNNrz(element is not a combination of iterablerr,)r)r3rrrrSrr) rrrTyZindexesrrr tmprrrrrrrrs.    (rcCsLd}t|}ttt|dd|D]\}}||}|||}||=q|S)aEquivalent to ``list(permutations(iterable, r)).index(element)``` The subsequences of *iterable* that are of length *r* where order is important can be ordered lexicographically. :func:`permutation_index` computes the index of the first *element* directly, without computing the previous permutations. >>> permutation_index([1, 3, 2], range(5)) 19 ``ValueError`` will be raised if the given *element* isn't one of the permutations of *iterable*. rr)rrrrr)rrrrrr rrrrrs  rc@r) r?aWrap *iterable* and keep a count of how many items have been consumed. The ``items_seen`` attribute starts at ``0`` and increments as the iterable is consumed: >>> iterable = map(str, range(10)) >>> it = countable(iterable) >>> it.items_seen 0 >>> next(it), next(it) ('0', '1') >>> list(it) ['2', '3', '4', '5', '6', '7', '8', '9'] >>> it.items_seen 10 cCst||_d|_dSrp)rr items_seenrrrrrs  zcountable.__init__cCrrrrrrrrrzcountable.__iter__cCst|j}|jd7_|Sr)rrrrrrrrs zcountable.__next__Nrrrrrr?s  r?)Frrrr)NNN)rF)r)NNF)r5FN)r@NFrb)r collectionsrrrrcollections.abcrconcurrent.futuresr functoolsrr r heapqr r r r itertoolsrrrrrrrrrrrrmathrrrrqueuerr r!r"r#operatorr$r%r&r'r(sysr)r*timer+Zrecipesr-r.r/r0r1r2__all__objectrr9rIrSrYrbr<r>rKrPr|r]rDrNryr{rvrwr7rsrMrLr;rkrlrnrprorqrrr_rcrErtrr}r>r~rrmrzrFrrr5r4rJHashabler\r@rArdrTrUrfrurOr~r6r=rBrjrirgrGr:rVrXrerdr`rarxr^rQrCrHrWrrrhrR BaseExceptionr3r8rrr[rZrrrrr?rrrrs  8   V  !  &&   C d !3 " `+  0 = " , # $- -  # . 'B13 5 '- Z%0.`0*-  AC += 8 -)%( # $| (#.+PKH]ahBpython3.10/site-packages/setuptools/_vendor/more_itertools/more.pynu[import warnings from collections import Counter, defaultdict, deque, abc from collections.abc import Sequence from concurrent.futures import ThreadPoolExecutor from functools import partial, reduce, wraps from heapq import merge, heapify, heapreplace, heappop from itertools import ( chain, compress, count, cycle, dropwhile, groupby, islice, repeat, starmap, takewhile, tee, zip_longest, ) from math import exp, factorial, floor, log from queue import Empty, Queue from random import random, randrange, uniform from operator import itemgetter, mul, sub, gt, lt from sys import hexversion, maxsize from time import monotonic from .recipes import ( consume, flatten, pairwise, powerset, take, unique_everseen, ) __all__ = [ 'AbortThread', 'adjacent', 'always_iterable', 'always_reversible', 'bucket', 'callback_iter', 'chunked', 'circular_shifts', 'collapse', 'collate', 'consecutive_groups', 'consumer', 'countable', 'count_cycle', 'mark_ends', 'difference', 'distinct_combinations', 'distinct_permutations', 'distribute', 'divide', 'exactly_n', 'filter_except', 'first', 'groupby_transform', 'ilen', 'interleave_longest', 'interleave', 'intersperse', 'islice_extended', 'iterate', 'ichunked', 'is_sorted', 'last', 'locate', 'lstrip', 'make_decorator', 'map_except', 'map_reduce', 'nth_or_last', 'nth_permutation', 'nth_product', 'numeric_range', 'one', 'only', 'padded', 'partitions', 'set_partitions', 'peekable', 'repeat_last', 'replace', 'rlocate', 'rstrip', 'run_length', 'sample', 'seekable', 'SequenceView', 'side_effect', 'sliced', 'sort_together', 'split_at', 'split_after', 'split_before', 'split_when', 'split_into', 'spy', 'stagger', 'strip', 'substrings', 'substrings_indexes', 'time_limited', 'unique_to_each', 'unzip', 'windowed', 'with_iter', 'UnequalIterablesError', 'zip_equal', 'zip_offset', 'windowed_complete', 'all_unique', 'value_chain', 'product_index', 'combination_index', 'permutation_index', ] _marker = object() def chunked(iterable, n, strict=False): """Break *iterable* into lists of length *n*: >>> list(chunked([1, 2, 3, 4, 5, 6], 3)) [[1, 2, 3], [4, 5, 6]] By the default, the last yielded list will have fewer than *n* elements if the length of *iterable* is not divisible by *n*: >>> list(chunked([1, 2, 3, 4, 5, 6, 7, 8], 3)) [[1, 2, 3], [4, 5, 6], [7, 8]] To use a fill-in value instead, see the :func:`grouper` recipe. If the length of *iterable* is not divisible by *n* and *strict* is ``True``, then ``ValueError`` will be raised before the last list is yielded. """ iterator = iter(partial(take, n, iter(iterable)), []) if strict: def ret(): for chunk in iterator: if len(chunk) != n: raise ValueError('iterable is not divisible by n.') yield chunk return iter(ret()) else: return iterator def first(iterable, default=_marker): """Return the first item of *iterable*, or *default* if *iterable* is empty. >>> first([0, 1, 2, 3]) 0 >>> first([], 'some default') 'some default' If *default* is not provided and there are no items in the iterable, raise ``ValueError``. :func:`first` is useful when you have a generator of expensive-to-retrieve values and want any arbitrary one. It is marginally shorter than ``next(iter(iterable), default)``. """ try: return next(iter(iterable)) except StopIteration as e: if default is _marker: raise ValueError( 'first() was called on an empty iterable, and no ' 'default value was provided.' ) from e return default def last(iterable, default=_marker): """Return the last item of *iterable*, or *default* if *iterable* is empty. >>> last([0, 1, 2, 3]) 3 >>> last([], 'some default') 'some default' If *default* is not provided and there are no items in the iterable, raise ``ValueError``. """ try: if isinstance(iterable, Sequence): return iterable[-1] # Work around https://bugs.python.org/issue38525 elif hasattr(iterable, '__reversed__') and (hexversion != 0x030800F0): return next(reversed(iterable)) else: return deque(iterable, maxlen=1)[-1] except (IndexError, TypeError, StopIteration): if default is _marker: raise ValueError( 'last() was called on an empty iterable, and no default was ' 'provided.' ) return default def nth_or_last(iterable, n, default=_marker): """Return the nth or the last item of *iterable*, or *default* if *iterable* is empty. >>> nth_or_last([0, 1, 2, 3], 2) 2 >>> nth_or_last([0, 1], 2) 1 >>> nth_or_last([], 0, 'some default') 'some default' If *default* is not provided and there are no items in the iterable, raise ``ValueError``. """ return last(islice(iterable, n + 1), default=default) class peekable: """Wrap an iterator to allow lookahead and prepending elements. Call :meth:`peek` on the result to get the value that will be returned by :func:`next`. This won't advance the iterator: >>> p = peekable(['a', 'b']) >>> p.peek() 'a' >>> next(p) 'a' Pass :meth:`peek` a default value to return that instead of raising ``StopIteration`` when the iterator is exhausted. >>> p = peekable([]) >>> p.peek('hi') 'hi' peekables also offer a :meth:`prepend` method, which "inserts" items at the head of the iterable: >>> p = peekable([1, 2, 3]) >>> p.prepend(10, 11, 12) >>> next(p) 10 >>> p.peek() 11 >>> list(p) [11, 12, 1, 2, 3] peekables can be indexed. Index 0 is the item that will be returned by :func:`next`, index 1 is the item after that, and so on: The values up to the given index will be cached. >>> p = peekable(['a', 'b', 'c', 'd']) >>> p[0] 'a' >>> p[1] 'b' >>> next(p) 'a' Negative indexes are supported, but be aware that they will cache the remaining items in the source iterator, which may require significant storage. To check whether a peekable is exhausted, check its truth value: >>> p = peekable(['a', 'b']) >>> if p: # peekable has items ... list(p) ['a', 'b'] >>> if not p: # peekable is exhausted ... list(p) [] """ def __init__(self, iterable): self._it = iter(iterable) self._cache = deque() def __iter__(self): return self def __bool__(self): try: self.peek() except StopIteration: return False return True def peek(self, default=_marker): """Return the item that will be next returned from ``next()``. Return ``default`` if there are no items left. If ``default`` is not provided, raise ``StopIteration``. """ if not self._cache: try: self._cache.append(next(self._it)) except StopIteration: if default is _marker: raise return default return self._cache[0] def prepend(self, *items): """Stack up items to be the next ones returned from ``next()`` or ``self.peek()``. The items will be returned in first in, first out order:: >>> p = peekable([1, 2, 3]) >>> p.prepend(10, 11, 12) >>> next(p) 10 >>> list(p) [11, 12, 1, 2, 3] It is possible, by prepending items, to "resurrect" a peekable that previously raised ``StopIteration``. >>> p = peekable([]) >>> next(p) Traceback (most recent call last): ... StopIteration >>> p.prepend(1) >>> next(p) 1 >>> next(p) Traceback (most recent call last): ... StopIteration """ self._cache.extendleft(reversed(items)) def __next__(self): if self._cache: return self._cache.popleft() return next(self._it) def _get_slice(self, index): # Normalize the slice's arguments step = 1 if (index.step is None) else index.step if step > 0: start = 0 if (index.start is None) else index.start stop = maxsize if (index.stop is None) else index.stop elif step < 0: start = -1 if (index.start is None) else index.start stop = (-maxsize - 1) if (index.stop is None) else index.stop else: raise ValueError('slice step cannot be zero') # If either the start or stop index is negative, we'll need to cache # the rest of the iterable in order to slice from the right side. if (start < 0) or (stop < 0): self._cache.extend(self._it) # Otherwise we'll need to find the rightmost index and cache to that # point. else: n = min(max(start, stop) + 1, maxsize) cache_len = len(self._cache) if n >= cache_len: self._cache.extend(islice(self._it, n - cache_len)) return list(self._cache)[index] def __getitem__(self, index): if isinstance(index, slice): return self._get_slice(index) cache_len = len(self._cache) if index < 0: self._cache.extend(self._it) elif index >= cache_len: self._cache.extend(islice(self._it, index + 1 - cache_len)) return self._cache[index] def collate(*iterables, **kwargs): """Return a sorted merge of the items from each of several already-sorted *iterables*. >>> list(collate('ACDZ', 'AZ', 'JKL')) ['A', 'A', 'C', 'D', 'J', 'K', 'L', 'Z', 'Z'] Works lazily, keeping only the next value from each iterable in memory. Use :func:`collate` to, for example, perform a n-way mergesort of items that don't fit in memory. If a *key* function is specified, the iterables will be sorted according to its result: >>> key = lambda s: int(s) # Sort by numeric value, not by string >>> list(collate(['1', '10'], ['2', '11'], key=key)) ['1', '2', '10', '11'] If the *iterables* are sorted in descending order, set *reverse* to ``True``: >>> list(collate([5, 3, 1], [4, 2, 0], reverse=True)) [5, 4, 3, 2, 1, 0] If the elements of the passed-in iterables are out of order, you might get unexpected results. On Python 3.5+, this function is an alias for :func:`heapq.merge`. """ warnings.warn( "collate is no longer part of more_itertools, use heapq.merge", DeprecationWarning, ) return merge(*iterables, **kwargs) def consumer(func): """Decorator that automatically advances a PEP-342-style "reverse iterator" to its first yield point so you don't have to call ``next()`` on it manually. >>> @consumer ... def tally(): ... i = 0 ... while True: ... print('Thing number %s is %s.' % (i, (yield))) ... i += 1 ... >>> t = tally() >>> t.send('red') Thing number 0 is red. >>> t.send('fish') Thing number 1 is fish. Without the decorator, you would have to call ``next(t)`` before ``t.send()`` could be used. """ @wraps(func) def wrapper(*args, **kwargs): gen = func(*args, **kwargs) next(gen) return gen return wrapper def ilen(iterable): """Return the number of items in *iterable*. >>> ilen(x for x in range(1000000) if x % 3 == 0) 333334 This consumes the iterable, so handle with care. """ # This approach was selected because benchmarks showed it's likely the # fastest of the known implementations at the time of writing. # See GitHub tracker: #236, #230. counter = count() deque(zip(iterable, counter), maxlen=0) return next(counter) def iterate(func, start): """Return ``start``, ``func(start)``, ``func(func(start))``, ... >>> from itertools import islice >>> list(islice(iterate(lambda x: 2*x, 1), 10)) [1, 2, 4, 8, 16, 32, 64, 128, 256, 512] """ while True: yield start start = func(start) def with_iter(context_manager): """Wrap an iterable in a ``with`` statement, so it closes once exhausted. For example, this will close the file when the iterator is exhausted:: upper_lines = (line.upper() for line in with_iter(open('foo'))) Any context manager which returns an iterable is a candidate for ``with_iter``. """ with context_manager as iterable: yield from iterable def one(iterable, too_short=None, too_long=None): """Return the first item from *iterable*, which is expected to contain only that item. Raise an exception if *iterable* is empty or has more than one item. :func:`one` is useful for ensuring that an iterable contains only one item. For example, it can be used to retrieve the result of a database query that is expected to return a single row. If *iterable* is empty, ``ValueError`` will be raised. You may specify a different exception with the *too_short* keyword: >>> it = [] >>> one(it) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... ValueError: too many items in iterable (expected 1)' >>> too_short = IndexError('too few items') >>> one(it, too_short=too_short) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... IndexError: too few items Similarly, if *iterable* contains more than one item, ``ValueError`` will be raised. You may specify a different exception with the *too_long* keyword: >>> it = ['too', 'many'] >>> one(it) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... ValueError: Expected exactly one item in iterable, but got 'too', 'many', and perhaps more. >>> too_long = RuntimeError >>> one(it, too_long=too_long) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... RuntimeError Note that :func:`one` attempts to advance *iterable* twice to ensure there is only one item. See :func:`spy` or :func:`peekable` to check iterable contents less destructively. """ it = iter(iterable) try: first_value = next(it) except StopIteration as e: raise ( too_short or ValueError('too few items in iterable (expected 1)') ) from e try: second_value = next(it) except StopIteration: pass else: msg = ( 'Expected exactly one item in iterable, but got {!r}, {!r}, ' 'and perhaps more.'.format(first_value, second_value) ) raise too_long or ValueError(msg) return first_value def distinct_permutations(iterable, r=None): """Yield successive distinct permutations of the elements in *iterable*. >>> sorted(distinct_permutations([1, 0, 1])) [(0, 1, 1), (1, 0, 1), (1, 1, 0)] Equivalent to ``set(permutations(iterable))``, except duplicates are not generated and thrown away. For larger input sequences this is much more efficient. Duplicate permutations arise when there are duplicated elements in the input iterable. The number of items returned is `n! / (x_1! * x_2! * ... * x_n!)`, where `n` is the total number of items input, and each `x_i` is the count of a distinct item in the input sequence. If *r* is given, only the *r*-length permutations are yielded. >>> sorted(distinct_permutations([1, 0, 1], r=2)) [(0, 1), (1, 0), (1, 1)] >>> sorted(distinct_permutations(range(3), r=2)) [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)] """ # Algorithm: https://w.wiki/Qai def _full(A): while True: # Yield the permutation we have yield tuple(A) # Find the largest index i such that A[i] < A[i + 1] for i in range(size - 2, -1, -1): if A[i] < A[i + 1]: break # If no such index exists, this permutation is the last one else: return # Find the largest index j greater than j such that A[i] < A[j] for j in range(size - 1, i, -1): if A[i] < A[j]: break # Swap the value of A[i] with that of A[j], then reverse the # sequence from A[i + 1] to form the new permutation A[i], A[j] = A[j], A[i] A[i + 1 :] = A[: i - size : -1] # A[i + 1:][::-1] # Algorithm: modified from the above def _partial(A, r): # Split A into the first r items and the last r items head, tail = A[:r], A[r:] right_head_indexes = range(r - 1, -1, -1) left_tail_indexes = range(len(tail)) while True: # Yield the permutation we have yield tuple(head) # Starting from the right, find the first index of the head with # value smaller than the maximum value of the tail - call it i. pivot = tail[-1] for i in right_head_indexes: if head[i] < pivot: break pivot = head[i] else: return # Starting from the left, find the first value of the tail # with a value greater than head[i] and swap. for j in left_tail_indexes: if tail[j] > head[i]: head[i], tail[j] = tail[j], head[i] break # If we didn't find one, start from the right and find the first # index of the head with a value greater than head[i] and swap. else: for j in right_head_indexes: if head[j] > head[i]: head[i], head[j] = head[j], head[i] break # Reverse head[i + 1:] and swap it with tail[:r - (i + 1)] tail += head[: i - r : -1] # head[i + 1:][::-1] i += 1 head[i:], tail[:] = tail[: r - i], tail[r - i :] items = sorted(iterable) size = len(items) if r is None: r = size if 0 < r <= size: return _full(items) if (r == size) else _partial(items, r) return iter(() if r else ((),)) def intersperse(e, iterable, n=1): """Intersperse filler element *e* among the items in *iterable*, leaving *n* items between each filler element. >>> list(intersperse('!', [1, 2, 3, 4, 5])) [1, '!', 2, '!', 3, '!', 4, '!', 5] >>> list(intersperse(None, [1, 2, 3, 4, 5], n=2)) [1, 2, None, 3, 4, None, 5] """ if n == 0: raise ValueError('n must be > 0') elif n == 1: # interleave(repeat(e), iterable) -> e, x_0, e, e, x_1, e, x_2... # islice(..., 1, None) -> x_0, e, e, x_1, e, x_2... return islice(interleave(repeat(e), iterable), 1, None) else: # interleave(filler, chunks) -> [e], [x_0, x_1], [e], [x_2, x_3]... # islice(..., 1, None) -> [x_0, x_1], [e], [x_2, x_3]... # flatten(...) -> x_0, x_1, e, x_2, x_3... filler = repeat([e]) chunks = chunked(iterable, n) return flatten(islice(interleave(filler, chunks), 1, None)) def unique_to_each(*iterables): """Return the elements from each of the input iterables that aren't in the other input iterables. For example, suppose you have a set of packages, each with a set of dependencies:: {'pkg_1': {'A', 'B'}, 'pkg_2': {'B', 'C'}, 'pkg_3': {'B', 'D'}} If you remove one package, which dependencies can also be removed? If ``pkg_1`` is removed, then ``A`` is no longer necessary - it is not associated with ``pkg_2`` or ``pkg_3``. Similarly, ``C`` is only needed for ``pkg_2``, and ``D`` is only needed for ``pkg_3``:: >>> unique_to_each({'A', 'B'}, {'B', 'C'}, {'B', 'D'}) [['A'], ['C'], ['D']] If there are duplicates in one input iterable that aren't in the others they will be duplicated in the output. Input order is preserved:: >>> unique_to_each("mississippi", "missouri") [['p', 'p'], ['o', 'u', 'r']] It is assumed that the elements of each iterable are hashable. """ pool = [list(it) for it in iterables] counts = Counter(chain.from_iterable(map(set, pool))) uniques = {element for element in counts if counts[element] == 1} return [list(filter(uniques.__contains__, it)) for it in pool] def windowed(seq, n, fillvalue=None, step=1): """Return a sliding window of width *n* over the given iterable. >>> all_windows = windowed([1, 2, 3, 4, 5], 3) >>> list(all_windows) [(1, 2, 3), (2, 3, 4), (3, 4, 5)] When the window is larger than the iterable, *fillvalue* is used in place of missing values: >>> list(windowed([1, 2, 3], 4)) [(1, 2, 3, None)] Each window will advance in increments of *step*: >>> list(windowed([1, 2, 3, 4, 5, 6], 3, fillvalue='!', step=2)) [(1, 2, 3), (3, 4, 5), (5, 6, '!')] To slide into the iterable's items, use :func:`chain` to add filler items to the left: >>> iterable = [1, 2, 3, 4] >>> n = 3 >>> padding = [None] * (n - 1) >>> list(windowed(chain(padding, iterable), 3)) [(None, None, 1), (None, 1, 2), (1, 2, 3), (2, 3, 4)] """ if n < 0: raise ValueError('n must be >= 0') if n == 0: yield tuple() return if step < 1: raise ValueError('step must be >= 1') window = deque(maxlen=n) i = n for _ in map(window.append, seq): i -= 1 if not i: i = step yield tuple(window) size = len(window) if size < n: yield tuple(chain(window, repeat(fillvalue, n - size))) elif 0 < i < min(step, n): window += (fillvalue,) * i yield tuple(window) def substrings(iterable): """Yield all of the substrings of *iterable*. >>> [''.join(s) for s in substrings('more')] ['m', 'o', 'r', 'e', 'mo', 'or', 're', 'mor', 'ore', 'more'] Note that non-string iterables can also be subdivided. >>> list(substrings([0, 1, 2])) [(0,), (1,), (2,), (0, 1), (1, 2), (0, 1, 2)] """ # The length-1 substrings seq = [] for item in iter(iterable): seq.append(item) yield (item,) seq = tuple(seq) item_count = len(seq) # And the rest for n in range(2, item_count + 1): for i in range(item_count - n + 1): yield seq[i : i + n] def substrings_indexes(seq, reverse=False): """Yield all substrings and their positions in *seq* The items yielded will be a tuple of the form ``(substr, i, j)``, where ``substr == seq[i:j]``. This function only works for iterables that support slicing, such as ``str`` objects. >>> for item in substrings_indexes('more'): ... print(item) ('m', 0, 1) ('o', 1, 2) ('r', 2, 3) ('e', 3, 4) ('mo', 0, 2) ('or', 1, 3) ('re', 2, 4) ('mor', 0, 3) ('ore', 1, 4) ('more', 0, 4) Set *reverse* to ``True`` to yield the same items in the opposite order. """ r = range(1, len(seq) + 1) if reverse: r = reversed(r) return ( (seq[i : i + L], i, i + L) for L in r for i in range(len(seq) - L + 1) ) class bucket: """Wrap *iterable* and return an object that buckets it iterable into child iterables based on a *key* function. >>> iterable = ['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'b3'] >>> s = bucket(iterable, key=lambda x: x[0]) # Bucket by 1st character >>> sorted(list(s)) # Get the keys ['a', 'b', 'c'] >>> a_iterable = s['a'] >>> next(a_iterable) 'a1' >>> next(a_iterable) 'a2' >>> list(s['b']) ['b1', 'b2', 'b3'] The original iterable will be advanced and its items will be cached until they are used by the child iterables. This may require significant storage. By default, attempting to select a bucket to which no items belong will exhaust the iterable and cache all values. If you specify a *validator* function, selected buckets will instead be checked against it. >>> from itertools import count >>> it = count(1, 2) # Infinite sequence of odd numbers >>> key = lambda x: x % 10 # Bucket by last digit >>> validator = lambda x: x in {1, 3, 5, 7, 9} # Odd digits only >>> s = bucket(it, key=key, validator=validator) >>> 2 in s False >>> list(s[2]) [] """ def __init__(self, iterable, key, validator=None): self._it = iter(iterable) self._key = key self._cache = defaultdict(deque) self._validator = validator or (lambda x: True) def __contains__(self, value): if not self._validator(value): return False try: item = next(self[value]) except StopIteration: return False else: self._cache[value].appendleft(item) return True def _get_values(self, value): """ Helper to yield items from the parent iterator that match *value*. Items that don't match are stored in the local cache as they are encountered. """ while True: # If we've cached some items that match the target value, emit # the first one and evict it from the cache. if self._cache[value]: yield self._cache[value].popleft() # Otherwise we need to advance the parent iterator to search for # a matching item, caching the rest. else: while True: try: item = next(self._it) except StopIteration: return item_value = self._key(item) if item_value == value: yield item break elif self._validator(item_value): self._cache[item_value].append(item) def __iter__(self): for item in self._it: item_value = self._key(item) if self._validator(item_value): self._cache[item_value].append(item) yield from self._cache.keys() def __getitem__(self, value): if not self._validator(value): return iter(()) return self._get_values(value) def spy(iterable, n=1): """Return a 2-tuple with a list containing the first *n* elements of *iterable*, and an iterator with the same items as *iterable*. This allows you to "look ahead" at the items in the iterable without advancing it. There is one item in the list by default: >>> iterable = 'abcdefg' >>> head, iterable = spy(iterable) >>> head ['a'] >>> list(iterable) ['a', 'b', 'c', 'd', 'e', 'f', 'g'] You may use unpacking to retrieve items instead of lists: >>> (head,), iterable = spy('abcdefg') >>> head 'a' >>> (first, second), iterable = spy('abcdefg', 2) >>> first 'a' >>> second 'b' The number of items requested can be larger than the number of items in the iterable: >>> iterable = [1, 2, 3, 4, 5] >>> head, iterable = spy(iterable, 10) >>> head [1, 2, 3, 4, 5] >>> list(iterable) [1, 2, 3, 4, 5] """ it = iter(iterable) head = take(n, it) return head.copy(), chain(head, it) def interleave(*iterables): """Return a new iterable yielding from each iterable in turn, until the shortest is exhausted. >>> list(interleave([1, 2, 3], [4, 5], [6, 7, 8])) [1, 4, 6, 2, 5, 7] For a version that doesn't terminate after the shortest iterable is exhausted, see :func:`interleave_longest`. """ return chain.from_iterable(zip(*iterables)) def interleave_longest(*iterables): """Return a new iterable yielding from each iterable in turn, skipping any that are exhausted. >>> list(interleave_longest([1, 2, 3], [4, 5], [6, 7, 8])) [1, 4, 6, 2, 5, 7, 3, 8] This function produces the same output as :func:`roundrobin`, but may perform better for some inputs (in particular when the number of iterables is large). """ i = chain.from_iterable(zip_longest(*iterables, fillvalue=_marker)) return (x for x in i if x is not _marker) def collapse(iterable, base_type=None, levels=None): """Flatten an iterable with multiple levels of nesting (e.g., a list of lists of tuples) into non-iterable types. >>> iterable = [(1, 2), ([3, 4], [[5], [6]])] >>> list(collapse(iterable)) [1, 2, 3, 4, 5, 6] Binary and text strings are not considered iterable and will not be collapsed. To avoid collapsing other types, specify *base_type*: >>> iterable = ['ab', ('cd', 'ef'), ['gh', 'ij']] >>> list(collapse(iterable, base_type=tuple)) ['ab', ('cd', 'ef'), 'gh', 'ij'] Specify *levels* to stop flattening after a certain level: >>> iterable = [('a', ['b']), ('c', ['d'])] >>> list(collapse(iterable)) # Fully flattened ['a', 'b', 'c', 'd'] >>> list(collapse(iterable, levels=1)) # Only one level flattened ['a', ['b'], 'c', ['d']] """ def walk(node, level): if ( ((levels is not None) and (level > levels)) or isinstance(node, (str, bytes)) or ((base_type is not None) and isinstance(node, base_type)) ): yield node return try: tree = iter(node) except TypeError: yield node return else: for child in tree: yield from walk(child, level + 1) yield from walk(iterable, 0) def side_effect(func, iterable, chunk_size=None, before=None, after=None): """Invoke *func* on each item in *iterable* (or on each *chunk_size* group of items) before yielding the item. `func` must be a function that takes a single argument. Its return value will be discarded. *before* and *after* are optional functions that take no arguments. They will be executed before iteration starts and after it ends, respectively. `side_effect` can be used for logging, updating progress bars, or anything that is not functionally "pure." Emitting a status message: >>> from more_itertools import consume >>> func = lambda item: print('Received {}'.format(item)) >>> consume(side_effect(func, range(2))) Received 0 Received 1 Operating on chunks of items: >>> pair_sums = [] >>> func = lambda chunk: pair_sums.append(sum(chunk)) >>> list(side_effect(func, [0, 1, 2, 3, 4, 5], 2)) [0, 1, 2, 3, 4, 5] >>> list(pair_sums) [1, 5, 9] Writing to a file-like object: >>> from io import StringIO >>> from more_itertools import consume >>> f = StringIO() >>> func = lambda x: print(x, file=f) >>> before = lambda: print(u'HEADER', file=f) >>> after = f.close >>> it = [u'a', u'b', u'c'] >>> consume(side_effect(func, it, before=before, after=after)) >>> f.closed True """ try: if before is not None: before() if chunk_size is None: for item in iterable: func(item) yield item else: for chunk in chunked(iterable, chunk_size): func(chunk) yield from chunk finally: if after is not None: after() def sliced(seq, n, strict=False): """Yield slices of length *n* from the sequence *seq*. >>> list(sliced((1, 2, 3, 4, 5, 6), 3)) [(1, 2, 3), (4, 5, 6)] By the default, the last yielded slice will have fewer than *n* elements if the length of *seq* is not divisible by *n*: >>> list(sliced((1, 2, 3, 4, 5, 6, 7, 8), 3)) [(1, 2, 3), (4, 5, 6), (7, 8)] If the length of *seq* is not divisible by *n* and *strict* is ``True``, then ``ValueError`` will be raised before the last slice is yielded. This function will only work for iterables that support slicing. For non-sliceable iterables, see :func:`chunked`. """ iterator = takewhile(len, (seq[i : i + n] for i in count(0, n))) if strict: def ret(): for _slice in iterator: if len(_slice) != n: raise ValueError("seq is not divisible by n.") yield _slice return iter(ret()) else: return iterator def split_at(iterable, pred, maxsplit=-1, keep_separator=False): """Yield lists of items from *iterable*, where each list is delimited by an item where callable *pred* returns ``True``. >>> list(split_at('abcdcba', lambda x: x == 'b')) [['a'], ['c', 'd', 'c'], ['a']] >>> list(split_at(range(10), lambda n: n % 2 == 1)) [[0], [2], [4], [6], [8], []] At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, then there is no limit on the number of splits: >>> list(split_at(range(10), lambda n: n % 2 == 1, maxsplit=2)) [[0], [2], [4, 5, 6, 7, 8, 9]] By default, the delimiting items are not included in the output. The include them, set *keep_separator* to ``True``. >>> list(split_at('abcdcba', lambda x: x == 'b', keep_separator=True)) [['a'], ['b'], ['c', 'd', 'c'], ['b'], ['a']] """ if maxsplit == 0: yield list(iterable) return buf = [] it = iter(iterable) for item in it: if pred(item): yield buf if keep_separator: yield [item] if maxsplit == 1: yield list(it) return buf = [] maxsplit -= 1 else: buf.append(item) yield buf def split_before(iterable, pred, maxsplit=-1): """Yield lists of items from *iterable*, where each list ends just before an item for which callable *pred* returns ``True``: >>> list(split_before('OneTwo', lambda s: s.isupper())) [['O', 'n', 'e'], ['T', 'w', 'o']] >>> list(split_before(range(10), lambda n: n % 3 == 0)) [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, then there is no limit on the number of splits: >>> list(split_before(range(10), lambda n: n % 3 == 0, maxsplit=2)) [[0, 1, 2], [3, 4, 5], [6, 7, 8, 9]] """ if maxsplit == 0: yield list(iterable) return buf = [] it = iter(iterable) for item in it: if pred(item) and buf: yield buf if maxsplit == 1: yield [item] + list(it) return buf = [] maxsplit -= 1 buf.append(item) if buf: yield buf def split_after(iterable, pred, maxsplit=-1): """Yield lists of items from *iterable*, where each list ends with an item where callable *pred* returns ``True``: >>> list(split_after('one1two2', lambda s: s.isdigit())) [['o', 'n', 'e', '1'], ['t', 'w', 'o', '2']] >>> list(split_after(range(10), lambda n: n % 3 == 0)) [[0], [1, 2, 3], [4, 5, 6], [7, 8, 9]] At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, then there is no limit on the number of splits: >>> list(split_after(range(10), lambda n: n % 3 == 0, maxsplit=2)) [[0], [1, 2, 3], [4, 5, 6, 7, 8, 9]] """ if maxsplit == 0: yield list(iterable) return buf = [] it = iter(iterable) for item in it: buf.append(item) if pred(item) and buf: yield buf if maxsplit == 1: yield list(it) return buf = [] maxsplit -= 1 if buf: yield buf def split_when(iterable, pred, maxsplit=-1): """Split *iterable* into pieces based on the output of *pred*. *pred* should be a function that takes successive pairs of items and returns ``True`` if the iterable should be split in between them. For example, to find runs of increasing numbers, split the iterable when element ``i`` is larger than element ``i + 1``: >>> list(split_when([1, 2, 3, 3, 2, 5, 2, 4, 2], lambda x, y: x > y)) [[1, 2, 3, 3], [2, 5], [2, 4], [2]] At most *maxsplit* splits are done. If *maxsplit* is not specified or -1, then there is no limit on the number of splits: >>> list(split_when([1, 2, 3, 3, 2, 5, 2, 4, 2], ... lambda x, y: x > y, maxsplit=2)) [[1, 2, 3, 3], [2, 5], [2, 4, 2]] """ if maxsplit == 0: yield list(iterable) return it = iter(iterable) try: cur_item = next(it) except StopIteration: return buf = [cur_item] for next_item in it: if pred(cur_item, next_item): yield buf if maxsplit == 1: yield [next_item] + list(it) return buf = [] maxsplit -= 1 buf.append(next_item) cur_item = next_item yield buf def split_into(iterable, sizes): """Yield a list of sequential items from *iterable* of length 'n' for each integer 'n' in *sizes*. >>> list(split_into([1,2,3,4,5,6], [1,2,3])) [[1], [2, 3], [4, 5, 6]] If the sum of *sizes* is smaller than the length of *iterable*, then the remaining items of *iterable* will not be returned. >>> list(split_into([1,2,3,4,5,6], [2,3])) [[1, 2], [3, 4, 5]] If the sum of *sizes* is larger than the length of *iterable*, fewer items will be returned in the iteration that overruns *iterable* and further lists will be empty: >>> list(split_into([1,2,3,4], [1,2,3,4])) [[1], [2, 3], [4], []] When a ``None`` object is encountered in *sizes*, the returned list will contain items up to the end of *iterable* the same way that itertools.slice does: >>> list(split_into([1,2,3,4,5,6,7,8,9,0], [2,3,None])) [[1, 2], [3, 4, 5], [6, 7, 8, 9, 0]] :func:`split_into` can be useful for grouping a series of items where the sizes of the groups are not uniform. An example would be where in a row from a table, multiple columns represent elements of the same feature (e.g. a point represented by x,y,z) but, the format is not the same for all columns. """ # convert the iterable argument into an iterator so its contents can # be consumed by islice in case it is a generator it = iter(iterable) for size in sizes: if size is None: yield list(it) return else: yield list(islice(it, size)) def padded(iterable, fillvalue=None, n=None, next_multiple=False): """Yield the elements from *iterable*, followed by *fillvalue*, such that at least *n* items are emitted. >>> list(padded([1, 2, 3], '?', 5)) [1, 2, 3, '?', '?'] If *next_multiple* is ``True``, *fillvalue* will be emitted until the number of items emitted is a multiple of *n*:: >>> list(padded([1, 2, 3, 4], n=3, next_multiple=True)) [1, 2, 3, 4, None, None] If *n* is ``None``, *fillvalue* will be emitted indefinitely. """ it = iter(iterable) if n is None: yield from chain(it, repeat(fillvalue)) elif n < 1: raise ValueError('n must be at least 1') else: item_count = 0 for item in it: yield item item_count += 1 remaining = (n - item_count) % n if next_multiple else n - item_count for _ in range(remaining): yield fillvalue def repeat_last(iterable, default=None): """After the *iterable* is exhausted, keep yielding its last element. >>> list(islice(repeat_last(range(3)), 5)) [0, 1, 2, 2, 2] If the iterable is empty, yield *default* forever:: >>> list(islice(repeat_last(range(0), 42), 5)) [42, 42, 42, 42, 42] """ item = _marker for item in iterable: yield item final = default if item is _marker else item yield from repeat(final) def distribute(n, iterable): """Distribute the items from *iterable* among *n* smaller iterables. >>> group_1, group_2 = distribute(2, [1, 2, 3, 4, 5, 6]) >>> list(group_1) [1, 3, 5] >>> list(group_2) [2, 4, 6] If the length of *iterable* is not evenly divisible by *n*, then the length of the returned iterables will not be identical: >>> children = distribute(3, [1, 2, 3, 4, 5, 6, 7]) >>> [list(c) for c in children] [[1, 4, 7], [2, 5], [3, 6]] If the length of *iterable* is smaller than *n*, then the last returned iterables will be empty: >>> children = distribute(5, [1, 2, 3]) >>> [list(c) for c in children] [[1], [2], [3], [], []] This function uses :func:`itertools.tee` and may require significant storage. If you need the order items in the smaller iterables to match the original iterable, see :func:`divide`. """ if n < 1: raise ValueError('n must be at least 1') children = tee(iterable, n) return [islice(it, index, None, n) for index, it in enumerate(children)] def stagger(iterable, offsets=(-1, 0, 1), longest=False, fillvalue=None): """Yield tuples whose elements are offset from *iterable*. The amount by which the `i`-th item in each tuple is offset is given by the `i`-th item in *offsets*. >>> list(stagger([0, 1, 2, 3])) [(None, 0, 1), (0, 1, 2), (1, 2, 3)] >>> list(stagger(range(8), offsets=(0, 2, 4))) [(0, 2, 4), (1, 3, 5), (2, 4, 6), (3, 5, 7)] By default, the sequence will end when the final element of a tuple is the last item in the iterable. To continue until the first element of a tuple is the last item in the iterable, set *longest* to ``True``:: >>> list(stagger([0, 1, 2, 3], longest=True)) [(None, 0, 1), (0, 1, 2), (1, 2, 3), (2, 3, None), (3, None, None)] By default, ``None`` will be used to replace offsets beyond the end of the sequence. Specify *fillvalue* to use some other value. """ children = tee(iterable, len(offsets)) return zip_offset( *children, offsets=offsets, longest=longest, fillvalue=fillvalue ) class UnequalIterablesError(ValueError): def __init__(self, details=None): msg = 'Iterables have different lengths' if details is not None: msg += (': index 0 has length {}; index {} has length {}').format( *details ) super().__init__(msg) def _zip_equal_generator(iterables): for combo in zip_longest(*iterables, fillvalue=_marker): for val in combo: if val is _marker: raise UnequalIterablesError() yield combo def zip_equal(*iterables): """``zip`` the input *iterables* together, but raise ``UnequalIterablesError`` if they aren't all the same length. >>> it_1 = range(3) >>> it_2 = iter('abc') >>> list(zip_equal(it_1, it_2)) [(0, 'a'), (1, 'b'), (2, 'c')] >>> it_1 = range(3) >>> it_2 = iter('abcd') >>> list(zip_equal(it_1, it_2)) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... more_itertools.more.UnequalIterablesError: Iterables have different lengths """ if hexversion >= 0x30A00A6: warnings.warn( ( 'zip_equal will be removed in a future version of ' 'more-itertools. Use the builtin zip function with ' 'strict=True instead.' ), DeprecationWarning, ) # Check whether the iterables are all the same size. try: first_size = len(iterables[0]) for i, it in enumerate(iterables[1:], 1): size = len(it) if size != first_size: break else: # If we didn't break out, we can use the built-in zip. return zip(*iterables) # If we did break out, there was a mismatch. raise UnequalIterablesError(details=(first_size, i, size)) # If any one of the iterables didn't have a length, start reading # them until one runs out. except TypeError: return _zip_equal_generator(iterables) def zip_offset(*iterables, offsets, longest=False, fillvalue=None): """``zip`` the input *iterables* together, but offset the `i`-th iterable by the `i`-th item in *offsets*. >>> list(zip_offset('0123', 'abcdef', offsets=(0, 1))) [('0', 'b'), ('1', 'c'), ('2', 'd'), ('3', 'e')] This can be used as a lightweight alternative to SciPy or pandas to analyze data sets in which some series have a lead or lag relationship. By default, the sequence will end when the shortest iterable is exhausted. To continue until the longest iterable is exhausted, set *longest* to ``True``. >>> list(zip_offset('0123', 'abcdef', offsets=(0, 1), longest=True)) [('0', 'b'), ('1', 'c'), ('2', 'd'), ('3', 'e'), (None, 'f')] By default, ``None`` will be used to replace offsets beyond the end of the sequence. Specify *fillvalue* to use some other value. """ if len(iterables) != len(offsets): raise ValueError("Number of iterables and offsets didn't match") staggered = [] for it, n in zip(iterables, offsets): if n < 0: staggered.append(chain(repeat(fillvalue, -n), it)) elif n > 0: staggered.append(islice(it, n, None)) else: staggered.append(it) if longest: return zip_longest(*staggered, fillvalue=fillvalue) return zip(*staggered) def sort_together(iterables, key_list=(0,), key=None, reverse=False): """Return the input iterables sorted together, with *key_list* as the priority for sorting. All iterables are trimmed to the length of the shortest one. This can be used like the sorting function in a spreadsheet. If each iterable represents a column of data, the key list determines which columns are used for sorting. By default, all iterables are sorted using the ``0``-th iterable:: >>> iterables = [(4, 3, 2, 1), ('a', 'b', 'c', 'd')] >>> sort_together(iterables) [(1, 2, 3, 4), ('d', 'c', 'b', 'a')] Set a different key list to sort according to another iterable. Specifying multiple keys dictates how ties are broken:: >>> iterables = [(3, 1, 2), (0, 1, 0), ('c', 'b', 'a')] >>> sort_together(iterables, key_list=(1, 2)) [(2, 3, 1), (0, 0, 1), ('a', 'c', 'b')] To sort by a function of the elements of the iterable, pass a *key* function. Its arguments are the elements of the iterables corresponding to the key list:: >>> names = ('a', 'b', 'c') >>> lengths = (1, 2, 3) >>> widths = (5, 2, 1) >>> def area(length, width): ... return length * width >>> sort_together([names, lengths, widths], key_list=(1, 2), key=area) [('c', 'b', 'a'), (3, 2, 1), (1, 2, 5)] Set *reverse* to ``True`` to sort in descending order. >>> sort_together([(1, 2, 3), ('c', 'b', 'a')], reverse=True) [(3, 2, 1), ('a', 'b', 'c')] """ if key is None: # if there is no key function, the key argument to sorted is an # itemgetter key_argument = itemgetter(*key_list) else: # if there is a key function, call it with the items at the offsets # specified by the key function as arguments key_list = list(key_list) if len(key_list) == 1: # if key_list contains a single item, pass the item at that offset # as the only argument to the key function key_offset = key_list[0] key_argument = lambda zipped_items: key(zipped_items[key_offset]) else: # if key_list contains multiple items, use itemgetter to return a # tuple of items, which we pass as *args to the key function get_key_items = itemgetter(*key_list) key_argument = lambda zipped_items: key( *get_key_items(zipped_items) ) return list( zip(*sorted(zip(*iterables), key=key_argument, reverse=reverse)) ) def unzip(iterable): """The inverse of :func:`zip`, this function disaggregates the elements of the zipped *iterable*. The ``i``-th iterable contains the ``i``-th element from each element of the zipped iterable. The first element is used to to determine the length of the remaining elements. >>> iterable = [('a', 1), ('b', 2), ('c', 3), ('d', 4)] >>> letters, numbers = unzip(iterable) >>> list(letters) ['a', 'b', 'c', 'd'] >>> list(numbers) [1, 2, 3, 4] This is similar to using ``zip(*iterable)``, but it avoids reading *iterable* into memory. Note, however, that this function uses :func:`itertools.tee` and thus may require significant storage. """ head, iterable = spy(iter(iterable)) if not head: # empty iterable, e.g. zip([], [], []) return () # spy returns a one-length iterable as head head = head[0] iterables = tee(iterable, len(head)) def itemgetter(i): def getter(obj): try: return obj[i] except IndexError: # basically if we have an iterable like # iter([(1, 2, 3), (4, 5), (6,)]) # the second unzipped iterable would fail at the third tuple # since it would try to access tup[1] # same with the third unzipped iterable and the second tuple # to support these "improperly zipped" iterables, # we create a custom itemgetter # which just stops the unzipped iterables # at first length mismatch raise StopIteration return getter return tuple(map(itemgetter(i), it) for i, it in enumerate(iterables)) def divide(n, iterable): """Divide the elements from *iterable* into *n* parts, maintaining order. >>> group_1, group_2 = divide(2, [1, 2, 3, 4, 5, 6]) >>> list(group_1) [1, 2, 3] >>> list(group_2) [4, 5, 6] If the length of *iterable* is not evenly divisible by *n*, then the length of the returned iterables will not be identical: >>> children = divide(3, [1, 2, 3, 4, 5, 6, 7]) >>> [list(c) for c in children] [[1, 2, 3], [4, 5], [6, 7]] If the length of the iterable is smaller than n, then the last returned iterables will be empty: >>> children = divide(5, [1, 2, 3]) >>> [list(c) for c in children] [[1], [2], [3], [], []] This function will exhaust the iterable before returning and may require significant storage. If order is not important, see :func:`distribute`, which does not first pull the iterable into memory. """ if n < 1: raise ValueError('n must be at least 1') try: iterable[:0] except TypeError: seq = tuple(iterable) else: seq = iterable q, r = divmod(len(seq), n) ret = [] stop = 0 for i in range(1, n + 1): start = stop stop += q + 1 if i <= r else q ret.append(iter(seq[start:stop])) return ret def always_iterable(obj, base_type=(str, bytes)): """If *obj* is iterable, return an iterator over its items:: >>> obj = (1, 2, 3) >>> list(always_iterable(obj)) [1, 2, 3] If *obj* is not iterable, return a one-item iterable containing *obj*:: >>> obj = 1 >>> list(always_iterable(obj)) [1] If *obj* is ``None``, return an empty iterable: >>> obj = None >>> list(always_iterable(None)) [] By default, binary and text strings are not considered iterable:: >>> obj = 'foo' >>> list(always_iterable(obj)) ['foo'] If *base_type* is set, objects for which ``isinstance(obj, base_type)`` returns ``True`` won't be considered iterable. >>> obj = {'a': 1} >>> list(always_iterable(obj)) # Iterate over the dict's keys ['a'] >>> list(always_iterable(obj, base_type=dict)) # Treat dicts as a unit [{'a': 1}] Set *base_type* to ``None`` to avoid any special handling and treat objects Python considers iterable as iterable: >>> obj = 'foo' >>> list(always_iterable(obj, base_type=None)) ['f', 'o', 'o'] """ if obj is None: return iter(()) if (base_type is not None) and isinstance(obj, base_type): return iter((obj,)) try: return iter(obj) except TypeError: return iter((obj,)) def adjacent(predicate, iterable, distance=1): """Return an iterable over `(bool, item)` tuples where the `item` is drawn from *iterable* and the `bool` indicates whether that item satisfies the *predicate* or is adjacent to an item that does. For example, to find whether items are adjacent to a ``3``:: >>> list(adjacent(lambda x: x == 3, range(6))) [(False, 0), (False, 1), (True, 2), (True, 3), (True, 4), (False, 5)] Set *distance* to change what counts as adjacent. For example, to find whether items are two places away from a ``3``: >>> list(adjacent(lambda x: x == 3, range(6), distance=2)) [(False, 0), (True, 1), (True, 2), (True, 3), (True, 4), (True, 5)] This is useful for contextualizing the results of a search function. For example, a code comparison tool might want to identify lines that have changed, but also surrounding lines to give the viewer of the diff context. The predicate function will only be called once for each item in the iterable. See also :func:`groupby_transform`, which can be used with this function to group ranges of items with the same `bool` value. """ # Allow distance=0 mainly for testing that it reproduces results with map() if distance < 0: raise ValueError('distance must be at least 0') i1, i2 = tee(iterable) padding = [False] * distance selected = chain(padding, map(predicate, i1), padding) adjacent_to_selected = map(any, windowed(selected, 2 * distance + 1)) return zip(adjacent_to_selected, i2) def groupby_transform(iterable, keyfunc=None, valuefunc=None, reducefunc=None): """An extension of :func:`itertools.groupby` that can apply transformations to the grouped data. * *keyfunc* is a function computing a key value for each item in *iterable* * *valuefunc* is a function that transforms the individual items from *iterable* after grouping * *reducefunc* is a function that transforms each group of items >>> iterable = 'aAAbBBcCC' >>> keyfunc = lambda k: k.upper() >>> valuefunc = lambda v: v.lower() >>> reducefunc = lambda g: ''.join(g) >>> list(groupby_transform(iterable, keyfunc, valuefunc, reducefunc)) [('A', 'aaa'), ('B', 'bbb'), ('C', 'ccc')] Each optional argument defaults to an identity function if not specified. :func:`groupby_transform` is useful when grouping elements of an iterable using a separate iterable as the key. To do this, :func:`zip` the iterables and pass a *keyfunc* that extracts the first element and a *valuefunc* that extracts the second element:: >>> from operator import itemgetter >>> keys = [0, 0, 1, 1, 1, 2, 2, 2, 3] >>> values = 'abcdefghi' >>> iterable = zip(keys, values) >>> grouper = groupby_transform(iterable, itemgetter(0), itemgetter(1)) >>> [(k, ''.join(g)) for k, g in grouper] [(0, 'ab'), (1, 'cde'), (2, 'fgh'), (3, 'i')] Note that the order of items in the iterable is significant. Only adjacent items are grouped together, so if you don't want any duplicate groups, you should sort the iterable by the key function. """ ret = groupby(iterable, keyfunc) if valuefunc: ret = ((k, map(valuefunc, g)) for k, g in ret) if reducefunc: ret = ((k, reducefunc(g)) for k, g in ret) return ret class numeric_range(abc.Sequence, abc.Hashable): """An extension of the built-in ``range()`` function whose arguments can be any orderable numeric type. With only *stop* specified, *start* defaults to ``0`` and *step* defaults to ``1``. The output items will match the type of *stop*: >>> list(numeric_range(3.5)) [0.0, 1.0, 2.0, 3.0] With only *start* and *stop* specified, *step* defaults to ``1``. The output items will match the type of *start*: >>> from decimal import Decimal >>> start = Decimal('2.1') >>> stop = Decimal('5.1') >>> list(numeric_range(start, stop)) [Decimal('2.1'), Decimal('3.1'), Decimal('4.1')] With *start*, *stop*, and *step* specified the output items will match the type of ``start + step``: >>> from fractions import Fraction >>> start = Fraction(1, 2) # Start at 1/2 >>> stop = Fraction(5, 2) # End at 5/2 >>> step = Fraction(1, 2) # Count by 1/2 >>> list(numeric_range(start, stop, step)) [Fraction(1, 2), Fraction(1, 1), Fraction(3, 2), Fraction(2, 1)] If *step* is zero, ``ValueError`` is raised. Negative steps are supported: >>> list(numeric_range(3, -1, -1.0)) [3.0, 2.0, 1.0, 0.0] Be aware of the limitations of floating point numbers; the representation of the yielded numbers may be surprising. ``datetime.datetime`` objects can be used for *start* and *stop*, if *step* is a ``datetime.timedelta`` object: >>> import datetime >>> start = datetime.datetime(2019, 1, 1) >>> stop = datetime.datetime(2019, 1, 3) >>> step = datetime.timedelta(days=1) >>> items = iter(numeric_range(start, stop, step)) >>> next(items) datetime.datetime(2019, 1, 1, 0, 0) >>> next(items) datetime.datetime(2019, 1, 2, 0, 0) """ _EMPTY_HASH = hash(range(0, 0)) def __init__(self, *args): argc = len(args) if argc == 1: (self._stop,) = args self._start = type(self._stop)(0) self._step = type(self._stop - self._start)(1) elif argc == 2: self._start, self._stop = args self._step = type(self._stop - self._start)(1) elif argc == 3: self._start, self._stop, self._step = args elif argc == 0: raise TypeError( 'numeric_range expected at least ' '1 argument, got {}'.format(argc) ) else: raise TypeError( 'numeric_range expected at most ' '3 arguments, got {}'.format(argc) ) self._zero = type(self._step)(0) if self._step == self._zero: raise ValueError('numeric_range() arg 3 must not be zero') self._growing = self._step > self._zero self._init_len() def __bool__(self): if self._growing: return self._start < self._stop else: return self._start > self._stop def __contains__(self, elem): if self._growing: if self._start <= elem < self._stop: return (elem - self._start) % self._step == self._zero else: if self._start >= elem > self._stop: return (self._start - elem) % (-self._step) == self._zero return False def __eq__(self, other): if isinstance(other, numeric_range): empty_self = not bool(self) empty_other = not bool(other) if empty_self or empty_other: return empty_self and empty_other # True if both empty else: return ( self._start == other._start and self._step == other._step and self._get_by_index(-1) == other._get_by_index(-1) ) else: return False def __getitem__(self, key): if isinstance(key, int): return self._get_by_index(key) elif isinstance(key, slice): step = self._step if key.step is None else key.step * self._step if key.start is None or key.start <= -self._len: start = self._start elif key.start >= self._len: start = self._stop else: # -self._len < key.start < self._len start = self._get_by_index(key.start) if key.stop is None or key.stop >= self._len: stop = self._stop elif key.stop <= -self._len: stop = self._start else: # -self._len < key.stop < self._len stop = self._get_by_index(key.stop) return numeric_range(start, stop, step) else: raise TypeError( 'numeric range indices must be ' 'integers or slices, not {}'.format(type(key).__name__) ) def __hash__(self): if self: return hash((self._start, self._get_by_index(-1), self._step)) else: return self._EMPTY_HASH def __iter__(self): values = (self._start + (n * self._step) for n in count()) if self._growing: return takewhile(partial(gt, self._stop), values) else: return takewhile(partial(lt, self._stop), values) def __len__(self): return self._len def _init_len(self): if self._growing: start = self._start stop = self._stop step = self._step else: start = self._stop stop = self._start step = -self._step distance = stop - start if distance <= self._zero: self._len = 0 else: # distance > 0 and step > 0: regular euclidean division q, r = divmod(distance, step) self._len = int(q) + int(r != self._zero) def __reduce__(self): return numeric_range, (self._start, self._stop, self._step) def __repr__(self): if self._step == 1: return "numeric_range({}, {})".format( repr(self._start), repr(self._stop) ) else: return "numeric_range({}, {}, {})".format( repr(self._start), repr(self._stop), repr(self._step) ) def __reversed__(self): return iter( numeric_range( self._get_by_index(-1), self._start - self._step, -self._step ) ) def count(self, value): return int(value in self) def index(self, value): if self._growing: if self._start <= value < self._stop: q, r = divmod(value - self._start, self._step) if r == self._zero: return int(q) else: if self._start >= value > self._stop: q, r = divmod(self._start - value, -self._step) if r == self._zero: return int(q) raise ValueError("{} is not in numeric range".format(value)) def _get_by_index(self, i): if i < 0: i += self._len if i < 0 or i >= self._len: raise IndexError("numeric range object index out of range") return self._start + i * self._step def count_cycle(iterable, n=None): """Cycle through the items from *iterable* up to *n* times, yielding the number of completed cycles along with each item. If *n* is omitted the process repeats indefinitely. >>> list(count_cycle('AB', 3)) [(0, 'A'), (0, 'B'), (1, 'A'), (1, 'B'), (2, 'A'), (2, 'B')] """ iterable = tuple(iterable) if not iterable: return iter(()) counter = count() if n is None else range(n) return ((i, item) for i in counter for item in iterable) def mark_ends(iterable): """Yield 3-tuples of the form ``(is_first, is_last, item)``. >>> list(mark_ends('ABC')) [(True, False, 'A'), (False, False, 'B'), (False, True, 'C')] Use this when looping over an iterable to take special action on its first and/or last items: >>> iterable = ['Header', 100, 200, 'Footer'] >>> total = 0 >>> for is_first, is_last, item in mark_ends(iterable): ... if is_first: ... continue # Skip the header ... if is_last: ... continue # Skip the footer ... total += item >>> print(total) 300 """ it = iter(iterable) try: b = next(it) except StopIteration: return try: for i in count(): a = b b = next(it) yield i == 0, False, a except StopIteration: yield i == 0, True, a def locate(iterable, pred=bool, window_size=None): """Yield the index of each item in *iterable* for which *pred* returns ``True``. *pred* defaults to :func:`bool`, which will select truthy items: >>> list(locate([0, 1, 1, 0, 1, 0, 0])) [1, 2, 4] Set *pred* to a custom function to, e.g., find the indexes for a particular item. >>> list(locate(['a', 'b', 'c', 'b'], lambda x: x == 'b')) [1, 3] If *window_size* is given, then the *pred* function will be called with that many items. This enables searching for sub-sequences: >>> iterable = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3] >>> pred = lambda *args: args == (1, 2, 3) >>> list(locate(iterable, pred=pred, window_size=3)) [1, 5, 9] Use with :func:`seekable` to find indexes and then retrieve the associated items: >>> from itertools import count >>> from more_itertools import seekable >>> source = (3 * n + 1 if (n % 2) else n // 2 for n in count()) >>> it = seekable(source) >>> pred = lambda x: x > 100 >>> indexes = locate(it, pred=pred) >>> i = next(indexes) >>> it.seek(i) >>> next(it) 106 """ if window_size is None: return compress(count(), map(pred, iterable)) if window_size < 1: raise ValueError('window size must be at least 1') it = windowed(iterable, window_size, fillvalue=_marker) return compress(count(), starmap(pred, it)) def lstrip(iterable, pred): """Yield the items from *iterable*, but strip any from the beginning for which *pred* returns ``True``. For example, to remove a set of items from the start of an iterable: >>> iterable = (None, False, None, 1, 2, None, 3, False, None) >>> pred = lambda x: x in {None, False, ''} >>> list(lstrip(iterable, pred)) [1, 2, None, 3, False, None] This function is analogous to to :func:`str.lstrip`, and is essentially an wrapper for :func:`itertools.dropwhile`. """ return dropwhile(pred, iterable) def rstrip(iterable, pred): """Yield the items from *iterable*, but strip any from the end for which *pred* returns ``True``. For example, to remove a set of items from the end of an iterable: >>> iterable = (None, False, None, 1, 2, None, 3, False, None) >>> pred = lambda x: x in {None, False, ''} >>> list(rstrip(iterable, pred)) [None, False, None, 1, 2, None, 3] This function is analogous to :func:`str.rstrip`. """ cache = [] cache_append = cache.append cache_clear = cache.clear for x in iterable: if pred(x): cache_append(x) else: yield from cache cache_clear() yield x def strip(iterable, pred): """Yield the items from *iterable*, but strip any from the beginning and end for which *pred* returns ``True``. For example, to remove a set of items from both ends of an iterable: >>> iterable = (None, False, None, 1, 2, None, 3, False, None) >>> pred = lambda x: x in {None, False, ''} >>> list(strip(iterable, pred)) [1, 2, None, 3] This function is analogous to :func:`str.strip`. """ return rstrip(lstrip(iterable, pred), pred) class islice_extended: """An extension of :func:`itertools.islice` that supports negative values for *stop*, *start*, and *step*. >>> iterable = iter('abcdefgh') >>> list(islice_extended(iterable, -4, -1)) ['e', 'f', 'g'] Slices with negative values require some caching of *iterable*, but this function takes care to minimize the amount of memory required. For example, you can use a negative step with an infinite iterator: >>> from itertools import count >>> list(islice_extended(count(), 110, 99, -2)) [110, 108, 106, 104, 102, 100] You can also use slice notation directly: >>> iterable = map(str, count()) >>> it = islice_extended(iterable)[10:20:2] >>> list(it) ['10', '12', '14', '16', '18'] """ def __init__(self, iterable, *args): it = iter(iterable) if args: self._iterable = _islice_helper(it, slice(*args)) else: self._iterable = it def __iter__(self): return self def __next__(self): return next(self._iterable) def __getitem__(self, key): if isinstance(key, slice): return islice_extended(_islice_helper(self._iterable, key)) raise TypeError('islice_extended.__getitem__ argument must be a slice') def _islice_helper(it, s): start = s.start stop = s.stop if s.step == 0: raise ValueError('step argument must be a non-zero integer or None.') step = s.step or 1 if step > 0: start = 0 if (start is None) else start if start < 0: # Consume all but the last -start items cache = deque(enumerate(it, 1), maxlen=-start) len_iter = cache[-1][0] if cache else 0 # Adjust start to be positive i = max(len_iter + start, 0) # Adjust stop to be positive if stop is None: j = len_iter elif stop >= 0: j = min(stop, len_iter) else: j = max(len_iter + stop, 0) # Slice the cache n = j - i if n <= 0: return for index, item in islice(cache, 0, n, step): yield item elif (stop is not None) and (stop < 0): # Advance to the start position next(islice(it, start, start), None) # When stop is negative, we have to carry -stop items while # iterating cache = deque(islice(it, -stop), maxlen=-stop) for index, item in enumerate(it): cached_item = cache.popleft() if index % step == 0: yield cached_item cache.append(item) else: # When both start and stop are positive we have the normal case yield from islice(it, start, stop, step) else: start = -1 if (start is None) else start if (stop is not None) and (stop < 0): # Consume all but the last items n = -stop - 1 cache = deque(enumerate(it, 1), maxlen=n) len_iter = cache[-1][0] if cache else 0 # If start and stop are both negative they are comparable and # we can just slice. Otherwise we can adjust start to be negative # and then slice. if start < 0: i, j = start, stop else: i, j = min(start - len_iter, -1), None for index, item in list(cache)[i:j:step]: yield item else: # Advance to the stop position if stop is not None: m = stop + 1 next(islice(it, m, m), None) # stop is positive, so if start is negative they are not comparable # and we need the rest of the items. if start < 0: i = start n = None # stop is None and start is positive, so we just need items up to # the start index. elif stop is None: i = None n = start + 1 # Both stop and start are positive, so they are comparable. else: i = None n = start - stop if n <= 0: return cache = list(islice(it, n)) yield from cache[i::step] def always_reversible(iterable): """An extension of :func:`reversed` that supports all iterables, not just those which implement the ``Reversible`` or ``Sequence`` protocols. >>> print(*always_reversible(x for x in range(3))) 2 1 0 If the iterable is already reversible, this function returns the result of :func:`reversed()`. If the iterable is not reversible, this function will cache the remaining items in the iterable and yield them in reverse order, which may require significant storage. """ try: return reversed(iterable) except TypeError: return reversed(list(iterable)) def consecutive_groups(iterable, ordering=lambda x: x): """Yield groups of consecutive items using :func:`itertools.groupby`. The *ordering* function determines whether two items are adjacent by returning their position. By default, the ordering function is the identity function. This is suitable for finding runs of numbers: >>> iterable = [1, 10, 11, 12, 20, 30, 31, 32, 33, 40] >>> for group in consecutive_groups(iterable): ... print(list(group)) [1] [10, 11, 12] [20] [30, 31, 32, 33] [40] For finding runs of adjacent letters, try using the :meth:`index` method of a string of letters: >>> from string import ascii_lowercase >>> iterable = 'abcdfgilmnop' >>> ordering = ascii_lowercase.index >>> for group in consecutive_groups(iterable, ordering): ... print(list(group)) ['a', 'b', 'c', 'd'] ['f', 'g'] ['i'] ['l', 'm', 'n', 'o', 'p'] Each group of consecutive items is an iterator that shares it source with *iterable*. When an an output group is advanced, the previous group is no longer available unless its elements are copied (e.g., into a ``list``). >>> iterable = [1, 2, 11, 12, 21, 22] >>> saved_groups = [] >>> for group in consecutive_groups(iterable): ... saved_groups.append(list(group)) # Copy group elements >>> saved_groups [[1, 2], [11, 12], [21, 22]] """ for k, g in groupby( enumerate(iterable), key=lambda x: x[0] - ordering(x[1]) ): yield map(itemgetter(1), g) def difference(iterable, func=sub, *, initial=None): """This function is the inverse of :func:`itertools.accumulate`. By default it will compute the first difference of *iterable* using :func:`operator.sub`: >>> from itertools import accumulate >>> iterable = accumulate([0, 1, 2, 3, 4]) # produces 0, 1, 3, 6, 10 >>> list(difference(iterable)) [0, 1, 2, 3, 4] *func* defaults to :func:`operator.sub`, but other functions can be specified. They will be applied as follows:: A, B, C, D, ... --> A, func(B, A), func(C, B), func(D, C), ... For example, to do progressive division: >>> iterable = [1, 2, 6, 24, 120] >>> func = lambda x, y: x // y >>> list(difference(iterable, func)) [1, 2, 3, 4, 5] If the *initial* keyword is set, the first element will be skipped when computing successive differences. >>> it = [10, 11, 13, 16] # from accumulate([1, 2, 3], initial=10) >>> list(difference(it, initial=10)) [1, 2, 3] """ a, b = tee(iterable) try: first = [next(b)] except StopIteration: return iter([]) if initial is not None: first = [] return chain(first, starmap(func, zip(b, a))) class SequenceView(Sequence): """Return a read-only view of the sequence object *target*. :class:`SequenceView` objects are analogous to Python's built-in "dictionary view" types. They provide a dynamic view of a sequence's items, meaning that when the sequence updates, so does the view. >>> seq = ['0', '1', '2'] >>> view = SequenceView(seq) >>> view SequenceView(['0', '1', '2']) >>> seq.append('3') >>> view SequenceView(['0', '1', '2', '3']) Sequence views support indexing, slicing, and length queries. They act like the underlying sequence, except they don't allow assignment: >>> view[1] '1' >>> view[1:-1] ['1', '2'] >>> len(view) 4 Sequence views are useful as an alternative to copying, as they don't require (much) extra storage. """ def __init__(self, target): if not isinstance(target, Sequence): raise TypeError self._target = target def __getitem__(self, index): return self._target[index] def __len__(self): return len(self._target) def __repr__(self): return '{}({})'.format(self.__class__.__name__, repr(self._target)) class seekable: """Wrap an iterator to allow for seeking backward and forward. This progressively caches the items in the source iterable so they can be re-visited. Call :meth:`seek` with an index to seek to that position in the source iterable. To "reset" an iterator, seek to ``0``: >>> from itertools import count >>> it = seekable((str(n) for n in count())) >>> next(it), next(it), next(it) ('0', '1', '2') >>> it.seek(0) >>> next(it), next(it), next(it) ('0', '1', '2') >>> next(it) '3' You can also seek forward: >>> it = seekable((str(n) for n in range(20))) >>> it.seek(10) >>> next(it) '10' >>> it.seek(20) # Seeking past the end of the source isn't a problem >>> list(it) [] >>> it.seek(0) # Resetting works even after hitting the end >>> next(it), next(it), next(it) ('0', '1', '2') Call :meth:`peek` to look ahead one item without advancing the iterator: >>> it = seekable('1234') >>> it.peek() '1' >>> list(it) ['1', '2', '3', '4'] >>> it.peek(default='empty') 'empty' Before the iterator is at its end, calling :func:`bool` on it will return ``True``. After it will return ``False``: >>> it = seekable('5678') >>> bool(it) True >>> list(it) ['5', '6', '7', '8'] >>> bool(it) False You may view the contents of the cache with the :meth:`elements` method. That returns a :class:`SequenceView`, a view that updates automatically: >>> it = seekable((str(n) for n in range(10))) >>> next(it), next(it), next(it) ('0', '1', '2') >>> elements = it.elements() >>> elements SequenceView(['0', '1', '2']) >>> next(it) '3' >>> elements SequenceView(['0', '1', '2', '3']) By default, the cache grows as the source iterable progresses, so beware of wrapping very large or infinite iterables. Supply *maxlen* to limit the size of the cache (this of course limits how far back you can seek). >>> from itertools import count >>> it = seekable((str(n) for n in count()), maxlen=2) >>> next(it), next(it), next(it), next(it) ('0', '1', '2', '3') >>> list(it.elements()) ['2', '3'] >>> it.seek(0) >>> next(it), next(it), next(it), next(it) ('2', '3', '4', '5') >>> next(it) '6' """ def __init__(self, iterable, maxlen=None): self._source = iter(iterable) if maxlen is None: self._cache = [] else: self._cache = deque([], maxlen) self._index = None def __iter__(self): return self def __next__(self): if self._index is not None: try: item = self._cache[self._index] except IndexError: self._index = None else: self._index += 1 return item item = next(self._source) self._cache.append(item) return item def __bool__(self): try: self.peek() except StopIteration: return False return True def peek(self, default=_marker): try: peeked = next(self) except StopIteration: if default is _marker: raise return default if self._index is None: self._index = len(self._cache) self._index -= 1 return peeked def elements(self): return SequenceView(self._cache) def seek(self, index): self._index = index remainder = index - len(self._cache) if remainder > 0: consume(self, remainder) class run_length: """ :func:`run_length.encode` compresses an iterable with run-length encoding. It yields groups of repeated items with the count of how many times they were repeated: >>> uncompressed = 'abbcccdddd' >>> list(run_length.encode(uncompressed)) [('a', 1), ('b', 2), ('c', 3), ('d', 4)] :func:`run_length.decode` decompresses an iterable that was previously compressed with run-length encoding. It yields the items of the decompressed iterable: >>> compressed = [('a', 1), ('b', 2), ('c', 3), ('d', 4)] >>> list(run_length.decode(compressed)) ['a', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd', 'd'] """ @staticmethod def encode(iterable): return ((k, ilen(g)) for k, g in groupby(iterable)) @staticmethod def decode(iterable): return chain.from_iterable(repeat(k, n) for k, n in iterable) def exactly_n(iterable, n, predicate=bool): """Return ``True`` if exactly ``n`` items in the iterable are ``True`` according to the *predicate* function. >>> exactly_n([True, True, False], 2) True >>> exactly_n([True, True, False], 1) False >>> exactly_n([0, 1, 2, 3, 4, 5], 3, lambda x: x < 3) True The iterable will be advanced until ``n + 1`` truthy items are encountered, so avoid calling it on infinite iterables. """ return len(take(n + 1, filter(predicate, iterable))) == n def circular_shifts(iterable): """Return a list of circular shifts of *iterable*. >>> circular_shifts(range(4)) [(0, 1, 2, 3), (1, 2, 3, 0), (2, 3, 0, 1), (3, 0, 1, 2)] """ lst = list(iterable) return take(len(lst), windowed(cycle(lst), len(lst))) def make_decorator(wrapping_func, result_index=0): """Return a decorator version of *wrapping_func*, which is a function that modifies an iterable. *result_index* is the position in that function's signature where the iterable goes. This lets you use itertools on the "production end," i.e. at function definition. This can augment what the function returns without changing the function's code. For example, to produce a decorator version of :func:`chunked`: >>> from more_itertools import chunked >>> chunker = make_decorator(chunked, result_index=0) >>> @chunker(3) ... def iter_range(n): ... return iter(range(n)) ... >>> list(iter_range(9)) [[0, 1, 2], [3, 4, 5], [6, 7, 8]] To only allow truthy items to be returned: >>> truth_serum = make_decorator(filter, result_index=1) >>> @truth_serum(bool) ... def boolean_test(): ... return [0, 1, '', ' ', False, True] ... >>> list(boolean_test()) [1, ' ', True] The :func:`peekable` and :func:`seekable` wrappers make for practical decorators: >>> from more_itertools import peekable >>> peekable_function = make_decorator(peekable) >>> @peekable_function() ... def str_range(*args): ... return (str(x) for x in range(*args)) ... >>> it = str_range(1, 20, 2) >>> next(it), next(it), next(it) ('1', '3', '5') >>> it.peek() '7' >>> next(it) '7' """ # See https://sites.google.com/site/bbayles/index/decorator_factory for # notes on how this works. def decorator(*wrapping_args, **wrapping_kwargs): def outer_wrapper(f): def inner_wrapper(*args, **kwargs): result = f(*args, **kwargs) wrapping_args_ = list(wrapping_args) wrapping_args_.insert(result_index, result) return wrapping_func(*wrapping_args_, **wrapping_kwargs) return inner_wrapper return outer_wrapper return decorator def map_reduce(iterable, keyfunc, valuefunc=None, reducefunc=None): """Return a dictionary that maps the items in *iterable* to categories defined by *keyfunc*, transforms them with *valuefunc*, and then summarizes them by category with *reducefunc*. *valuefunc* defaults to the identity function if it is unspecified. If *reducefunc* is unspecified, no summarization takes place: >>> keyfunc = lambda x: x.upper() >>> result = map_reduce('abbccc', keyfunc) >>> sorted(result.items()) [('A', ['a']), ('B', ['b', 'b']), ('C', ['c', 'c', 'c'])] Specifying *valuefunc* transforms the categorized items: >>> keyfunc = lambda x: x.upper() >>> valuefunc = lambda x: 1 >>> result = map_reduce('abbccc', keyfunc, valuefunc) >>> sorted(result.items()) [('A', [1]), ('B', [1, 1]), ('C', [1, 1, 1])] Specifying *reducefunc* summarizes the categorized items: >>> keyfunc = lambda x: x.upper() >>> valuefunc = lambda x: 1 >>> reducefunc = sum >>> result = map_reduce('abbccc', keyfunc, valuefunc, reducefunc) >>> sorted(result.items()) [('A', 1), ('B', 2), ('C', 3)] You may want to filter the input iterable before applying the map/reduce procedure: >>> all_items = range(30) >>> items = [x for x in all_items if 10 <= x <= 20] # Filter >>> keyfunc = lambda x: x % 2 # Evens map to 0; odds to 1 >>> categories = map_reduce(items, keyfunc=keyfunc) >>> sorted(categories.items()) [(0, [10, 12, 14, 16, 18, 20]), (1, [11, 13, 15, 17, 19])] >>> summaries = map_reduce(items, keyfunc=keyfunc, reducefunc=sum) >>> sorted(summaries.items()) [(0, 90), (1, 75)] Note that all items in the iterable are gathered into a list before the summarization step, which may require significant storage. The returned object is a :obj:`collections.defaultdict` with the ``default_factory`` set to ``None``, such that it behaves like a normal dictionary. """ valuefunc = (lambda x: x) if (valuefunc is None) else valuefunc ret = defaultdict(list) for item in iterable: key = keyfunc(item) value = valuefunc(item) ret[key].append(value) if reducefunc is not None: for key, value_list in ret.items(): ret[key] = reducefunc(value_list) ret.default_factory = None return ret def rlocate(iterable, pred=bool, window_size=None): """Yield the index of each item in *iterable* for which *pred* returns ``True``, starting from the right and moving left. *pred* defaults to :func:`bool`, which will select truthy items: >>> list(rlocate([0, 1, 1, 0, 1, 0, 0])) # Truthy at 1, 2, and 4 [4, 2, 1] Set *pred* to a custom function to, e.g., find the indexes for a particular item: >>> iterable = iter('abcb') >>> pred = lambda x: x == 'b' >>> list(rlocate(iterable, pred)) [3, 1] If *window_size* is given, then the *pred* function will be called with that many items. This enables searching for sub-sequences: >>> iterable = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3] >>> pred = lambda *args: args == (1, 2, 3) >>> list(rlocate(iterable, pred=pred, window_size=3)) [9, 5, 1] Beware, this function won't return anything for infinite iterables. If *iterable* is reversible, ``rlocate`` will reverse it and search from the right. Otherwise, it will search from the left and return the results in reverse order. See :func:`locate` to for other example applications. """ if window_size is None: try: len_iter = len(iterable) return (len_iter - i - 1 for i in locate(reversed(iterable), pred)) except TypeError: pass return reversed(list(locate(iterable, pred, window_size))) def replace(iterable, pred, substitutes, count=None, window_size=1): """Yield the items from *iterable*, replacing the items for which *pred* returns ``True`` with the items from the iterable *substitutes*. >>> iterable = [1, 1, 0, 1, 1, 0, 1, 1] >>> pred = lambda x: x == 0 >>> substitutes = (2, 3) >>> list(replace(iterable, pred, substitutes)) [1, 1, 2, 3, 1, 1, 2, 3, 1, 1] If *count* is given, the number of replacements will be limited: >>> iterable = [1, 1, 0, 1, 1, 0, 1, 1, 0] >>> pred = lambda x: x == 0 >>> substitutes = [None] >>> list(replace(iterable, pred, substitutes, count=2)) [1, 1, None, 1, 1, None, 1, 1, 0] Use *window_size* to control the number of items passed as arguments to *pred*. This allows for locating and replacing subsequences. >>> iterable = [0, 1, 2, 5, 0, 1, 2, 5] >>> window_size = 3 >>> pred = lambda *args: args == (0, 1, 2) # 3 items passed to pred >>> substitutes = [3, 4] # Splice in these items >>> list(replace(iterable, pred, substitutes, window_size=window_size)) [3, 4, 5, 3, 4, 5] """ if window_size < 1: raise ValueError('window_size must be at least 1') # Save the substitutes iterable, since it's used more than once substitutes = tuple(substitutes) # Add padding such that the number of windows matches the length of the # iterable it = chain(iterable, [_marker] * (window_size - 1)) windows = windowed(it, window_size) n = 0 for w in windows: # If the current window matches our predicate (and we haven't hit # our maximum number of replacements), splice in the substitutes # and then consume the following windows that overlap with this one. # For example, if the iterable is (0, 1, 2, 3, 4...) # and the window size is 2, we have (0, 1), (1, 2), (2, 3)... # If the predicate matches on (0, 1), we need to zap (0, 1) and (1, 2) if pred(*w): if (count is None) or (n < count): n += 1 yield from substitutes consume(windows, window_size - 1) continue # If there was no match (or we've reached the replacement limit), # yield the first item from the window. if w and (w[0] is not _marker): yield w[0] def partitions(iterable): """Yield all possible order-preserving partitions of *iterable*. >>> iterable = 'abc' >>> for part in partitions(iterable): ... print([''.join(p) for p in part]) ['abc'] ['a', 'bc'] ['ab', 'c'] ['a', 'b', 'c'] This is unrelated to :func:`partition`. """ sequence = list(iterable) n = len(sequence) for i in powerset(range(1, n)): yield [sequence[i:j] for i, j in zip((0,) + i, i + (n,))] def set_partitions(iterable, k=None): """ Yield the set partitions of *iterable* into *k* parts. Set partitions are not order-preserving. >>> iterable = 'abc' >>> for part in set_partitions(iterable, 2): ... print([''.join(p) for p in part]) ['a', 'bc'] ['ab', 'c'] ['b', 'ac'] If *k* is not given, every set partition is generated. >>> iterable = 'abc' >>> for part in set_partitions(iterable): ... print([''.join(p) for p in part]) ['abc'] ['a', 'bc'] ['ab', 'c'] ['b', 'ac'] ['a', 'b', 'c'] """ L = list(iterable) n = len(L) if k is not None: if k < 1: raise ValueError( "Can't partition in a negative or zero number of groups" ) elif k > n: return def set_partitions_helper(L, k): n = len(L) if k == 1: yield [L] elif n == k: yield [[s] for s in L] else: e, *M = L for p in set_partitions_helper(M, k - 1): yield [[e], *p] for p in set_partitions_helper(M, k): for i in range(len(p)): yield p[:i] + [[e] + p[i]] + p[i + 1 :] if k is None: for k in range(1, n + 1): yield from set_partitions_helper(L, k) else: yield from set_partitions_helper(L, k) class time_limited: """ Yield items from *iterable* until *limit_seconds* have passed. If the time limit expires before all items have been yielded, the ``timed_out`` parameter will be set to ``True``. >>> from time import sleep >>> def generator(): ... yield 1 ... yield 2 ... sleep(0.2) ... yield 3 >>> iterable = time_limited(0.1, generator()) >>> list(iterable) [1, 2] >>> iterable.timed_out True Note that the time is checked before each item is yielded, and iteration stops if the time elapsed is greater than *limit_seconds*. If your time limit is 1 second, but it takes 2 seconds to generate the first item from the iterable, the function will run for 2 seconds and not yield anything. """ def __init__(self, limit_seconds, iterable): if limit_seconds < 0: raise ValueError('limit_seconds must be positive') self.limit_seconds = limit_seconds self._iterable = iter(iterable) self._start_time = monotonic() self.timed_out = False def __iter__(self): return self def __next__(self): item = next(self._iterable) if monotonic() - self._start_time > self.limit_seconds: self.timed_out = True raise StopIteration return item def only(iterable, default=None, too_long=None): """If *iterable* has only one item, return it. If it has zero items, return *default*. If it has more than one item, raise the exception given by *too_long*, which is ``ValueError`` by default. >>> only([], default='missing') 'missing' >>> only([1]) 1 >>> only([1, 2]) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... ValueError: Expected exactly one item in iterable, but got 1, 2, and perhaps more.' >>> only([1, 2], too_long=TypeError) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... TypeError Note that :func:`only` attempts to advance *iterable* twice to ensure there is only one item. See :func:`spy` or :func:`peekable` to check iterable contents less destructively. """ it = iter(iterable) first_value = next(it, default) try: second_value = next(it) except StopIteration: pass else: msg = ( 'Expected exactly one item in iterable, but got {!r}, {!r}, ' 'and perhaps more.'.format(first_value, second_value) ) raise too_long or ValueError(msg) return first_value def ichunked(iterable, n): """Break *iterable* into sub-iterables with *n* elements each. :func:`ichunked` is like :func:`chunked`, but it yields iterables instead of lists. If the sub-iterables are read in order, the elements of *iterable* won't be stored in memory. If they are read out of order, :func:`itertools.tee` is used to cache elements as necessary. >>> from itertools import count >>> all_chunks = ichunked(count(), 4) >>> c_1, c_2, c_3 = next(all_chunks), next(all_chunks), next(all_chunks) >>> list(c_2) # c_1's elements have been cached; c_3's haven't been [4, 5, 6, 7] >>> list(c_1) [0, 1, 2, 3] >>> list(c_3) [8, 9, 10, 11] """ source = iter(iterable) while True: # Check to see whether we're at the end of the source iterable item = next(source, _marker) if item is _marker: return # Clone the source and yield an n-length slice source, it = tee(chain([item], source)) yield islice(it, n) # Advance the source iterable consume(source, n) def distinct_combinations(iterable, r): """Yield the distinct combinations of *r* items taken from *iterable*. >>> list(distinct_combinations([0, 0, 1], 2)) [(0, 0), (0, 1)] Equivalent to ``set(combinations(iterable))``, except duplicates are not generated and thrown away. For larger input sequences this is much more efficient. """ if r < 0: raise ValueError('r must be non-negative') elif r == 0: yield () return pool = tuple(iterable) generators = [unique_everseen(enumerate(pool), key=itemgetter(1))] current_combo = [None] * r level = 0 while generators: try: cur_idx, p = next(generators[-1]) except StopIteration: generators.pop() level -= 1 continue current_combo[level] = p if level + 1 == r: yield tuple(current_combo) else: generators.append( unique_everseen( enumerate(pool[cur_idx + 1 :], cur_idx + 1), key=itemgetter(1), ) ) level += 1 def filter_except(validator, iterable, *exceptions): """Yield the items from *iterable* for which the *validator* function does not raise one of the specified *exceptions*. *validator* is called for each item in *iterable*. It should be a function that accepts one argument and raises an exception if that item is not valid. >>> iterable = ['1', '2', 'three', '4', None] >>> list(filter_except(int, iterable, ValueError, TypeError)) ['1', '2', '4'] If an exception other than one given by *exceptions* is raised by *validator*, it is raised like normal. """ for item in iterable: try: validator(item) except exceptions: pass else: yield item def map_except(function, iterable, *exceptions): """Transform each item from *iterable* with *function* and yield the result, unless *function* raises one of the specified *exceptions*. *function* is called to transform each item in *iterable*. It should be a accept one argument. >>> iterable = ['1', '2', 'three', '4', None] >>> list(map_except(int, iterable, ValueError, TypeError)) [1, 2, 4] If an exception other than one given by *exceptions* is raised by *function*, it is raised like normal. """ for item in iterable: try: yield function(item) except exceptions: pass def _sample_unweighted(iterable, k): # Implementation of "Algorithm L" from the 1994 paper by Kim-Hung Li: # "Reservoir-Sampling Algorithms of Time Complexity O(n(1+log(N/n)))". # Fill up the reservoir (collection of samples) with the first `k` samples reservoir = take(k, iterable) # Generate random number that's the largest in a sample of k U(0,1) numbers # Largest order statistic: https://en.wikipedia.org/wiki/Order_statistic W = exp(log(random()) / k) # The number of elements to skip before changing the reservoir is a random # number with a geometric distribution. Sample it using random() and logs. next_index = k + floor(log(random()) / log(1 - W)) for index, element in enumerate(iterable, k): if index == next_index: reservoir[randrange(k)] = element # The new W is the largest in a sample of k U(0, `old_W`) numbers W *= exp(log(random()) / k) next_index += floor(log(random()) / log(1 - W)) + 1 return reservoir def _sample_weighted(iterable, k, weights): # Implementation of "A-ExpJ" from the 2006 paper by Efraimidis et al. : # "Weighted random sampling with a reservoir". # Log-transform for numerical stability for weights that are small/large weight_keys = (log(random()) / weight for weight in weights) # Fill up the reservoir (collection of samples) with the first `k` # weight-keys and elements, then heapify the list. reservoir = take(k, zip(weight_keys, iterable)) heapify(reservoir) # The number of jumps before changing the reservoir is a random variable # with an exponential distribution. Sample it using random() and logs. smallest_weight_key, _ = reservoir[0] weights_to_skip = log(random()) / smallest_weight_key for weight, element in zip(weights, iterable): if weight >= weights_to_skip: # The notation here is consistent with the paper, but we store # the weight-keys in log-space for better numerical stability. smallest_weight_key, _ = reservoir[0] t_w = exp(weight * smallest_weight_key) r_2 = uniform(t_w, 1) # generate U(t_w, 1) weight_key = log(r_2) / weight heapreplace(reservoir, (weight_key, element)) smallest_weight_key, _ = reservoir[0] weights_to_skip = log(random()) / smallest_weight_key else: weights_to_skip -= weight # Equivalent to [element for weight_key, element in sorted(reservoir)] return [heappop(reservoir)[1] for _ in range(k)] def sample(iterable, k, weights=None): """Return a *k*-length list of elements chosen (without replacement) from the *iterable*. Like :func:`random.sample`, but works on iterables of unknown length. >>> iterable = range(100) >>> sample(iterable, 5) # doctest: +SKIP [81, 60, 96, 16, 4] An iterable with *weights* may also be given: >>> iterable = range(100) >>> weights = (i * i + 1 for i in range(100)) >>> sampled = sample(iterable, 5, weights=weights) # doctest: +SKIP [79, 67, 74, 66, 78] The algorithm can also be used to generate weighted random permutations. The relative weight of each item determines the probability that it appears late in the permutation. >>> data = "abcdefgh" >>> weights = range(1, len(data) + 1) >>> sample(data, k=len(data), weights=weights) # doctest: +SKIP ['c', 'a', 'b', 'e', 'g', 'd', 'h', 'f'] """ if k == 0: return [] iterable = iter(iterable) if weights is None: return _sample_unweighted(iterable, k) else: weights = iter(weights) return _sample_weighted(iterable, k, weights) def is_sorted(iterable, key=None, reverse=False): """Returns ``True`` if the items of iterable are in sorted order, and ``False`` otherwise. *key* and *reverse* have the same meaning that they do in the built-in :func:`sorted` function. >>> is_sorted(['1', '2', '3', '4', '5'], key=int) True >>> is_sorted([5, 4, 3, 1, 2], reverse=True) False The function returns ``False`` after encountering the first out-of-order item. If there are no out-of-order items, the iterable is exhausted. """ compare = lt if reverse else gt it = iterable if (key is None) else map(key, iterable) return not any(starmap(compare, pairwise(it))) class AbortThread(BaseException): pass class callback_iter: """Convert a function that uses callbacks to an iterator. Let *func* be a function that takes a `callback` keyword argument. For example: >>> def func(callback=None): ... for i, c in [(1, 'a'), (2, 'b'), (3, 'c')]: ... if callback: ... callback(i, c) ... return 4 Use ``with callback_iter(func)`` to get an iterator over the parameters that are delivered to the callback. >>> with callback_iter(func) as it: ... for args, kwargs in it: ... print(args) (1, 'a') (2, 'b') (3, 'c') The function will be called in a background thread. The ``done`` property indicates whether it has completed execution. >>> it.done True If it completes successfully, its return value will be available in the ``result`` property. >>> it.result 4 Notes: * If the function uses some keyword argument besides ``callback``, supply *callback_kwd*. * If it finished executing, but raised an exception, accessing the ``result`` property will raise the same exception. * If it hasn't finished executing, accessing the ``result`` property from within the ``with`` block will raise ``RuntimeError``. * If it hasn't finished executing, accessing the ``result`` property from outside the ``with`` block will raise a ``more_itertools.AbortThread`` exception. * Provide *wait_seconds* to adjust how frequently the it is polled for output. """ def __init__(self, func, callback_kwd='callback', wait_seconds=0.1): self._func = func self._callback_kwd = callback_kwd self._aborted = False self._future = None self._wait_seconds = wait_seconds self._executor = ThreadPoolExecutor(max_workers=1) self._iterator = self._reader() def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): self._aborted = True self._executor.shutdown() def __iter__(self): return self def __next__(self): return next(self._iterator) @property def done(self): if self._future is None: return False return self._future.done() @property def result(self): if not self.done: raise RuntimeError('Function has not yet completed') return self._future.result() def _reader(self): q = Queue() def callback(*args, **kwargs): if self._aborted: raise AbortThread('canceled by user') q.put((args, kwargs)) self._future = self._executor.submit( self._func, **{self._callback_kwd: callback} ) while True: try: item = q.get(timeout=self._wait_seconds) except Empty: pass else: q.task_done() yield item if self._future.done(): break remaining = [] while True: try: item = q.get_nowait() except Empty: break else: q.task_done() remaining.append(item) q.join() yield from remaining def windowed_complete(iterable, n): """ Yield ``(beginning, middle, end)`` tuples, where: * Each ``middle`` has *n* items from *iterable* * Each ``beginning`` has the items before the ones in ``middle`` * Each ``end`` has the items after the ones in ``middle`` >>> iterable = range(7) >>> n = 3 >>> for beginning, middle, end in windowed_complete(iterable, n): ... print(beginning, middle, end) () (0, 1, 2) (3, 4, 5, 6) (0,) (1, 2, 3) (4, 5, 6) (0, 1) (2, 3, 4) (5, 6) (0, 1, 2) (3, 4, 5) (6,) (0, 1, 2, 3) (4, 5, 6) () Note that *n* must be at least 0 and most equal to the length of *iterable*. This function will exhaust the iterable and may require significant storage. """ if n < 0: raise ValueError('n must be >= 0') seq = tuple(iterable) size = len(seq) if n > size: raise ValueError('n must be <= len(seq)') for i in range(size - n + 1): beginning = seq[:i] middle = seq[i : i + n] end = seq[i + n :] yield beginning, middle, end def all_unique(iterable, key=None): """ Returns ``True`` if all the elements of *iterable* are unique (no two elements are equal). >>> all_unique('ABCB') False If a *key* function is specified, it will be used to make comparisons. >>> all_unique('ABCb') True >>> all_unique('ABCb', str.lower) False The function returns as soon as the first non-unique element is encountered. Iterables with a mix of hashable and unhashable items can be used, but the function will be slower for unhashable items. """ seenset = set() seenset_add = seenset.add seenlist = [] seenlist_add = seenlist.append for element in map(key, iterable) if key else iterable: try: if element in seenset: return False seenset_add(element) except TypeError: if element in seenlist: return False seenlist_add(element) return True def nth_product(index, *args): """Equivalent to ``list(product(*args))[index]``. The products of *args* can be ordered lexicographically. :func:`nth_product` computes the product at sort position *index* without computing the previous products. >>> nth_product(8, range(2), range(2), range(2), range(2)) (1, 0, 0, 0) ``IndexError`` will be raised if the given *index* is invalid. """ pools = list(map(tuple, reversed(args))) ns = list(map(len, pools)) c = reduce(mul, ns) if index < 0: index += c if not 0 <= index < c: raise IndexError result = [] for pool, n in zip(pools, ns): result.append(pool[index % n]) index //= n return tuple(reversed(result)) def nth_permutation(iterable, r, index): """Equivalent to ``list(permutations(iterable, r))[index]``` The subsequences of *iterable* that are of length *r* where order is important can be ordered lexicographically. :func:`nth_permutation` computes the subsequence at sort position *index* directly, without computing the previous subsequences. >>> nth_permutation('ghijk', 2, 5) ('h', 'i') ``ValueError`` will be raised If *r* is negative or greater than the length of *iterable*. ``IndexError`` will be raised if the given *index* is invalid. """ pool = list(iterable) n = len(pool) if r is None or r == n: r, c = n, factorial(n) elif not 0 <= r < n: raise ValueError else: c = factorial(n) // factorial(n - r) if index < 0: index += c if not 0 <= index < c: raise IndexError if c == 0: return tuple() result = [0] * r q = index * factorial(n) // c if r < n else index for d in range(1, n + 1): q, i = divmod(q, d) if 0 <= n - d < r: result[n - d] = i if q == 0: break return tuple(map(pool.pop, result)) def value_chain(*args): """Yield all arguments passed to the function in the same order in which they were passed. If an argument itself is iterable then iterate over its values. >>> list(value_chain(1, 2, 3, [4, 5, 6])) [1, 2, 3, 4, 5, 6] Binary and text strings are not considered iterable and are emitted as-is: >>> list(value_chain('12', '34', ['56', '78'])) ['12', '34', '56', '78'] Multiple levels of nesting are not flattened. """ for value in args: if isinstance(value, (str, bytes)): yield value continue try: yield from value except TypeError: yield value def product_index(element, *args): """Equivalent to ``list(product(*args)).index(element)`` The products of *args* can be ordered lexicographically. :func:`product_index` computes the first index of *element* without computing the previous products. >>> product_index([8, 2], range(10), range(5)) 42 ``ValueError`` will be raised if the given *element* isn't in the product of *args*. """ index = 0 for x, pool in zip_longest(element, args, fillvalue=_marker): if x is _marker or pool is _marker: raise ValueError('element is not a product of args') pool = tuple(pool) index = index * len(pool) + pool.index(x) return index def combination_index(element, iterable): """Equivalent to ``list(combinations(iterable, r)).index(element)`` The subsequences of *iterable* that are of length *r* can be ordered lexicographically. :func:`combination_index` computes the index of the first *element*, without computing the previous combinations. >>> combination_index('adf', 'abcdefg') 10 ``ValueError`` will be raised if the given *element* isn't one of the combinations of *iterable*. """ element = enumerate(element) k, y = next(element, (None, None)) if k is None: return 0 indexes = [] pool = enumerate(iterable) for n, x in pool: if x == y: indexes.append(n) tmp, y = next(element, (None, None)) if tmp is None: break else: k = tmp else: raise ValueError('element is not a combination of iterable') n, _ = last(pool, default=(n, None)) # Python versiosn below 3.8 don't have math.comb index = 1 for i, j in enumerate(reversed(indexes), start=1): j = n - j if i <= j: index += factorial(j) // (factorial(i) * factorial(j - i)) return factorial(n + 1) // (factorial(k + 1) * factorial(n - k)) - index def permutation_index(element, iterable): """Equivalent to ``list(permutations(iterable, r)).index(element)``` The subsequences of *iterable* that are of length *r* where order is important can be ordered lexicographically. :func:`permutation_index` computes the index of the first *element* directly, without computing the previous permutations. >>> permutation_index([1, 3, 2], range(5)) 19 ``ValueError`` will be raised if the given *element* isn't one of the permutations of *iterable*. """ index = 0 pool = list(iterable) for i, x in zip(range(len(pool), -1, -1), element): r = pool.index(x) index = index * i + r del pool[r] return index class countable: """Wrap *iterable* and keep a count of how many items have been consumed. The ``items_seen`` attribute starts at ``0`` and increments as the iterable is consumed: >>> iterable = map(str, range(10)) >>> it = countable(iterable) >>> it.items_seen 0 >>> next(it), next(it) ('0', '1') >>> list(it) ['2', '3', '4', '5', '6', '7', '8', '9'] >>> it.items_seen 10 """ def __init__(self, iterable): self._it = iter(iterable) self.items_seen = 0 def __iter__(self): return self def __next__(self): item = next(self._it) self.items_seen += 1 return item PKH]ʀ??Epython3.10/site-packages/setuptools/_vendor/more_itertools/recipes.pynu["""Imported from the recipes section of the itertools documentation. All functions taken from the recipes section of the itertools library docs [1]_. Some backward-compatible usability improvements have been made. .. [1] http://docs.python.org/library/itertools.html#recipes """ import warnings from collections import deque from itertools import ( chain, combinations, count, cycle, groupby, islice, repeat, starmap, tee, zip_longest, ) import operator from random import randrange, sample, choice __all__ = [ 'all_equal', 'consume', 'convolve', 'dotproduct', 'first_true', 'flatten', 'grouper', 'iter_except', 'ncycles', 'nth', 'nth_combination', 'padnone', 'pad_none', 'pairwise', 'partition', 'powerset', 'prepend', 'quantify', 'random_combination_with_replacement', 'random_combination', 'random_permutation', 'random_product', 'repeatfunc', 'roundrobin', 'tabulate', 'tail', 'take', 'unique_everseen', 'unique_justseen', ] def take(n, iterable): """Return first *n* items of the iterable as a list. >>> take(3, range(10)) [0, 1, 2] If there are fewer than *n* items in the iterable, all of them are returned. >>> take(10, range(3)) [0, 1, 2] """ return list(islice(iterable, n)) def tabulate(function, start=0): """Return an iterator over the results of ``func(start)``, ``func(start + 1)``, ``func(start + 2)``... *func* should be a function that accepts one integer argument. If *start* is not specified it defaults to 0. It will be incremented each time the iterator is advanced. >>> square = lambda x: x ** 2 >>> iterator = tabulate(square, -3) >>> take(4, iterator) [9, 4, 1, 0] """ return map(function, count(start)) def tail(n, iterable): """Return an iterator over the last *n* items of *iterable*. >>> t = tail(3, 'ABCDEFG') >>> list(t) ['E', 'F', 'G'] """ return iter(deque(iterable, maxlen=n)) def consume(iterator, n=None): """Advance *iterable* by *n* steps. If *n* is ``None``, consume it entirely. Efficiently exhausts an iterator without returning values. Defaults to consuming the whole iterator, but an optional second argument may be provided to limit consumption. >>> i = (x for x in range(10)) >>> next(i) 0 >>> consume(i, 3) >>> next(i) 4 >>> consume(i) >>> next(i) Traceback (most recent call last): File "", line 1, in StopIteration If the iterator has fewer items remaining than the provided limit, the whole iterator will be consumed. >>> i = (x for x in range(3)) >>> consume(i, 5) >>> next(i) Traceback (most recent call last): File "", line 1, in StopIteration """ # Use functions that consume iterators at C speed. if n is None: # feed the entire iterator into a zero-length deque deque(iterator, maxlen=0) else: # advance to the empty slice starting at position n next(islice(iterator, n, n), None) def nth(iterable, n, default=None): """Returns the nth item or a default value. >>> l = range(10) >>> nth(l, 3) 3 >>> nth(l, 20, "zebra") 'zebra' """ return next(islice(iterable, n, None), default) def all_equal(iterable): """ Returns ``True`` if all the elements are equal to each other. >>> all_equal('aaaa') True >>> all_equal('aaab') False """ g = groupby(iterable) return next(g, True) and not next(g, False) def quantify(iterable, pred=bool): """Return the how many times the predicate is true. >>> quantify([True, False, True]) 2 """ return sum(map(pred, iterable)) def pad_none(iterable): """Returns the sequence of elements and then returns ``None`` indefinitely. >>> take(5, pad_none(range(3))) [0, 1, 2, None, None] Useful for emulating the behavior of the built-in :func:`map` function. See also :func:`padded`. """ return chain(iterable, repeat(None)) padnone = pad_none def ncycles(iterable, n): """Returns the sequence elements *n* times >>> list(ncycles(["a", "b"], 3)) ['a', 'b', 'a', 'b', 'a', 'b'] """ return chain.from_iterable(repeat(tuple(iterable), n)) def dotproduct(vec1, vec2): """Returns the dot product of the two iterables. >>> dotproduct([10, 10], [20, 20]) 400 """ return sum(map(operator.mul, vec1, vec2)) def flatten(listOfLists): """Return an iterator flattening one level of nesting in a list of lists. >>> list(flatten([[0, 1], [2, 3]])) [0, 1, 2, 3] See also :func:`collapse`, which can flatten multiple levels of nesting. """ return chain.from_iterable(listOfLists) def repeatfunc(func, times=None, *args): """Call *func* with *args* repeatedly, returning an iterable over the results. If *times* is specified, the iterable will terminate after that many repetitions: >>> from operator import add >>> times = 4 >>> args = 3, 5 >>> list(repeatfunc(add, times, *args)) [8, 8, 8, 8] If *times* is ``None`` the iterable will not terminate: >>> from random import randrange >>> times = None >>> args = 1, 11 >>> take(6, repeatfunc(randrange, times, *args)) # doctest:+SKIP [2, 4, 8, 1, 8, 4] """ if times is None: return starmap(func, repeat(args)) return starmap(func, repeat(args, times)) def _pairwise(iterable): """Returns an iterator of paired items, overlapping, from the original >>> take(4, pairwise(count())) [(0, 1), (1, 2), (2, 3), (3, 4)] On Python 3.10 and above, this is an alias for :func:`itertools.pairwise`. """ a, b = tee(iterable) next(b, None) yield from zip(a, b) try: from itertools import pairwise as itertools_pairwise except ImportError: pairwise = _pairwise else: def pairwise(iterable): yield from itertools_pairwise(iterable) pairwise.__doc__ = _pairwise.__doc__ def grouper(iterable, n, fillvalue=None): """Collect data into fixed-length chunks or blocks. >>> list(grouper('ABCDEFG', 3, 'x')) [('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')] """ if isinstance(iterable, int): warnings.warn( "grouper expects iterable as first parameter", DeprecationWarning ) n, iterable = iterable, n args = [iter(iterable)] * n return zip_longest(fillvalue=fillvalue, *args) def roundrobin(*iterables): """Yields an item from each iterable, alternating between them. >>> list(roundrobin('ABC', 'D', 'EF')) ['A', 'D', 'E', 'B', 'F', 'C'] This function produces the same output as :func:`interleave_longest`, but may perform better for some inputs (in particular when the number of iterables is small). """ # Recipe credited to George Sakkis pending = len(iterables) nexts = cycle(iter(it).__next__ for it in iterables) while pending: try: for next in nexts: yield next() except StopIteration: pending -= 1 nexts = cycle(islice(nexts, pending)) def partition(pred, iterable): """ Returns a 2-tuple of iterables derived from the input iterable. The first yields the items that have ``pred(item) == False``. The second yields the items that have ``pred(item) == True``. >>> is_odd = lambda x: x % 2 != 0 >>> iterable = range(10) >>> even_items, odd_items = partition(is_odd, iterable) >>> list(even_items), list(odd_items) ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9]) If *pred* is None, :func:`bool` is used. >>> iterable = [0, 1, False, True, '', ' '] >>> false_items, true_items = partition(None, iterable) >>> list(false_items), list(true_items) ([0, False, ''], [1, True, ' ']) """ if pred is None: pred = bool evaluations = ((pred(x), x) for x in iterable) t1, t2 = tee(evaluations) return ( (x for (cond, x) in t1 if not cond), (x for (cond, x) in t2 if cond), ) def powerset(iterable): """Yields all possible subsets of the iterable. >>> list(powerset([1, 2, 3])) [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] :func:`powerset` will operate on iterables that aren't :class:`set` instances, so repeated elements in the input will produce repeated elements in the output. Use :func:`unique_everseen` on the input to avoid generating duplicates: >>> seq = [1, 1, 0] >>> list(powerset(seq)) [(), (1,), (1,), (0,), (1, 1), (1, 0), (1, 0), (1, 1, 0)] >>> from more_itertools import unique_everseen >>> list(powerset(unique_everseen(seq))) [(), (1,), (0,), (1, 0)] """ s = list(iterable) return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1)) def unique_everseen(iterable, key=None): """ Yield unique elements, preserving order. >>> list(unique_everseen('AAAABBBCCDAABBB')) ['A', 'B', 'C', 'D'] >>> list(unique_everseen('ABBCcAD', str.lower)) ['A', 'B', 'C', 'D'] Sequences with a mix of hashable and unhashable items can be used. The function will be slower (i.e., `O(n^2)`) for unhashable items. Remember that ``list`` objects are unhashable - you can use the *key* parameter to transform the list to a tuple (which is hashable) to avoid a slowdown. >>> iterable = ([1, 2], [2, 3], [1, 2]) >>> list(unique_everseen(iterable)) # Slow [[1, 2], [2, 3]] >>> list(unique_everseen(iterable, key=tuple)) # Faster [[1, 2], [2, 3]] Similary, you may want to convert unhashable ``set`` objects with ``key=frozenset``. For ``dict`` objects, ``key=lambda x: frozenset(x.items())`` can be used. """ seenset = set() seenset_add = seenset.add seenlist = [] seenlist_add = seenlist.append use_key = key is not None for element in iterable: k = key(element) if use_key else element try: if k not in seenset: seenset_add(k) yield element except TypeError: if k not in seenlist: seenlist_add(k) yield element def unique_justseen(iterable, key=None): """Yields elements in order, ignoring serial duplicates >>> list(unique_justseen('AAAABBBCCDAABBB')) ['A', 'B', 'C', 'D', 'A', 'B'] >>> list(unique_justseen('ABBCcAD', str.lower)) ['A', 'B', 'C', 'A', 'D'] """ return map(next, map(operator.itemgetter(1), groupby(iterable, key))) def iter_except(func, exception, first=None): """Yields results from a function repeatedly until an exception is raised. Converts a call-until-exception interface to an iterator interface. Like ``iter(func, sentinel)``, but uses an exception instead of a sentinel to end the loop. >>> l = [0, 1, 2] >>> list(iter_except(l.pop, IndexError)) [2, 1, 0] """ try: if first is not None: yield first() while 1: yield func() except exception: pass def first_true(iterable, default=None, pred=None): """ Returns the first true value in the iterable. If no true value is found, returns *default* If *pred* is not None, returns the first item for which ``pred(item) == True`` . >>> first_true(range(10)) 1 >>> first_true(range(10), pred=lambda x: x > 5) 6 >>> first_true(range(10), default='missing', pred=lambda x: x > 9) 'missing' """ return next(filter(pred, iterable), default) def random_product(*args, repeat=1): """Draw an item at random from each of the input iterables. >>> random_product('abc', range(4), 'XYZ') # doctest:+SKIP ('c', 3, 'Z') If *repeat* is provided as a keyword argument, that many items will be drawn from each iterable. >>> random_product('abcd', range(4), repeat=2) # doctest:+SKIP ('a', 2, 'd', 3) This equivalent to taking a random selection from ``itertools.product(*args, **kwarg)``. """ pools = [tuple(pool) for pool in args] * repeat return tuple(choice(pool) for pool in pools) def random_permutation(iterable, r=None): """Return a random *r* length permutation of the elements in *iterable*. If *r* is not specified or is ``None``, then *r* defaults to the length of *iterable*. >>> random_permutation(range(5)) # doctest:+SKIP (3, 4, 0, 1, 2) This equivalent to taking a random selection from ``itertools.permutations(iterable, r)``. """ pool = tuple(iterable) r = len(pool) if r is None else r return tuple(sample(pool, r)) def random_combination(iterable, r): """Return a random *r* length subsequence of the elements in *iterable*. >>> random_combination(range(5), 3) # doctest:+SKIP (2, 3, 4) This equivalent to taking a random selection from ``itertools.combinations(iterable, r)``. """ pool = tuple(iterable) n = len(pool) indices = sorted(sample(range(n), r)) return tuple(pool[i] for i in indices) def random_combination_with_replacement(iterable, r): """Return a random *r* length subsequence of elements in *iterable*, allowing individual elements to be repeated. >>> random_combination_with_replacement(range(3), 5) # doctest:+SKIP (0, 0, 1, 2, 2) This equivalent to taking a random selection from ``itertools.combinations_with_replacement(iterable, r)``. """ pool = tuple(iterable) n = len(pool) indices = sorted(randrange(n) for i in range(r)) return tuple(pool[i] for i in indices) def nth_combination(iterable, r, index): """Equivalent to ``list(combinations(iterable, r))[index]``. The subsequences of *iterable* that are of length *r* can be ordered lexicographically. :func:`nth_combination` computes the subsequence at sort position *index* directly, without computing the previous subsequences. >>> nth_combination(range(5), 3, 5) (0, 3, 4) ``ValueError`` will be raised If *r* is negative or greater than the length of *iterable*. ``IndexError`` will be raised if the given *index* is invalid. """ pool = tuple(iterable) n = len(pool) if (r < 0) or (r > n): raise ValueError c = 1 k = min(r, n - r) for i in range(1, k + 1): c = c * (n - k + i) // i if index < 0: index += c if (index < 0) or (index >= c): raise IndexError result = [] while r: c, n, r = c * r // n, n - 1, r - 1 while index >= c: index -= c c, n = c * (n - r) // n, n - 1 result.append(pool[-1 - n]) return tuple(result) def prepend(value, iterator): """Yield *value*, followed by the elements in *iterator*. >>> value = '0' >>> iterator = ['1', '2', '3'] >>> list(prepend(value, iterator)) ['0', '1', '2', '3'] To prepend multiple values, see :func:`itertools.chain` or :func:`value_chain`. """ return chain([value], iterator) def convolve(signal, kernel): """Convolve the iterable *signal* with the iterable *kernel*. >>> signal = (1, 2, 3, 4, 5) >>> kernel = [3, 2, 1] >>> list(convolve(signal, kernel)) [3, 8, 14, 20, 26, 14, 5] Note: the input arguments are not interchangeable, as the *kernel* is immediately consumed and stored. """ kernel = tuple(kernel)[::-1] n = len(kernel) window = deque([0], maxlen=n) * n for x in chain(signal, repeat(0, n - 1)): window.append(x) yield sum(map(operator.mul, kernel, window)) PKH]!Q8RRFpython3.10/site-packages/setuptools/_vendor/more_itertools/__init__.pynu[from .more import * # noqa from .recipes import * # noqa __version__ = '8.8.0' PKH]m@33Ypython3.10/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-310.pycnu[o Xain< @sddlmZmZmZddlZddlZddlZddlmZm Z ddl m Z e rddl m Z mZmZmZmZmZmZddlmZmZeeefZeeeeeffZeeeefZeeeeeeeefeeeffdffZeeeedfeeeefZeeeedffZe eeefeeefgefZgd Z e!d gd Z"d d Z#Gddde$Z%Gddde&Z'Gddde'Z(e)dej*Z+ddddddZ,ddZ-ddZ.dZ/Gddde'Z0d d!Z1e)d"Z2d#d$Z3d%d&Z4dS)')absolute_importdivisionprint_functionN)InfinityNegativeInfinity) TYPE_CHECKING)CallableIteratorListOptional SupportsIntTupleUnion) InfinityTypeNegativeInfinityType.)parseVersion LegacyVersionInvalidVersionVERSION_PATTERN_Version)epochreleasedevprepostlocalcCs&zt|WStyt|YSw)z Parse the given version string and return either a :class:`Version` object or a :class:`LegacyVersion` object depending on if the given version is a valid PEP 440 version or a legacy version. )rrr)versionr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/packaging/version.pyr0s    rc@seZdZdZdS)rzF An invalid version was found, users should refer to PEP 440. N)__name__ __module__ __qualname____doc__rrrr r=src@sPeZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ dS) _BaseVersionNcCs t|jSN)hash_keyselfrrr __hash__Fs z_BaseVersion.__hash__cC||ddS)NcSs||kSr&rsorrr Lz%_BaseVersion.__lt__.._comparer*otherrrr __lt__Jz_BaseVersion.__lt__cCr,)NcSs||kSr&rr-rrr r0Pr1z%_BaseVersion.__le__..r2r4rrr __le__Nr7z_BaseVersion.__le__cCr,)NcSs||kSr&rr-rrr r0Tr1z%_BaseVersion.__eq__..r2r4rrr __eq__Rr7z_BaseVersion.__eq__cCr,)NcSs||kSr&rr-rrr r0Xr1z%_BaseVersion.__ge__..r2r4rrr __ge__Vr7z_BaseVersion.__ge__cCr,)NcSs||kSr&rr-rrr r0\r1z%_BaseVersion.__gt__..r2r4rrr __gt__Zr7z_BaseVersion.__gt__cCr,)NcSs||kSr&rr-rrr r0`r1z%_BaseVersion.__ne__..r2r4rrr __ne__^r7z_BaseVersion.__ne__cCst|tstS||j|jSr&) isinstancer%NotImplementedr()r*r5methodrrr r3bs z_BaseVersion._compare) r!r"r#r(r+r6r8r9r:r;r<r3rrrr r%Cs r%c@seZdZddZddZddZeddZed d Zed d Z ed dZ eddZ eddZ eddZ eddZeddZeddZeddZdS)rcCst||_t|j|_dSr&)str_version_legacy_cmpkeyr()r*rrrr __init__ks zLegacyVersion.__init__cC|jSr&rAr)rrr __str__pszLegacyVersion.__str__cCdtt|S)Nzformatreprr@r)rrr __repr__tzLegacyVersion.__repr__cCrDr&rEr)rrr publicxzLegacyVersion.publiccCrDr&rEr)rrr base_version}rNzLegacyVersion.base_versioncCdS)Nrr)rrr rzLegacyVersion.epochcCdSr&rr)rrr rrRzLegacyVersion.releasecCrSr&rr)rrr rrRzLegacyVersion.precCrSr&rr)rrr rrRzLegacyVersion.postcCrSr&rr)rrr rrRzLegacyVersion.devcCrSr&rr)rrr rrRzLegacyVersion.localcCrPNFrr)rrr is_prereleaserRzLegacyVersion.is_prereleasecCrPrTrr)rrr is_postreleaserRzLegacyVersion.is_postreleasecCrPrTrr)rrr is_devreleaserRzLegacyVersion.is_devreleaseN)r!r"r#rCrFrKpropertyrMrOrrrrrrrUrVrWrrrr rjs4          rz(\d+ | [a-z]+ | \.| -)czfinal-@)rpreview-rcrccs^t|D]#}t||}|r|dkrq|dddvr$|dVqd|VqdVdS)N.r 0123456789**final)_legacy_version_component_resplit_legacy_version_replacement_mapgetzfill)r.partrrr _parse_version_partss    ricCsd}g}t|D]8}|dr=|dkr)|r)|ddkr)||r)|ddks|r=|ddkr=||r=|ddks1||q |t|fS)NrQrarbz*final-00000000)rilower startswithpopappendtuple)rrpartsrhrrr rBs   rBa v? (?: (?:(?P[0-9]+)!)? # epoch (?P[0-9]+(?:\.[0-9]+)*) # release segment (?P
                                          # pre-release
            [-_\.]?
            (?P(a|b|c|rc|alpha|beta|pre|preview))
            [-_\.]?
            (?P[0-9]+)?
        )?
        (?P                                         # post release
            (?:-(?P[0-9]+))
            |
            (?:
                [-_\.]?
                (?Ppost|rev|r)
                [-_\.]?
                (?P[0-9]+)?
            )
        )?
        (?P                                          # dev release
            [-_\.]?
            (?Pdev)
            [-_\.]?
            (?P[0-9]+)?
        )?
    )
    (?:\+(?P[a-z0-9]+(?:[-_\.][a-z0-9]+)*))?       # local version
c@seZdZededejejBZddZ	ddZ
ddZed	d
Z
eddZed
dZeddZeddZeddZeddZeddZeddZeddZeddZedd Zed!d"Zed#d$Zd%S)&rz^\s*z\s*$c
Cs|j|}|std|t|drt|dndtdd|ddDt	|d|d	t	|d
|dpC|dt	|d
|dt
|dd|_t|jj
|jj|jj|jj|jj|jj|_dS)NzInvalid version: '{0}'rrcs|]}t|VqdSr&)int.0irrr 	z#Version.__init__..rr^pre_lpre_npost_lpost_n1post_n2dev_ldev_nr)rrrrrr)_regexsearchrrIrgrouprrrord_parse_letter_version_parse_local_versionrA_cmpkeyrrrrrrr()r*rmatchrrr rCs*
zVersion.__init__cCrG)NzrHr)rrr rK-rLzVersion.__repr__cCsg}|jdkr|d|j|ddd|jD|jdur1|ddd|jD|jdur?|d|j|jdurM|d	|j|jdur[|d
|jd|S)Nr{0}!r^csrqr&r@rtxrrr rv:rwz"Version.__str__..csrqr&rrrrr rv>rwz.post{0}z.dev{0}z+{0})	rrnrIjoinrrrrrr*rprrr rF1s





zVersion.__str__cC|jj}|Sr&)rAr)r*_epochrrr rNz
Version.epochcCrr&)rAr)r*_releaserrr rTrzVersion.releasecCrr&)rAr)r*_prerrr rZrzVersion.precC|jjr
|jjdSdSNr)rArr)rrr r`zVersion.postcCrr)rArr)rrr rerzVersion.devcCs$|jjrddd|jjDSdS)Nr^csrqr&rrrrr rvnrwz Version.local..)rArrr)rrr rjsz
Version.localcCst|dddS)N+rr)r@rdr)rrr rMrzVersion.publiccCsFg}|jdkr|d|j|ddd|jDd|S)Nrrr^csrqr&rrrrr rvrwz'Version.base_version..r)rrnrIrrrrrr rOws


zVersion.base_versioncCs|jdup	|jduSr&)rrr)rrr rUrzVersion.is_prereleasecC
|jduSr&)rr)rrr rV
zVersion.is_postreleasecCrr&)rr)rrr rWrzVersion.is_devreleasecCst|jdkr|jdSdS)Nrrlenrr)rrr majorz
Version.majorcCt|jdkr|jdSdS)Nrrrr)rrr minorrz
Version.minorcCr)Nrrrr)rrr microrz
Version.microN)r!r"r#recompilerVERBOSE
IGNORECASErrCrKrFrXrrrrrrrMrOrUrVrWrrrrrrr rsB












rcCsv|r-|durd}|}|dkrd}n|dkrd}n
|dvr!d}n|dvr'd	}|t|fS|s9|r9d	}|t|fSdS)
Nralphaabetab)rYrr[r])revrr)rkrr)letternumberrrr rs"rz[\._-]cCs$|durtddt|DSdS)zR
    Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
    Ncss(|]}|s|nt|VqdSr&)isdigitrkrr)rtrhrrr rvs

z'_parse_local_version..)ro_local_version_separatorsrd)rrrr rs
rcCsttttddt|}|dur|dur|durt}n	|dur&t}n|}|dur/t}n|}|dur8t}	n|}	|durAt}
n	tdd|D}
|||||	|
fS)NcSs|dkS)Nrr)rrrr r0r1z_cmpkey..css*|]}t|tr
|dfnt|fVqdS)rN)r=rrrrsrrr rvs
z_cmpkey..)roreversedlist	itertools	dropwhilerr)rrrrrrrr_post_dev_localrrr rs(	r)5
__future__rrrcollectionsrr_structuresrrZ_typingrtypingr	r
rrr
rrrr
InfiniteTypesr@rrPrePostDevTypeSubLocalType	LocalTypeCmpKeyLegacyCmpKeyboolVersionComparisonMethod__all__
namedtuplerr
ValueErrorrobjectr%rrrrcrerirBrrrrrrrrrr sr$


'F	 
&
PKH],)

]python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-310.pycnu[o

Xai@sDddlmZmZmZGdddeZeZGdddeZeZdS))absolute_importdivisionprint_functionc@TeZdZddZddZddZddZd	d
ZddZd
dZ	ddZ
ddZdS)InfinityTypecCdS)NInfinityselfr	r	/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/packaging/_structures.py__repr__zInfinityType.__repr__cCtt|SNhashreprr
r	r	r__hash__zInfinityType.__hash__cCrNFr	rotherr	r	r__lt__rzInfinityType.__lt__cCrrr	rr	r	r__le__rzInfinityType.__le__cCt||jSr
isinstance	__class__rr	r	r__eq__rzInfinityType.__eq__cCt||jSrrrr	r	r__ne__zInfinityType.__ne__cCrNTr	rr	r	r__gt__ rzInfinityType.__gt__cCrr#r	rr	r	r__ge__$rzInfinityType.__ge__cCtSr)NegativeInfinityr
r	r	r__neg__(rzInfinityType.__neg__N__name__
__module____qualname__r
rrrrr!r$r%r(r	r	r	rrrc@r)NegativeInfinityTypecCr)Nz	-Infinityr	r
r	r	rr
1rzNegativeInfinityType.__repr__cCrrrr
r	r	rr5rzNegativeInfinityType.__hash__cCrr#r	rr	r	rr9rzNegativeInfinityType.__lt__cCrr#r	rr	r	rr=rzNegativeInfinityType.__le__cCrrrrr	r	rrArzNegativeInfinityType.__eq__cCr rrrr	r	rr!Er"zNegativeInfinityType.__ne__cCrrr	rr	r	rr$IrzNegativeInfinityType.__gt__cCrrr	rr	r	rr%MrzNegativeInfinityType.__ge__cCr&r)rr
r	r	rr(QrzNegativeInfinityType.__neg__Nr)r	r	r	rr.0r-r.N)	
__future__rrrobjectrrr.r'r	r	r	rs
&
&PKH]D$$Ypython3.10/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-310.pycnu[o

Xai%%	@sddlmZmZmZddlZddlZddlZddlZddlm	Z	m
Z
mZmZddlm
Z
mZmZmZddlmZddlmZddlmZdd	lmZmZerhdd
lmZmZmZmZmZm Z m!Z!ee"e"ge#fZ$gdZ%Gdd
d
e&Z'Gddde&Z(Gddde&Z)Gddde*Z+Gddde+Z,Gddde+Z-Gddde+Z.ededBedBedBedBedBed Bed!Bed"Bed#Bed$Bed%Bed&Bed'Bed(Bed)Bed*Bed+BZ/d$d#dd ddd,Z0e/1d-d.ed/ed0Bed1Bed2Bed3Bed4Bed5Bed6BZ2e2ed7Bed8BZ3e31d9d.ed:ed;BZ4e41dBZ5e/e4BZ6ee6e3e6Z7e71d?d.ed@8Z9edA8Z:eZ;e7ee9e;e:BZee;eZ=dBdCZ>dXdEdFZ?dGd.dHd.ej@ejAejBejCejDejEdIZFdJdKZGGdLdMdMe*ZHeHZIdNdOZJdPdQZKdRdSZLdTdUZMGdVdWdWe*ZNdS)Y)absolute_importdivisionprint_functionN)ParseExceptionParseResultsstringStart	stringEnd)
ZeroOrMoreGroupForwardQuotedString)Literal)string_types)
TYPE_CHECKING)	SpecifierInvalidSpecifier)AnyCallableDictListOptionalTupleUnion)
InvalidMarkerUndefinedComparisonUndefinedEnvironmentNameMarkerdefault_environmentc@eZdZdZdS)rzE
    An invalid marker was found, users should refer to PEP 508.
    N__name__
__module____qualname____doc__r%r%/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/packaging/markers.pyr"rc@r)rzP
    An invalid operation was attempted on a value that doesn't support it.
    Nr r%r%r%r&r(r'rc@r)rz\
    A name was attempted to be used that does not exist inside of the
    environment.
    Nr r%r%r%r&r.r'rc@s,eZdZddZddZddZddZd	S)
NodecCs
||_dSN)value)selfr*r%r%r&__init__6
z
Node.__init__cC
t|jSr))strr*r+r%r%r&__str__:r-zNode.__str__cCsd|jjt|S)Nz<{0}({1!r})>)format	__class__r!r/r0r%r%r&__repr__>sz
Node.__repr__cCstr))NotImplementedErrorr0r%r%r&	serializeBszNode.serializeN)r!r"r#r,r1r4r6r%r%r%r&r(5s
r(c@eZdZddZdS)VariablecCt|Sr)r/r0r%r%r&r6HzVariable.serializeNr!r"r#r6r%r%r%r&r8Gr8c@r7)ValuecCs
d|S)Nz"{0}")r2r0r%r%r&r6Nr-zValue.serializeNr<r%r%r%r&r>Mr=r>c@r7)OpcCr9r)r:r0r%r%r&r6Tr;zOp.serializeNr<r%r%r%r&r?Sr=r?implementation_versionplatform_python_implementationimplementation_namepython_full_versionplatform_releaseplatform_versionplatform_machineplatform_systempython_versionsys_platformos_nameos.namesys.platformplatform.versionplatform.machineplatform.python_implementationpython_implementationextra)rKrLrMrNrOrPcCstt|d|dSNr)r8ALIASESgetsltr%r%r&usrYz=====>=<=!=z~=><not inincCt|dSrR)r?rUr%r%r&rY|'"cCrbrR)r>rUr%r%r&rYrcandorcCrbrR)tuplerUr%r%r&rYrc()cCst|trdd|DS|S)NcSsg|]}t|qSr%)_coerce_parse_result).0ir%r%r&
z(_coerce_parse_result..)
isinstancer)resultsr%r%r&rks
rkTcCst|tttfs
Jt|tr$t|dkr$t|dttfr$t|dSt|tr@dd|D}|r7d|Sdd|dSt|trOddd	|DS|S)
Nrrcss|]	}t|ddVqdS)F)firstN)_format_markerrlmr%r%r&	sz!_format_marker.. rirjcSsg|]}|qSr%)r6rtr%r%r&rnroz"_format_marker..)rplistrhrlenrsjoin)markerrrinnerr%r%r&rss


rscCs||vSr)r%lhsrhsr%r%r&rYcCs||vSr)r%r}r%r%r&rYr)rar`r_r\rZr]r[r^cCsjz
td||g}Wn	tyYnw||St|}|dur0td||||||S)Nz#Undefined {0!r} on {1!r} and {2!r}.)	rrzr6rcontains
_operatorsrTrr2)r~oprspecoperr%r%r&_eval_ops

rc@seZdZdS)	UndefinedN)r!r"r#r%r%r%r&rsrcCs(||t}t|trtd||S)Nz/{0!r} does not exist in evaluation environment.)rT
_undefinedrprrr2)environmentnamer*r%r%r&_get_envs
rc	Csgg}|D]Y}t|tttfsJt|tr!|dt||qt|trO|\}}}t|tr:t||j}|j}n	|j}t||j}|dt	|||q|dvsUJ|dkr^|gqt
dd|DS)N)rfrgrgcss|]}t|VqdSr))all)rlitemr%r%r&rvsz$_evaluate_markers..)rprxrhrappend_evaluate_markersr8rr*rany)	markersrgroupsr{r~rr	lhs_value	rhs_valuer%r%r&rs$




rcCs2d|}|j}|dkr||dt|j7}|S)Nz{0.major}.{0.minor}.{0.micro}finalr)r2releaselevelr/serial)infoversionkindr%r%r&format_full_versions

rcCsrttdrttjj}tjj}nd}d}||tjtt	t
tttd
tddtjdS)Nimplementation0r.)rBr@rJrFrDrGrErCrArHrI)hasattrsysrrrrosplatformmachinereleasesystemrHrPrzpython_version_tuple)iverrBr%r%r&rs"

rc@s.eZdZddZddZddZd
dd	ZdS)rc
CsTztt||_WdSty)}zd|||j|jd}t|d}~ww)Nz+Invalid marker: {0!r}, parse error at {1!r})rkMARKERparseString_markersrr2locr)r+r{eZerr_strr%r%r&r,(szMarker.__init__cCr.r))rsrr0r%r%r&r12r-zMarker.__str__cCsdt|S)Nz)r2r/r0r%r%r&r46szMarker.__repr__NcCs$t}|dur||t|j|S)a$Evaluate a marker.

        Return the boolean from evaluating the given marker against the
        environment. environment is an optional argument to override all or
        part of the determined environment.

        The environment is determined from the current Python process.
        N)rupdaterr)r+rcurrent_environmentr%r%r&evaluate:s

zMarker.evaluater))r!r"r#r,r1r4rr%r%r%r&r's

r)T)O
__future__rrroperatorrrrZsetuptools.extern.pyparsingrrrrr	r
rrr
LZ_compatrZ_typingr
specifiersrrtypingrrrrrrrr/boolOperator__all__
ValueErrorrrrobjectr(r8r>r?VARIABLErSsetParseActionVERSION_CMP	MARKER_OPMARKER_VALUEBOOLOP
MARKER_VARMARKER_ITEMsuppressLPARENRPARENMARKER_EXPRMARKER_ATOMrrkrsltleeqnegegtrrrrrrrrrr%r%r%r&s$		

>
	PKH]wjYpython3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_typing.cpython-310.pycnu[o

Xai@s2dZddgZ	dZerddlmZdSddZdS)	a;For neatly implementing static typing in packaging.

`mypy` - the static type analysis tool we use - uses the `typing` module, which
provides core functionality fundamental to mypy's functioning.

Generally, `typing` would be imported at runtime and used in that fashion -
it acts as a no-op at runtime and does not have any run-time overhead by
design.

As it turns out, `typing` is not vendorable - it uses separate sources for
Python 2/Python 3. Thus, this codebase can not expect it to be present.
To work around this, mypy allows the typing import to be behind a False-y
optional to prevent it from running at runtime and type-comments can be used
to remove the need for the types to be accessible directly during runtime.

This module provides the False-y guard in a nicely named fashion so that a
curious maintainer can reach here to read this.

In packaging, all static-typing related imports should be guarded as follows:

    from packaging._typing import TYPE_CHECKING

    if TYPE_CHECKING:
        from typing import ...

Ref: https://github.com/python/mypy/issues/3216

TYPE_CHECKINGcastF)r)rcCs|S)N)type_valuerr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/packaging/_typing.pyr/sN)__doc____all__typingrrrrrrsPKH]{u_[python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-310.pycnu[o

Xai@sDddlmZmZmZgdZdZdZdZdZdZ	dZ
d	Zd
e	ZdS))absolute_importdivisionprint_function)	__title____summary____uri____version__
__author__	__email____license__
__copyright__	packagingz"Core utilities for Python packagesz!https://github.com/pypa/packagingz20.4z)Donald Stufft and individual contributorszdonald@stufft.iozBSD-2-Clause or Apache-2.0zCopyright 2014-2019 %sN)
__future__rrr__all__rrrrr	r
rrrr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/packaging/__about__.pysPKH]][[Zpython3.10/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-310.pycnu[o

Xai2@sHddlmZmZmZddlmZmZmZmZm	Z	m
Z
mZmZgdZ
dS))absolute_importdivisionprint_function)
__author__
__copyright__	__email____license____summary__	__title____uri____version__)rr
rr
rrr	rN)
__future__rrr	__about__rrrr	r
rrr
__all__rr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/packaging/__init__.pys(PKH].ѱ22^python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-310.pycnu[o

Xai5@sddlmZmZmZddlZddlZddlmZmZm	Z	m
Z
ddlmZmZm
Z
mZmZddlmZddlmZddlmZdd	lmZmZdd
lmZmZmZerXddlmZGdd
d
e Z!eej"ej#Z$ed%Z&ed%Z'ed%Z(ed%Z)ed%Z*ed%Z+ed%Z,edZ-e$ee-e$BZ.ee$ee.Z/e/dZ0e/Z1eddZ2e,e2Z3e1ee*e1Z4e&e
e4e'dZ5eej6ej7ej8BZ9eej6ej7ej8BZ:e9e:AZ;ee;ee*e;ddddZdde	e=dZ?e?>d de	ed!Ze>d"de+Z@e@eZAe?e
eAZBe3e
eAZCe0e
e5eCeBBZDeeDeZEeEFd#Gd$d%d%eGZHdS)&)absolute_importdivisionprint_functionN)stringStart	stringEndoriginalTextForParseException)
ZeroOrMoreWordOptionalRegexCombine)Literal)parse)
TYPE_CHECKING)MARKER_EXPRMarker)LegacySpecifier	SpecifierSpecifierSet)Listc@seZdZdZdS)InvalidRequirementzJ
    An invalid requirement was found, users should refer to PEP 508.
    N)__name__
__module____qualname____doc__rr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/packaging/requirements.pyrsr[](),;@z-_.namez[^ ]+urlextrasF)
joinStringadjacent	_raw_speccCs
|jpdS)N)r+sltrrr;s
r1	specifiercCs|dS)Nrrr-rrrr1>smarkercCst||j|jS)N)r_original_start
_original_endr-rrrr1Bszx[]c@s(eZdZdZddZddZddZdS)	RequirementzParse a requirement.

    Parse a given requirement string into its parts, such as name, specifier,
    URL, and extras. Raises InvalidRequirement on a badly-formed requirement
    string.
    c
Cszt|}Wnty$}ztd||j|jd|jd}~ww|j|_|jr]t		|j}|j
dkrDt	||jkrCtdn|j
rP|jrP|j
sX|jsXtd|j|j|_nd|_t
|jri|jng|_t|j|_|jr||j|_dSd|_dS)NzParse error at "{0!r}": {1}filezInvalid URL givenzInvalid URL: {0})REQUIREMENTparseStringrrformatlocmsgr&r'urlparsescheme
urlunparsenetlocsetr(asListrr2r3)selfrequirement_stringreqe
parsed_urlrrr__init___s8

zRequirement.__init__cCs|jg}|jr|ddt|j|jr |t|j|jr4|d|j|j	r4|d|j	r@|d|j	d|S)Nz[{0}]r#z@ {0} z; {0}r,)
r&r(appendr;joinsortedr2strr'r3)rDpartsrrr__str__{s

zRequirement.__str__cCsdt|S)Nz)r;rN)rDrrr__repr__szRequirement.__repr__N)rrrrrIrPrQrrrrr6Rs
r6)I
__future__rrrstringreZsetuptools.extern.pyparsingrrrrr	r
rrr
rLurllibrr>Z_typingrmarkersrr
specifiersrrrtypingr
ValueErrorr
ascii_lettersdigitsALPHANUMsuppressLBRACKETRBRACKETLPARENRPARENCOMMA	SEMICOLONATPUNCTUATIONIDENTIFIER_END
IDENTIFIERNAMEEXTRAURIURLEXTRAS_LISTEXTRAS
_regex_strVERBOSE
IGNORECASEVERSION_PEP440VERSION_LEGACYVERSION_ONEVERSION_MANY
_VERSION_SPECsetParseActionVERSION_SPECMARKER_SEPARATORMARKERVERSION_AND_MARKERURL_AND_MARKERNAMED_REQUIREMENTr9r:objectr6rrrrsl
PKH]}SWpython3.10/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-310.pycnu[o

Xai@sxddlmZmZmZddlZddlmZmZddlm	Z	m
Z
er-ddlmZm
Z
edeZedZd	d
ZddZdS)
)absolute_importdivisionprint_functionN)
TYPE_CHECKINGcast)InvalidVersionVersion)NewTypeUnionNormalizedNamez[-_.]+cCstd|}td|S)N-r)_canonicalize_regexsublowerr)namevaluer/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/packaging/utils.pycanonicalize_names
rc
Cszt|}Wnty|YSwg}|jdkr"|d|j|tddddd|jD|j	durH|dd	d|j	D|j
durV|d
|j
|jdurd|d|j|jdurr|d|jd|S)
z
    This is very similar to Version.__str__, but has one subtle difference
    with the way it handles the release segment.
    rz{0}!z(\.0)+$.cs|]}t|VqdSNstr.0xrrr	/z'canonicalize_version..Ncsrrrrrrrr3r z.post{0}z.dev{0}z+{0})
r	repochappendformatrerjoinreleaseprepostdevlocal)_versionversionpartsrrrcanonicalize_versions$
&




r.)
__future__rrrr$Z_typingrrr,rr	typingr
rrrcompilerrr.rrrrs

PKH]CCVpython3.10/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-310.pycnu[o

Xai^@s^ddlmZddlZzddlmZWney)ddlZddeDZ[Ynwddl	Z	ddl
Z
ddlZddlZddl
Z
ddlZddlZddlZddlmZmZer|ddlmZmZmZmZmZmZmZmZmZmZeeZ eeefZ!eeefZ"e	#e$Z%d	d
ddd
dZ&ej'dkZ(Gddde)Z*ddZ+ddZ,dSddZ-ddZ.ddZ/dSddZ0			dTdd Z1d!d"Z2			dTd#d$Z3d%d&Z4			dTd'd(Z5e(fd)d*Z6d+d,Z7dUd-d.Z8d/d0Z9d1d2Z:d3d4Z;d5d6ZGd;d<dZ@d?d@ZAdAdBZBdCdDZCe(fdEdFZDdGdHZEdIdJZFdKdLZGdMdNZHdOdPZIdQdRZJdS)V)absolute_importN)EXTENSION_SUFFIXEScCsg|]}|dqS)r).0xrr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/packaging/tags.py
sr)
TYPE_CHECKINGcast)
Dict	FrozenSetIOIterableIteratorListOptionalSequenceTupleUnionpycpppipjy)pythoncpythonpypy
ironpythonjythonlc@sdeZdZdZgdZddZeddZeddZed	d
Z	ddZ
d
dZddZddZ
dS)Tagz
    A representation of the tag triple for a wheel.

    Instances are considered immutable and thus are hashable. Equality checking
    is also supported.
    )_interpreter_abi	_platformcCs"||_||_||_dSN)lowerr!r"r#)selfinterpreterabiplatformrrr__init__Fs

zTag.__init__cC|jSr$)r!r&rrrr'LzTag.interpretercCr+r$)r"r,rrrr(Qr-zTag.abicCr+r$)r#r,rrrr)Vr-zTag.platformcCs2t|tstS|j|jko|j|jko|j|jkSr$)
isinstancer NotImplementedr)r(r')r&otherrrr__eq__[s


z
Tag.__eq__cCst|j|j|jfSr$)hashr!r"r#r,rrr__hash__fzTag.__hash__cCsd|j|j|jS)Nz{}-{}-{})formatr!r"r#r,rrr__str__jr4zTag.__str__cCsdj|t|dS)Nz<{self} @ {self_id}>)r&self_id)r5idr,rrr__repr__nszTag.__repr__N)__name__
__module____qualname____doc__	__slots__r*propertyr'r(r)r1r3r6r9rrrrr <s


r c	Cs`t}|d\}}}|dD]}|dD]}|dD]}|t|||qqqt|S)z
    Parses the provided tag (e.g. `py3-none-any`) into a frozenset of Tag instances.

    Returning a set is required due to the possibility that the tag is a
    compressed tag set.
    -.)setsplitaddr 	frozenset)tagtagsinterpretersabis	platformsr'r(	platform_rrr	parse_tagssrLcCsP|sdSt|dksd|vr$|ddtt|}td|||dS)z[
    Backwards-compatibility with Python 2.7 to allow treating 'warn' as keyword-only.
    Fr	warnNz,{}() got an unexpected keyword argument {!r})lenpopnextiterkeys	TypeErrorr5)	func_namekwargsargrrr_warn_keyword_parameters
rWFcCs&t|}|dur|rtd||S)Nz>Config variable '%s' is unset, Python ABI tag may be incorrect)	sysconfigget_config_varloggerdebug)namerMvaluerrr_get_config_vars
r^cCs|ddddS)NrA_r@)replace)stringrrr_normalize_stringr4rbcCst|dkot|dkS)zj
    Determine if the Python version supports abi3.

    PEP 384 was first implemented in Python 3.2.
    r	))rNtuple)python_versionrrr
_abi3_appliessrgc	Cst|}g}t|dd}d}}}td|}ttd}dtv}	|s,|dur.|s,|	r.d}|dkrXtd|}
|
s=|
dur?d	}|d
krWtd|}|dksU|durWtjd
krWd}n|rc|dj|d|	ddj||||d|S)NrdPy_DEBUGgettotalrefcountz_d.pydd)rc
WITH_PYMALLOCm)rcrcPy_UNICODE_SIZEiucp{version}versionrz"cp{version}{debug}{pymalloc}{ucs4})rtr[pymallocucs4)
re_version_nodotr^hasattrsysr
maxunicodeappendr5insert)
py_versionrMrIrtr[rurv
with_debughas_refcounthas_ext
with_pymallocunicode_sizerrr
_cpython_abiss8



rc
	+sXtd|}|stjdd}dt|dd|dur,t|dkr*t||}ng}t|}dD]}z||Wq2t	yDYq2wt|pJt
}|D]}|D]	}t||VqRqNt|rpfdd|DD]}|Vqjfd	d|DD]}|Vqyt|rt
|dddd
D]}	|D]}djt|d|	fd
td|VqqdSdS)a
    Yields the tags for a CPython interpreter.

    The tags consist of:
    - cp--
    - cp-abi3-
    - cp-none-
    - cp-abi3-  # Older Python versions down to 3.2.

    If python_version only specifies a major version then user-provided ABIs and
    the 'none' ABItag will be used.

    If 'abi3' or 'none' are specified in 'abis' then they will be yielded at
    their normal position and not at the beginning.
    cpython_tagsNrdzcp{}r	)abi3nonec3|]	}td|VqdS)rNr rrKr'rr	zcpython_tags..c3r)rNrrrrrrrrrrrsr)rWryversion_infor5rwrNrlistremove
ValueError_platform_tagsr rgrange)
rfrIrJrUrMexplicit_abir(rKrF
minor_versionrrrrsH
rccs"td}|rt|VdSdS)NSOABI)rXrYrb)r(rrr_generic_abis

rc	kstd|}|st}t|d}d||g}|durt}t|p#t}t|}d|vr2|d|D]}|D]	}t|||Vq8q4dS)z
    Yields the tags for a generic interpreter.

    The tags consist of:
    - --

    The "none" ABI will be added if it was not explicitly provided.
    generic_tagsrMrhNr)	rWinterpreter_nameinterpreter_versionjoinrrrr{r )	r'rIrJrUrMinterp_nameinterp_versionr(rKrrrrs"


rccst|dkrdjt|dddVdj|ddVt|dkr=t|ddd	d	D]}djt|d|fdVq-dSdS)
z
    Yields Python versions in descending order.

    After the latest version, the major-only version will be yielded, and then
    all previous versions of that major version.
    r	zpy{version}Nrdrsz	py{major}r)majorr)rNr5rwr)r}minorrrr_py_interpreter_range4srccsz|s
tjdd}t|pt}t|D]}|D]	}t|d|Vqq|r-t|ddVt|D]	}t|ddVq1dS)z
    Yields the sequence of tags that are compatible with a specific version of Python.

    The tags consist of:
    - py*-none-
    - -none-any  # ... if `interpreter` is provided.
    - py*-none-any
    Nrdrany)ryrrrrr )rfr'rJrtrKrrrcompatible_tagsDsrcCs|s|S|drdSdS)Nppci386)
startswith)archis_32bitrrr	_mac_arch^s

rcCs|g}|dkr|dkr
gS|gdn7|dkr'|dkrgS|gdn%|dkr;|dks3|dkr5gS|dn|d	krL|d
krEgS|ddg|d
|S)Nx86_64)
rp)intelfat64fat32r)rrfatppc64)rrr)rrr	universal)extendr{)rtcpu_archformatsrrr_mac_binary_formatsis&
rc	cst\}}}|durtdttt|ddd}n|}|dur)t|}n|}t|dddD]}|d|f}t	||}|D]}dj
|d|d|d	VqBq3dS)
aD
    Yields the platform tags for a macOS system.

    The `version` parameter is a two-item tuple specifying the macOS version to
    generate platform tags for. The `arch` parameter is the CPU architecture to
    generate platform tags for. Both parameters default to the appropriate value
    for the current system.
    N
MacVersionrArdr	rrz&macosx_{major}_{minor}_{binary_format})rr
binary_format)r)mac_verrremapintrCrrrr5)	rtrversion_strr_rrcompat_versionbinary_formatsrrrr
mac_platformss&
$


rc	Cs:zddl}tt||dWSttfyYt|Sw)NrZ_compatible)
_manylinuxboolgetattrImportErrorAttributeError_have_compatible_glibc)r\
glibc_versionrrrr_is_manylinux_compatiblesrcCstptSr$)_glibc_version_string_confstr_glibc_version_string_ctypesrrrr_glibc_version_stringsrcCsFztd}|dusJ|\}}W|Sttttfy"YdSw)zJ
    Primary implementation of glibc_version_string using os.confstr.
    CS_GNU_LIBC_VERSIONN)osconfstrrCAssertionErrorrOSErrorr)version_stringr_rtrrrrs	rcCsrzddl}Wn
tyYdSw|d}z|j}Wn
ty%YdSw|j|_|}t|ts7|	d}|S)zG
    Fallback implementation of glibc_version_string using ctypes.
    rNascii)
ctypesrCDLLgnu_get_libc_versionrc_char_prestyper.strdecode)rprocess_namespacerrrrrrs 
	


rcCsHtd|}|std|tdSt|d|ko#t|d|kS)Nz$(?P[0-9]+)\.(?P[0-9]+)z=Expected glibc version with 2 components major.minor, got: %sFrr)rematchwarningsrMRuntimeWarningrgroup)rrequired_major
minimum_minorrnrrr_check_glibc_versionsrcCst}|dur	dSt|||SNF)rr)rrrrrrrsrc@sTeZdZGdddeZdZdZdZdZdZ	dZ
dZdZd	Z
d
ZdZdZd
dZdS)_ELFFileHeaderc@seZdZdZdS)z$_ELFFileHeader._InvalidELFFileHeaderz7
        An invalid ELF file header was found.
        N)r:r;r<r=rrrr_InvalidELFFileHeadersriFLEr	rdrc(>l~iicsrfdd}|d|_|j|jkrt|d|_|j|j|jhvr't|d|_|j|j|j	hvr9t|d|_
|d|_|d|_
d|_|j|jkrVdnd}|j|jkr`dnd}|j|jkrjd	nd
}|j|jkrt|n|}|||_|||_|||_|||_|||_|||_|||_|||_|||_|||_|||_|||_|||_dS)Ncs:zt|t|\}W|Stjytwr$)structunpackreadcalcsizeerrorrr)fmtresultfilerrr)sz'_ELFFileHeader.__init__..unpackz>IBzHzQ)
e_ident_magicELF_MAGIC_NUMBERrr
e_ident_class
ELFCLASS32
ELFCLASS64e_ident_dataELFDATA2LSBELFDATA2MSBe_ident_version
e_ident_osabie_ident_abiversionre_ident_pade_type	e_machine	e_versione_entrye_phoffe_shoffe_flagse_ehsizee_phentsizee_phnume_shentsizee_shnum
e_shstrndx)r&rrformat_hformat_iformat_qformat_prrrr*'s>


















z_ELFFileHeader.__init__N)r:r;r<rrrrrrrEM_386EM_S390EM_ARM	EM_X86_64EF_ARM_ABIMASKEF_ARM_ABI_VER5EF_ARM_ABI_FLOAT_HARDr*rrrrrsrcCs^zttjd}t|}WdW|S1swYW|Sttttjfy.YdSw)Nrb)openry
executablerIOErrorrrSr)f
elf_headerrrr_get_elf_headerSs
rcCsnt}|dur	dS|j|jk}||j|jkM}||j|jkM}||j|j@|j	kM}||j|j
@|j
kM}|Sr)rrrrrrrrrrrrrrrr_is_linux_armhf]s

r cCsBt}|dur	dS|j|jk}||j|jkM}||j|jkM}|Sr)rrrrrrrrrrr_is_linux_i686qsr!cCs |dkrtS|dkrtSdS)Narmv7li686T)r r!)rrrr_have_compatible_manylinux_abi|s
r$ccsttj}|r|dkrd}n|dkrd}g}|dd\}}t|r<|dvr.|d|d	vr<|d
|dt|}|D]\}}t||rT|	d|VnqB|D]\}}|	d|VqW|VdS)
Nlinux_x86_64
linux_i686
linux_aarch64linux_armv7lr_r	>rs390xrppc64leaarch64r"r#)
manylinux2014)rd>rr#)
manylinux2010)rd)
manylinux1)rdrlinux)
rb	distutilsutilget_platformrCr$r{rQrr`)rr1Zmanylinux_supportr_rZmanylinux_support_iterr\rrrr_linux_platformss<

r5ccsttjVdSr$)rbr2r3r4rrrr_generic_platformssr6cCs*tdkr	tStdkrtStS)z;
    Provides the platform tags for this installation.
    DarwinLinux)r)systemrr5r6rrrrrs
rcCs:ztjj}Wntyt}Ynwt|p|S)z6
    Returns the name of the running interpreter.
    )	ryimplementationr\rr)python_implementationr%INTERPRETER_SHORT_NAMESget)r\rrrrsrcKs<td|}td|d}|rt|}|Sttjdd}|S)z9
    Returns the version of the running interpreter.
    rpy_version_nodotrNrd)rWr^rrwryr)rUrMrtrrrrs
rcCs,tdd|Drd}nd}|tt|S)Ncss|]}|dkVqdS)rNr)rvrrrrsz!_version_nodot..r_rh)rrrr)rtseprrrrwsrwcksZtd|}t}|dkrt|dD]}|Vqn	tD]}|VqtD]}|Vq%dS)z
    Returns the sequence of tag triples for the running interpreter.

    The order of the sequence corresponds to priority order for the
    interpreter, from most to least important.
    sys_tagsrrN)rWrrrr)rUrMrrFrrrrAs


rA)F)NNN)NN)K
__future__rdistutils.utilr2importlib.machineryrrimpZget_suffixesloggingrr)rrryrXrZ_typingr
rtypingrr
rrrrrrrrr
PythonVersionrZGlibcVersion	getLoggerr:rZr<maxsize_32_BIT_INTERPRETERobjectr rLrWr^rbrgrrrrrrrrrrrrrrrrrr r!r$r5r6rrrrwrArrrrs0


	7



&
<


#@
	!

	PKH]؅Ypython3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-310.pycnu[o

Xaih@s~ddlmZmZmZddlZddlmZer"ddlmZm	Z	m
Z
mZejddkZ
ejddkZer6efZnefZdd	ZdS)
)absolute_importdivisionprint_functionN)
TYPE_CHECKING)AnyDictTupleTypecs&Gfddd}t|ddiS)z/
    Create a base class with a metaclass.
    cseZdZfddZdS)z!with_metaclass..metaclasscs||S)N)clsname
this_basesdbasesmetar
/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/packaging/_compat.py__new__"sz)with_metaclass..metaclass.__new__N)__name__
__module____qualname__rr
rr
r	metaclass!srtemporary_classr
)typer)rrrr
rrwith_metaclasssr)
__future__rrrsysZ_typingrtypingrrr	r
version_infoPY2PY3strstring_types
basestringrr
r
r
rsPKH]V8#PP\python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-310.pycnu[o

Xai|@sXddlmZmZmZddlZddlZddlZddlZddlm	Z	m
Z
ddlmZddl
mZddlmZmZmZereddlmZmZmZmZmZmZmZmZmZeeefZeeeefZeeege fZ!Gd	d
d
e"Z#Gddde
ej$e%Z&Gd
dde&Z'Gddde'Z(ddZ)Gddde'Z*e+dZ,ddZ-ddZ.Gddde&Z/dS))absolute_importdivisionprint_functionN)string_typeswith_metaclass)
TYPE_CHECKING)canonicalize_version)Version
LegacyVersionparse)	ListDictUnionIterableIteratorOptionalCallableTuple	FrozenSetc@seZdZdZdS)InvalidSpecifierzH
    An invalid specifier was found, users should refer to PEP 440.
    N)__name__
__module____qualname____doc__rr/builddir/build/BUILDROOT/alt-python310-setuptools-58.3.0-4.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/setuptools/_vendor/packaging/specifiers.pyr"src@seZdZejddZejddZejddZejddZej	d	d
Z
e
jdd
Z
ejdd
dZejdddZ
dS)
BaseSpecifiercCdS)z
        Returns the str representation of this Specifier like object. This
        should be representative of the Specifier itself.
        Nrselfrrr__str__)zBaseSpecifier.__str__cCr)zF
        Returns a hash value for this Specifier like object.
        Nrrrrr__hash__1r"zBaseSpecifier.__hash__cCr)zq
        Returns a boolean representing whether or not the two Specifier like
        objects are equal.
        Nrr otherrrr__eq__8r"zBaseSpecifier.__eq__cCr)zu
        Returns a boolean representing whether or not the two Specifier like
        objects are not equal.
        Nrr$rrr__ne__@r"zBaseSpecifier.__ne__cCr)zg
        Returns whether or not pre-releases as a whole are allowed by this
        specifier.
        NrrrrrprereleasesHr"zBaseSpecifier.prereleasescCr)zd
        Sets whether or not pre-releases as a whole are allowed by this
        specifier.
        Nrr valuerrrr(Pr"NcCr)zR
        Determines if the given item is contained within this specifier.
        Nrr itemr(rrrcontainsXr"zBaseSpecifier.containscCr)z
        Takes an iterable of items and filters them so that only items which
        are contained within this specifier are allowed in it.
        Nr)r iterabler(rrrfilter_r"zBaseSpecifier.filterN)rrrabcabstractmethodr!r#r&r'abstractpropertyr(setterr-r/rrrrr(s"





rc@seZdZiZd"ddZddZddZed	d
ZddZ	d
dZ
ddZddZddZ
eddZeddZeddZejddZddZd#ddZd#d d!ZdS)$_IndividualSpecifierNcCsF|j|}|std||d|df|_||_dS)NzInvalid specifier: '{0}'operatorversion)_regexsearchrformatgroupstrip_spec_prereleases)r specr(matchrrr__init__ls
z_IndividualSpecifier.__init__cCs0|jdurd|jnd}d|jjt||S)N, prereleases={0!r}r6z<{0}({1!r}{2})>)r?r;r(	__class__rstrr prerrr__repr__zs

z_IndividualSpecifier.__repr__cCsdj|jS)Nz{0}{1})r;r>rrrrr!sz_IndividualSpecifier.__str__cCs|jdt|jdfS)Nrr)r>r	rrrr_canonical_specsz$_IndividualSpecifier._canonical_speccC
t|jSr0)hashrIrrrrr#
z_IndividualSpecifier.__hash__cCsPt|trz	|t|}WntytYSwt||js"tS|j|jkSr0)
isinstancerrDrErNotImplementedrIr$rrrr&
z_IndividualSpecifier.__eq__cCsPt|trz	|t|}WntytYSwt||js"tS|j|jkSr0)rMrrDrErrNr>r$rrrr'rOz_IndividualSpecifier.__ne__cCst|d|j|}|S)Nz_compare_{0})getattrr;
_operators)r opoperator_callablerrr
_get_operatorsz"_IndividualSpecifier._get_operatorcCst|ttfst|}|Sr0)rMrr
rr r8rrr_coerce_versionsz$_IndividualSpecifier._coerce_versioncC
|jdS)Nrr>rrrrr7
z_IndividualSpecifier.operatorcCrW)NrrXrrrrr8rYz_IndividualSpecifier.versioncCs|jSr0r?rrrrr(sz _IndividualSpecifier.prereleasescC
||_dSr0rZr)rrrr(rYcC
||Sr0r-r r,rrr__contains__rLz!_IndividualSpecifier.__contains__cCs>|dur|j}||}|jr|sdS||j}|||jSNF)r(rV
is_prereleaserTr7r8)r r,r(normalized_itemrSrrrr-s

z_IndividualSpecifier.containsccsd}g}d|dur|ndi}|D]#}||}|j|fi|r4|jr/|s/|js/||qd}|Vq|sA|rC|D]	}|Vq;dSdSdS)NFr(T)rVr-rar(append)r r.r(yieldedfound_prereleaseskwr8parsed_versionrrrr/s*
z_IndividualSpecifier.filterr6Nr0)rrrrQrBrHr!propertyrIr#r&r'rTrVr7r8r(r4r_r-r/rrrrr5hs.







r5c@sveZdZdZededejejBZdddddd	d
Z	ddZ
d
dZddZddZ
ddZddZddZdS)LegacySpecifiera
        (?P(==|!=|<=|>=|<|>))
        \s*
        (?P
            [^,;\s)]* # Since this is a "legacy" specifier, and the version
                      # string can be just about anything, we match everything
                      # except for whitespace, a semi-colon for marker support,
                      # a closing paren since versions can be enclosed in
                      # them, and a comma since it's a version separator.
        )
        ^\s*\s*$equal	not_equalless_than_equalgreater_than_equal	less_thangreater_than)==!=<=>=<>cCst|tstt|}|Sr0)rMrrErUrrrrV s
zLegacySpecifier._coerce_versioncCs|||kSr0rVr prospectiver@rrr_compare_equal&zLegacySpecifier._compare_equalcCs|||kSr0ryrzrrr_compare_not_equal*r}z"LegacySpecifier._compare_not_equalcCs|||kSr0ryrzrrr_compare_less_than_equal.r}z(LegacySpecifier._compare_less_than_equalcCs|||kSr0ryrzrrr_compare_greater_than_equal2r}z+LegacySpecifier._compare_greater_than_equalcCs|||kSr0ryrzrrr_compare_less_than6r}z"LegacySpecifier._compare_less_thancCs|||kSr0ryrzrrr_compare_greater_than:r}z%LegacySpecifier._compare_greater_thanN)rrr
_regex_strrecompileVERBOSE
IGNORECASEr9rQrVr|r~rrrrrrrrrjs"	rjcstfdd}|S)Ncst|tsdS|||Sr`)rMr
rzfnrrwrappedCs
z)_require_version_compare..wrapped)	functoolswraps)rrrrr_require_version_compare?src	@seZdZdZededejejBZdddddd	d
ddZ	e
d
dZe
ddZe
ddZ
e
ddZe
ddZe
ddZe
ddZddZeddZejddZd S)!	Specifiera
        (?P(~=|==|!=|<=|>=|<|>|===))
        (?P
            (?:
                # The identity operators allow for an escape hatch that will
                # do an exact string match of the version you wish to install.
                # This will not be parsed by PEP 440 and we cannot determine
                # any semantic meaning from it. This operator is discouraged
                # but included entirely as an escape hatch.
                (?<====)  # Only match for the identity operator
                \s*
                [^\s]*    # We just match everything, except for whitespace
                          # since we are only testing for strict identity.
            )
            |
            (?:
                # The (non)equality operators allow for wild card and local
                # versions to be specified so we have to define these two
                # operators separately to enable that.
                (?<===|!=)            # Only match for equals and not equals

                \s*
                v?
                (?:[0-9]+!)?          # epoch
                [0-9]+(?:\.[0-9]+)*   # release
                (?:                   # pre release
                    [-_\.]?
                    (a|b|c|rc|alpha|beta|pre|preview)
                    [-_\.]?
                    [0-9]*
                )?
                (?:                   # post release
                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
                )?

                # You cannot use a wild card and a dev or local version
                # together so group them with a | and make them optional.
                (?:
                    (?:[-_\.]?dev[-_\.]?[0-9]*)?         # dev release
                    (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
                    |
                    \.\*  # Wild card syntax of .*
                )?
            )
            |
            (?:
                # The compatible operator requires at least two digits in the
                # release segment.
                (?<=~=)               # Only match for the compatible operator

                \s*
                v?
                (?:[0-9]+!)?          # epoch
                [0-9]+(?:\.[0-9]+)+   # release  (We have a + instead of a *)
                (?:                   # pre release
                    [-_\.]?
                    (a|b|c|rc|alpha|beta|pre|preview)
                    [-_\.]?
                    [0-9]*
                )?
                (?:                                   # post release
                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
                )?
                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
            )
            |
            (?:
                # All other operators only allow a sub set of what the
                # (non)equality operators do. Specifically they do not allow
                # local versions to be specified nor do they allow the prefix
                # matching wild cards.
                (?sz/Specifier._compare_compatible...*rvrs)joinlist	itertools	takewhile_version_splitrT)r r{r@prefixrrr_compare_compatibles

zSpecifier._compare_compatiblec	Csv|dr+t|j}t|dd}tt|}|dt|}t||\}}||kSt|}|js7t|j}||kS)Nr)endswithr
publicrrElen_pad_versionlocal)	r r{r@
split_specsplit_prospectiveshortened_prospectivepadded_specpadded_prospectivespec_versionrrrr|s


zSpecifier._compare_equalcCs|||Sr0)r|rzrrrr~szSpecifier._compare_not_equalcCst|jt|kSr0r
rrzrrrrz"Specifier._compare_less_than_equalcCst|jt|kSr0rrzrrrr
rz%Specifier._compare_greater_than_equalcCs<t|}||ks
dS|js|jrt|jt|jkrdSdSNFT)r
rabase_versionr r{spec_strr@rrrrszSpecifier._compare_less_thancCs^t|}||ks
dS|js|jrt|jt|jkrdS|jdur-t|jt|jkr-dSdSr)r
is_postreleaserrrrrrr1s
zSpecifier._compare_greater_thancCst|t|kSr0)rElowerrzrrr_compare_arbitraryRszSpecifier._compare_arbitrarycCsR|jdur|jS|j\}}|dvr'|dkr |dr |dd}t|jr'dSdS)N)rsrvrurrrsrrTF)r?r>rrra)r r7r8rrrr(Vs


zSpecifier.prereleasescCr[r0rZr)rrrr(prYN)rrrrrrrrr9rQrrr|r~rrrrrrir(r4rrrrrMs>]

(




 
rz^([0-9]+)((?:a|b|c|rc)[0-9]+)$cCs@g}|dD]}t|}|r||q||q|S)Nr)split
_prefix_regexr:extendgroupsrc)r8resultr,rArrrrys
rc
Csgg}}|ttdd||ttdd|||t|dd||t|dd|ddgtdt|dt|d|ddgtdt|dt|dttj|ttj|fS)NcS|Sr0isdigitrrrrrz_pad_version..cSrr0rrrrrrrrr0)rcrrrrinsertmaxchain)leftright
left_splitright_splitrrrrs
,,rc@seZdZdddZddZddZd	d
ZddZd
dZddZ	ddZ
ddZeddZ
e
jddZ
ddZdddZ	dddZdS) SpecifierSetr6Nc	Csjdd|dD}t}|D]}z	|t|Wqty*|t|Yqwt||_||_dS)NcSsg|]
}|r|qSr)r=.0srrr
sz)SpecifierSet.__init__..,)	rsetaddrrrj	frozenset_specsr?)r 
specifiersr(split_specifiersparsed	specifierrrrrBs

zSpecifierSet.__init__cCs*|jdurd|jnd}dt||S)NrCr6z)r?r;r(rErFrrrrHs

zSpecifierSet.__repr__cCsdtdd|jDS)Nrcss|]}t|VqdSr0)rErrrr	sz'SpecifierSet.__str__..)rsortedrrrrrr!szSpecifierSet.__str__cCrJr0)rKrrrrrr#rLzSpecifierSet.__hash__cCst|tr
t|}nt|tstSt}t|j|jB|_|jdur-|jdur-|j|_|S|jdur=|jdur=|j|_|S|j|jkrI|j|_|Std)NzFCannot combine SpecifierSets with True and False prerelease overrides.)rMrrrNrrr?
ValueError)r r%rrrr__and__s$


	zSpecifierSet.__and__cCs6t|ttfrtt|}nt|tstS|j|jkSr0rMrr5rrErNrr$rrrr&

zSpecifierSet.__eq__cCs6t|ttfrtt|}nt|tstS|j|jkSr0rr$rrrr'rzSpecifierSet.__ne__cCrJr0)rrrrrr__len__rLzSpecifierSet.__len__cCrJr0)iterrrrrr__iter__rLzSpecifierSet.__iter__cCs.|jdur|jS|js
dStdd|jDS)Ncss|]}|jVqdSr0r(rrrrrsz+SpecifierSet.prereleases..)r?ranyrrrrr(s

zSpecifierSet.prereleasescCr[r0rZr)rrrr(rYcCr\r0r]r^rrrr_rLzSpecifierSet.__contains__csLtttfstdur|jsjrdStfdd|jDS)NFc3s|]
}|jdVqdS)rNr]rr,r(rrr*sz(SpecifierSet.contains..)rMrr
rr(raallrr+rrrr-s
zSpecifierSet.containscCs|dur|j}|jr|jD]}|j|t|d}q
|Sg}g}|D](}t|ttfs/t|}n|}t|tr7q!|jrD|sD|sC|	|q!|	|q!|sT|rT|durT|S|S)Nr)
r(rr/boolrMrr
rrarc)r r.r(r@filteredrer,rgrrrr/,s,





zSpecifierSet.filterrhr0)rrrrBrHr!r#rr&r'rrrir(r4r_r-r/rrrrrs$

		


r)0
__future__rrrr1rrrZ_compatrrZ_typingrutilsr	r8r
rrtypingr
rrrrrrrr
ParsedVersionrEUnparsedVersionrCallableOperatorrrABCMetaobjectrr5rjrrrrrrrrrrrs6,@ 8
+PKH]Jzhh@python3.10/site-packages/setuptools/_vendor/packaging/_compat.pynu[# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function

import sys

from ._typing import TYPE_CHECKING

if TYPE_CHECKING:  # pragma: no cover
    from typing import Any, Dict, Tuple, Type


PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] == 3

# flake8: noqa

if PY3:
    string_types = (str,)
else:
    string_types = (basestring,)


def with_metaclass(meta, *bases):
    # type: (Type[Any], Tuple[Type[Any], ...]) -> Any
    """
    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(meta):  # type: ignore
        def __new__(cls, name, this_bases, d):
            # type: (Type[Any], str, Tuple[Any], Dict[Any, Any]) -> Any
            return meta(name, bases, d)

    return type.__new__(metaclass, "temporary_class", (), {})
PKH]'^^=python3.10/site-packages/setuptools/_vendor/packaging/tags.pynu[# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.

from __future__ import absolute_import

import distutils.util

try:
    from importlib.machinery import EXTENSION_SUFFIXES
except ImportError:  # pragma: no cover
    import imp

    EXTENSION_SUFFIXES = [x[0] for x in imp.get_suffixes()]
    del imp
import logging
import os
import platform
import re
import struct
import sys
import sysconfig
import warnings

from ._typing import TYPE_CHECKING, cast

if TYPE_CHECKING:  # pragma: no cover
    from typing import (
        Dict,
        FrozenSet,
        IO,
        Iterable,
        Iterator,
        List,
        Optional,
        Sequence,
        Tuple,
        Union,
    )

    PythonVersion = Sequence[int]
    MacVersion = Tuple[int, int]
    GlibcVersion = Tuple[int, int]


logger = logging.getLogger(__name__)

INTERPRETER_SHORT_NAMES = {
    "python": "py",  # Generic.
    "cpython": "cp",
    "pypy": "pp",
    "ironpython": "ip",
    "jython": "jy",
}  # type: Dict[str, str]


_32_BIT_INTERPRETER = sys.maxsize <= 2 ** 32


class Tag(object):
    """
    A representation of the tag triple for a wheel.

    Instances are considered immutable and thus are hashable. Equality checking
    is also supported.
    """

    __slots__ = ["_interpreter", "_abi", "_platform"]

    def __init__(self, interpreter, abi, platform):
        # type: (str, str, str) -> None
        self._interpreter = interpreter.lower()
        self._abi = abi.lower()
        self._platform = platform.lower()

    @property
    def interpreter(self):
        # type: () -> str
        return self._interpreter

    @property
    def abi(self):
        # type: () -> str
        return self._abi

    @property
    def platform(self):
        # type: () -> str
        return self._platform

    def __eq__(self, other):
        # type: (object) -> bool
        if not isinstance(other, Tag):
            return NotImplemented

        return (
            (self.platform == other.platform)
            and (self.abi == other.abi)
            and (self.interpreter == other.interpreter)
        )

    def __hash__(self):
        # type: () -> int
        return hash((self._interpreter, self._abi, self._platform))

    def __str__(self):
        # type: () -> str
        return "{}-{}-{}".format(self._interpreter, self._abi, self._platform)

    def __repr__(self):
        # type: () -> str
        return "<{self} @ {self_id}>".format(self=self, self_id=id(self))


def parse_tag(tag):
    # type: (str) -> FrozenSet[Tag]
    """
    Parses the provided tag (e.g. `py3-none-any`) into a frozenset of Tag instances.

    Returning a set is required due to the possibility that the tag is a
    compressed tag set.
    """
    tags = set()
    interpreters, abis, platforms = tag.split("-")
    for interpreter in interpreters.split("."):
        for abi in abis.split("."):
            for platform_ in platforms.split("."):
                tags.add(Tag(interpreter, abi, platform_))
    return frozenset(tags)


def _warn_keyword_parameter(func_name, kwargs):
    # type: (str, Dict[str, bool]) -> bool
    """
    Backwards-compatibility with Python 2.7 to allow treating 'warn' as keyword-only.
    """
    if not kwargs:
        return False
    elif len(kwargs) > 1 or "warn" not in kwargs:
        kwargs.pop("warn", None)
        arg = next(iter(kwargs.keys()))
        raise TypeError(
            "{}() got an unexpected keyword argument {!r}".format(func_name, arg)
        )
    return kwargs["warn"]


def _get_config_var(name, warn=False):
    # type: (str, bool) -> Union[int, str, None]
    value = sysconfig.get_config_var(name)
    if value is None and warn:
        logger.debug(
            "Config variable '%s' is unset, Python ABI tag may be incorrect", name
        )
    return value


def _normalize_string(string):
    # type: (str) -> str
    return string.replace(".", "_").replace("-", "_")


def _abi3_applies(python_version):
    # type: (PythonVersion) -> bool
    """
    Determine if the Python version supports abi3.

    PEP 384 was first implemented in Python 3.2.
    """
    return len(python_version) > 1 and tuple(python_version) >= (3, 2)


def _cpython_abis(py_version, warn=False):
    # type: (PythonVersion, bool) -> List[str]
    py_version = tuple(py_version)  # To allow for version comparison.
    abis = []
    version = _version_nodot(py_version[:2])
    debug = pymalloc = ucs4 = ""
    with_debug = _get_config_var("Py_DEBUG", warn)
    has_refcount = hasattr(sys, "gettotalrefcount")
    # Windows doesn't set Py_DEBUG, so checking for support of debug-compiled
    # extension modules is the best option.
    # https://github.com/pypa/pip/issues/3383#issuecomment-173267692
    has_ext = "_d.pyd" in EXTENSION_SUFFIXES
    if with_debug or (with_debug is None and (has_refcount or has_ext)):
        debug = "d"
    if py_version < (3, 8):
        with_pymalloc = _get_config_var("WITH_PYMALLOC", warn)
        if with_pymalloc or with_pymalloc is None:
            pymalloc = "m"
        if py_version < (3, 3):
            unicode_size = _get_config_var("Py_UNICODE_SIZE", warn)
            if unicode_size == 4 or (
                unicode_size is None and sys.maxunicode == 0x10FFFF
            ):
                ucs4 = "u"
    elif debug:
        # Debug builds can also load "normal" extension modules.
        # We can also assume no UCS-4 or pymalloc requirement.
        abis.append("cp{version}".format(version=version))
    abis.insert(
        0,
        "cp{version}{debug}{pymalloc}{ucs4}".format(
            version=version, debug=debug, pymalloc=pymalloc, ucs4=ucs4
        ),
    )
    return abis


def cpython_tags(
    python_version=None,  # type: Optional[PythonVersion]
    abis=None,  # type: Optional[Iterable[str]]
    platforms=None,  # type: Optional[Iterable[str]]
    **kwargs  # type: bool
):
    # type: (...) -> Iterator[Tag]
    """
    Yields the tags for a CPython interpreter.

    The tags consist of:
    - cp--
    - cp-abi3-
    - cp-none-
    - cp-abi3-  # Older Python versions down to 3.2.

    If python_version only specifies a major version then user-provided ABIs and
    the 'none' ABItag will be used.

    If 'abi3' or 'none' are specified in 'abis' then they will be yielded at
    their normal position and not at the beginning.
    """
    warn = _warn_keyword_parameter("cpython_tags", kwargs)
    if not python_version:
        python_version = sys.version_info[:2]

    interpreter = "cp{}".format(_version_nodot(python_version[:2]))

    if abis is None:
        if len(python_version) > 1:
            abis = _cpython_abis(python_version, warn)
        else:
            abis = []
    abis = list(abis)
    # 'abi3' and 'none' are explicitly handled later.
    for explicit_abi in ("abi3", "none"):
        try:
            abis.remove(explicit_abi)
        except ValueError:
            pass

    platforms = list(platforms or _platform_tags())
    for abi in abis:
        for platform_ in platforms:
            yield Tag(interpreter, abi, platform_)
    if _abi3_applies(python_version):
        for tag in (Tag(interpreter, "abi3", platform_) for platform_ in platforms):
            yield tag
    for tag in (Tag(interpreter, "none", platform_) for platform_ in platforms):
        yield tag

    if _abi3_applies(python_version):
        for minor_version in range(python_version[1] - 1, 1, -1):
            for platform_ in platforms:
                interpreter = "cp{version}".format(
                    version=_version_nodot((python_version[0], minor_version))
                )
                yield Tag(interpreter, "abi3", platform_)


def _generic_abi():
    # type: () -> Iterator[str]
    abi = sysconfig.get_config_var("SOABI")
    if abi:
        yield _normalize_string(abi)


def generic_tags(
    interpreter=None,  # type: Optional[str]
    abis=None,  # type: Optional[Iterable[str]]
    platforms=None,  # type: Optional[Iterable[str]]
    **kwargs  # type: bool
):
    # type: (...) -> Iterator[Tag]
    """
    Yields the tags for a generic interpreter.

    The tags consist of:
    - --

    The "none" ABI will be added if it was not explicitly provided.
    """
    warn = _warn_keyword_parameter("generic_tags", kwargs)
    if not interpreter:
        interp_name = interpreter_name()
        interp_version = interpreter_version(warn=warn)
        interpreter = "".join([interp_name, interp_version])
    if abis is None:
        abis = _generic_abi()
    platforms = list(platforms or _platform_tags())
    abis = list(abis)
    if "none" not in abis:
        abis.append("none")
    for abi in abis:
        for platform_ in platforms:
            yield Tag(interpreter, abi, platform_)


def _py_interpreter_range(py_version):
    # type: (PythonVersion) -> Iterator[str]
    """
    Yields Python versions in descending order.

    After the latest version, the major-only version will be yielded, and then
    all previous versions of that major version.
    """
    if len(py_version) > 1:
        yield "py{version}".format(version=_version_nodot(py_version[:2]))
    yield "py{major}".format(major=py_version[0])
    if len(py_version) > 1:
        for minor in range(py_version[1] - 1, -1, -1):
            yield "py{version}".format(version=_version_nodot((py_version[0], minor)))


def compatible_tags(
    python_version=None,  # type: Optional[PythonVersion]
    interpreter=None,  # type: Optional[str]
    platforms=None,  # type: Optional[Iterable[str]]
):
    # type: (...) -> Iterator[Tag]
    """
    Yields the sequence of tags that are compatible with a specific version of Python.

    The tags consist of:
    - py*-none-
    - -none-any  # ... if `interpreter` is provided.
    - py*-none-any
    """
    if not python_version:
        python_version = sys.version_info[:2]
    platforms = list(platforms or _platform_tags())
    for version in _py_interpreter_range(python_version):
        for platform_ in platforms:
            yield Tag(version, "none", platform_)
    if interpreter:
        yield Tag(interpreter, "none", "any")
    for version in _py_interpreter_range(python_version):
        yield Tag(version, "none", "any")


def _mac_arch(arch, is_32bit=_32_BIT_INTERPRETER):
    # type: (str, bool) -> str
    if not is_32bit:
        return arch

    if arch.startswith("ppc"):
        return "ppc"

    return "i386"


def _mac_binary_formats(version, cpu_arch):
    # type: (MacVersion, str) -> List[str]
    formats = [cpu_arch]
    if cpu_arch == "x86_64":
        if version < (10, 4):
            return []
        formats.extend(["intel", "fat64", "fat32"])

    elif cpu_arch == "i386":
        if version < (10, 4):
            return []
        formats.extend(["intel", "fat32", "fat"])

    elif cpu_arch == "ppc64":
        # TODO: Need to care about 32-bit PPC for ppc64 through 10.2?
        if version > (10, 5) or version < (10, 4):
            return []
        formats.append("fat64")

    elif cpu_arch == "ppc":
        if version > (10, 6):
            return []
        formats.extend(["fat32", "fat"])

    formats.append("universal")
    return formats


def mac_platforms(version=None, arch=None):
    # type: (Optional[MacVersion], Optional[str]) -> Iterator[str]
    """
    Yields the platform tags for a macOS system.

    The `version` parameter is a two-item tuple specifying the macOS version to
    generate platform tags for. The `arch` parameter is the CPU architecture to
    generate platform tags for. Both parameters default to the appropriate value
    for the current system.
    """
    version_str, _, cpu_arch = platform.mac_ver()  # type: ignore
    if version is None:
        version = cast("MacVersion", tuple(map(int, version_str.split(".")[:2])))
    else:
        version = version
    if arch is None:
        arch = _mac_arch(cpu_arch)
    else:
        arch = arch
    for minor_version in range(version[1], -1, -1):
        compat_version = version[0], minor_version
        binary_formats = _mac_binary_formats(compat_version, arch)
        for binary_format in binary_formats:
            yield "macosx_{major}_{minor}_{binary_format}".format(
                major=compat_version[0],
                minor=compat_version[1],
                binary_format=binary_format,
            )


# From PEP 513.
def _is_manylinux_compatible(name, glibc_version):
    # type: (str, GlibcVersion) -> bool
    # Check for presence of _manylinux module.
    try:
        import _manylinux  # noqa

        return bool(getattr(_manylinux, name + "_compatible"))
    except (ImportError, AttributeError):
        # Fall through to heuristic check below.
        pass

    return _have_compatible_glibc(*glibc_version)


def _glibc_version_string():
    # type: () -> Optional[str]
    # Returns glibc version string, or None if not using glibc.
    return _glibc_version_string_confstr() or _glibc_version_string_ctypes()


def _glibc_version_string_confstr():
    # type: () -> Optional[str]
    """
    Primary implementation of glibc_version_string using os.confstr.
    """
    # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely
    # to be broken or missing. This strategy is used in the standard library
    # platform module.
    # https://github.com/python/cpython/blob/fcf1d003bf4f0100c9d0921ff3d70e1127ca1b71/Lib/platform.py#L175-L183
    try:
        # os.confstr("CS_GNU_LIBC_VERSION") returns a string like "glibc 2.17".
        version_string = os.confstr(  # type: ignore[attr-defined] # noqa: F821
            "CS_GNU_LIBC_VERSION"
        )
        assert version_string is not None
        _, version = version_string.split()  # type: Tuple[str, str]
    except (AssertionError, AttributeError, OSError, ValueError):
        # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)...
        return None
    return version


def _glibc_version_string_ctypes():
    # type: () -> Optional[str]
    """
    Fallback implementation of glibc_version_string using ctypes.
    """
    try:
        import ctypes
    except ImportError:
        return None

    # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
    # manpage says, "If filename is NULL, then the returned handle is for the
    # main program". This way we can let the linker do the work to figure out
    # which libc our process is actually using.
    #
    # Note: typeshed is wrong here so we are ignoring this line.
    process_namespace = ctypes.CDLL(None)  # type: ignore
    try:
        gnu_get_libc_version = process_namespace.gnu_get_libc_version
    except AttributeError:
        # Symbol doesn't exist -> therefore, we are not linked to
        # glibc.
        return None

    # Call gnu_get_libc_version, which returns a string like "2.5"
    gnu_get_libc_version.restype = ctypes.c_char_p
    version_str = gnu_get_libc_version()  # type: str
    # py2 / py3 compatibility:
    if not isinstance(version_str, str):
        version_str = version_str.decode("ascii")

    return version_str


# Separated out from have_compatible_glibc for easier unit testing.
def _check_glibc_version(version_str, required_major, minimum_minor):
    # type: (str, int, int) -> bool
    # Parse string and check against requested version.
    #
    # We use a regexp instead of str.split because we want to discard any
    # random junk that might come after the minor version -- this might happen
    # in patched/forked versions of glibc (e.g. Linaro's version of glibc
    # uses version strings like "2.20-2014.11"). See gh-3588.
    m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str)
    if not m:
        warnings.warn(
            "Expected glibc version with 2 components major.minor,"
            " got: %s" % version_str,
            RuntimeWarning,
        )
        return False
    return (
        int(m.group("major")) == required_major
        and int(m.group("minor")) >= minimum_minor
    )


def _have_compatible_glibc(required_major, minimum_minor):
    # type: (int, int) -> bool
    version_str = _glibc_version_string()
    if version_str is None:
        return False
    return _check_glibc_version(version_str, required_major, minimum_minor)


# Python does not provide platform information at sufficient granularity to
# identify the architecture of the running executable in some cases, so we
# determine it dynamically by reading the information from the running
# process. This only applies on Linux, which uses the ELF format.
class _ELFFileHeader(object):
    # https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header
    class _InvalidELFFileHeader(ValueError):
        """
        An invalid ELF file header was found.
        """

    ELF_MAGIC_NUMBER = 0x7F454C46
    ELFCLASS32 = 1
    ELFCLASS64 = 2
    ELFDATA2LSB = 1
    ELFDATA2MSB = 2
    EM_386 = 3
    EM_S390 = 22
    EM_ARM = 40
    EM_X86_64 = 62
    EF_ARM_ABIMASK = 0xFF000000
    EF_ARM_ABI_VER5 = 0x05000000
    EF_ARM_ABI_FLOAT_HARD = 0x00000400

    def __init__(self, file):
        # type: (IO[bytes]) -> None
        def unpack(fmt):
            # type: (str) -> int
            try:
                (result,) = struct.unpack(
                    fmt, file.read(struct.calcsize(fmt))
                )  # type: (int, )
            except struct.error:
                raise _ELFFileHeader._InvalidELFFileHeader()
            return result

        self.e_ident_magic = unpack(">I")
        if self.e_ident_magic != self.ELF_MAGIC_NUMBER:
            raise _ELFFileHeader._InvalidELFFileHeader()
        self.e_ident_class = unpack("B")
        if self.e_ident_class not in {self.ELFCLASS32, self.ELFCLASS64}:
            raise _ELFFileHeader._InvalidELFFileHeader()
        self.e_ident_data = unpack("B")
        if self.e_ident_data not in {self.ELFDATA2LSB, self.ELFDATA2MSB}:
            raise _ELFFileHeader._InvalidELFFileHeader()
        self.e_ident_version = unpack("B")
        self.e_ident_osabi = unpack("B")
        self.e_ident_abiversion = unpack("B")
        self.e_ident_pad = file.read(7)
        format_h = "H"
        format_i = "I"
        format_q = "Q"
        format_p = format_i if self.e_ident_class == self.ELFCLASS32 else format_q
        self.e_type = unpack(format_h)
        self.e_machine = unpack(format_h)
        self.e_version = unpack(format_i)
        self.e_entry = unpack(format_p)
        self.e_phoff = unpack(format_p)
        self.e_shoff = unpack(format_p)
        self.e_flags = unpack(format_i)
        self.e_ehsize = unpack(format_h)
        self.e_phentsize = unpack(format_h)
        self.e_phnum = unpack(format_h)
        self.e_shentsize = unpack(format_h)
        self.e_shnum = unpack(format_h)
        self.e_shstrndx = unpack(format_h)


def _get_elf_header():
    # type: () -> Optional[_ELFFileHeader]
    try:
        with open(sys.executable, "rb") as f:
            elf_header = _ELFFileHeader(f)
    except (IOError, OSError, TypeError, _ELFFileHeader._InvalidELFFileHeader):
        return None
    return elf_header


def _is_linux_armhf():
    # type: () -> bool
    # hard-float ABI can be detected from the ELF header of the running
    # process
    # https://static.docs.arm.com/ihi0044/g/aaelf32.pdf
    elf_header = _get_elf_header()
    if elf_header is None:
        return False
    result = elf_header.e_ident_class == elf_header.ELFCLASS32
    result &= elf_header.e_ident_data == elf_header.ELFDATA2LSB
    result &= elf_header.e_machine == elf_header.EM_ARM
    result &= (
        elf_header.e_flags & elf_header.EF_ARM_ABIMASK
    ) == elf_header.EF_ARM_ABI_VER5
    result &= (
        elf_header.e_flags & elf_header.EF_ARM_ABI_FLOAT_HARD
    ) == elf_header.EF_ARM_ABI_FLOAT_HARD
    return result


def _is_linux_i686():
    # type: () -> bool
    elf_header = _get_elf_header()
    if elf_header is None:
        return False
    result = elf_header.e_ident_class == elf_header.ELFCLASS32
    result &= elf_header.e_ident_data == elf_header.ELFDATA2LSB
    result &= elf_header.e_machine == elf_header.EM_386
    return result


def _have_compatible_manylinux_abi(arch):
    # type: (str) -> bool
    if arch == "armv7l":
        return _is_linux_armhf()
    if arch == "i686":
        return _is_linux_i686()
    return True


def _linux_platforms(is_32bit=_32_BIT_INTERPRETER):
    # type: (bool) -> Iterator[str]
    linux = _normalize_string(distutils.util.get_platform())
    if is_32bit:
        if linux == "linux_x86_64":
            linux = "linux_i686"
        elif linux == "linux_aarch64":
            linux = "linux_armv7l"
    manylinux_support = []
    _, arch = linux.split("_", 1)
    if _have_compatible_manylinux_abi(arch):
        if arch in {"x86_64", "i686", "aarch64", "armv7l", "ppc64", "ppc64le", "s390x"}:
            manylinux_support.append(
                ("manylinux2014", (2, 17))
            )  # CentOS 7 w/ glibc 2.17 (PEP 599)
        if arch in {"x86_64", "i686"}:
            manylinux_support.append(
                ("manylinux2010", (2, 12))
            )  # CentOS 6 w/ glibc 2.12 (PEP 571)
            manylinux_support.append(
                ("manylinux1", (2, 5))
            )  # CentOS 5 w/ glibc 2.5 (PEP 513)
    manylinux_support_iter = iter(manylinux_support)
    for name, glibc_version in manylinux_support_iter:
        if _is_manylinux_compatible(name, glibc_version):
            yield linux.replace("linux", name)
            break
    # Support for a later manylinux implies support for an earlier version.
    for name, _ in manylinux_support_iter:
        yield linux.replace("linux", name)
    yield linux


def _generic_platforms():
    # type: () -> Iterator[str]
    yield _normalize_string(distutils.util.get_platform())


def _platform_tags():
    # type: () -> Iterator[str]
    """
    Provides the platform tags for this installation.
    """
    if platform.system() == "Darwin":
        return mac_platforms()
    elif platform.system() == "Linux":
        return _linux_platforms()
    else:
        return _generic_platforms()


def interpreter_name():
    # type: () -> str
    """
    Returns the name of the running interpreter.
    """
    try:
        name = sys.implementation.name  # type: ignore
    except AttributeError:  # pragma: no cover
        # Python 2.7 compatibility.
        name = platform.python_implementation().lower()
    return INTERPRETER_SHORT_NAMES.get(name) or name


def interpreter_version(**kwargs):
    # type: (bool) -> str
    """
    Returns the version of the running interpreter.
    """
    warn = _warn_keyword_parameter("interpreter_version", kwargs)
    version = _get_config_var("py_version_nodot", warn=warn)
    if version:
        version = str(version)
    else:
        version = _version_nodot(sys.version_info[:2])
    return version


def _version_nodot(version):
    # type: (PythonVersion) -> str
    if any(v >= 10 for v in version):
        sep = "_"
    else:
        sep = ""
    return sep.join(map(str, version))


def sys_tags(**kwargs):
    # type: (bool) -> Iterator[Tag]
    """
    Returns the sequence of tag triples for the running interpreter.

    The order of the sequence corresponds to priority order for the
    interpreter, from most to least important.
    """
    warn = _warn_keyword_parameter("sys_tags", kwargs)

    interp_name = interpreter_name()
    if interp_name == "cp":
        for tag in cpython_tags(warn=warn):
            yield tag
    else:
        for tag in generic_tags():
            yield tag

    for tag in compatible_tags():
        yield tag
PKH]iS55Epython3.10/site-packages/setuptools/_vendor/packaging/requirements.pynu[# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function

import string
import re

from setuptools.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException
from setuptools.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine
from setuptools.extern.pyparsing import Literal as L  # noqa
from urllib import parse as urlparse

from ._typing import TYPE_CHECKING
from .markers import MARKER_EXPR, Marker
from .specifiers import LegacySpecifier, Specifier, SpecifierSet

if TYPE_CHECKING:  # pragma: no cover
    from typing import List


class InvalidRequirement(ValueError):
    """
    An invalid requirement was found, users should refer to PEP 508.
    """


ALPHANUM = Word(string.ascii_letters + string.digits)

LBRACKET = L("[").suppress()
RBRACKET = L("]").suppress()
LPAREN = L("(").suppress()
RPAREN = L(")").suppress()
COMMA = L(",").suppress()
SEMICOLON = L(";").suppress()
AT = L("@").suppress()

PUNCTUATION = Word("-_.")
IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM)
IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END))

NAME = IDENTIFIER("name")
EXTRA = IDENTIFIER

URI = Regex(r"[^ ]+")("url")
URL = AT + URI

EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA)
EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras")

VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE)
VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE)

VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY
VERSION_MANY = Combine(
    VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=",", adjacent=False
)("_raw_spec")
_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY))
_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or "")

VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier")
VERSION_SPEC.setParseAction(lambda s, l, t: t[1])

MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
MARKER_EXPR.setParseAction(
    lambda s, l, t: Marker(s[t._original_start : t._original_end])
)
MARKER_SEPARATOR = SEMICOLON
MARKER = MARKER_SEPARATOR + MARKER_EXPR

VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER)
URL_AND_MARKER = URL + Optional(MARKER)

NAMED_REQUIREMENT = NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)

REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd
# setuptools.extern.pyparsing isn't thread safe during initialization, so we do it eagerly, see
# issue #104
REQUIREMENT.parseString("x[]")


class Requirement(object):
    """Parse a requirement.

    Parse a given requirement string into its parts, such as name, specifier,
    URL, and extras. Raises InvalidRequirement on a badly-formed requirement
    string.
    """

    # TODO: Can we test whether something is contained within a requirement?
    #       If so how do we do that? Do we need to test against the _name_ of
    #       the thing as well as the version? What about the markers?
    # TODO: Can we normalize the name and extra name?

    def __init__(self, requirement_string):
        # type: (str) -> None
        try:
            req = REQUIREMENT.parseString(requirement_string)
        except ParseException as e:
            raise InvalidRequirement(
                'Parse error at "{0!r}": {1}'.format(
                    requirement_string[e.loc : e.loc + 8], e.msg
                )
            )

        self.name = req.name
        if req.url:
            parsed_url = urlparse.urlparse(req.url)
            if parsed_url.scheme == "file":
                if urlparse.urlunparse(parsed_url) != req.url:
                    raise InvalidRequirement("Invalid URL given")
            elif not (parsed_url.scheme and parsed_url.netloc) or (
                not parsed_url.scheme and not parsed_url.netloc
            ):
                raise InvalidRequirement("Invalid URL: {0}".format(req.url))
            self.url = req.url
        else:
            self.url = None
        self.extras = set(req.extras.asList() if req.extras else [])
        self.specifier = SpecifierSet(req.specifier)
        self.marker = req.marker if req.marker else None

    def __str__(self):
        # type: () -> str
        parts = [self.name]  # type: List[str]

        if self.extras:
            parts.append("[{0}]".format(",".join(sorted(self.extras))))

        if self.specifier:
            parts.append(str(self.specifier))

        if self.url:
            parts.append("@ {0}".format(self.url))
            if self.marker:
                parts.append(" ")

        if self.marker:
            parts.append("; {0}".format(self.marker))

        return "".join(parts)

    def __repr__(self):
        # type: () -> str
        return "".format(str(self))
PKH]Pzn<n<@python3.10/site-packages/setuptools/_vendor/packaging/version.pynu[# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function

import collections
import itertools
import re

from ._structures import Infinity, NegativeInfinity
from ._typing import TYPE_CHECKING

if TYPE_CHECKING:  # pragma: no cover
    from typing import Callable, Iterator, List, Optional, SupportsInt, Tuple, Union

    from ._structures import InfinityType, NegativeInfinityType

    InfiniteTypes = Union[InfinityType, NegativeInfinityType]
    PrePostDevType = Union[InfiniteTypes, Tuple[str, int]]
    SubLocalType = Union[InfiniteTypes, int, str]
    LocalType = Union[
        NegativeInfinityType,
        Tuple[
            Union[
                SubLocalType,
                Tuple[SubLocalType, str],
                Tuple[NegativeInfinityType, SubLocalType],
            ],
            ...,
        ],
    ]
    CmpKey = Tuple[
        int, Tuple[int, ...], PrePostDevType, PrePostDevType, PrePostDevType, LocalType
    ]
    LegacyCmpKey = Tuple[int, Tuple[str, ...]]
    VersionComparisonMethod = Callable[
        [Union[CmpKey, LegacyCmpKey], Union[CmpKey, LegacyCmpKey]], bool
    ]

__all__ = ["parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"]


_Version = collections.namedtuple(
    "_Version", ["epoch", "release", "dev", "pre", "post", "local"]
)


def parse(version):
    # type: (str) -> Union[LegacyVersion, Version]
    """
    Parse the given version string and return either a :class:`Version` object
    or a :class:`LegacyVersion` object depending on if the given version is
    a valid PEP 440 version or a legacy version.
    """
    try:
        return Version(version)
    except InvalidVersion:
        return LegacyVersion(version)


class InvalidVersion(ValueError):
    """
    An invalid version was found, users should refer to PEP 440.
    """


class _BaseVersion(object):
    _key = None  # type: Union[CmpKey, LegacyCmpKey]

    def __hash__(self):
        # type: () -> int
        return hash(self._key)

    def __lt__(self, other):
        # type: (_BaseVersion) -> bool
        return self._compare(other, lambda s, o: s < o)

    def __le__(self, other):
        # type: (_BaseVersion) -> bool
        return self._compare(other, lambda s, o: s <= o)

    def __eq__(self, other):
        # type: (object) -> bool
        return self._compare(other, lambda s, o: s == o)

    def __ge__(self, other):
        # type: (_BaseVersion) -> bool
        return self._compare(other, lambda s, o: s >= o)

    def __gt__(self, other):
        # type: (_BaseVersion) -> bool
        return self._compare(other, lambda s, o: s > o)

    def __ne__(self, other):
        # type: (object) -> bool
        return self._compare(other, lambda s, o: s != o)

    def _compare(self, other, method):
        # type: (object, VersionComparisonMethod) -> Union[bool, NotImplemented]
        if not isinstance(other, _BaseVersion):
            return NotImplemented

        return method(self._key, other._key)


class LegacyVersion(_BaseVersion):
    def __init__(self, version):
        # type: (str) -> None
        self._version = str(version)
        self._key = _legacy_cmpkey(self._version)

    def __str__(self):
        # type: () -> str
        return self._version

    def __repr__(self):
        # type: () -> str
        return "".format(repr(str(self)))

    @property
    def public(self):
        # type: () -> str
        return self._version

    @property
    def base_version(self):
        # type: () -> str
        return self._version

    @property
    def epoch(self):
        # type: () -> int
        return -1

    @property
    def release(self):
        # type: () -> None
        return None

    @property
    def pre(self):
        # type: () -> None
        return None

    @property
    def post(self):
        # type: () -> None
        return None

    @property
    def dev(self):
        # type: () -> None
        return None

    @property
    def local(self):
        # type: () -> None
        return None

    @property
    def is_prerelease(self):
        # type: () -> bool
        return False

    @property
    def is_postrelease(self):
        # type: () -> bool
        return False

    @property
    def is_devrelease(self):
        # type: () -> bool
        return False


_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE)

_legacy_version_replacement_map = {
    "pre": "c",
    "preview": "c",
    "-": "final-",
    "rc": "c",
    "dev": "@",
}


def _parse_version_parts(s):
    # type: (str) -> Iterator[str]
    for part in _legacy_version_component_re.split(s):
        part = _legacy_version_replacement_map.get(part, part)

        if not part or part == ".":
            continue

        if part[:1] in "0123456789":
            # pad for numeric comparison
            yield part.zfill(8)
        else:
            yield "*" + part

    # ensure that alpha/beta/candidate are before final
    yield "*final"


def _legacy_cmpkey(version):
    # type: (str) -> LegacyCmpKey

    # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch
    # greater than or equal to 0. This will effectively put the LegacyVersion,
    # which uses the defacto standard originally implemented by setuptools,
    # as before all PEP 440 versions.
    epoch = -1

    # This scheme is taken from pkg_resources.parse_version setuptools prior to
    # it's adoption of the packaging library.
    parts = []  # type: List[str]
    for part in _parse_version_parts(version.lower()):
        if part.startswith("*"):
            # remove "-" before a prerelease tag
            if part < "*final":
                while parts and parts[-1] == "*final-":
                    parts.pop()

            # remove trailing zeros from each series of numeric parts
            while parts and parts[-1] == "00000000":
                parts.pop()

        parts.append(part)

    return epoch, tuple(parts)


# Deliberately not anchored to the start and end of the string, to make it
# easier for 3rd party code to reuse
VERSION_PATTERN = r"""
    v?
    (?:
        (?:(?P[0-9]+)!)?                           # epoch
        (?P[0-9]+(?:\.[0-9]+)*)                  # release segment
        (?P
                                          # pre-release
            [-_\.]?
            (?P(a|b|c|rc|alpha|beta|pre|preview))
            [-_\.]?
            (?P[0-9]+)?
        )?
        (?P                                         # post release
            (?:-(?P[0-9]+))
            |
            (?:
                [-_\.]?
                (?Ppost|rev|r)
                [-_\.]?
                (?P[0-9]+)?
            )
        )?
        (?P                                          # dev release
            [-_\.]?
            (?Pdev)
            [-_\.]?
            (?P[0-9]+)?
        )?
    )
    (?:\+(?P[a-z0-9]+(?:[-_\.][a-z0-9]+)*))?       # local version
"""


class Version(_BaseVersion):

    _regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE)

    def __init__(self, version):
        # type: (str) -> None

        # Validate the version and parse it into pieces
        match = self._regex.search(version)
        if not match:
            raise InvalidVersion("Invalid version: '{0}'".format(version))

        # Store the parsed out pieces of the version
        self._version = _Version(
            epoch=int(match.group("epoch")) if match.group("epoch") else 0,
            release=tuple(int(i) for i in match.group("release").split(".")),
            pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")),
            post=_parse_letter_version(
                match.group("post_l"), match.group("post_n1") or match.group("post_n2")
            ),
            dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")),
            local=_parse_local_version(match.group("local")),
        )

        # Generate a key which will be used for sorting
        self._key = _cmpkey(
            self._version.epoch,
            self._version.release,
            self._version.pre,
            self._version.post,
            self._version.dev,
            self._version.local,
        )

    def __repr__(self):
        # type: () -> str
        return "".format(repr(str(self)))

    def __str__(self):
        # type: () -> str
        parts = []

        # Epoch
        if self.epoch != 0:
            parts.append("{0}!".format(self.epoch))

        # Release segment
        parts.append(".".join(str(x) for x in self.release))

        # Pre-release
        if self.pre is not None:
            parts.append("".join(str(x) for x in self.pre))

        # Post-release
        if self.post is not None:
            parts.append(".post{0}".format(self.post))

        # Development release
        if self.dev is not None:
            parts.append(".dev{0}".format(self.dev))

        # Local version segment
        if self.local is not None:
            parts.append("+{0}".format(self.local))

        return "".join(parts)

    @property
    def epoch(self):
        # type: () -> int
        _epoch = self._version.epoch  # type: int
        return _epoch

    @property
    def release(self):
        # type: () -> Tuple[int, ...]
        _release = self._version.release  # type: Tuple[int, ...]
        return _release

    @property
    def pre(self):
        # type: () -> Optional[Tuple[str, int]]
        _pre = self._version.pre  # type: Optional[Tuple[str, int]]
        return _pre

    @property
    def post(self):
        # type: () -> Optional[Tuple[str, int]]
        return self._version.post[1] if self._version.post else None

    @property
    def dev(self):
        # type: () -> Optional[Tuple[str, int]]
        return self._version.dev[1] if self._version.dev else None

    @property
    def local(self):
        # type: () -> Optional[str]
        if self._version.local:
            return ".".join(str(x) for x in self._version.local)
        else:
            return None

    @property
    def public(self):
        # type: () -> str
        return str(self).split("+", 1)[0]

    @property
    def base_version(self):
        # type: () -> str
        parts = []

        # Epoch
        if self.epoch != 0:
            parts.append("{0}!".format(self.epoch))

        # Release segment
        parts.append(".".join(str(x) for x in self.release))

        return "".join(parts)

    @property
    def is_prerelease(self):
        # type: () -> bool
        return self.dev is not None or self.pre is not None

    @property
    def is_postrelease(self):
        # type: () -> bool
        return self.post is not None

    @property
    def is_devrelease(self):
        # type: () -> bool
        return self.dev is not None

    @property
    def major(self):
        # type: () -> int
        return self.release[0] if len(self.release) >= 1 else 0

    @property
    def minor(self):
        # type: () -> int
        return self.release[1] if len(self.release) >= 2 else 0

    @property
    def micro(self):
        # type: () -> int
        return self.release[2] if len(self.release) >= 3 else 0


def _parse_letter_version(
    letter,  # type: str
    number,  # type: Union[str, bytes, SupportsInt]
):
    # type: (...) -> Optional[Tuple[str, int]]

    if letter:
        # We consider there to be an implicit 0 in a pre-release if there is
        # not a numeral associated with it.
        if number is None:
            number = 0

        # We normalize any letters to their lower case form
        letter = letter.lower()

        # We consider some words to be alternate spellings of other words and
        # in those cases we want to normalize the spellings to our preferred
        # spelling.
        if letter == "alpha":
            letter = "a"
        elif letter == "beta":
            letter = "b"
        elif letter in ["c", "pre", "preview"]:
            letter = "rc"
        elif letter in ["rev", "r"]:
            letter = "post"

        return letter, int(number)
    if not letter and number:
        # We assume if we are given a number, but we are not given a letter
        # then this is using the implicit post release syntax (e.g. 1.0-1)
        letter = "post"

        return letter, int(number)

    return None


_local_version_separators = re.compile(r"[\._-]")


def _parse_local_version(local):
    # type: (str) -> Optional[LocalType]
    """
    Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
    """
    if local is not None:
        return tuple(
            part.lower() if not part.isdigit() else int(part)
            for part in _local_version_separators.split(local)
        )
    return None


def _cmpkey(
    epoch,  # type: int
    release,  # type: Tuple[int, ...]
    pre,  # type: Optional[Tuple[str, int]]
    post,  # type: Optional[Tuple[str, int]]
    dev,  # type: Optional[Tuple[str, int]]
    local,  # type: Optional[Tuple[SubLocalType]]
):
    # type: (...) -> CmpKey

    # When we compare a release version, we want to compare it with all of the
    # trailing zeros removed. So we'll use a reverse the list, drop all the now
    # leading zeros until we come to something non zero, then take the rest
    # re-reverse it back into the correct order and make it a tuple and use
    # that for our sorting key.
    _release = tuple(
        reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release))))
    )

    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
    # We'll do this by abusing the pre segment, but we _only_ want to do this
    # if there is not a pre or a post segment. If we have one of those then
    # the normal sorting rules will handle this case correctly.
    if pre is None and post is None and dev is not None:
        _pre = NegativeInfinity  # type: PrePostDevType
    # Versions without a pre-release (except as noted above) should sort after
    # those with one.
    elif pre is None:
        _pre = Infinity
    else:
        _pre = pre

    # Versions without a post segment should sort before those with one.
    if post is None:
        _post = NegativeInfinity  # type: PrePostDevType

    else:
        _post = post

    # Versions without a development segment should sort after those with one.
    if dev is None:
        _dev = Infinity  # type: PrePostDevType

    else:
        _dev = dev

    if local is None:
        # Versions without a local segment should sort before those with one.
        _local = NegativeInfinity  # type: LocalType
    else:
        # Versions with a local segment need that segment parsed to implement
        # the sorting rules in PEP440.
        # - Alpha numeric segments sort before numeric segments
        # - Alpha numeric segments sort lexicographically
        # - Numeric segments sort numerically
        # - Shorter versions sort before longer versions when the prefixes
        #   match exactly
        _local = tuple(
            (i, "") if isinstance(i, int) else (NegativeInfinity, i) for i in local
        )

    return epoch, _release, _pre, _post, _dev, _local
PKH]n@python3.10/site-packages/setuptools/_vendor/packaging/_typing.pynu["""For neatly implementing static typing in packaging.

`mypy` - the static type analysis tool we use - uses the `typing` module, which
provides core functionality fundamental to mypy's functioning.

Generally, `typing` would be imported at runtime and used in that fashion -
it acts as a no-op at runtime and does not have any run-time overhead by
design.

As it turns out, `typing` is not vendorable - it uses separate sources for
Python 2/Python 3. Thus, this codebase can not expect it to be present.
To work around this, mypy allows the typing import to be behind a False-y
optional to prevent it from running at runtime and type-comments can be used
to remove the need for the types to be accessible directly during runtime.

This module provides the False-y guard in a nicely named fashion so that a
curious maintainer can reach here to read this.

In packaging, all static-typing related imports should be guarded as follows:

    from packaging._typing import TYPE_CHECKING

    if TYPE_CHECKING:
        from typing import ...

Ref: https://github.com/python/mypy/issues/3216
"""

__all__ = ["TYPE_CHECKING", "cast"]

# The TYPE_CHECKING constant defined by the typing module is False at runtime
# but True while type checking.
if False:  # pragma: no cover
    from typing import TYPE_CHECKING
else:
    TYPE_CHECKING = False

# typing's cast syntax requires calling typing.cast at runtime, but we don't
# want to import typing at runtime. Here, we inform the type checkers that
# we're importing `typing.cast` as `cast` and re-implement typing.cast's
# runtime behavior in a block that is ignored by type checkers.
if TYPE_CHECKING:  # pragma: no cover
    # not executed at runtime
    from typing import cast
else:
    # executed at runtime
    def cast(type_, value):  # noqa
        return value
PKH]ZkBpython3.10/site-packages/setuptools/_vendor/packaging/__about__.pynu[# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function

__all__ = [
    "__title__",
    "__summary__",
    "__uri__",
    "__version__",
    "__author__",
    "__email__",
    "__license__",
    "__copyright__",
]

__title__ = "packaging"
__summary__ = "Core utilities for Python packages"
__uri__ = "https://github.com/pypa/packaging"

__version__ = "20.4"

__author__ = "Donald Stufft and individual contributors"
__email__ = "donald@stufft.io"

__license__ = "BSD-2-Clause or Apache-2.0"
__copyright__ = "Copyright 2014-2019 %s" % __author__
PKH])||Cpython3.10/site-packages/setuptools/_vendor/packaging/specifiers.pynu[# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function

import abc
import functools
import itertools
import re

from ._compat import string_types, with_metaclass
from ._typing import TYPE_CHECKING
from .utils import canonicalize_version
from .version import Version, LegacyVersion, parse

if TYPE_CHECKING:  # pragma: no cover
    from typing import (
        List,
        Dict,
        Union,
        Iterable,
        Iterator,
        Optional,
        Callable,
        Tuple,
        FrozenSet,
    )

    ParsedVersion = Union[Version, LegacyVersion]
    UnparsedVersion = Union[Version, LegacyVersion, str]
    CallableOperator = Callable[[ParsedVersion, str], bool]


class InvalidSpecifier(ValueError):
    """
    An invalid specifier was found, users should refer to PEP 440.
    """


class BaseSpecifier(with_metaclass(abc.ABCMeta, object)):  # type: ignore
    @abc.abstractmethod
    def __str__(self):
        # type: () -> str
        """
        Returns the str representation of this Specifier like object. This
        should be representative of the Specifier itself.
        """

    @abc.abstractmethod
    def __hash__(self):
        # type: () -> int
        """
        Returns a hash value for this Specifier like object.
        """

    @abc.abstractmethod
    def __eq__(self, other):
        # type: (object) -> bool
        """
        Returns a boolean representing whether or not the two Specifier like
        objects are equal.
        """

    @abc.abstractmethod
    def __ne__(self, other):
        # type: (object) -> bool
        """
        Returns a boolean representing whether or not the two Specifier like
        objects are not equal.
        """

    @abc.abstractproperty
    def prereleases(self):
        # type: () -> Optional[bool]
        """
        Returns whether or not pre-releases as a whole are allowed by this
        specifier.
        """

    @prereleases.setter
    def prereleases(self, value):
        # type: (bool) -> None
        """
        Sets whether or not pre-releases as a whole are allowed by this
        specifier.
        """

    @abc.abstractmethod
    def contains(self, item, prereleases=None):
        # type: (str, Optional[bool]) -> bool
        """
        Determines if the given item is contained within this specifier.
        """

    @abc.abstractmethod
    def filter(self, iterable, prereleases=None):
        # type: (Iterable[UnparsedVersion], Optional[bool]) -> Iterable[UnparsedVersion]
        """
        Takes an iterable of items and filters them so that only items which
        are contained within this specifier are allowed in it.
        """


class _IndividualSpecifier(BaseSpecifier):

    _operators = {}  # type: Dict[str, str]

    def __init__(self, spec="", prereleases=None):
        # type: (str, Optional[bool]) -> None
        match = self._regex.search(spec)
        if not match:
            raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))

        self._spec = (
            match.group("operator").strip(),
            match.group("version").strip(),
        )  # type: Tuple[str, str]

        # Store whether or not this Specifier should accept prereleases
        self._prereleases = prereleases

    def __repr__(self):
        # type: () -> str
        pre = (
            ", prereleases={0!r}".format(self.prereleases)
            if self._prereleases is not None
            else ""
        )

        return "<{0}({1!r}{2})>".format(self.__class__.__name__, str(self), pre)

    def __str__(self):
        # type: () -> str
        return "{0}{1}".format(*self._spec)

    @property
    def _canonical_spec(self):
        # type: () -> Tuple[str, Union[Version, str]]
        return self._spec[0], canonicalize_version(self._spec[1])

    def __hash__(self):
        # type: () -> int
        return hash(self._canonical_spec)

    def __eq__(self, other):
        # type: (object) -> bool
        if isinstance(other, string_types):
            try:
                other = self.__class__(str(other))
            except InvalidSpecifier:
                return NotImplemented
        elif not isinstance(other, self.__class__):
            return NotImplemented

        return self._canonical_spec == other._canonical_spec

    def __ne__(self, other):
        # type: (object) -> bool
        if isinstance(other, string_types):
            try:
                other = self.__class__(str(other))
            except InvalidSpecifier:
                return NotImplemented
        elif not isinstance(other, self.__class__):
            return NotImplemented

        return self._spec != other._spec

    def _get_operator(self, op):
        # type: (str) -> CallableOperator
        operator_callable = getattr(
            self, "_compare_{0}".format(self._operators[op])
        )  # type: CallableOperator
        return operator_callable

    def _coerce_version(self, version):
        # type: (UnparsedVersion) -> ParsedVersion
        if not isinstance(version, (LegacyVersion, Version)):
            version = parse(version)
        return version

    @property
    def operator(self):
        # type: () -> str
        return self._spec[0]

    @property
    def version(self):
        # type: () -> str
        return self._spec[1]

    @property
    def prereleases(self):
        # type: () -> Optional[bool]
        return self._prereleases

    @prereleases.setter
    def prereleases(self, value):
        # type: (bool) -> None
        self._prereleases = value

    def __contains__(self, item):
        # type: (str) -> bool
        return self.contains(item)

    def contains(self, item, prereleases=None):
        # type: (UnparsedVersion, Optional[bool]) -> bool

        # Determine if prereleases are to be allowed or not.
        if prereleases is None:
            prereleases = self.prereleases

        # Normalize item to a Version or LegacyVersion, this allows us to have
        # a shortcut for ``"2.0" in Specifier(">=2")
        normalized_item = self._coerce_version(item)

        # Determine if we should be supporting prereleases in this specifier
        # or not, if we do not support prereleases than we can short circuit
        # logic if this version is a prereleases.
        if normalized_item.is_prerelease and not prereleases:
            return False

        # Actually do the comparison to determine if this item is contained
        # within this Specifier or not.
        operator_callable = self._get_operator(self.operator)  # type: CallableOperator
        return operator_callable(normalized_item, self.version)

    def filter(self, iterable, prereleases=None):
        # type: (Iterable[UnparsedVersion], Optional[bool]) -> Iterable[UnparsedVersion]

        yielded = False
        found_prereleases = []

        kw = {"prereleases": prereleases if prereleases is not None else True}

        # Attempt to iterate over all the values in the iterable and if any of
        # them match, yield them.
        for version in iterable:
            parsed_version = self._coerce_version(version)

            if self.contains(parsed_version, **kw):
                # If our version is a prerelease, and we were not set to allow
                # prereleases, then we'll store it for later incase nothing
                # else matches this specifier.
                if parsed_version.is_prerelease and not (
                    prereleases or self.prereleases
                ):
                    found_prereleases.append(version)
                # Either this is not a prerelease, or we should have been
                # accepting prereleases from the beginning.
                else:
                    yielded = True
                    yield version

        # Now that we've iterated over everything, determine if we've yielded
        # any values, and if we have not and we have any prereleases stored up
        # then we will go ahead and yield the prereleases.
        if not yielded and found_prereleases:
            for version in found_prereleases:
                yield version


class LegacySpecifier(_IndividualSpecifier):

    _regex_str = r"""
        (?P(==|!=|<=|>=|<|>))
        \s*
        (?P
            [^,;\s)]* # Since this is a "legacy" specifier, and the version
                      # string can be just about anything, we match everything
                      # except for whitespace, a semi-colon for marker support,
                      # a closing paren since versions can be enclosed in
                      # them, and a comma since it's a version separator.
        )
        """

    _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)

    _operators = {
        "==": "equal",
        "!=": "not_equal",
        "<=": "less_than_equal",
        ">=": "greater_than_equal",
        "<": "less_than",
        ">": "greater_than",
    }

    def _coerce_version(self, version):
        # type: (Union[ParsedVersion, str]) -> LegacyVersion
        if not isinstance(version, LegacyVersion):
            version = LegacyVersion(str(version))
        return version

    def _compare_equal(self, prospective, spec):
        # type: (LegacyVersion, str) -> bool
        return prospective == self._coerce_version(spec)

    def _compare_not_equal(self, prospective, spec):
        # type: (LegacyVersion, str) -> bool
        return prospective != self._coerce_version(spec)

    def _compare_less_than_equal(self, prospective, spec):
        # type: (LegacyVersion, str) -> bool
        return prospective <= self._coerce_version(spec)

    def _compare_greater_than_equal(self, prospective, spec):
        # type: (LegacyVersion, str) -> bool
        return prospective >= self._coerce_version(spec)

    def _compare_less_than(self, prospective, spec):
        # type: (LegacyVersion, str) -> bool
        return prospective < self._coerce_version(spec)

    def _compare_greater_than(self, prospective, spec):
        # type: (LegacyVersion, str) -> bool
        return prospective > self._coerce_version(spec)


def _require_version_compare(
    fn  # type: (Callable[[Specifier, ParsedVersion, str], bool])
):
    # type: (...) -> Callable[[Specifier, ParsedVersion, str], bool]
    @functools.wraps(fn)
    def wrapped(self, prospective, spec):
        # type: (Specifier, ParsedVersion, str) -> bool
        if not isinstance(prospective, Version):
            return False
        return fn(self, prospective, spec)

    return wrapped


class Specifier(_IndividualSpecifier):

    _regex_str = r"""
        (?P(~=|==|!=|<=|>=|<|>|===))
        (?P
            (?:
                # The identity operators allow for an escape hatch that will
                # do an exact string match of the version you wish to install.
                # This will not be parsed by PEP 440 and we cannot determine
                # any semantic meaning from it. This operator is discouraged
                # but included entirely as an escape hatch.
                (?<====)  # Only match for the identity operator
                \s*
                [^\s]*    # We just match everything, except for whitespace
                          # since we are only testing for strict identity.
            )
            |
            (?:
                # The (non)equality operators allow for wild card and local
                # versions to be specified so we have to define these two
                # operators separately to enable that.
                (?<===|!=)            # Only match for equals and not equals

                \s*
                v?
                (?:[0-9]+!)?          # epoch
                [0-9]+(?:\.[0-9]+)*   # release
                (?:                   # pre release
                    [-_\.]?
                    (a|b|c|rc|alpha|beta|pre|preview)
                    [-_\.]?
                    [0-9]*
                )?
                (?:                   # post release
                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
                )?

                # You cannot use a wild card and a dev or local version
                # together so group them with a | and make them optional.
                (?:
                    (?:[-_\.]?dev[-_\.]?[0-9]*)?         # dev release
                    (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
                    |
                    \.\*  # Wild card syntax of .*
                )?
            )
            |
            (?:
                # The compatible operator requires at least two digits in the
                # release segment.
                (?<=~=)               # Only match for the compatible operator

                \s*
                v?
                (?:[0-9]+!)?          # epoch
                [0-9]+(?:\.[0-9]+)+   # release  (We have a + instead of a *)
                (?:                   # pre release
                    [-_\.]?
                    (a|b|c|rc|alpha|beta|pre|preview)
                    [-_\.]?
                    [0-9]*
                )?
                (?:                                   # post release
                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
                )?
                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
            )
            |
            (?:
                # All other operators only allow a sub set of what the
                # (non)equality operators do. Specifically they do not allow
                # local versions to be specified nor do they allow the prefix
                # matching wild cards.
                (?=": "greater_than_equal",
        "<": "less_than",
        ">": "greater_than",
        "===": "arbitrary",
    }

    @_require_version_compare
    def _compare_compatible(self, prospective, spec):
        # type: (ParsedVersion, str) -> bool

        # Compatible releases have an equivalent combination of >= and ==. That
        # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to
        # implement this in terms of the other specifiers instead of
        # implementing it ourselves. The only thing we need to do is construct
        # the other specifiers.

        # We want everything but the last item in the version, but we want to
        # ignore post and dev releases and we want to treat the pre-release as
        # it's own separate segment.
        prefix = ".".join(
            list(
                itertools.takewhile(
                    lambda x: (not x.startswith("post") and not x.startswith("dev")),
                    _version_split(spec),
                )
            )[:-1]
        )

        # Add the prefix notation to the end of our string
        prefix += ".*"

        return self._get_operator(">=")(prospective, spec) and self._get_operator("==")(
            prospective, prefix
        )

    @_require_version_compare
    def _compare_equal(self, prospective, spec):
        # type: (ParsedVersion, str) -> bool

        # We need special logic to handle prefix matching
        if spec.endswith(".*"):
            # In the case of prefix matching we want to ignore local segment.
            prospective = Version(prospective.public)
            # Split the spec out by dots, and pretend that there is an implicit
            # dot in between a release segment and a pre-release segment.
            split_spec = _version_split(spec[:-2])  # Remove the trailing .*

            # Split the prospective version out by dots, and pretend that there
            # is an implicit dot in between a release segment and a pre-release
            # segment.
            split_prospective = _version_split(str(prospective))

            # Shorten the prospective version to be the same length as the spec
            # so that we can determine if the specifier is a prefix of the
            # prospective version or not.
            shortened_prospective = split_prospective[: len(split_spec)]

            # Pad out our two sides with zeros so that they both equal the same
            # length.
            padded_spec, padded_prospective = _pad_version(
                split_spec, shortened_prospective
            )

            return padded_prospective == padded_spec
        else:
            # Convert our spec string into a Version
            spec_version = Version(spec)

            # If the specifier does not have a local segment, then we want to
            # act as if the prospective version also does not have a local
            # segment.
            if not spec_version.local:
                prospective = Version(prospective.public)

            return prospective == spec_version

    @_require_version_compare
    def _compare_not_equal(self, prospective, spec):
        # type: (ParsedVersion, str) -> bool
        return not self._compare_equal(prospective, spec)

    @_require_version_compare
    def _compare_less_than_equal(self, prospective, spec):
        # type: (ParsedVersion, str) -> bool

        # NB: Local version identifiers are NOT permitted in the version
        # specifier, so local version labels can be universally removed from
        # the prospective version.
        return Version(prospective.public) <= Version(spec)

    @_require_version_compare
    def _compare_greater_than_equal(self, prospective, spec):
        # type: (ParsedVersion, str) -> bool

        # NB: Local version identifiers are NOT permitted in the version
        # specifier, so local version labels can be universally removed from
        # the prospective version.
        return Version(prospective.public) >= Version(spec)

    @_require_version_compare
    def _compare_less_than(self, prospective, spec_str):
        # type: (ParsedVersion, str) -> bool

        # Convert our spec to a Version instance, since we'll want to work with
        # it as a version.
        spec = Version(spec_str)

        # Check to see if the prospective version is less than the spec
        # version. If it's not we can short circuit and just return False now
        # instead of doing extra unneeded work.
        if not prospective < spec:
            return False

        # This special case is here so that, unless the specifier itself
        # includes is a pre-release version, that we do not accept pre-release
        # versions for the version mentioned in the specifier (e.g. <3.1 should
        # not match 3.1.dev0, but should match 3.0.dev0).
        if not spec.is_prerelease and prospective.is_prerelease:
            if Version(prospective.base_version) == Version(spec.base_version):
                return False

        # If we've gotten to here, it means that prospective version is both
        # less than the spec version *and* it's not a pre-release of the same
        # version in the spec.
        return True

    @_require_version_compare
    def _compare_greater_than(self, prospective, spec_str):
        # type: (ParsedVersion, str) -> bool

        # Convert our spec to a Version instance, since we'll want to work with
        # it as a version.
        spec = Version(spec_str)

        # Check to see if the prospective version is greater than the spec
        # version. If it's not we can short circuit and just return False now
        # instead of doing extra unneeded work.
        if not prospective > spec:
            return False

        # This special case is here so that, unless the specifier itself
        # includes is a post-release version, that we do not accept
        # post-release versions for the version mentioned in the specifier
        # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0).
        if not spec.is_postrelease and prospective.is_postrelease:
            if Version(prospective.base_version) == Version(spec.base_version):
                return False

        # Ensure that we do not allow a local version of the version mentioned
        # in the specifier, which is technically greater than, to match.
        if prospective.local is not None:
            if Version(prospective.base_version) == Version(spec.base_version):
                return False

        # If we've gotten to here, it means that prospective version is both
        # greater than the spec version *and* it's not a pre-release of the
        # same version in the spec.
        return True

    def _compare_arbitrary(self, prospective, spec):
        # type: (Version, str) -> bool
        return str(prospective).lower() == str(spec).lower()

    @property
    def prereleases(self):
        # type: () -> bool

        # If there is an explicit prereleases set for this, then we'll just
        # blindly use that.
        if self._prereleases is not None:
            return self._prereleases

        # Look at all of our specifiers and determine if they are inclusive
        # operators, and if they are if they are including an explicit
        # prerelease.
        operator, version = self._spec
        if operator in ["==", ">=", "<=", "~=", "==="]:
            # The == specifier can include a trailing .*, if it does we
            # want to remove before parsing.
            if operator == "==" and version.endswith(".*"):
                version = version[:-2]

            # Parse the version, and if it is a pre-release than this
            # specifier allows pre-releases.
            if parse(version).is_prerelease:
                return True

        return False

    @prereleases.setter
    def prereleases(self, value):
        # type: (bool) -> None
        self._prereleases = value


_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")


def _version_split(version):
    # type: (str) -> List[str]
    result = []  # type: List[str]
    for item in version.split("."):
        match = _prefix_regex.search(item)
        if match:
            result.extend(match.groups())
        else:
            result.append(item)
    return result


def _pad_version(left, right):
    # type: (List[str], List[str]) -> Tuple[List[str], List[str]]
    left_split, right_split = [], []

    # Get the release segment of our versions
    left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left)))
    right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))

    # Get the rest of our versions
    left_split.append(left[len(left_split[0]) :])
    right_split.append(right[len(right_split[0]) :])

    # Insert our padding
    left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0])))
    right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0])))

    return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split)))


class SpecifierSet(BaseSpecifier):
    def __init__(self, specifiers="", prereleases=None):
        # type: (str, Optional[bool]) -> None

        # Split on , to break each individual specifier into it's own item, and
        # strip each item to remove leading/trailing whitespace.
        split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]

        # Parsed each individual specifier, attempting first to make it a
        # Specifier and falling back to a LegacySpecifier.
        parsed = set()
        for specifier in split_specifiers:
            try:
                parsed.add(Specifier(specifier))
            except InvalidSpecifier:
                parsed.add(LegacySpecifier(specifier))

        # Turn our parsed specifiers into a frozen set and save them for later.
        self._specs = frozenset(parsed)

        # Store our prereleases value so we can use it later to determine if
        # we accept prereleases or not.
        self._prereleases = prereleases

    def __repr__(self):
        # type: () -> str
        pre = (
            ", prereleases={0!r}".format(self.prereleases)
            if self._prereleases is not None
            else ""
        )

        return "".format(str(self), pre)

    def __str__(self):
        # type: () -> str
        return ",".join(sorted(str(s) for s in self._specs))

    def __hash__(self):
        # type: () -> int
        return hash(self._specs)

    def __and__(self, other):
        # type: (Union[SpecifierSet, str]) -> SpecifierSet
        if isinstance(other, string_types):
            other = SpecifierSet(other)
        elif not isinstance(other, SpecifierSet):
            return NotImplemented

        specifier = SpecifierSet()
        specifier._specs = frozenset(self._specs | other._specs)

        if self._prereleases is None and other._prereleases is not None:
            specifier._prereleases = other._prereleases
        elif self._prereleases is not None and other._prereleases is None:
            specifier._prereleases = self._prereleases
        elif self._prereleases == other._prereleases:
            specifier._prereleases = self._prereleases
        else:
            raise ValueError(
                "Cannot combine SpecifierSets with True and False prerelease "
                "overrides."
            )

        return specifier

    def __eq__(self, other):
        # type: (object) -> bool
        if isinstance(other, (string_types, _IndividualSpecifier)):
            other = SpecifierSet(str(other))
        elif not isinstance(other, SpecifierSet):
            return NotImplemented

        return self._specs == other._specs

    def __ne__(self, other):
        # type: (object) -> bool
        if isinstance(other, (string_types, _IndividualSpecifier)):
            other = SpecifierSet(str(other))
        elif not isinstance(other, SpecifierSet):
            return NotImplemented

        return self._specs != other._specs

    def __len__(self):
        # type: () -> int
        return len(self._specs)

    def __iter__(self):
        # type: () -> Iterator[FrozenSet[_IndividualSpecifier]]
        return iter(self._specs)

    @property
    def prereleases(self):
        # type: () -> Optional[bool]

        # If we have been given an explicit prerelease modifier, then we'll
        # pass that through here.
        if self._prereleases is not None:
            return self._prereleases

        # If we don't have any specifiers, and we don't have a forced value,
        # then we'll just return None since we don't know if this should have
        # pre-releases or not.
        if not self._specs:
            return None

        # Otherwise we'll see if any of the given specifiers accept
        # prereleases, if any of them do we'll return True, otherwise False.
        return any(s.prereleases for s in self._specs)

    @prereleases.setter
    def prereleases(self, value):
        # type: (bool) -> None
        self._prereleases = value

    def __contains__(self, item):
        # type: (Union[ParsedVersion, str]) -> bool
        return self.contains(item)

    def contains(self, item, prereleases=None):
        # type: (Union[ParsedVersion, str], Optional[bool]) -> bool

        # Ensure that our item is a Version or LegacyVersion instance.
        if not isinstance(item, (LegacyVersion, Version)):
            item = parse(item)

        # Determine if we're forcing a prerelease or not, if we're not forcing
        # one for this particular filter call, then we'll use whatever the
        # SpecifierSet thinks for whether or not we should support prereleases.
        if prereleases is None:
            prereleases = self.prereleases

        # We can determine if we're going to allow pre-releases by looking to
        # see if any of the underlying items supports them. If none of them do
        # and this item is a pre-release then we do not allow it and we can
        # short circuit that here.
        # Note: This means that 1.0.dev1 would not be contained in something
        #       like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0
        if not prereleases and item.is_prerelease:
            return False

        # We simply dispatch to the underlying specs here to make sure that the
        # given version is contained within all of them.
        # Note: This use of all() here means that an empty set of specifiers
        #       will always return True, this is an explicit design decision.
        return all(s.contains(item, prereleases=prereleases) for s in self._specs)

    def filter(
        self,
        iterable,  # type: Iterable[Union[ParsedVersion, str]]
        prereleases=None,  # type: Optional[bool]
    ):
        # type: (...) -> Iterable[Union[ParsedVersion, str]]

        # Determine if we're forcing a prerelease or not, if we're not forcing
        # one for this particular filter call, then we'll use whatever the
        # SpecifierSet thinks for whether or not we should support prereleases.
        if prereleases is None:
            prereleases = self.prereleases

        # If we have any specifiers, then we want to wrap our iterable in the
        # filter method for each one, this will act as a logical AND amongst
        # each specifier.
        if self._specs:
            for spec in self._specs:
                iterable = spec.filter(iterable, prereleases=bool(prereleases))
            return iterable
        # If we do not have any specifiers, then we need to have a rough filter
        # which will filter out any pre-releases, unless there are no final
        # releases, and which will filter out LegacyVersion in general.
        else:
            filtered = []  # type: List[Union[ParsedVersion, str]]
            found_prereleases = []  # type: List[Union[ParsedVersion, str]]

            for item in iterable:
                # Ensure that we some kind of Version class for this item.
                if not isinstance(item, (LegacyVersion, Version)):
                    parsed_version = parse(item)
                else:
                    parsed_version = item

                # Filter out any item which is parsed as a LegacyVersion
                if isinstance(parsed_version, LegacyVersion):
                    continue

                # Store any item which is a pre-release for later unless we've
                # already found a final version or we are accepting prereleases
                if parsed_version.is_prerelease and not prereleases:
                    if not filtered:
                        found_prereleases.append(item)
                else:
                    filtered.append(item)

            # If we've found no items except for pre-releases, then we'll go
            # ahead and use the pre-releases
            if not filtered and found_prereleases and prereleases is None:
                return found_prereleases

            return filtered
PKH]Jf`>python3.10/site-packages/setuptools/_vendor/packaging/utils.pynu[# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function

import re

from ._typing import TYPE_CHECKING, cast
from .version import InvalidVersion, Version

if TYPE_CHECKING:  # pragma: no cover
    from typing import NewType, Union

    NormalizedName = NewType("NormalizedName", str)

_canonicalize_regex = re.compile(r"[-_.]+")


def canonicalize_name(name):
    # type: (str) -> NormalizedName
    # This is taken from PEP 503.
    value = _canonicalize_regex.sub("-", name).lower()
    return cast("NormalizedName", value)


def canonicalize_version(_version):
    # type: (str) -> Union[Version, str]
    """
    This is very similar to Version.__str__, but has one subtle difference
    with the way it handles the release segment.
    """

    try:
        version = Version(_version)
    except InvalidVersion:
        # Legacy versions cannot be normalized
        return _version

    parts = []

    # Epoch
    if version.epoch != 0:
        parts.append("{0}!".format(version.epoch))

    # Release segment
    # NB: This strips trailing '.0's to normalize
    parts.append(re.sub(r"(\.0)+$", "", ".".join(str(x) for x in version.release)))

    # Pre-release
    if version.pre is not None:
        parts.append("".join(str(x) for x in version.pre))

    # Post-release
    if version.post is not None:
        parts.append(".post{0}".format(version.post))

    # Development release
    if version.dev is not None:
        parts.append(".dev{0}".format(version.dev))

    # Local version segment
    if version.local is not None:
        parts.append("+{0}".format(version.local))

    return "".join(parts)
PKH]eD22Apython3.10/site-packages/setuptools/_vendor/packaging/__init__.pynu[# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function

from .__about__ import (
    __author__,
    __copyright__,
    __email__,
    __license__,
    __summary__,
    __title__,
    __uri__,
    __version__,
)

__all__ = [
    "__title__",
    "__summary__",
    "__uri__",
    "__version__",
    "__author__",
    "__email__",
    "__license__",
    "__copyright__",
]
PKH]d%%%%@python3.10/site-packages/setuptools/_vendor/packaging/markers.pynu[# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function

import operator
import os
import platform
import sys

from setuptools.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd
from setuptools.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString
from setuptools.extern.pyparsing import Literal as L  # noqa

from ._compat import string_types
from ._typing import TYPE_CHECKING
from .specifiers import Specifier, InvalidSpecifier

if TYPE_CHECKING:  # pragma: no cover
    from typing import Any, Callable, Dict, List, Optional, Tuple, Union

    Operator = Callable[[str, str], bool]


__all__ = [
    "InvalidMarker",
    "UndefinedComparison",
    "UndefinedEnvironmentName",
    "Marker",
    "default_environment",
]


class InvalidMarker(ValueError):
    """
    An invalid marker was found, users should refer to PEP 508.
    """


class UndefinedComparison(ValueError):
    """
    An invalid operation was attempted on a value that doesn't support it.
    """


class UndefinedEnvironmentName(ValueError):
    """
    A name was attempted to be used that does not exist inside of the
    environment.
    """


class Node(object):
    def __init__(self, value):
        # type: (Any) -> None
        self.value = value

    def __str__(self):
        # type: () -> str
        return str(self.value)

    def __repr__(self):
        # type: () -> str
        return "<{0}({1!r})>".format(self.__class__.__name__, str(self))

    def serialize(self):
        # type: () -> str
        raise NotImplementedError


class Variable(Node):
    def serialize(self):
        # type: () -> str
        return str(self)


class Value(Node):
    def serialize(self):
        # type: () -> str
        return '"{0}"'.format(self)


class Op(Node):
    def serialize(self):
        # type: () -> str
        return str(self)


VARIABLE = (
    L("implementation_version")
    | L("platform_python_implementation")
    | L("implementation_name")
    | L("python_full_version")
    | L("platform_release")
    | L("platform_version")
    | L("platform_machine")
    | L("platform_system")
    | L("python_version")
    | L("sys_platform")
    | L("os_name")
    | L("os.name")  # PEP-345
    | L("sys.platform")  # PEP-345
    | L("platform.version")  # PEP-345
    | L("platform.machine")  # PEP-345
    | L("platform.python_implementation")  # PEP-345
    | L("python_implementation")  # undocumented setuptools legacy
    | L("extra")  # PEP-508
)
ALIASES = {
    "os.name": "os_name",
    "sys.platform": "sys_platform",
    "platform.version": "platform_version",
    "platform.machine": "platform_machine",
    "platform.python_implementation": "platform_python_implementation",
    "python_implementation": "platform_python_implementation",
}
VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0])))

VERSION_CMP = (
    L("===") | L("==") | L(">=") | L("<=") | L("!=") | L("~=") | L(">") | L("<")
)

MARKER_OP = VERSION_CMP | L("not in") | L("in")
MARKER_OP.setParseAction(lambda s, l, t: Op(t[0]))

MARKER_VALUE = QuotedString("'") | QuotedString('"')
MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0]))

BOOLOP = L("and") | L("or")

MARKER_VAR = VARIABLE | MARKER_VALUE

MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR)
MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0]))

LPAREN = L("(").suppress()
RPAREN = L(")").suppress()

MARKER_EXPR = Forward()
MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN)
MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR)

MARKER = stringStart + MARKER_EXPR + stringEnd


def _coerce_parse_result(results):
    # type: (Union[ParseResults, List[Any]]) -> List[Any]
    if isinstance(results, ParseResults):
        return [_coerce_parse_result(i) for i in results]
    else:
        return results


def _format_marker(marker, first=True):
    # type: (Union[List[str], Tuple[Node, ...], str], Optional[bool]) -> str

    assert isinstance(marker, (list, tuple, string_types))

    # Sometimes we have a structure like [[...]] which is a single item list
    # where the single item is itself it's own list. In that case we want skip
    # the rest of this function so that we don't get extraneous () on the
    # outside.
    if (
        isinstance(marker, list)
        and len(marker) == 1
        and isinstance(marker[0], (list, tuple))
    ):
        return _format_marker(marker[0])

    if isinstance(marker, list):
        inner = (_format_marker(m, first=False) for m in marker)
        if first:
            return " ".join(inner)
        else:
            return "(" + " ".join(inner) + ")"
    elif isinstance(marker, tuple):
        return " ".join([m.serialize() for m in marker])
    else:
        return marker


_operators = {
    "in": lambda lhs, rhs: lhs in rhs,
    "not in": lambda lhs, rhs: lhs not in rhs,
    "<": operator.lt,
    "<=": operator.le,
    "==": operator.eq,
    "!=": operator.ne,
    ">=": operator.ge,
    ">": operator.gt,
}  # type: Dict[str, Operator]


def _eval_op(lhs, op, rhs):
    # type: (str, Op, str) -> bool
    try:
        spec = Specifier("".join([op.serialize(), rhs]))
    except InvalidSpecifier:
        pass
    else:
        return spec.contains(lhs)

    oper = _operators.get(op.serialize())  # type: Optional[Operator]
    if oper is None:
        raise UndefinedComparison(
            "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs)
        )

    return oper(lhs, rhs)


class Undefined(object):
    pass


_undefined = Undefined()


def _get_env(environment, name):
    # type: (Dict[str, str], str) -> str
    value = environment.get(name, _undefined)  # type: Union[str, Undefined]

    if isinstance(value, Undefined):
        raise UndefinedEnvironmentName(
            "{0!r} does not exist in evaluation environment.".format(name)
        )

    return value


def _evaluate_markers(markers, environment):
    # type: (List[Any], Dict[str, str]) -> bool
    groups = [[]]  # type: List[List[bool]]

    for marker in markers:
        assert isinstance(marker, (list, tuple, string_types))

        if isinstance(marker, list):
            groups[-1].append(_evaluate_markers(marker, environment))
        elif isinstance(marker, tuple):
            lhs, op, rhs = marker

            if isinstance(lhs, Variable):
                lhs_value = _get_env(environment, lhs.value)
                rhs_value = rhs.value
            else:
                lhs_value = lhs.value
                rhs_value = _get_env(environment, rhs.value)

            groups[-1].append(_eval_op(lhs_value, op, rhs_value))
        else:
            assert marker in ["and", "or"]
            if marker == "or":
                groups.append([])

    return any(all(item) for item in groups)


def format_full_version(info):
    # type: (sys._version_info) -> str
    version = "{0.major}.{0.minor}.{0.micro}".format(info)
    kind = info.releaselevel
    if kind != "final":
        version += kind[0] + str(info.serial)
    return version


def default_environment():
    # type: () -> Dict[str, str]
    if hasattr(sys, "implementation"):
        # Ignoring the `sys.implementation` reference for type checking due to
        # mypy not liking that the attribute doesn't exist in Python 2.7 when
        # run with the `--py27` flag.
        iver = format_full_version(sys.implementation.version)  # type: ignore
        implementation_name = sys.implementation.name  # type: ignore
    else:
        iver = "0"
        implementation_name = ""

    return {
        "implementation_name": implementation_name,
        "implementation_version": iver,
        "os_name": os.name,
        "platform_machine": platform.machine(),
        "platform_release": platform.release(),
        "platform_system": platform.system(),
        "platform_version": platform.version(),
        "python_full_version": platform.python_version(),
        "platform_python_implementation": platform.python_implementation(),
        "python_version": ".".join(platform.python_version_tuple()[:2]),
        "sys_platform": sys.platform,
    }


class Marker(object):
    def __init__(self, marker):
        # type: (str) -> None
        try:
            self._markers = _coerce_parse_result(MARKER.parseString(marker))
        except ParseException as e:
            err_str = "Invalid marker: {0!r}, parse error at {1!r}".format(
                marker, marker[e.loc : e.loc + 8]
            )
            raise InvalidMarker(err_str)

    def __str__(self):
        # type: () -> str
        return _format_marker(self._markers)

    def __repr__(self):
        # type: () -> str
        return "".format(str(self))

    def evaluate(self, environment=None):
        # type: (Optional[Dict[str, str]]) -> bool
        """Evaluate a marker.

        Return the boolean from evaluating the given marker against the
        environment. environment is an optional argument to override all or
        part of the determined environment.

        The environment is determined from the current Python process.
        """
        current_environment = default_environment()
        if environment is not None:
            current_environment.update(environment)

        return _evaluate_markers(self._markers, current_environment)
PKH]]Dpython3.10/site-packages/setuptools/_vendor/packaging/_structures.pynu[# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function


class InfinityType(object):
    def __repr__(self):
        # type: () -> str
        return "Infinity"

    def __hash__(self):
        # type: () -> int
        return hash(repr(self))

    def __lt__(self, other):
        # type: (object) -> bool
        return False

    def __le__(self, other):
        # type: (object) -> bool
        return False

    def __eq__(self, other):
        # type: (object) -> bool
        return isinstance(other, self.__class__)

    def __ne__(self, other):
        # type: (object) -> bool
        return not isinstance(other, self.__class__)

    def __gt__(self, other):
        # type: (object) -> bool
        return True

    def __ge__(self, other):
        # type: (object) -> bool
        return True

    def __neg__(self):
        # type: (object) -> NegativeInfinityType
        return NegativeInfinity


Infinity = InfinityType()


class NegativeInfinityType(object):
    def __repr__(self):
        # type: () -> str
        return "-Infinity"

    def __hash__(self):
        # type: () -> int
        return hash(repr(self))

    def __lt__(self, other):
        # type: (object) -> bool
        return True

    def __le__(self, other):
        # type: (object) -> bool
        return True

    def __eq__(self, other):
        # type: (object) -> bool
        return isinstance(other, self.__class__)

    def __ne__(self, other):
        # type: (object) -> bool
        return not isinstance(other, self.__class__)

    def __gt__(self, other):
        # type: (object) -> bool
        return False

    def __ge__(self, other):
        # type: (object) -> bool
        return False

    def __neg__(self):
        # type: (object) -> InfinityType
        return Infinity


NegativeInfinity = NegativeInfinityType()
PKH]D*;;:python3.10/site-packages/setuptools/_vendor/ordered_set.pynu["""
An OrderedSet is a custom MutableSet that remembers its order, so that every
entry has an index that can be looked up.

Based on a recipe originally posted to ActiveState Recipes by Raymond Hettiger,
and released under the MIT license.
"""
import itertools as it
from collections import deque

try:
    # Python 3
    from collections.abc import MutableSet, Sequence
except ImportError:
    # Python 2.7
    from collections import MutableSet, Sequence

SLICE_ALL = slice(None)
__version__ = "3.1"


def is_iterable(obj):
    """
    Are we being asked to look up a list of things, instead of a single thing?
    We check for the `__iter__` attribute so that this can cover types that
    don't have to be known by this module, such as NumPy arrays.

    Strings, however, should be considered as atomic values to look up, not
    iterables. The same goes for tuples, since they are immutable and therefore
    valid entries.

    We don't need to check for the Python 2 `unicode` type, because it doesn't
    have an `__iter__` attribute anyway.
    """
    return (
        hasattr(obj, "__iter__")
        and not isinstance(obj, str)
        and not isinstance(obj, tuple)
    )


class OrderedSet(MutableSet, Sequence):
    """
    An OrderedSet is a custom MutableSet that remembers its order, so that
    every entry has an index that can be looked up.

    Example:
        >>> OrderedSet([1, 1, 2, 3, 2])
        OrderedSet([1, 2, 3])
    """

    def __init__(self, iterable=None):
        self.items = []
        self.map = {}
        if iterable is not None:
            self |= iterable

    def __len__(self):
        """
        Returns the number of unique elements in the ordered set

        Example:
            >>> len(OrderedSet([]))
            0
            >>> len(OrderedSet([1, 2]))
            2
        """
        return len(self.items)

    def __getitem__(self, index):
        """
        Get the item at a given index.

        If `index` is a slice, you will get back that slice of items, as a
        new OrderedSet.

        If `index` is a list or a similar iterable, you'll get a list of
        items corresponding to those indices. This is similar to NumPy's
        "fancy indexing". The result is not an OrderedSet because you may ask
        for duplicate indices, and the number of elements returned should be
        the number of elements asked for.

        Example:
            >>> oset = OrderedSet([1, 2, 3])
            >>> oset[1]
            2
        """
        if isinstance(index, slice) and index == SLICE_ALL:
            return self.copy()
        elif is_iterable(index):
            return [self.items[i] for i in index]
        elif hasattr(index, "__index__") or isinstance(index, slice):
            result = self.items[index]
            if isinstance(result, list):
                return self.__class__(result)
            else:
                return result
        else:
            raise TypeError("Don't know how to index an OrderedSet by %r" % index)

    def copy(self):
        """
        Return a shallow copy of this object.

        Example:
            >>> this = OrderedSet([1, 2, 3])
            >>> other = this.copy()
            >>> this == other
            True
            >>> this is other
            False
        """
        return self.__class__(self)

    def __getstate__(self):
        if len(self) == 0:
            # The state can't be an empty list.
            # We need to return a truthy value, or else __setstate__ won't be run.
            #
            # This could have been done more gracefully by always putting the state
            # in a tuple, but this way is backwards- and forwards- compatible with
            # previous versions of OrderedSet.
            return (None,)
        else:
            return list(self)

    def __setstate__(self, state):
        if state == (None,):
            self.__init__([])
        else:
            self.__init__(state)

    def __contains__(self, key):
        """
        Test if the item is in this ordered set

        Example:
            >>> 1 in OrderedSet([1, 3, 2])
            True
            >>> 5 in OrderedSet([1, 3, 2])
            False
        """
        return key in self.map

    def add(self, key):
        """
        Add `key` as an item to this OrderedSet, then return its index.

        If `key` is already in the OrderedSet, return the index it already
        had.

        Example:
            >>> oset = OrderedSet()
            >>> oset.append(3)
            0
            >>> print(oset)
            OrderedSet([3])
        """
        if key not in self.map:
            self.map[key] = len(self.items)
            self.items.append(key)
        return self.map[key]

    append = add

    def update(self, sequence):
        """
        Update the set with the given iterable sequence, then return the index
        of the last element inserted.

        Example:
            >>> oset = OrderedSet([1, 2, 3])
            >>> oset.update([3, 1, 5, 1, 4])
            4
            >>> print(oset)
            OrderedSet([1, 2, 3, 5, 4])
        """
        item_index = None
        try:
            for item in sequence:
                item_index = self.add(item)
        except TypeError:
            raise ValueError(
                "Argument needs to be an iterable, got %s" % type(sequence)
            )
        return item_index

    def index(self, key):
        """
        Get the index of a given entry, raising an IndexError if it's not
        present.

        `key` can be an iterable of entries that is not a string, in which case
        this returns a list of indices.

        Example:
            >>> oset = OrderedSet([1, 2, 3])
            >>> oset.index(2)
            1
        """
        if is_iterable(key):
            return [self.index(subkey) for subkey in key]
        return self.map[key]

    # Provide some compatibility with pd.Index
    get_loc = index
    get_indexer = index

    def pop(self):
        """
        Remove and return the last element from the set.

        Raises KeyError if the set is empty.

        Example:
            >>> oset = OrderedSet([1, 2, 3])
            >>> oset.pop()
            3
        """
        if not self.items:
            raise KeyError("Set is empty")

        elem = self.items[-1]
        del self.items[-1]
        del self.map[elem]
        return elem

    def discard(self, key):
        """
        Remove an element.  Do not raise an exception if absent.

        The MutableSet mixin uses this to implement the .remove() method, which
        *does* raise an error when asked to remove a non-existent item.

        Example:
            >>> oset = OrderedSet([1, 2, 3])
            >>> oset.discard(2)
            >>> print(oset)
            OrderedSet([1, 3])
            >>> oset.discard(2)
            >>> print(oset)
            OrderedSet([1, 3])
        """
        if key in self:
            i = self.map[key]
            del self.items[i]
            del self.map[key]
            for k, v in self.map.items():
                if v >= i:
                    self.map[k] = v - 1

    def clear(self):
        """
        Remove all items from this OrderedSet.
        """
        del self.items[:]
        self.map.clear()

    def __iter__(self):
        """
        Example:
            >>> list(iter(OrderedSet([1, 2, 3])))
            [1, 2, 3]
        """
        return iter(self.items)

    def __reversed__(self):
        """
        Example:
            >>> list(reversed(OrderedSet([1, 2, 3])))
            [3, 2, 1]
        """
        return reversed(self.items)

    def __repr__(self):
        if not self:
            return "%s()" % (self.__class__.__name__,)
        return "%s(%r)" % (self.__class__.__name__, list(self))

    def __eq__(self, other):
        """
        Returns true if the containers have the same items. If `other` is a
        Sequence, then order is checked, otherwise it is ignored.

        Example:
            >>> oset = OrderedSet([1, 3, 2])
            >>> oset == [1, 3, 2]
            True
            >>> oset == [1, 2, 3]
            False
            >>> oset == [2, 3]
            False
            >>> oset == OrderedSet([3, 2, 1])
            False
        """
        # In Python 2 deque is not a Sequence, so treat it as one for
        # consistent behavior with Python 3.
        if isinstance(other, (Sequence, deque)):
            # Check that this OrderedSet contains the same elements, in the
            # same order, as the other object.
            return list(self) == list(other)
        try:
            other_as_set = set(other)
        except TypeError:
            # If `other` can't be converted into a set, it's not equal.
            return False
        else:
            return set(self) == other_as_set

    def union(self, *sets):
        """
        Combines all unique items.
        Each items order is defined by its first appearance.

        Example:
            >>> oset = OrderedSet.union(OrderedSet([3, 1, 4, 1, 5]), [1, 3], [2, 0])
            >>> print(oset)
            OrderedSet([3, 1, 4, 5, 2, 0])
            >>> oset.union([8, 9])
            OrderedSet([3, 1, 4, 5, 2, 0, 8, 9])
            >>> oset | {10}
            OrderedSet([3, 1, 4, 5, 2, 0, 10])
        """
        cls = self.__class__ if isinstance(self, OrderedSet) else OrderedSet
        containers = map(list, it.chain([self], sets))
        items = it.chain.from_iterable(containers)
        return cls(items)

    def __and__(self, other):
        # the parent implementation of this is backwards
        return self.intersection(other)

    def intersection(self, *sets):
        """
        Returns elements in common between all sets. Order is defined only
        by the first set.

        Example:
            >>> oset = OrderedSet.intersection(OrderedSet([0, 1, 2, 3]), [1, 2, 3])
            >>> print(oset)
            OrderedSet([1, 2, 3])
            >>> oset.intersection([2, 4, 5], [1, 2, 3, 4])
            OrderedSet([2])
            >>> oset.intersection()
            OrderedSet([1, 2, 3])
        """
        cls = self.__class__ if isinstance(self, OrderedSet) else OrderedSet
        if sets:
            common = set.intersection(*map(set, sets))
            items = (item for item in self if item in common)
        else:
            items = self
        return cls(items)

    def difference(self, *sets):
        """
        Returns all elements that are in this set but not the others.

        Example:
            >>> OrderedSet([1, 2, 3]).difference(OrderedSet([2]))
            OrderedSet([1, 3])
            >>> OrderedSet([1, 2, 3]).difference(OrderedSet([2]), OrderedSet([3]))
            OrderedSet([1])
            >>> OrderedSet([1, 2, 3]) - OrderedSet([2])
            OrderedSet([1, 3])
            >>> OrderedSet([1, 2, 3]).difference()
            OrderedSet([1, 2, 3])
        """
        cls = self.__class__
        if sets:
            other = set.union(*map(set, sets))
            items = (item for item in self if item not in other)
        else:
            items = self
        return cls(items)

    def issubset(self, other):
        """
        Report whether another set contains this set.

        Example:
            >>> OrderedSet([1, 2, 3]).issubset({1, 2})
            False
            >>> OrderedSet([1, 2, 3]).issubset({1, 2, 3, 4})
            True
            >>> OrderedSet([1, 2, 3]).issubset({1, 4, 3, 5})
            False
        """
        if len(self) > len(other):  # Fast check for obvious cases
            return False
        return all(item in other for item in self)

    def issuperset(self, other):
        """
        Report whether this set contains another set.

        Example:
            >>> OrderedSet([1, 2]).issuperset([1, 2, 3])
            False
            >>> OrderedSet([1, 2, 3, 4]).issuperset({1, 2, 3})
            True
            >>> OrderedSet([1, 4, 3, 5]).issuperset({1, 2, 3})
            False
        """
        if len(self) < len(other):  # Fast check for obvious cases
            return False
        return all(item in self for item in other)

    def symmetric_difference(self, other):
        """
        Return the symmetric difference of two OrderedSets as a new set.
        That is, the new set will contain all elements that are in exactly
        one of the sets.

        Their order will be preserved, with elements from `self` preceding
        elements from `other`.

        Example:
            >>> this = OrderedSet([1, 4, 3, 5, 7])
            >>> other = OrderedSet([9, 7, 1, 3, 2])
            >>> this.symmetric_difference(other)
            OrderedSet([4, 5, 9, 2])
        """
        cls = self.__class__ if isinstance(self, OrderedSet) else OrderedSet
        diff1 = cls(self).difference(other)
        diff2 = cls(other).difference(self)
        return diff1.union(diff2)

    def _update_items(self, items):
        """
        Replace the 'items' list of this OrderedSet with a new one, updating
        self.map accordingly.
        """
        self.items = items
        self.map = {item: idx for (idx, item) in enumerate(items)}

    def difference_update(self, *sets):
        """
        Update this OrderedSet to remove items from one or more other sets.

        Example:
            >>> this = OrderedSet([1, 2, 3])
            >>> this.difference_update(OrderedSet([2, 4]))
            >>> print(this)
            OrderedSet([1, 3])

            >>> this = OrderedSet([1, 2, 3, 4, 5])
            >>> this.difference_update(OrderedSet([2, 4]), OrderedSet([1, 4, 6]))
            >>> print(this)
            OrderedSet([3, 5])
        """
        items_to_remove = set()
        for other in sets:
            items_to_remove |= set(other)
        self._update_items([item for item in self.items if item not in items_to_remove])

    def intersection_update(self, other):
        """
        Update this OrderedSet to keep only items in another set, preserving
        their order in this set.

        Example:
            >>> this = OrderedSet([1, 4, 3, 5, 7])
            >>> other = OrderedSet([9, 7, 1, 3, 2])
            >>> this.intersection_update(other)
            >>> print(this)
            OrderedSet([1, 3, 7])
        """
        other = set(other)
        self._update_items([item for item in self.items if item in other])

    def symmetric_difference_update(self, other):
        """
        Update this OrderedSet to remove items from another set, then
        add items from the other set that were not present in this set.

        Example:
            >>> this = OrderedSet([1, 4, 3, 5, 7])
            >>> other = OrderedSet([9, 7, 1, 3, 2])
            >>> this.symmetric_difference_update(other)
            >>> print(this)
            OrderedSet([4, 5, 9, 2])
        """
        items_to_add = [item for item in other if item not in self]
        items_to_remove = set(other)
        self._update_items(
            [item for item in self.items if item not in items_to_remove] + items_to_add
        )
PKH]7python3.10/site-packages/setuptools/_vendor/__init__.pynu[PKH]+xx8python3.10/site-packages/setuptools/_vendor/pyparsing.pynu[# module pyparsing.py
#
# Copyright (c) 2003-2018  Paul T. McGuire
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

__doc__ = \
"""
pyparsing module - Classes and methods to define and execute parsing grammars
=============================================================================

The pyparsing module is an alternative approach to creating and executing simple grammars,
vs. the traditional lex/yacc approach, or the use of regular expressions.  With pyparsing, you
don't need to learn a new syntax for defining grammars or matching expressions - the parsing module
provides a library of classes that you use to construct the grammar directly in Python.

Here is a program to parse "Hello, World!" (or any greeting of the form 
C{", !"}), built up using L{Word}, L{Literal}, and L{And} elements 
(L{'+'} operator gives L{And} expressions, strings are auto-converted to
L{Literal} expressions)::

    from pyparsing import Word, alphas

    # define grammar of a greeting
    greet = Word(alphas) + "," + Word(alphas) + "!"

    hello = "Hello, World!"
    print (hello, "->", greet.parseString(hello))

The program outputs the following::

    Hello, World! -> ['Hello', ',', 'World', '!']

The Python representation of the grammar is quite readable, owing to the self-explanatory
class names, and the use of '+', '|' and '^' operators.

The L{ParseResults} object returned from L{ParserElement.parseString} can be accessed as a nested list, a dictionary, or an
object with named attributes.

The pyparsing module handles some of the problems that are typically vexing when writing text parsers:
 - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello  ,  World  !", etc.)
 - quoted strings
 - embedded comments


Getting Started -
-----------------
Visit the classes L{ParserElement} and L{ParseResults} to see the base classes that most other pyparsing
classes inherit from. Use the docstrings for examples of how to:
 - construct literal match expressions from L{Literal} and L{CaselessLiteral} classes
 - construct character word-group expressions using the L{Word} class
 - see how to create repetitive expressions using L{ZeroOrMore} and L{OneOrMore} classes
 - use L{'+'}, L{'|'}, L{'^'}, and L{'&'} operators to combine simple expressions into more complex ones
 - associate names with your parsed results using L{ParserElement.setResultsName}
 - find some helpful expression short-cuts like L{delimitedList} and L{oneOf}
 - find more useful common expressions in the L{pyparsing_common} namespace class
"""

__version__ = "2.2.1"
__versionTime__ = "18 Sep 2018 00:49 UTC"
__author__ = "Paul McGuire "

import string
from weakref import ref as wkref
import copy
import sys
import warnings
import re
import sre_constants
import collections
import pprint
import traceback
import types
from datetime import datetime

try:
    from _thread import RLock
except ImportError:
    from threading import RLock

try:
    # Python 3
    from collections.abc import Iterable
    from collections.abc import MutableMapping
except ImportError:
    # Python 2.7
    from collections import Iterable
    from collections import MutableMapping

try:
    from collections import OrderedDict as _OrderedDict
except ImportError:
    try:
        from ordereddict import OrderedDict as _OrderedDict
    except ImportError:
        _OrderedDict = None

#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) )

__all__ = [
'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty',
'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal',
'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or',
'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException',
'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException',
'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', 
'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore',
'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col',
'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString',
'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums',
'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno',
'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral',
'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables',
'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', 
'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd',
'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute',
'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass',
'CloseMatch', 'tokenMap', 'pyparsing_common',
]

system_version = tuple(sys.version_info)[:3]
PY_3 = system_version[0] == 3
if PY_3:
    _MAX_INT = sys.maxsize
    basestring = str
    unichr = chr
    _ustr = str

    # build list of single arg builtins, that can be used as parse actions
    singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max]

else:
    _MAX_INT = sys.maxint
    range = xrange

    def _ustr(obj):
        """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries
           str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It
           then < returns the unicode object | encodes it with the default encoding | ... >.
        """
        if isinstance(obj,unicode):
            return obj

        try:
            # If this works, then _ustr(obj) has the same behaviour as str(obj), so
            # it won't break any existing code.
            return str(obj)

        except UnicodeEncodeError:
            # Else encode it
            ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace')
            xmlcharref = Regex(r'&#\d+;')
            xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:])
            return xmlcharref.transformString(ret)

    # build list of single arg builtins, tolerant of Python version, that can be used as parse actions
    singleArgBuiltins = []
    import __builtin__
    for fname in "sum len sorted reversed list tuple set any all min max".split():
        try:
            singleArgBuiltins.append(getattr(__builtin__,fname))
        except AttributeError:
            continue
            
_generatorType = type((y for y in range(1)))
 
def _xml_escape(data):
    """Escape &, <, >, ", ', etc. in a string of data."""

    # ampersand must be replaced first
    from_symbols = '&><"\''
    to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split())
    for from_,to_ in zip(from_symbols, to_symbols):
        data = data.replace(from_, to_)
    return data

class _Constants(object):
    pass

alphas     = string.ascii_uppercase + string.ascii_lowercase
nums       = "0123456789"
hexnums    = nums + "ABCDEFabcdef"
alphanums  = alphas + nums
_bslash    = chr(92)
printables = "".join(c for c in string.printable if c not in string.whitespace)

class ParseBaseException(Exception):
    """base exception class for all parsing runtime exceptions"""
    # Performance tuning: we construct a *lot* of these, so keep this
    # constructor as small and fast as possible
    def __init__( self, pstr, loc=0, msg=None, elem=None ):
        self.loc = loc
        if msg is None:
            self.msg = pstr
            self.pstr = ""
        else:
            self.msg = msg
            self.pstr = pstr
        self.parserElement = elem
        self.args = (pstr, loc, msg)

    @classmethod
    def _from_exception(cls, pe):
        """
        internal factory method to simplify creating one type of ParseException 
        from another - avoids having __init__ signature conflicts among subclasses
        """
        return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement)

    def __getattr__( self, aname ):
        """supported attributes by name are:
            - lineno - returns the line number of the exception text
            - col - returns the column number of the exception text
            - line - returns the line containing the exception text
        """
        if( aname == "lineno" ):
            return lineno( self.loc, self.pstr )
        elif( aname in ("col", "column") ):
            return col( self.loc, self.pstr )
        elif( aname == "line" ):
            return line( self.loc, self.pstr )
        else:
            raise AttributeError(aname)

    def __str__( self ):
        return "%s (at char %d), (line:%d, col:%d)" % \
                ( self.msg, self.loc, self.lineno, self.column )
    def __repr__( self ):
        return _ustr(self)
    def markInputline( self, markerString = ">!<" ):
        """Extracts the exception line from the input string, and marks
           the location of the exception with a special symbol.
        """
        line_str = self.line
        line_column = self.column - 1
        if markerString:
            line_str = "".join((line_str[:line_column],
                                markerString, line_str[line_column:]))
        return line_str.strip()
    def __dir__(self):
        return "lineno col line".split() + dir(type(self))

class ParseException(ParseBaseException):
    """
    Exception thrown when parse expressions don't match class;
    supported attributes by name are:
     - lineno - returns the line number of the exception text
     - col - returns the column number of the exception text
     - line - returns the line containing the exception text
        
    Example::
        try:
            Word(nums).setName("integer").parseString("ABC")
        except ParseException as pe:
            print(pe)
            print("column: {}".format(pe.col))
            
    prints::
       Expected integer (at char 0), (line:1, col:1)
        column: 1
    """
    pass

class ParseFatalException(ParseBaseException):
    """user-throwable exception thrown when inconsistent parse content
       is found; stops all parsing immediately"""
    pass

class ParseSyntaxException(ParseFatalException):
    """just like L{ParseFatalException}, but thrown internally when an
       L{ErrorStop} ('-' operator) indicates that parsing is to stop 
       immediately because an unbacktrackable syntax error has been found"""
    pass

#~ class ReparseException(ParseBaseException):
    #~ """Experimental class - parse actions can raise this exception to cause
       #~ pyparsing to reparse the input string:
        #~ - with a modified input string, and/or
        #~ - with a modified start location
       #~ Set the values of the ReparseException in the constructor, and raise the
       #~ exception in a parse action to cause pyparsing to use the new string/location.
       #~ Setting the values as None causes no change to be made.
       #~ """
    #~ def __init_( self, newstring, restartLoc ):
        #~ self.newParseText = newstring
        #~ self.reparseLoc = restartLoc

class RecursiveGrammarException(Exception):
    """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive"""
    def __init__( self, parseElementList ):
        self.parseElementTrace = parseElementList

    def __str__( self ):
        return "RecursiveGrammarException: %s" % self.parseElementTrace

class _ParseResultsWithOffset(object):
    def __init__(self,p1,p2):
        self.tup = (p1,p2)
    def __getitem__(self,i):
        return self.tup[i]
    def __repr__(self):
        return repr(self.tup[0])
    def setOffset(self,i):
        self.tup = (self.tup[0],i)

class ParseResults(object):
    """
    Structured parse results, to provide multiple means of access to the parsed data:
       - as a list (C{len(results)})
       - by list index (C{results[0], results[1]}, etc.)
       - by attribute (C{results.} - see L{ParserElement.setResultsName})

    Example::
        integer = Word(nums)
        date_str = (integer.setResultsName("year") + '/' 
                        + integer.setResultsName("month") + '/' 
                        + integer.setResultsName("day"))
        # equivalent form:
        # date_str = integer("year") + '/' + integer("month") + '/' + integer("day")

        # parseString returns a ParseResults object
        result = date_str.parseString("1999/12/31")

        def test(s, fn=repr):
            print("%s -> %s" % (s, fn(eval(s))))
        test("list(result)")
        test("result[0]")
        test("result['month']")
        test("result.day")
        test("'month' in result")
        test("'minutes' in result")
        test("result.dump()", str)
    prints::
        list(result) -> ['1999', '/', '12', '/', '31']
        result[0] -> '1999'
        result['month'] -> '12'
        result.day -> '31'
        'month' in result -> True
        'minutes' in result -> False
        result.dump() -> ['1999', '/', '12', '/', '31']
        - day: 31
        - month: 12
        - year: 1999
    """
    def __new__(cls, toklist=None, name=None, asList=True, modal=True ):
        if isinstance(toklist, cls):
            return toklist
        retobj = object.__new__(cls)
        retobj.__doinit = True
        return retobj

    # Performance tuning: we construct a *lot* of these, so keep this
    # constructor as small and fast as possible
    def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ):
        if self.__doinit:
            self.__doinit = False
            self.__name = None
            self.__parent = None
            self.__accumNames = {}
            self.__asList = asList
            self.__modal = modal
            if toklist is None:
                toklist = []
            if isinstance(toklist, list):
                self.__toklist = toklist[:]
            elif isinstance(toklist, _generatorType):
                self.__toklist = list(toklist)
            else:
                self.__toklist = [toklist]
            self.__tokdict = dict()

        if name is not None and name:
            if not modal:
                self.__accumNames[name] = 0
            if isinstance(name,int):
                name = _ustr(name) # will always return a str, but use _ustr for consistency
            self.__name = name
            if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])):
                if isinstance(toklist,basestring):
                    toklist = [ toklist ]
                if asList:
                    if isinstance(toklist,ParseResults):
                        self[name] = _ParseResultsWithOffset(toklist.copy(),0)
                    else:
                        self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0)
                    self[name].__name = name
                else:
                    try:
                        self[name] = toklist[0]
                    except (KeyError,TypeError,IndexError):
                        self[name] = toklist

    def __getitem__( self, i ):
        if isinstance( i, (int,slice) ):
            return self.__toklist[i]
        else:
            if i not in self.__accumNames:
                return self.__tokdict[i][-1][0]
            else:
                return ParseResults([ v[0] for v in self.__tokdict[i] ])

    def __setitem__( self, k, v, isinstance=isinstance ):
        if isinstance(v,_ParseResultsWithOffset):
            self.__tokdict[k] = self.__tokdict.get(k,list()) + [v]
            sub = v[0]
        elif isinstance(k,(int,slice)):
            self.__toklist[k] = v
            sub = v
        else:
            self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)]
            sub = v
        if isinstance(sub,ParseResults):
            sub.__parent = wkref(self)

    def __delitem__( self, i ):
        if isinstance(i,(int,slice)):
            mylen = len( self.__toklist )
            del self.__toklist[i]

            # convert int to slice
            if isinstance(i, int):
                if i < 0:
                    i += mylen
                i = slice(i, i+1)
            # get removed indices
            removed = list(range(*i.indices(mylen)))
            removed.reverse()
            # fixup indices in token dictionary
            for name,occurrences in self.__tokdict.items():
                for j in removed:
                    for k, (value, position) in enumerate(occurrences):
                        occurrences[k] = _ParseResultsWithOffset(value, position - (position > j))
        else:
            del self.__tokdict[i]

    def __contains__( self, k ):
        return k in self.__tokdict

    def __len__( self ): return len( self.__toklist )
    def __bool__(self): return ( not not self.__toklist )
    __nonzero__ = __bool__
    def __iter__( self ): return iter( self.__toklist )
    def __reversed__( self ): return iter( self.__toklist[::-1] )
    def _iterkeys( self ):
        if hasattr(self.__tokdict, "iterkeys"):
            return self.__tokdict.iterkeys()
        else:
            return iter(self.__tokdict)

    def _itervalues( self ):
        return (self[k] for k in self._iterkeys())
            
    def _iteritems( self ):
        return ((k, self[k]) for k in self._iterkeys())

    if PY_3:
        keys = _iterkeys       
        """Returns an iterator of all named result keys (Python 3.x only)."""

        values = _itervalues
        """Returns an iterator of all named result values (Python 3.x only)."""

        items = _iteritems
        """Returns an iterator of all named result key-value tuples (Python 3.x only)."""

    else:
        iterkeys = _iterkeys
        """Returns an iterator of all named result keys (Python 2.x only)."""

        itervalues = _itervalues
        """Returns an iterator of all named result values (Python 2.x only)."""

        iteritems = _iteritems
        """Returns an iterator of all named result key-value tuples (Python 2.x only)."""

        def keys( self ):
            """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x)."""
            return list(self.iterkeys())

        def values( self ):
            """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x)."""
            return list(self.itervalues())
                
        def items( self ):
            """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x)."""
            return list(self.iteritems())

    def haskeys( self ):
        """Since keys() returns an iterator, this method is helpful in bypassing
           code that looks for the existence of any defined results names."""
        return bool(self.__tokdict)
        
    def pop( self, *args, **kwargs):
        """
        Removes and returns item at specified index (default=C{last}).
        Supports both C{list} and C{dict} semantics for C{pop()}. If passed no
        argument or an integer argument, it will use C{list} semantics
        and pop tokens from the list of parsed tokens. If passed a 
        non-integer argument (most likely a string), it will use C{dict}
        semantics and pop the corresponding value from any defined 
        results names. A second default return value argument is 
        supported, just as in C{dict.pop()}.

        Example::
            def remove_first(tokens):
                tokens.pop(0)
            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
            print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321']

            label = Word(alphas)
            patt = label("LABEL") + OneOrMore(Word(nums))
            print(patt.parseString("AAB 123 321").dump())

            # Use pop() in a parse action to remove named result (note that corresponding value is not
            # removed from list form of results)
            def remove_LABEL(tokens):
                tokens.pop("LABEL")
                return tokens
            patt.addParseAction(remove_LABEL)
            print(patt.parseString("AAB 123 321").dump())
        prints::
            ['AAB', '123', '321']
            - LABEL: AAB

            ['AAB', '123', '321']
        """
        if not args:
            args = [-1]
        for k,v in kwargs.items():
            if k == 'default':
                args = (args[0], v)
            else:
                raise TypeError("pop() got an unexpected keyword argument '%s'" % k)
        if (isinstance(args[0], int) or 
                        len(args) == 1 or 
                        args[0] in self):
            index = args[0]
            ret = self[index]
            del self[index]
            return ret
        else:
            defaultvalue = args[1]
            return defaultvalue

    def get(self, key, defaultValue=None):
        """
        Returns named result matching the given key, or if there is no
        such name, then returns the given C{defaultValue} or C{None} if no
        C{defaultValue} is specified.

        Similar to C{dict.get()}.
        
        Example::
            integer = Word(nums)
            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           

            result = date_str.parseString("1999/12/31")
            print(result.get("year")) # -> '1999'
            print(result.get("hour", "not specified")) # -> 'not specified'
            print(result.get("hour")) # -> None
        """
        if key in self:
            return self[key]
        else:
            return defaultValue

    def insert( self, index, insStr ):
        """
        Inserts new element at location index in the list of parsed tokens.
        
        Similar to C{list.insert()}.

        Example::
            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']

            # use a parse action to insert the parse location in the front of the parsed results
            def insert_locn(locn, tokens):
                tokens.insert(0, locn)
            print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321']
        """
        self.__toklist.insert(index, insStr)
        # fixup indices in token dictionary
        for name,occurrences in self.__tokdict.items():
            for k, (value, position) in enumerate(occurrences):
                occurrences[k] = _ParseResultsWithOffset(value, position + (position > index))

    def append( self, item ):
        """
        Add single element to end of ParseResults list of elements.

        Example::
            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
            
            # use a parse action to compute the sum of the parsed integers, and add it to the end
            def append_sum(tokens):
                tokens.append(sum(map(int, tokens)))
            print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444]
        """
        self.__toklist.append(item)

    def extend( self, itemseq ):
        """
        Add sequence of elements to end of ParseResults list of elements.

        Example::
            patt = OneOrMore(Word(alphas))
            
            # use a parse action to append the reverse of the matched strings, to make a palindrome
            def make_palindrome(tokens):
                tokens.extend(reversed([t[::-1] for t in tokens]))
                return ''.join(tokens)
            print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl'
        """
        if isinstance(itemseq, ParseResults):
            self += itemseq
        else:
            self.__toklist.extend(itemseq)

    def clear( self ):
        """
        Clear all elements and results names.
        """
        del self.__toklist[:]
        self.__tokdict.clear()

    def __getattr__( self, name ):
        try:
            return self[name]
        except KeyError:
            return ""
            
        if name in self.__tokdict:
            if name not in self.__accumNames:
                return self.__tokdict[name][-1][0]
            else:
                return ParseResults([ v[0] for v in self.__tokdict[name] ])
        else:
            return ""

    def __add__( self, other ):
        ret = self.copy()
        ret += other
        return ret

    def __iadd__( self, other ):
        if other.__tokdict:
            offset = len(self.__toklist)
            addoffset = lambda a: offset if a<0 else a+offset
            otheritems = other.__tokdict.items()
            otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) )
                                for (k,vlist) in otheritems for v in vlist]
            for k,v in otherdictitems:
                self[k] = v
                if isinstance(v[0],ParseResults):
                    v[0].__parent = wkref(self)
            
        self.__toklist += other.__toklist
        self.__accumNames.update( other.__accumNames )
        return self

    def __radd__(self, other):
        if isinstance(other,int) and other == 0:
            # useful for merging many ParseResults using sum() builtin
            return self.copy()
        else:
            # this may raise a TypeError - so be it
            return other + self
        
    def __repr__( self ):
        return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) )

    def __str__( self ):
        return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']'

    def _asStringList( self, sep='' ):
        out = []
        for item in self.__toklist:
            if out and sep:
                out.append(sep)
            if isinstance( item, ParseResults ):
                out += item._asStringList()
            else:
                out.append( _ustr(item) )
        return out

    def asList( self ):
        """
        Returns the parse results as a nested list of matching tokens, all converted to strings.

        Example::
            patt = OneOrMore(Word(alphas))
            result = patt.parseString("sldkj lsdkj sldkj")
            # even though the result prints in string-like form, it is actually a pyparsing ParseResults
            print(type(result), result) # ->  ['sldkj', 'lsdkj', 'sldkj']
            
            # Use asList() to create an actual list
            result_list = result.asList()
            print(type(result_list), result_list) # ->  ['sldkj', 'lsdkj', 'sldkj']
        """
        return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist]

    def asDict( self ):
        """
        Returns the named parse results as a nested dictionary.

        Example::
            integer = Word(nums)
            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
            
            result = date_str.parseString('12/31/1999')
            print(type(result), repr(result)) # ->  (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]})
            
            result_dict = result.asDict()
            print(type(result_dict), repr(result_dict)) # ->  {'day': '1999', 'year': '12', 'month': '31'}

            # even though a ParseResults supports dict-like access, sometime you just need to have a dict
            import json
            print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable
            print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"}
        """
        if PY_3:
            item_fn = self.items
        else:
            item_fn = self.iteritems
            
        def toItem(obj):
            if isinstance(obj, ParseResults):
                if obj.haskeys():
                    return obj.asDict()
                else:
                    return [toItem(v) for v in obj]
            else:
                return obj
                
        return dict((k,toItem(v)) for k,v in item_fn())

    def copy( self ):
        """
        Returns a new copy of a C{ParseResults} object.
        """
        ret = ParseResults( self.__toklist )
        ret.__tokdict = self.__tokdict.copy()
        ret.__parent = self.__parent
        ret.__accumNames.update( self.__accumNames )
        ret.__name = self.__name
        return ret

    def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ):
        """
        (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.
        """
        nl = "\n"
        out = []
        namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items()
                                                            for v in vlist)
        nextLevelIndent = indent + "  "

        # collapse out indents if formatting is not desired
        if not formatted:
            indent = ""
            nextLevelIndent = ""
            nl = ""

        selfTag = None
        if doctag is not None:
            selfTag = doctag
        else:
            if self.__name:
                selfTag = self.__name

        if not selfTag:
            if namedItemsOnly:
                return ""
            else:
                selfTag = "ITEM"

        out += [ nl, indent, "<", selfTag, ">" ]

        for i,res in enumerate(self.__toklist):
            if isinstance(res,ParseResults):
                if i in namedItems:
                    out += [ res.asXML(namedItems[i],
                                        namedItemsOnly and doctag is None,
                                        nextLevelIndent,
                                        formatted)]
                else:
                    out += [ res.asXML(None,
                                        namedItemsOnly and doctag is None,
                                        nextLevelIndent,
                                        formatted)]
            else:
                # individual token, see if there is a name for it
                resTag = None
                if i in namedItems:
                    resTag = namedItems[i]
                if not resTag:
                    if namedItemsOnly:
                        continue
                    else:
                        resTag = "ITEM"
                xmlBodyText = _xml_escape(_ustr(res))
                out += [ nl, nextLevelIndent, "<", resTag, ">",
                                                xmlBodyText,
                                                "" ]

        out += [ nl, indent, "" ]
        return "".join(out)

    def __lookup(self,sub):
        for k,vlist in self.__tokdict.items():
            for v,loc in vlist:
                if sub is v:
                    return k
        return None

    def getName(self):
        r"""
        Returns the results name for this token expression. Useful when several 
        different expressions might match at a particular location.

        Example::
            integer = Word(nums)
            ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d")
            house_number_expr = Suppress('#') + Word(nums, alphanums)
            user_data = (Group(house_number_expr)("house_number") 
                        | Group(ssn_expr)("ssn")
                        | Group(integer)("age"))
            user_info = OneOrMore(user_data)
            
            result = user_info.parseString("22 111-22-3333 #221B")
            for item in result:
                print(item.getName(), ':', item[0])
        prints::
            age : 22
            ssn : 111-22-3333
            house_number : 221B
        """
        if self.__name:
            return self.__name
        elif self.__parent:
            par = self.__parent()
            if par:
                return par.__lookup(self)
            else:
                return None
        elif (len(self) == 1 and
               len(self.__tokdict) == 1 and
               next(iter(self.__tokdict.values()))[0][1] in (0,-1)):
            return next(iter(self.__tokdict.keys()))
        else:
            return None

    def dump(self, indent='', depth=0, full=True):
        """
        Diagnostic method for listing out the contents of a C{ParseResults}.
        Accepts an optional C{indent} argument so that this string can be embedded
        in a nested display of other data.

        Example::
            integer = Word(nums)
            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
            
            result = date_str.parseString('12/31/1999')
            print(result.dump())
        prints::
            ['12', '/', '31', '/', '1999']
            - day: 1999
            - month: 31
            - year: 12
        """
        out = []
        NL = '\n'
        out.append( indent+_ustr(self.asList()) )
        if full:
            if self.haskeys():
                items = sorted((str(k), v) for k,v in self.items())
                for k,v in items:
                    if out:
                        out.append(NL)
                    out.append( "%s%s- %s: " % (indent,('  '*depth), k) )
                    if isinstance(v,ParseResults):
                        if v:
                            out.append( v.dump(indent,depth+1) )
                        else:
                            out.append(_ustr(v))
                    else:
                        out.append(repr(v))
            elif any(isinstance(vv,ParseResults) for vv in self):
                v = self
                for i,vv in enumerate(v):
                    if isinstance(vv,ParseResults):
                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),vv.dump(indent,depth+1) ))
                    else:
                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),_ustr(vv)))
            
        return "".join(out)

    def pprint(self, *args, **kwargs):
        """
        Pretty-printer for parsed results as a list, using the C{pprint} module.
        Accepts additional positional or keyword args as defined for the 
        C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint})

        Example::
            ident = Word(alphas, alphanums)
            num = Word(nums)
            func = Forward()
            term = ident | num | Group('(' + func + ')')
            func <<= ident + Group(Optional(delimitedList(term)))
            result = func.parseString("fna a,b,(fnb c,d,200),100")
            result.pprint(width=40)
        prints::
            ['fna',
             ['a',
              'b',
              ['(', 'fnb', ['c', 'd', '200'], ')'],
              '100']]
        """
        pprint.pprint(self.asList(), *args, **kwargs)

    # add support for pickle protocol
    def __getstate__(self):
        return ( self.__toklist,
                 ( self.__tokdict.copy(),
                   self.__parent is not None and self.__parent() or None,
                   self.__accumNames,
                   self.__name ) )

    def __setstate__(self,state):
        self.__toklist = state[0]
        (self.__tokdict,
         par,
         inAccumNames,
         self.__name) = state[1]
        self.__accumNames = {}
        self.__accumNames.update(inAccumNames)
        if par is not None:
            self.__parent = wkref(par)
        else:
            self.__parent = None

    def __getnewargs__(self):
        return self.__toklist, self.__name, self.__asList, self.__modal

    def __dir__(self):
        return (dir(type(self)) + list(self.keys()))

MutableMapping.register(ParseResults)

def col (loc,strg):
    """Returns current column within a string, counting newlines as line separators.
   The first column is number 1.

   Note: the default parsing behavior is to expand tabs in the input string
   before starting the parsing process.  See L{I{ParserElement.parseString}} for more information
   on parsing strings containing C{}s, and suggested methods to maintain a
   consistent view of the parsed string, the parse location, and line and column
   positions within the parsed string.
   """
    s = strg
    return 1 if 0} for more information
   on parsing strings containing C{}s, and suggested methods to maintain a
   consistent view of the parsed string, the parse location, and line and column
   positions within the parsed string.
   """
    return strg.count("\n",0,loc) + 1

def line( loc, strg ):
    """Returns the line of text containing loc within a string, counting newlines as line separators.
       """
    lastCR = strg.rfind("\n", 0, loc)
    nextCR = strg.find("\n", loc)
    if nextCR >= 0:
        return strg[lastCR+1:nextCR]
    else:
        return strg[lastCR+1:]

def _defaultStartDebugAction( instring, loc, expr ):
    print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )))

def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ):
    print ("Matched " + _ustr(expr) + " -> " + str(toks.asList()))

def _defaultExceptionDebugAction( instring, loc, expr, exc ):
    print ("Exception raised:" + _ustr(exc))

def nullDebugAction(*args):
    """'Do-nothing' debug action, to suppress debugging output during parsing."""
    pass

# Only works on Python 3.x - nonlocal is toxic to Python 2 installs
#~ 'decorator to trim function calls to match the arity of the target'
#~ def _trim_arity(func, maxargs=3):
    #~ if func in singleArgBuiltins:
        #~ return lambda s,l,t: func(t)
    #~ limit = 0
    #~ foundArity = False
    #~ def wrapper(*args):
        #~ nonlocal limit,foundArity
        #~ while 1:
            #~ try:
                #~ ret = func(*args[limit:])
                #~ foundArity = True
                #~ return ret
            #~ except TypeError:
                #~ if limit == maxargs or foundArity:
                    #~ raise
                #~ limit += 1
                #~ continue
    #~ return wrapper

# this version is Python 2.x-3.x cross-compatible
'decorator to trim function calls to match the arity of the target'
def _trim_arity(func, maxargs=2):
    if func in singleArgBuiltins:
        return lambda s,l,t: func(t)
    limit = [0]
    foundArity = [False]
    
    # traceback return data structure changed in Py3.5 - normalize back to plain tuples
    if system_version[:2] >= (3,5):
        def extract_stack(limit=0):
            # special handling for Python 3.5.0 - extra deep call stack by 1
            offset = -3 if system_version == (3,5,0) else -2
            frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset]
            return [frame_summary[:2]]
        def extract_tb(tb, limit=0):
            frames = traceback.extract_tb(tb, limit=limit)
            frame_summary = frames[-1]
            return [frame_summary[:2]]
    else:
        extract_stack = traceback.extract_stack
        extract_tb = traceback.extract_tb
    
    # synthesize what would be returned by traceback.extract_stack at the call to 
    # user's parse action 'func', so that we don't incur call penalty at parse time
    
    LINE_DIFF = 6
    # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND 
    # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!!
    this_line = extract_stack(limit=2)[-1]
    pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF)

    def wrapper(*args):
        while 1:
            try:
                ret = func(*args[limit[0]:])
                foundArity[0] = True
                return ret
            except TypeError:
                # re-raise TypeErrors if they did not come from our arity testing
                if foundArity[0]:
                    raise
                else:
                    try:
                        tb = sys.exc_info()[-1]
                        if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth:
                            raise
                    finally:
                        del tb

                if limit[0] <= maxargs:
                    limit[0] += 1
                    continue
                raise

    # copy func name to wrapper for sensible debug output
    func_name = ""
    try:
        func_name = getattr(func, '__name__', 
                            getattr(func, '__class__').__name__)
    except Exception:
        func_name = str(func)
    wrapper.__name__ = func_name

    return wrapper

class ParserElement(object):
    """Abstract base level parser element class."""
    DEFAULT_WHITE_CHARS = " \n\t\r"
    verbose_stacktrace = False

    @staticmethod
    def setDefaultWhitespaceChars( chars ):
        r"""
        Overrides the default whitespace chars

        Example::
            # default whitespace chars are space,  and newline
            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def', 'ghi', 'jkl']
            
            # change to just treat newline as significant
            ParserElement.setDefaultWhitespaceChars(" \t")
            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def']
        """
        ParserElement.DEFAULT_WHITE_CHARS = chars

    @staticmethod
    def inlineLiteralsUsing(cls):
        """
        Set class to be used for inclusion of string literals into a parser.
        
        Example::
            # default literal class used is Literal
            integer = Word(nums)
            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           

            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']


            # change to Suppress
            ParserElement.inlineLiteralsUsing(Suppress)
            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           

            date_str.parseString("1999/12/31")  # -> ['1999', '12', '31']
        """
        ParserElement._literalStringClass = cls

    def __init__( self, savelist=False ):
        self.parseAction = list()
        self.failAction = None
        #~ self.name = ""  # don't define self.name, let subclasses try/except upcall
        self.strRepr = None
        self.resultsName = None
        self.saveAsList = savelist
        self.skipWhitespace = True
        self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
        self.copyDefaultWhiteChars = True
        self.mayReturnEmpty = False # used when checking for left-recursion
        self.keepTabs = False
        self.ignoreExprs = list()
        self.debug = False
        self.streamlined = False
        self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index
        self.errmsg = ""
        self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all)
        self.debugActions = ( None, None, None ) #custom debug actions
        self.re = None
        self.callPreparse = True # used to avoid redundant calls to preParse
        self.callDuringTry = False

    def copy( self ):
        """
        Make a copy of this C{ParserElement}.  Useful for defining different parse actions
        for the same parsing pattern, using copies of the original parse element.
        
        Example::
            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
            integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K")
            integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
            
            print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M"))
        prints::
            [5120, 100, 655360, 268435456]
        Equivalent form of C{expr.copy()} is just C{expr()}::
            integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
        """
        cpy = copy.copy( self )
        cpy.parseAction = self.parseAction[:]
        cpy.ignoreExprs = self.ignoreExprs[:]
        if self.copyDefaultWhiteChars:
            cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
        return cpy

    def setName( self, name ):
        """
        Define name for this expression, makes debugging and exception messages clearer.
        
        Example::
            Word(nums).parseString("ABC")  # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1)
            Word(nums).setName("integer").parseString("ABC")  # -> Exception: Expected integer (at char 0), (line:1, col:1)
        """
        self.name = name
        self.errmsg = "Expected " + self.name
        if hasattr(self,"exception"):
            self.exception.msg = self.errmsg
        return self

    def setResultsName( self, name, listAllMatches=False ):
        """
        Define name for referencing matching tokens as a nested attribute
        of the returned parse results.
        NOTE: this returns a *copy* of the original C{ParserElement} object;
        this is so that the client can define a basic element, such as an
        integer, and reference it in multiple places with different names.

        You can also set results names using the abbreviated syntax,
        C{expr("name")} in place of C{expr.setResultsName("name")} - 
        see L{I{__call__}<__call__>}.

        Example::
            date_str = (integer.setResultsName("year") + '/' 
                        + integer.setResultsName("month") + '/' 
                        + integer.setResultsName("day"))

            # equivalent form:
            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
        """
        newself = self.copy()
        if name.endswith("*"):
            name = name[:-1]
            listAllMatches=True
        newself.resultsName = name
        newself.modalResults = not listAllMatches
        return newself

    def setBreak(self,breakFlag = True):
        """Method to invoke the Python pdb debugger when this element is
           about to be parsed. Set C{breakFlag} to True to enable, False to
           disable.
        """
        if breakFlag:
            _parseMethod = self._parse
            def breaker(instring, loc, doActions=True, callPreParse=True):
                import pdb
                pdb.set_trace()
                return _parseMethod( instring, loc, doActions, callPreParse )
            breaker._originalParseMethod = _parseMethod
            self._parse = breaker
        else:
            if hasattr(self._parse,"_originalParseMethod"):
                self._parse = self._parse._originalParseMethod
        return self

    def setParseAction( self, *fns, **kwargs ):
        """
        Define one or more actions to perform when successfully matching parse element definition.
        Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)},
        C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where:
         - s   = the original string being parsed (see note below)
         - loc = the location of the matching substring
         - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object
        If the functions in fns modify the tokens, they can return them as the return
        value from fn, and the modified list of tokens will replace the original.
        Otherwise, fn does not need to return any value.

        Optional keyword arguments:
         - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing

        Note: the default parsing behavior is to expand tabs in the input string
        before starting the parsing process.  See L{I{parseString}} for more information
        on parsing strings containing C{}s, and suggested methods to maintain a
        consistent view of the parsed string, the parse location, and line and column
        positions within the parsed string.
        
        Example::
            integer = Word(nums)
            date_str = integer + '/' + integer + '/' + integer

            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']

            # use parse action to convert to ints at parse time
            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
            date_str = integer + '/' + integer + '/' + integer

            # note that integer fields are now ints, not strings
            date_str.parseString("1999/12/31")  # -> [1999, '/', 12, '/', 31]
        """
        self.parseAction = list(map(_trim_arity, list(fns)))
        self.callDuringTry = kwargs.get("callDuringTry", False)
        return self

    def addParseAction( self, *fns, **kwargs ):
        """
        Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}}.
        
        See examples in L{I{copy}}.
        """
        self.parseAction += list(map(_trim_arity, list(fns)))
        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
        return self

    def addCondition(self, *fns, **kwargs):
        """Add a boolean predicate function to expression's list of parse actions. See 
        L{I{setParseAction}} for function call signatures. Unlike C{setParseAction}, 
        functions passed to C{addCondition} need to return boolean success/fail of the condition.

        Optional keyword arguments:
         - message = define a custom message to be used in the raised exception
         - fatal   = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException
         
        Example::
            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
            year_int = integer.copy()
            year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later")
            date_str = year_int + '/' + integer + '/' + integer

            result = date_str.parseString("1999/12/31")  # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1)
        """
        msg = kwargs.get("message", "failed user-defined condition")
        exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException
        for fn in fns:
            def pa(s,l,t):
                if not bool(_trim_arity(fn)(s,l,t)):
                    raise exc_type(s,l,msg)
            self.parseAction.append(pa)
        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
        return self

    def setFailAction( self, fn ):
        """Define action to perform if parsing fails at this expression.
           Fail acton fn is a callable function that takes the arguments
           C{fn(s,loc,expr,err)} where:
            - s = string being parsed
            - loc = location where expression match was attempted and failed
            - expr = the parse expression that failed
            - err = the exception thrown
           The function returns no value.  It may throw C{L{ParseFatalException}}
           if it is desired to stop parsing immediately."""
        self.failAction = fn
        return self

    def _skipIgnorables( self, instring, loc ):
        exprsFound = True
        while exprsFound:
            exprsFound = False
            for e in self.ignoreExprs:
                try:
                    while 1:
                        loc,dummy = e._parse( instring, loc )
                        exprsFound = True
                except ParseException:
                    pass
        return loc

    def preParse( self, instring, loc ):
        if self.ignoreExprs:
            loc = self._skipIgnorables( instring, loc )

        if self.skipWhitespace:
            wt = self.whiteChars
            instrlen = len(instring)
            while loc < instrlen and instring[loc] in wt:
                loc += 1

        return loc

    def parseImpl( self, instring, loc, doActions=True ):
        return loc, []

    def postParse( self, instring, loc, tokenlist ):
        return tokenlist

    #~ @profile
    def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ):
        debugging = ( self.debug ) #and doActions )

        if debugging or self.failAction:
            #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))
            if (self.debugActions[0] ):
                self.debugActions[0]( instring, loc, self )
            if callPreParse and self.callPreparse:
                preloc = self.preParse( instring, loc )
            else:
                preloc = loc
            tokensStart = preloc
            try:
                try:
                    loc,tokens = self.parseImpl( instring, preloc, doActions )
                except IndexError:
                    raise ParseException( instring, len(instring), self.errmsg, self )
            except ParseBaseException as err:
                #~ print ("Exception raised:", err)
                if self.debugActions[2]:
                    self.debugActions[2]( instring, tokensStart, self, err )
                if self.failAction:
                    self.failAction( instring, tokensStart, self, err )
                raise
        else:
            if callPreParse and self.callPreparse:
                preloc = self.preParse( instring, loc )
            else:
                preloc = loc
            tokensStart = preloc
            if self.mayIndexError or preloc >= len(instring):
                try:
                    loc,tokens = self.parseImpl( instring, preloc, doActions )
                except IndexError:
                    raise ParseException( instring, len(instring), self.errmsg, self )
            else:
                loc,tokens = self.parseImpl( instring, preloc, doActions )

        tokens = self.postParse( instring, loc, tokens )

        retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults )
        if self.parseAction and (doActions or self.callDuringTry):
            if debugging:
                try:
                    for fn in self.parseAction:
                        tokens = fn( instring, tokensStart, retTokens )
                        if tokens is not None:
                            retTokens = ParseResults( tokens,
                                                      self.resultsName,
                                                      asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
                                                      modal=self.modalResults )
                except ParseBaseException as err:
                    #~ print "Exception raised in user parse action:", err
                    if (self.debugActions[2] ):
                        self.debugActions[2]( instring, tokensStart, self, err )
                    raise
            else:
                for fn in self.parseAction:
                    tokens = fn( instring, tokensStart, retTokens )
                    if tokens is not None:
                        retTokens = ParseResults( tokens,
                                                  self.resultsName,
                                                  asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
                                                  modal=self.modalResults )
        if debugging:
            #~ print ("Matched",self,"->",retTokens.asList())
            if (self.debugActions[1] ):
                self.debugActions[1]( instring, tokensStart, loc, self, retTokens )

        return loc, retTokens

    def tryParse( self, instring, loc ):
        try:
            return self._parse( instring, loc, doActions=False )[0]
        except ParseFatalException:
            raise ParseException( instring, loc, self.errmsg, self)
    
    def canParseNext(self, instring, loc):
        try:
            self.tryParse(instring, loc)
        except (ParseException, IndexError):
            return False
        else:
            return True

    class _UnboundedCache(object):
        def __init__(self):
            cache = {}
            self.not_in_cache = not_in_cache = object()

            def get(self, key):
                return cache.get(key, not_in_cache)

            def set(self, key, value):
                cache[key] = value

            def clear(self):
                cache.clear()
                
            def cache_len(self):
                return len(cache)

            self.get = types.MethodType(get, self)
            self.set = types.MethodType(set, self)
            self.clear = types.MethodType(clear, self)
            self.__len__ = types.MethodType(cache_len, self)

    if _OrderedDict is not None:
        class _FifoCache(object):
            def __init__(self, size):
                self.not_in_cache = not_in_cache = object()

                cache = _OrderedDict()

                def get(self, key):
                    return cache.get(key, not_in_cache)

                def set(self, key, value):
                    cache[key] = value
                    while len(cache) > size:
                        try:
                            cache.popitem(False)
                        except KeyError:
                            pass

                def clear(self):
                    cache.clear()

                def cache_len(self):
                    return len(cache)

                self.get = types.MethodType(get, self)
                self.set = types.MethodType(set, self)
                self.clear = types.MethodType(clear, self)
                self.__len__ = types.MethodType(cache_len, self)

    else:
        class _FifoCache(object):
            def __init__(self, size):
                self.not_in_cache = not_in_cache = object()

                cache = {}
                key_fifo = collections.deque([], size)

                def get(self, key):
                    return cache.get(key, not_in_cache)

                def set(self, key, value):
                    cache[key] = value
                    while len(key_fifo) > size:
                        cache.pop(key_fifo.popleft(), None)
                    key_fifo.append(key)

                def clear(self):
                    cache.clear()
                    key_fifo.clear()

                def cache_len(self):
                    return len(cache)

                self.get = types.MethodType(get, self)
                self.set = types.MethodType(set, self)
                self.clear = types.MethodType(clear, self)
                self.__len__ = types.MethodType(cache_len, self)

    # argument cache for optimizing repeated calls when backtracking through recursive expressions
    packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail
    packrat_cache_lock = RLock()
    packrat_cache_stats = [0, 0]

    # this method gets repeatedly called during backtracking with the same arguments -
    # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression
    def _parseCache( self, instring, loc, doActions=True, callPreParse=True ):
        HIT, MISS = 0, 1
        lookup = (self, instring, loc, callPreParse, doActions)
        with ParserElement.packrat_cache_lock:
            cache = ParserElement.packrat_cache
            value = cache.get(lookup)
            if value is cache.not_in_cache:
                ParserElement.packrat_cache_stats[MISS] += 1
                try:
                    value = self._parseNoCache(instring, loc, doActions, callPreParse)
                except ParseBaseException as pe:
                    # cache a copy of the exception, without the traceback
                    cache.set(lookup, pe.__class__(*pe.args))
                    raise
                else:
                    cache.set(lookup, (value[0], value[1].copy()))
                    return value
            else:
                ParserElement.packrat_cache_stats[HIT] += 1
                if isinstance(value, Exception):
                    raise value
                return (value[0], value[1].copy())

    _parse = _parseNoCache

    @staticmethod
    def resetCache():
        ParserElement.packrat_cache.clear()
        ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats)

    _packratEnabled = False
    @staticmethod
    def enablePackrat(cache_size_limit=128):
        """Enables "packrat" parsing, which adds memoizing to the parsing logic.
           Repeated parse attempts at the same string location (which happens
           often in many complex grammars) can immediately return a cached value,
           instead of re-executing parsing/validating code.  Memoizing is done of
           both valid results and parsing exceptions.
           
           Parameters:
            - cache_size_limit - (default=C{128}) - if an integer value is provided
              will limit the size of the packrat cache; if None is passed, then
              the cache size will be unbounded; if 0 is passed, the cache will
              be effectively disabled.
            
           This speedup may break existing programs that use parse actions that
           have side-effects.  For this reason, packrat parsing is disabled when
           you first import pyparsing.  To activate the packrat feature, your
           program must call the class method C{ParserElement.enablePackrat()}.  If
           your program uses C{psyco} to "compile as you go", you must call
           C{enablePackrat} before calling C{psyco.full()}.  If you do not do this,
           Python will crash.  For best results, call C{enablePackrat()} immediately
           after importing pyparsing.
           
           Example::
               import pyparsing
               pyparsing.ParserElement.enablePackrat()
        """
        if not ParserElement._packratEnabled:
            ParserElement._packratEnabled = True
            if cache_size_limit is None:
                ParserElement.packrat_cache = ParserElement._UnboundedCache()
            else:
                ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit)
            ParserElement._parse = ParserElement._parseCache

    def parseString( self, instring, parseAll=False ):
        """
        Execute the parse expression with the given string.
        This is the main interface to the client code, once the complete
        expression has been built.

        If you want the grammar to require that the entire input string be
        successfully parsed, then set C{parseAll} to True (equivalent to ending
        the grammar with C{L{StringEnd()}}).

        Note: C{parseString} implicitly calls C{expandtabs()} on the input string,
        in order to report proper column numbers in parse actions.
        If the input string contains tabs and
        the grammar uses parse actions that use the C{loc} argument to index into the
        string being parsed, you can ensure you have a consistent view of the input
        string by:
         - calling C{parseWithTabs} on your grammar before calling C{parseString}
           (see L{I{parseWithTabs}})
         - define your parse action using the full C{(s,loc,toks)} signature, and
           reference the input string using the parse action's C{s} argument
         - explicitly expand the tabs in your input string before calling
           C{parseString}
        
        Example::
            Word('a').parseString('aaaaabaaa')  # -> ['aaaaa']
            Word('a').parseString('aaaaabaaa', parseAll=True)  # -> Exception: Expected end of text
        """
        ParserElement.resetCache()
        if not self.streamlined:
            self.streamline()
            #~ self.saveAsList = True
        for e in self.ignoreExprs:
            e.streamline()
        if not self.keepTabs:
            instring = instring.expandtabs()
        try:
            loc, tokens = self._parse( instring, 0 )
            if parseAll:
                loc = self.preParse( instring, loc )
                se = Empty() + StringEnd()
                se._parse( instring, loc )
        except ParseBaseException as exc:
            if ParserElement.verbose_stacktrace:
                raise
            else:
                # catch and re-raise exception from here, clears out pyparsing internal stack trace
                raise exc
        else:
            return tokens

    def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ):
        """
        Scan the input string for expression matches.  Each match will return the
        matching tokens, start location, and end location.  May be called with optional
        C{maxMatches} argument, to clip scanning after 'n' matches are found.  If
        C{overlap} is specified, then overlapping matches will be reported.

        Note that the start and end locations are reported relative to the string
        being parsed.  See L{I{parseString}} for more information on parsing
        strings with embedded tabs.

        Example::
            source = "sldjf123lsdjjkf345sldkjf879lkjsfd987"
            print(source)
            for tokens,start,end in Word(alphas).scanString(source):
                print(' '*start + '^'*(end-start))
                print(' '*start + tokens[0])
        
        prints::
        
            sldjf123lsdjjkf345sldkjf879lkjsfd987
            ^^^^^
            sldjf
                    ^^^^^^^
                    lsdjjkf
                              ^^^^^^
                              sldkjf
                                       ^^^^^^
                                       lkjsfd
        """
        if not self.streamlined:
            self.streamline()
        for e in self.ignoreExprs:
            e.streamline()

        if not self.keepTabs:
            instring = _ustr(instring).expandtabs()
        instrlen = len(instring)
        loc = 0
        preparseFn = self.preParse
        parseFn = self._parse
        ParserElement.resetCache()
        matches = 0
        try:
            while loc <= instrlen and matches < maxMatches:
                try:
                    preloc = preparseFn( instring, loc )
                    nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
                except ParseException:
                    loc = preloc+1
                else:
                    if nextLoc > loc:
                        matches += 1
                        yield tokens, preloc, nextLoc
                        if overlap:
                            nextloc = preparseFn( instring, loc )
                            if nextloc > loc:
                                loc = nextLoc
                            else:
                                loc += 1
                        else:
                            loc = nextLoc
                    else:
                        loc = preloc+1
        except ParseBaseException as exc:
            if ParserElement.verbose_stacktrace:
                raise
            else:
                # catch and re-raise exception from here, clears out pyparsing internal stack trace
                raise exc

    def transformString( self, instring ):
        """
        Extension to C{L{scanString}}, to modify matching text with modified tokens that may
        be returned from a parse action.  To use C{transformString}, define a grammar and
        attach a parse action to it that modifies the returned token list.
        Invoking C{transformString()} on a target string will then scan for matches,
        and replace the matched text patterns according to the logic in the parse
        action.  C{transformString()} returns the resulting transformed string.
        
        Example::
            wd = Word(alphas)
            wd.setParseAction(lambda toks: toks[0].title())
            
            print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york."))
        Prints::
            Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York.
        """
        out = []
        lastE = 0
        # force preservation of s, to minimize unwanted transformation of string, and to
        # keep string locs straight between transformString and scanString
        self.keepTabs = True
        try:
            for t,s,e in self.scanString( instring ):
                out.append( instring[lastE:s] )
                if t:
                    if isinstance(t,ParseResults):
                        out += t.asList()
                    elif isinstance(t,list):
                        out += t
                    else:
                        out.append(t)
                lastE = e
            out.append(instring[lastE:])
            out = [o for o in out if o]
            return "".join(map(_ustr,_flatten(out)))
        except ParseBaseException as exc:
            if ParserElement.verbose_stacktrace:
                raise
            else:
                # catch and re-raise exception from here, clears out pyparsing internal stack trace
                raise exc

    def searchString( self, instring, maxMatches=_MAX_INT ):
        """
        Another extension to C{L{scanString}}, simplifying the access to the tokens found
        to match the given parse expression.  May be called with optional
        C{maxMatches} argument, to clip searching after 'n' matches are found.
        
        Example::
            # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters
            cap_word = Word(alphas.upper(), alphas.lower())
            
            print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))

            # the sum() builtin can be used to merge results into a single ParseResults object
            print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")))
        prints::
            [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']]
            ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity']
        """
        try:
            return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ])
        except ParseBaseException as exc:
            if ParserElement.verbose_stacktrace:
                raise
            else:
                # catch and re-raise exception from here, clears out pyparsing internal stack trace
                raise exc

    def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False):
        """
        Generator method to split a string using the given expression as a separator.
        May be called with optional C{maxsplit} argument, to limit the number of splits;
        and the optional C{includeSeparators} argument (default=C{False}), if the separating
        matching text should be included in the split results.
        
        Example::        
            punc = oneOf(list(".,;:/-!?"))
            print(list(punc.split("This, this?, this sentence, is badly punctuated!")))
        prints::
            ['This', ' this', '', ' this sentence', ' is badly punctuated', '']
        """
        splits = 0
        last = 0
        for t,s,e in self.scanString(instring, maxMatches=maxsplit):
            yield instring[last:s]
            if includeSeparators:
                yield t[0]
            last = e
        yield instring[last:]

    def __add__(self, other ):
        """
        Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement
        converts them to L{Literal}s by default.
        
        Example::
            greet = Word(alphas) + "," + Word(alphas) + "!"
            hello = "Hello, World!"
            print (hello, "->", greet.parseString(hello))
        Prints::
            Hello, World! -> ['Hello', ',', 'World', '!']
        """
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        if not isinstance( other, ParserElement ):
            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
                    SyntaxWarning, stacklevel=2)
            return None
        return And( [ self, other ] )

    def __radd__(self, other ):
        """
        Implementation of + operator when left operand is not a C{L{ParserElement}}
        """
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        if not isinstance( other, ParserElement ):
            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
                    SyntaxWarning, stacklevel=2)
            return None
        return other + self

    def __sub__(self, other):
        """
        Implementation of - operator, returns C{L{And}} with error stop
        """
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        if not isinstance( other, ParserElement ):
            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
                    SyntaxWarning, stacklevel=2)
            return None
        return self + And._ErrorStop() + other

    def __rsub__(self, other ):
        """
        Implementation of - operator when left operand is not a C{L{ParserElement}}
        """
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        if not isinstance( other, ParserElement ):
            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
                    SyntaxWarning, stacklevel=2)
            return None
        return other - self

    def __mul__(self,other):
        """
        Implementation of * operator, allows use of C{expr * 3} in place of
        C{expr + expr + expr}.  Expressions may also me multiplied by a 2-integer
        tuple, similar to C{{min,max}} multipliers in regular expressions.  Tuples
        may also include C{None} as in:
         - C{expr*(n,None)} or C{expr*(n,)} is equivalent
              to C{expr*n + L{ZeroOrMore}(expr)}
              (read as "at least n instances of C{expr}")
         - C{expr*(None,n)} is equivalent to C{expr*(0,n)}
              (read as "0 to n instances of C{expr}")
         - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)}
         - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)}

        Note that C{expr*(None,n)} does not raise an exception if
        more than n exprs exist in the input stream; that is,
        C{expr*(None,n)} does not enforce a maximum number of expr
        occurrences.  If this behavior is desired, then write
        C{expr*(None,n) + ~expr}
        """
        if isinstance(other,int):
            minElements, optElements = other,0
        elif isinstance(other,tuple):
            other = (other + (None, None))[:2]
            if other[0] is None:
                other = (0, other[1])
            if isinstance(other[0],int) and other[1] is None:
                if other[0] == 0:
                    return ZeroOrMore(self)
                if other[0] == 1:
                    return OneOrMore(self)
                else:
                    return self*other[0] + ZeroOrMore(self)
            elif isinstance(other[0],int) and isinstance(other[1],int):
                minElements, optElements = other
                optElements -= minElements
            else:
                raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1]))
        else:
            raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other))

        if minElements < 0:
            raise ValueError("cannot multiply ParserElement by negative value")
        if optElements < 0:
            raise ValueError("second tuple value must be greater or equal to first tuple value")
        if minElements == optElements == 0:
            raise ValueError("cannot multiply ParserElement by 0 or (0,0)")

        if (optElements):
            def makeOptionalList(n):
                if n>1:
                    return Optional(self + makeOptionalList(n-1))
                else:
                    return Optional(self)
            if minElements:
                if minElements == 1:
                    ret = self + makeOptionalList(optElements)
                else:
                    ret = And([self]*minElements) + makeOptionalList(optElements)
            else:
                ret = makeOptionalList(optElements)
        else:
            if minElements == 1:
                ret = self
            else:
                ret = And([self]*minElements)
        return ret

    def __rmul__(self, other):
        return self.__mul__(other)

    def __or__(self, other ):
        """
        Implementation of | operator - returns C{L{MatchFirst}}
        """
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        if not isinstance( other, ParserElement ):
            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
                    SyntaxWarning, stacklevel=2)
            return None
        return MatchFirst( [ self, other ] )

    def __ror__(self, other ):
        """
        Implementation of | operator when left operand is not a C{L{ParserElement}}
        """
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        if not isinstance( other, ParserElement ):
            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
                    SyntaxWarning, stacklevel=2)
            return None
        return other | self

    def __xor__(self, other ):
        """
        Implementation of ^ operator - returns C{L{Or}}
        """
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        if not isinstance( other, ParserElement ):
            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
                    SyntaxWarning, stacklevel=2)
            return None
        return Or( [ self, other ] )

    def __rxor__(self, other ):
        """
        Implementation of ^ operator when left operand is not a C{L{ParserElement}}
        """
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        if not isinstance( other, ParserElement ):
            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
                    SyntaxWarning, stacklevel=2)
            return None
        return other ^ self

    def __and__(self, other ):
        """
        Implementation of & operator - returns C{L{Each}}
        """
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        if not isinstance( other, ParserElement ):
            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
                    SyntaxWarning, stacklevel=2)
            return None
        return Each( [ self, other ] )

    def __rand__(self, other ):
        """
        Implementation of & operator when left operand is not a C{L{ParserElement}}
        """
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        if not isinstance( other, ParserElement ):
            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
                    SyntaxWarning, stacklevel=2)
            return None
        return other & self

    def __invert__( self ):
        """
        Implementation of ~ operator - returns C{L{NotAny}}
        """
        return NotAny( self )

    def __call__(self, name=None):
        """
        Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}.
        
        If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be
        passed as C{True}.
           
        If C{name} is omitted, same as calling C{L{copy}}.

        Example::
            # these are equivalent
            userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno")
            userdata = Word(alphas)("name") + Word(nums+"-")("socsecno")             
        """
        if name is not None:
            return self.setResultsName(name)
        else:
            return self.copy()

    def suppress( self ):
        """
        Suppresses the output of this C{ParserElement}; useful to keep punctuation from
        cluttering up returned output.
        """
        return Suppress( self )

    def leaveWhitespace( self ):
        """
        Disables the skipping of whitespace before matching the characters in the
        C{ParserElement}'s defined pattern.  This is normally only used internally by
        the pyparsing module, but may be needed in some whitespace-sensitive grammars.
        """
        self.skipWhitespace = False
        return self

    def setWhitespaceChars( self, chars ):
        """
        Overrides the default whitespace chars
        """
        self.skipWhitespace = True
        self.whiteChars = chars
        self.copyDefaultWhiteChars = False
        return self

    def parseWithTabs( self ):
        """
        Overrides default behavior to expand C{}s to spaces before parsing the input string.
        Must be called before C{parseString} when the input grammar contains elements that
        match C{} characters.
        """
        self.keepTabs = True
        return self

    def ignore( self, other ):
        """
        Define expression to be ignored (e.g., comments) while doing pattern
        matching; may be called repeatedly, to define multiple comment or other
        ignorable patterns.
        
        Example::
            patt = OneOrMore(Word(alphas))
            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj']
            
            patt.ignore(cStyleComment)
            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd']
        """
        if isinstance(other, basestring):
            other = Suppress(other)

        if isinstance( other, Suppress ):
            if other not in self.ignoreExprs:
                self.ignoreExprs.append(other)
        else:
            self.ignoreExprs.append( Suppress( other.copy() ) )
        return self

    def setDebugActions( self, startAction, successAction, exceptionAction ):
        """
        Enable display of debugging messages while doing pattern matching.
        """
        self.debugActions = (startAction or _defaultStartDebugAction,
                             successAction or _defaultSuccessDebugAction,
                             exceptionAction or _defaultExceptionDebugAction)
        self.debug = True
        return self

    def setDebug( self, flag=True ):
        """
        Enable display of debugging messages while doing pattern matching.
        Set C{flag} to True to enable, False to disable.

        Example::
            wd = Word(alphas).setName("alphaword")
            integer = Word(nums).setName("numword")
            term = wd | integer
            
            # turn on debugging for wd
            wd.setDebug()

            OneOrMore(term).parseString("abc 123 xyz 890")
        
        prints::
            Match alphaword at loc 0(1,1)
            Matched alphaword -> ['abc']
            Match alphaword at loc 3(1,4)
            Exception raised:Expected alphaword (at char 4), (line:1, col:5)
            Match alphaword at loc 7(1,8)
            Matched alphaword -> ['xyz']
            Match alphaword at loc 11(1,12)
            Exception raised:Expected alphaword (at char 12), (line:1, col:13)
            Match alphaword at loc 15(1,16)
            Exception raised:Expected alphaword (at char 15), (line:1, col:16)

        The output shown is that produced by the default debug actions - custom debug actions can be
        specified using L{setDebugActions}. Prior to attempting
        to match the C{wd} expression, the debugging message C{"Match  at loc (,)"}
        is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"}
        message is shown. Also note the use of L{setName} to assign a human-readable name to the expression,
        which makes debugging and exception messages easier to understand - for instance, the default
        name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}.
        """
        if flag:
            self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction )
        else:
            self.debug = False
        return self

    def __str__( self ):
        return self.name

    def __repr__( self ):
        return _ustr(self)

    def streamline( self ):
        self.streamlined = True
        self.strRepr = None
        return self

    def checkRecursion( self, parseElementList ):
        pass

    def validate( self, validateTrace=[] ):
        """
        Check defined expressions for valid structure, check for infinite recursive definitions.
        """
        self.checkRecursion( [] )

    def parseFile( self, file_or_filename, parseAll=False ):
        """
        Execute the parse expression on the given file or filename.
        If a filename is specified (instead of a file object),
        the entire file is opened, read, and closed before parsing.
        """
        try:
            file_contents = file_or_filename.read()
        except AttributeError:
            with open(file_or_filename, "r") as f:
                file_contents = f.read()
        try:
            return self.parseString(file_contents, parseAll)
        except ParseBaseException as exc:
            if ParserElement.verbose_stacktrace:
                raise
            else:
                # catch and re-raise exception from here, clears out pyparsing internal stack trace
                raise exc

    def __eq__(self,other):
        if isinstance(other, ParserElement):
            return self is other or vars(self) == vars(other)
        elif isinstance(other, basestring):
            return self.matches(other)
        else:
            return super(ParserElement,self)==other

    def __ne__(self,other):
        return not (self == other)

    def __hash__(self):
        return hash(id(self))

    def __req__(self,other):
        return self == other

    def __rne__(self,other):
        return not (self == other)

    def matches(self, testString, parseAll=True):
        """
        Method for quick testing of a parser against a test string. Good for simple 
        inline microtests of sub expressions while building up larger parser.
           
        Parameters:
         - testString - to test against this expression for a match
         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests
            
        Example::
            expr = Word(nums)
            assert expr.matches("100")
        """
        try:
            self.parseString(_ustr(testString), parseAll=parseAll)
            return True
        except ParseBaseException:
            return False
                
    def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False):
        """
        Execute the parse expression on a series of test strings, showing each
        test, the parsed results or where the parse failed. Quick and easy way to
        run a parse expression against a list of sample strings.
           
        Parameters:
         - tests - a list of separate test strings, or a multiline string of test strings
         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests           
         - comment - (default=C{'#'}) - expression for indicating embedded comments in the test 
              string; pass None to disable comment filtering
         - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline;
              if False, only dump nested list
         - printResults - (default=C{True}) prints test output to stdout
         - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing

        Returns: a (success, results) tuple, where success indicates that all tests succeeded
        (or failed if C{failureTests} is True), and the results contain a list of lines of each 
        test's output
        
        Example::
            number_expr = pyparsing_common.number.copy()

            result = number_expr.runTests('''
                # unsigned integer
                100
                # negative integer
                -100
                # float with scientific notation
                6.02e23
                # integer with scientific notation
                1e-12
                ''')
            print("Success" if result[0] else "Failed!")

            result = number_expr.runTests('''
                # stray character
                100Z
                # missing leading digit before '.'
                -.100
                # too many '.'
                3.14.159
                ''', failureTests=True)
            print("Success" if result[0] else "Failed!")
        prints::
            # unsigned integer
            100
            [100]

            # negative integer
            -100
            [-100]

            # float with scientific notation
            6.02e23
            [6.02e+23]

            # integer with scientific notation
            1e-12
            [1e-12]

            Success
            
            # stray character
            100Z
               ^
            FAIL: Expected end of text (at char 3), (line:1, col:4)

            # missing leading digit before '.'
            -.100
            ^
            FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1)

            # too many '.'
            3.14.159
                ^
            FAIL: Expected end of text (at char 4), (line:1, col:5)

            Success

        Each test string must be on a single line. If you want to test a string that spans multiple
        lines, create a test like this::

            expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines")
        
        (Note that this is a raw string literal, you must include the leading 'r'.)
        """
        if isinstance(tests, basestring):
            tests = list(map(str.strip, tests.rstrip().splitlines()))
        if isinstance(comment, basestring):
            comment = Literal(comment)
        allResults = []
        comments = []
        success = True
        for t in tests:
            if comment is not None and comment.matches(t, False) or comments and not t:
                comments.append(t)
                continue
            if not t:
                continue
            out = ['\n'.join(comments), t]
            comments = []
            try:
                t = t.replace(r'\n','\n')
                result = self.parseString(t, parseAll=parseAll)
                out.append(result.dump(full=fullDump))
                success = success and not failureTests
            except ParseBaseException as pe:
                fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else ""
                if '\n' in t:
                    out.append(line(pe.loc, t))
                    out.append(' '*(col(pe.loc,t)-1) + '^' + fatal)
                else:
                    out.append(' '*pe.loc + '^' + fatal)
                out.append("FAIL: " + str(pe))
                success = success and failureTests
                result = pe
            except Exception as exc:
                out.append("FAIL-EXCEPTION: " + str(exc))
                success = success and failureTests
                result = exc

            if printResults:
                if fullDump:
                    out.append('')
                print('\n'.join(out))

            allResults.append((t, result))
        
        return success, allResults

        
class Token(ParserElement):
    """
    Abstract C{ParserElement} subclass, for defining atomic matching patterns.
    """
    def __init__( self ):
        super(Token,self).__init__( savelist=False )


class Empty(Token):
    """
    An empty token, will always match.
    """
    def __init__( self ):
        super(Empty,self).__init__()
        self.name = "Empty"
        self.mayReturnEmpty = True
        self.mayIndexError = False


class NoMatch(Token):
    """
    A token that will never match.
    """
    def __init__( self ):
        super(NoMatch,self).__init__()
        self.name = "NoMatch"
        self.mayReturnEmpty = True
        self.mayIndexError = False
        self.errmsg = "Unmatchable token"

    def parseImpl( self, instring, loc, doActions=True ):
        raise ParseException(instring, loc, self.errmsg, self)


class Literal(Token):
    """
    Token to exactly match a specified string.
    
    Example::
        Literal('blah').parseString('blah')  # -> ['blah']
        Literal('blah').parseString('blahfooblah')  # -> ['blah']
        Literal('blah').parseString('bla')  # -> Exception: Expected "blah"
    
    For case-insensitive matching, use L{CaselessLiteral}.
    
    For keyword matching (force word break before and after the matched string),
    use L{Keyword} or L{CaselessKeyword}.
    """
    def __init__( self, matchString ):
        super(Literal,self).__init__()
        self.match = matchString
        self.matchLen = len(matchString)
        try:
            self.firstMatchChar = matchString[0]
        except IndexError:
            warnings.warn("null string passed to Literal; use Empty() instead",
                            SyntaxWarning, stacklevel=2)
            self.__class__ = Empty
        self.name = '"%s"' % _ustr(self.match)
        self.errmsg = "Expected " + self.name
        self.mayReturnEmpty = False
        self.mayIndexError = False

    # Performance tuning: this routine gets called a *lot*
    # if this is a single character match string  and the first character matches,
    # short-circuit as quickly as possible, and avoid calling startswith
    #~ @profile
    def parseImpl( self, instring, loc, doActions=True ):
        if (instring[loc] == self.firstMatchChar and
            (self.matchLen==1 or instring.startswith(self.match,loc)) ):
            return loc+self.matchLen, self.match
        raise ParseException(instring, loc, self.errmsg, self)
_L = Literal
ParserElement._literalStringClass = Literal

class Keyword(Token):
    """
    Token to exactly match a specified string as a keyword, that is, it must be
    immediately followed by a non-keyword character.  Compare with C{L{Literal}}:
     - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}.
     - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'}
    Accepts two optional constructor arguments in addition to the keyword string:
     - C{identChars} is a string of characters that would be valid identifier characters,
          defaulting to all alphanumerics + "_" and "$"
     - C{caseless} allows case-insensitive matching, default is C{False}.
       
    Example::
        Keyword("start").parseString("start")  # -> ['start']
        Keyword("start").parseString("starting")  # -> Exception

    For case-insensitive matching, use L{CaselessKeyword}.
    """
    DEFAULT_KEYWORD_CHARS = alphanums+"_$"

    def __init__( self, matchString, identChars=None, caseless=False ):
        super(Keyword,self).__init__()
        if identChars is None:
            identChars = Keyword.DEFAULT_KEYWORD_CHARS
        self.match = matchString
        self.matchLen = len(matchString)
        try:
            self.firstMatchChar = matchString[0]
        except IndexError:
            warnings.warn("null string passed to Keyword; use Empty() instead",
                            SyntaxWarning, stacklevel=2)
        self.name = '"%s"' % self.match
        self.errmsg = "Expected " + self.name
        self.mayReturnEmpty = False
        self.mayIndexError = False
        self.caseless = caseless
        if caseless:
            self.caselessmatch = matchString.upper()
            identChars = identChars.upper()
        self.identChars = set(identChars)

    def parseImpl( self, instring, loc, doActions=True ):
        if self.caseless:
            if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
                 (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and
                 (loc == 0 or instring[loc-1].upper() not in self.identChars) ):
                return loc+self.matchLen, self.match
        else:
            if (instring[loc] == self.firstMatchChar and
                (self.matchLen==1 or instring.startswith(self.match,loc)) and
                (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and
                (loc == 0 or instring[loc-1] not in self.identChars) ):
                return loc+self.matchLen, self.match
        raise ParseException(instring, loc, self.errmsg, self)

    def copy(self):
        c = super(Keyword,self).copy()
        c.identChars = Keyword.DEFAULT_KEYWORD_CHARS
        return c

    @staticmethod
    def setDefaultKeywordChars( chars ):
        """Overrides the default Keyword chars
        """
        Keyword.DEFAULT_KEYWORD_CHARS = chars

class CaselessLiteral(Literal):
    """
    Token to match a specified string, ignoring case of letters.
    Note: the matched results will always be in the case of the given
    match string, NOT the case of the input text.

    Example::
        OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD']
        
    (Contrast with example for L{CaselessKeyword}.)
    """
    def __init__( self, matchString ):
        super(CaselessLiteral,self).__init__( matchString.upper() )
        # Preserve the defining literal.
        self.returnString = matchString
        self.name = "'%s'" % self.returnString
        self.errmsg = "Expected " + self.name

    def parseImpl( self, instring, loc, doActions=True ):
        if instring[ loc:loc+self.matchLen ].upper() == self.match:
            return loc+self.matchLen, self.returnString
        raise ParseException(instring, loc, self.errmsg, self)

class CaselessKeyword(Keyword):
    """
    Caseless version of L{Keyword}.

    Example::
        OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD']
        
    (Contrast with example for L{CaselessLiteral}.)
    """
    def __init__( self, matchString, identChars=None ):
        super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True )

    def parseImpl( self, instring, loc, doActions=True ):
        if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
             (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ):
            return loc+self.matchLen, self.match
        raise ParseException(instring, loc, self.errmsg, self)

class CloseMatch(Token):
    """
    A variation on L{Literal} which matches "close" matches, that is, 
    strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters:
     - C{match_string} - string to be matched
     - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match
    
    The results from a successful parse will contain the matched text from the input string and the following named results:
     - C{mismatches} - a list of the positions within the match_string where mismatches were found
     - C{original} - the original match_string used to compare against the input string
    
    If C{mismatches} is an empty list, then the match was an exact match.
    
    Example::
        patt = CloseMatch("ATCATCGAATGGA")
        patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']})
        patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1)

        # exact match
        patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']})

        # close match allowing up to 2 mismatches
        patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2)
        patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']})
    """
    def __init__(self, match_string, maxMismatches=1):
        super(CloseMatch,self).__init__()
        self.name = match_string
        self.match_string = match_string
        self.maxMismatches = maxMismatches
        self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches)
        self.mayIndexError = False
        self.mayReturnEmpty = False

    def parseImpl( self, instring, loc, doActions=True ):
        start = loc
        instrlen = len(instring)
        maxloc = start + len(self.match_string)

        if maxloc <= instrlen:
            match_string = self.match_string
            match_stringloc = 0
            mismatches = []
            maxMismatches = self.maxMismatches

            for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)):
                src,mat = s_m
                if src != mat:
                    mismatches.append(match_stringloc)
                    if len(mismatches) > maxMismatches:
                        break
            else:
                loc = match_stringloc + 1
                results = ParseResults([instring[start:loc]])
                results['original'] = self.match_string
                results['mismatches'] = mismatches
                return loc, results

        raise ParseException(instring, loc, self.errmsg, self)


class Word(Token):
    """
    Token for matching words composed of allowed character sets.
    Defined with string containing all allowed initial characters,
    an optional string containing allowed body characters (if omitted,
    defaults to the initial character set), and an optional minimum,
    maximum, and/or exact length.  The default value for C{min} is 1 (a
    minimum value < 1 is not valid); the default values for C{max} and C{exact}
    are 0, meaning no maximum or exact length restriction. An optional
    C{excludeChars} parameter can list characters that might be found in 
    the input C{bodyChars} string; useful to define a word of all printables
    except for one or two characters, for instance.
    
    L{srange} is useful for defining custom character set strings for defining 
    C{Word} expressions, using range notation from regular expression character sets.
    
    A common mistake is to use C{Word} to match a specific literal string, as in 
    C{Word("Address")}. Remember that C{Word} uses the string argument to define
    I{sets} of matchable characters. This expression would match "Add", "AAA",
    "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'.
    To match an exact literal string, use L{Literal} or L{Keyword}.

    pyparsing includes helper strings for building Words:
     - L{alphas}
     - L{nums}
     - L{alphanums}
     - L{hexnums}
     - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.)
     - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.)
     - L{printables} (any non-whitespace character)

    Example::
        # a word composed of digits
        integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9"))
        
        # a word with a leading capital, and zero or more lowercase
        capital_word = Word(alphas.upper(), alphas.lower())

        # hostnames are alphanumeric, with leading alpha, and '-'
        hostname = Word(alphas, alphanums+'-')
        
        # roman numeral (not a strict parser, accepts invalid mix of characters)
        roman = Word("IVXLCDM")
        
        # any string of non-whitespace characters, except for ','
        csv_value = Word(printables, excludeChars=",")
    """
    def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ):
        super(Word,self).__init__()
        if excludeChars:
            initChars = ''.join(c for c in initChars if c not in excludeChars)
            if bodyChars:
                bodyChars = ''.join(c for c in bodyChars if c not in excludeChars)
        self.initCharsOrig = initChars
        self.initChars = set(initChars)
        if bodyChars :
            self.bodyCharsOrig = bodyChars
            self.bodyChars = set(bodyChars)
        else:
            self.bodyCharsOrig = initChars
            self.bodyChars = set(initChars)

        self.maxSpecified = max > 0

        if min < 1:
            raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted")

        self.minLen = min

        if max > 0:
            self.maxLen = max
        else:
            self.maxLen = _MAX_INT

        if exact > 0:
            self.maxLen = exact
            self.minLen = exact

        self.name = _ustr(self)
        self.errmsg = "Expected " + self.name
        self.mayIndexError = False
        self.asKeyword = asKeyword

        if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0):
            if self.bodyCharsOrig == self.initCharsOrig:
                self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig)
            elif len(self.initCharsOrig) == 1:
                self.reString = "%s[%s]*" % \
                                      (re.escape(self.initCharsOrig),
                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
            else:
                self.reString = "[%s][%s]*" % \
                                      (_escapeRegexRangeChars(self.initCharsOrig),
                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
            if self.asKeyword:
                self.reString = r"\b"+self.reString+r"\b"
            try:
                self.re = re.compile( self.reString )
            except Exception:
                self.re = None

    def parseImpl( self, instring, loc, doActions=True ):
        if self.re:
            result = self.re.match(instring,loc)
            if not result:
                raise ParseException(instring, loc, self.errmsg, self)

            loc = result.end()
            return loc, result.group()

        if not(instring[ loc ] in self.initChars):
            raise ParseException(instring, loc, self.errmsg, self)

        start = loc
        loc += 1
        instrlen = len(instring)
        bodychars = self.bodyChars
        maxloc = start + self.maxLen
        maxloc = min( maxloc, instrlen )
        while loc < maxloc and instring[loc] in bodychars:
            loc += 1

        throwException = False
        if loc - start < self.minLen:
            throwException = True
        if self.maxSpecified and loc < instrlen and instring[loc] in bodychars:
            throwException = True
        if self.asKeyword:
            if (start>0 and instring[start-1] in bodychars) or (loc4:
                    return s[:4]+"..."
                else:
                    return s

            if ( self.initCharsOrig != self.bodyCharsOrig ):
                self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) )
            else:
                self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig)

        return self.strRepr


class Regex(Token):
    r"""
    Token for matching strings that match a given regular expression.
    Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module.
    If the given regex contains named groups (defined using C{(?P...)}), these will be preserved as 
    named parse results.

    Example::
        realnum = Regex(r"[+-]?\d+\.\d*")
        date = Regex(r'(?P\d{4})-(?P\d\d?)-(?P\d\d?)')
        # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression
        roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})")
    """
    compiledREtype = type(re.compile("[A-Z]"))
    def __init__( self, pattern, flags=0):
        """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags."""
        super(Regex,self).__init__()

        if isinstance(pattern, basestring):
            if not pattern:
                warnings.warn("null string passed to Regex; use Empty() instead",
                        SyntaxWarning, stacklevel=2)

            self.pattern = pattern
            self.flags = flags

            try:
                self.re = re.compile(self.pattern, self.flags)
                self.reString = self.pattern
            except sre_constants.error:
                warnings.warn("invalid pattern (%s) passed to Regex" % pattern,
                    SyntaxWarning, stacklevel=2)
                raise

        elif isinstance(pattern, Regex.compiledREtype):
            self.re = pattern
            self.pattern = \
            self.reString = str(pattern)
            self.flags = flags
            
        else:
            raise ValueError("Regex may only be constructed with a string or a compiled RE object")

        self.name = _ustr(self)
        self.errmsg = "Expected " + self.name
        self.mayIndexError = False
        self.mayReturnEmpty = True

    def parseImpl( self, instring, loc, doActions=True ):
        result = self.re.match(instring,loc)
        if not result:
            raise ParseException(instring, loc, self.errmsg, self)

        loc = result.end()
        d = result.groupdict()
        ret = ParseResults(result.group())
        if d:
            for k in d:
                ret[k] = d[k]
        return loc,ret

    def __str__( self ):
        try:
            return super(Regex,self).__str__()
        except Exception:
            pass

        if self.strRepr is None:
            self.strRepr = "Re:(%s)" % repr(self.pattern)

        return self.strRepr


class QuotedString(Token):
    r"""
    Token for matching strings that are delimited by quoting characters.
    
    Defined with the following parameters:
        - quoteChar - string of one or more characters defining the quote delimiting string
        - escChar - character to escape quotes, typically backslash (default=C{None})
        - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None})
        - multiline - boolean indicating whether quotes can span multiple lines (default=C{False})
        - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True})
        - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar)
        - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True})

    Example::
        qs = QuotedString('"')
        print(qs.searchString('lsjdf "This is the quote" sldjf'))
        complex_qs = QuotedString('{{', endQuoteChar='}}')
        print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf'))
        sql_qs = QuotedString('"', escQuote='""')
        print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf'))
    prints::
        [['This is the quote']]
        [['This is the "quote"']]
        [['This is the quote with "embedded" quotes']]
    """
    def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True):
        super(QuotedString,self).__init__()

        # remove white space from quote chars - wont work anyway
        quoteChar = quoteChar.strip()
        if not quoteChar:
            warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
            raise SyntaxError()

        if endQuoteChar is None:
            endQuoteChar = quoteChar
        else:
            endQuoteChar = endQuoteChar.strip()
            if not endQuoteChar:
                warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
                raise SyntaxError()

        self.quoteChar = quoteChar
        self.quoteCharLen = len(quoteChar)
        self.firstQuoteChar = quoteChar[0]
        self.endQuoteChar = endQuoteChar
        self.endQuoteCharLen = len(endQuoteChar)
        self.escChar = escChar
        self.escQuote = escQuote
        self.unquoteResults = unquoteResults
        self.convertWhitespaceEscapes = convertWhitespaceEscapes

        if multiline:
            self.flags = re.MULTILINE | re.DOTALL
            self.pattern = r'%s(?:[^%s%s]' % \
                ( re.escape(self.quoteChar),
                  _escapeRegexRangeChars(self.endQuoteChar[0]),
                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
        else:
            self.flags = 0
            self.pattern = r'%s(?:[^%s\n\r%s]' % \
                ( re.escape(self.quoteChar),
                  _escapeRegexRangeChars(self.endQuoteChar[0]),
                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
        if len(self.endQuoteChar) > 1:
            self.pattern += (
                '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]),
                                               _escapeRegexRangeChars(self.endQuoteChar[i]))
                                    for i in range(len(self.endQuoteChar)-1,0,-1)) + ')'
                )
        if escQuote:
            self.pattern += (r'|(?:%s)' % re.escape(escQuote))
        if escChar:
            self.pattern += (r'|(?:%s.)' % re.escape(escChar))
            self.escCharReplacePattern = re.escape(self.escChar)+"(.)"
        self.pattern += (r')*%s' % re.escape(self.endQuoteChar))

        try:
            self.re = re.compile(self.pattern, self.flags)
            self.reString = self.pattern
        except sre_constants.error:
            warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern,
                SyntaxWarning, stacklevel=2)
            raise

        self.name = _ustr(self)
        self.errmsg = "Expected " + self.name
        self.mayIndexError = False
        self.mayReturnEmpty = True

    def parseImpl( self, instring, loc, doActions=True ):
        result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None
        if not result:
            raise ParseException(instring, loc, self.errmsg, self)

        loc = result.end()
        ret = result.group()

        if self.unquoteResults:

            # strip off quotes
            ret = ret[self.quoteCharLen:-self.endQuoteCharLen]

            if isinstance(ret,basestring):
                # replace escaped whitespace
                if '\\' in ret and self.convertWhitespaceEscapes:
                    ws_map = {
                        r'\t' : '\t',
                        r'\n' : '\n',
                        r'\f' : '\f',
                        r'\r' : '\r',
                    }
                    for wslit,wschar in ws_map.items():
                        ret = ret.replace(wslit, wschar)

                # replace escaped characters
                if self.escChar:
                    ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret)

                # replace escaped quotes
                if self.escQuote:
                    ret = ret.replace(self.escQuote, self.endQuoteChar)

        return loc, ret

    def __str__( self ):
        try:
            return super(QuotedString,self).__str__()
        except Exception:
            pass

        if self.strRepr is None:
            self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar)

        return self.strRepr


class CharsNotIn(Token):
    """
    Token for matching words composed of characters I{not} in a given set (will
    include whitespace in matched characters if not listed in the provided exclusion set - see example).
    Defined with string containing all disallowed characters, and an optional
    minimum, maximum, and/or exact length.  The default value for C{min} is 1 (a
    minimum value < 1 is not valid); the default values for C{max} and C{exact}
    are 0, meaning no maximum or exact length restriction.

    Example::
        # define a comma-separated-value as anything that is not a ','
        csv_value = CharsNotIn(',')
        print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213"))
    prints::
        ['dkls', 'lsdkjf', 's12 34', '@!#', '213']
    """
    def __init__( self, notChars, min=1, max=0, exact=0 ):
        super(CharsNotIn,self).__init__()
        self.skipWhitespace = False
        self.notChars = notChars

        if min < 1:
            raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted")

        self.minLen = min

        if max > 0:
            self.maxLen = max
        else:
            self.maxLen = _MAX_INT

        if exact > 0:
            self.maxLen = exact
            self.minLen = exact

        self.name = _ustr(self)
        self.errmsg = "Expected " + self.name
        self.mayReturnEmpty = ( self.minLen == 0 )
        self.mayIndexError = False

    def parseImpl( self, instring, loc, doActions=True ):
        if instring[loc] in self.notChars:
            raise ParseException(instring, loc, self.errmsg, self)

        start = loc
        loc += 1
        notchars = self.notChars
        maxlen = min( start+self.maxLen, len(instring) )
        while loc < maxlen and \
              (instring[loc] not in notchars):
            loc += 1

        if loc - start < self.minLen:
            raise ParseException(instring, loc, self.errmsg, self)

        return loc, instring[start:loc]

    def __str__( self ):
        try:
            return super(CharsNotIn, self).__str__()
        except Exception:
            pass

        if self.strRepr is None:
            if len(self.notChars) > 4:
                self.strRepr = "!W:(%s...)" % self.notChars[:4]
            else:
                self.strRepr = "!W:(%s)" % self.notChars

        return self.strRepr

class White(Token):
    """
    Special matching class for matching whitespace.  Normally, whitespace is ignored
    by pyparsing grammars.  This class is included when some whitespace structures
    are significant.  Define with a string containing the whitespace characters to be
    matched; default is C{" \\t\\r\\n"}.  Also takes optional C{min}, C{max}, and C{exact} arguments,
    as defined for the C{L{Word}} class.
    """
    whiteStrs = {
        " " : "",
        "\t": "",
        "\n": "",
        "\r": "",
        "\f": "",
        }
    def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0):
        super(White,self).__init__()
        self.matchWhite = ws
        self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) )
        #~ self.leaveWhitespace()
        self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite))
        self.mayReturnEmpty = True
        self.errmsg = "Expected " + self.name

        self.minLen = min

        if max > 0:
            self.maxLen = max
        else:
            self.maxLen = _MAX_INT

        if exact > 0:
            self.maxLen = exact
            self.minLen = exact

    def parseImpl( self, instring, loc, doActions=True ):
        if not(instring[ loc ] in self.matchWhite):
            raise ParseException(instring, loc, self.errmsg, self)
        start = loc
        loc += 1
        maxloc = start + self.maxLen
        maxloc = min( maxloc, len(instring) )
        while loc < maxloc and instring[loc] in self.matchWhite:
            loc += 1

        if loc - start < self.minLen:
            raise ParseException(instring, loc, self.errmsg, self)

        return loc, instring[start:loc]


class _PositionToken(Token):
    def __init__( self ):
        super(_PositionToken,self).__init__()
        self.name=self.__class__.__name__
        self.mayReturnEmpty = True
        self.mayIndexError = False

class GoToColumn(_PositionToken):
    """
    Token to advance to a specific column of input text; useful for tabular report scraping.
    """
    def __init__( self, colno ):
        super(GoToColumn,self).__init__()
        self.col = colno

    def preParse( self, instring, loc ):
        if col(loc,instring) != self.col:
            instrlen = len(instring)
            if self.ignoreExprs:
                loc = self._skipIgnorables( instring, loc )
            while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col :
                loc += 1
        return loc

    def parseImpl( self, instring, loc, doActions=True ):
        thiscol = col( loc, instring )
        if thiscol > self.col:
            raise ParseException( instring, loc, "Text not in expected column", self )
        newloc = loc + self.col - thiscol
        ret = instring[ loc: newloc ]
        return newloc, ret


class LineStart(_PositionToken):
    """
    Matches if current position is at the beginning of a line within the parse string
    
    Example::
    
        test = '''\
        AAA this line
        AAA and this line
          AAA but not this one
        B AAA and definitely not this one
        '''

        for t in (LineStart() + 'AAA' + restOfLine).searchString(test):
            print(t)
    
    Prints::
        ['AAA', ' this line']
        ['AAA', ' and this line']    

    """
    def __init__( self ):
        super(LineStart,self).__init__()
        self.errmsg = "Expected start of line"

    def parseImpl( self, instring, loc, doActions=True ):
        if col(loc, instring) == 1:
            return loc, []
        raise ParseException(instring, loc, self.errmsg, self)

class LineEnd(_PositionToken):
    """
    Matches if current position is at the end of a line within the parse string
    """
    def __init__( self ):
        super(LineEnd,self).__init__()
        self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") )
        self.errmsg = "Expected end of line"

    def parseImpl( self, instring, loc, doActions=True ):
        if loc len(instring):
            return loc, []
        else:
            raise ParseException(instring, loc, self.errmsg, self)

class WordStart(_PositionToken):
    """
    Matches if the current position is at the beginning of a Word, and
    is not preceded by any character in a given set of C{wordChars}
    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
    use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of
    the string being parsed, or at the beginning of a line.
    """
    def __init__(self, wordChars = printables):
        super(WordStart,self).__init__()
        self.wordChars = set(wordChars)
        self.errmsg = "Not at the start of a word"

    def parseImpl(self, instring, loc, doActions=True ):
        if loc != 0:
            if (instring[loc-1] in self.wordChars or
                instring[loc] not in self.wordChars):
                raise ParseException(instring, loc, self.errmsg, self)
        return loc, []

class WordEnd(_PositionToken):
    """
    Matches if the current position is at the end of a Word, and
    is not followed by any character in a given set of C{wordChars}
    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
    use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of
    the string being parsed, or at the end of a line.
    """
    def __init__(self, wordChars = printables):
        super(WordEnd,self).__init__()
        self.wordChars = set(wordChars)
        self.skipWhitespace = False
        self.errmsg = "Not at the end of a word"

    def parseImpl(self, instring, loc, doActions=True ):
        instrlen = len(instring)
        if instrlen>0 and loc maxExcLoc:
                    maxException = err
                    maxExcLoc = err.loc
            except IndexError:
                if len(instring) > maxExcLoc:
                    maxException = ParseException(instring,len(instring),e.errmsg,self)
                    maxExcLoc = len(instring)
            else:
                # save match among all matches, to retry longest to shortest
                matches.append((loc2, e))

        if matches:
            matches.sort(key=lambda x: -x[0])
            for _,e in matches:
                try:
                    return e._parse( instring, loc, doActions )
                except ParseException as err:
                    err.__traceback__ = None
                    if err.loc > maxExcLoc:
                        maxException = err
                        maxExcLoc = err.loc

        if maxException is not None:
            maxException.msg = self.errmsg
            raise maxException
        else:
            raise ParseException(instring, loc, "no defined alternatives to match", self)


    def __ixor__(self, other ):
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        return self.append( other ) #Or( [ self, other ] )

    def __str__( self ):
        if hasattr(self,"name"):
            return self.name

        if self.strRepr is None:
            self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}"

        return self.strRepr

    def checkRecursion( self, parseElementList ):
        subRecCheckList = parseElementList[:] + [ self ]
        for e in self.exprs:
            e.checkRecursion( subRecCheckList )


class MatchFirst(ParseExpression):
    """
    Requires that at least one C{ParseExpression} is found.
    If two expressions match, the first one listed is the one that will match.
    May be constructed using the C{'|'} operator.

    Example::
        # construct MatchFirst using '|' operator
        
        # watch the order of expressions to match
        number = Word(nums) | Combine(Word(nums) + '.' + Word(nums))
        print(number.searchString("123 3.1416 789")) #  Fail! -> [['123'], ['3'], ['1416'], ['789']]

        # put more selective expression first
        number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums)
        print(number.searchString("123 3.1416 789")) #  Better -> [['123'], ['3.1416'], ['789']]
    """
    def __init__( self, exprs, savelist = False ):
        super(MatchFirst,self).__init__(exprs, savelist)
        if self.exprs:
            self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
        else:
            self.mayReturnEmpty = True

    def parseImpl( self, instring, loc, doActions=True ):
        maxExcLoc = -1
        maxException = None
        for e in self.exprs:
            try:
                ret = e._parse( instring, loc, doActions )
                return ret
            except ParseException as err:
                if err.loc > maxExcLoc:
                    maxException = err
                    maxExcLoc = err.loc
            except IndexError:
                if len(instring) > maxExcLoc:
                    maxException = ParseException(instring,len(instring),e.errmsg,self)
                    maxExcLoc = len(instring)

        # only got here if no expression matched, raise exception for match that made it the furthest
        else:
            if maxException is not None:
                maxException.msg = self.errmsg
                raise maxException
            else:
                raise ParseException(instring, loc, "no defined alternatives to match", self)

    def __ior__(self, other ):
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass( other )
        return self.append( other ) #MatchFirst( [ self, other ] )

    def __str__( self ):
        if hasattr(self,"name"):
            return self.name

        if self.strRepr is None:
            self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}"

        return self.strRepr

    def checkRecursion( self, parseElementList ):
        subRecCheckList = parseElementList[:] + [ self ]
        for e in self.exprs:
            e.checkRecursion( subRecCheckList )


class Each(ParseExpression):
    """
    Requires all given C{ParseExpression}s to be found, but in any order.
    Expressions may be separated by whitespace.
    May be constructed using the C{'&'} operator.

    Example::
        color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN")
        shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON")
        integer = Word(nums)
        shape_attr = "shape:" + shape_type("shape")
        posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn")
        color_attr = "color:" + color("color")
        size_attr = "size:" + integer("size")

        # use Each (using operator '&') to accept attributes in any order 
        # (shape and posn are required, color and size are optional)
        shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr)

        shape_spec.runTests('''
            shape: SQUARE color: BLACK posn: 100, 120
            shape: CIRCLE size: 50 color: BLUE posn: 50,80
            color:GREEN size:20 shape:TRIANGLE posn:20,40
            '''
            )
    prints::
        shape: SQUARE color: BLACK posn: 100, 120
        ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']]
        - color: BLACK
        - posn: ['100', ',', '120']
          - x: 100
          - y: 120
        - shape: SQUARE


        shape: CIRCLE size: 50 color: BLUE posn: 50,80
        ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']]
        - color: BLUE
        - posn: ['50', ',', '80']
          - x: 50
          - y: 80
        - shape: CIRCLE
        - size: 50


        color: GREEN size: 20 shape: TRIANGLE posn: 20,40
        ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']]
        - color: GREEN
        - posn: ['20', ',', '40']
          - x: 20
          - y: 40
        - shape: TRIANGLE
        - size: 20
    """
    def __init__( self, exprs, savelist = True ):
        super(Each,self).__init__(exprs, savelist)
        self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
        self.skipWhitespace = True
        self.initExprGroups = True

    def parseImpl( self, instring, loc, doActions=True ):
        if self.initExprGroups:
            self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional))
            opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ]
            opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)]
            self.optionals = opt1 + opt2
            self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ]
            self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ]
            self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ]
            self.required += self.multirequired
            self.initExprGroups = False
        tmpLoc = loc
        tmpReqd = self.required[:]
        tmpOpt  = self.optionals[:]
        matchOrder = []

        keepMatching = True
        while keepMatching:
            tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired
            failed = []
            for e in tmpExprs:
                try:
                    tmpLoc = e.tryParse( instring, tmpLoc )
                except ParseException:
                    failed.append(e)
                else:
                    matchOrder.append(self.opt1map.get(id(e),e))
                    if e in tmpReqd:
                        tmpReqd.remove(e)
                    elif e in tmpOpt:
                        tmpOpt.remove(e)
            if len(failed) == len(tmpExprs):
                keepMatching = False

        if tmpReqd:
            missing = ", ".join(_ustr(e) for e in tmpReqd)
            raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing )

        # add any unmatched Optionals, in case they have default values defined
        matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt]

        resultlist = []
        for e in matchOrder:
            loc,results = e._parse(instring,loc,doActions)
            resultlist.append(results)

        finalResults = sum(resultlist, ParseResults([]))
        return loc, finalResults

    def __str__( self ):
        if hasattr(self,"name"):
            return self.name

        if self.strRepr is None:
            self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}"

        return self.strRepr

    def checkRecursion( self, parseElementList ):
        subRecCheckList = parseElementList[:] + [ self ]
        for e in self.exprs:
            e.checkRecursion( subRecCheckList )


class ParseElementEnhance(ParserElement):
    """
    Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens.
    """
    def __init__( self, expr, savelist=False ):
        super(ParseElementEnhance,self).__init__(savelist)
        if isinstance( expr, basestring ):
            if issubclass(ParserElement._literalStringClass, Token):
                expr = ParserElement._literalStringClass(expr)
            else:
                expr = ParserElement._literalStringClass(Literal(expr))
        self.expr = expr
        self.strRepr = None
        if expr is not None:
            self.mayIndexError = expr.mayIndexError
            self.mayReturnEmpty = expr.mayReturnEmpty
            self.setWhitespaceChars( expr.whiteChars )
            self.skipWhitespace = expr.skipWhitespace
            self.saveAsList = expr.saveAsList
            self.callPreparse = expr.callPreparse
            self.ignoreExprs.extend(expr.ignoreExprs)

    def parseImpl( self, instring, loc, doActions=True ):
        if self.expr is not None:
            return self.expr._parse( instring, loc, doActions, callPreParse=False )
        else:
            raise ParseException("",loc,self.errmsg,self)

    def leaveWhitespace( self ):
        self.skipWhitespace = False
        self.expr = self.expr.copy()
        if self.expr is not None:
            self.expr.leaveWhitespace()
        return self

    def ignore( self, other ):
        if isinstance( other, Suppress ):
            if other not in self.ignoreExprs:
                super( ParseElementEnhance, self).ignore( other )
                if self.expr is not None:
                    self.expr.ignore( self.ignoreExprs[-1] )
        else:
            super( ParseElementEnhance, self).ignore( other )
            if self.expr is not None:
                self.expr.ignore( self.ignoreExprs[-1] )
        return self

    def streamline( self ):
        super(ParseElementEnhance,self).streamline()
        if self.expr is not None:
            self.expr.streamline()
        return self

    def checkRecursion( self, parseElementList ):
        if self in parseElementList:
            raise RecursiveGrammarException( parseElementList+[self] )
        subRecCheckList = parseElementList[:] + [ self ]
        if self.expr is not None:
            self.expr.checkRecursion( subRecCheckList )

    def validate( self, validateTrace=[] ):
        tmp = validateTrace[:]+[self]
        if self.expr is not None:
            self.expr.validate(tmp)
        self.checkRecursion( [] )

    def __str__( self ):
        try:
            return super(ParseElementEnhance,self).__str__()
        except Exception:
            pass

        if self.strRepr is None and self.expr is not None:
            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) )
        return self.strRepr


class FollowedBy(ParseElementEnhance):
    """
    Lookahead matching of the given parse expression.  C{FollowedBy}
    does I{not} advance the parsing position within the input string, it only
    verifies that the specified parse expression matches at the current
    position.  C{FollowedBy} always returns a null token list.

    Example::
        # use FollowedBy to match a label only if it is followed by a ':'
        data_word = Word(alphas)
        label = data_word + FollowedBy(':')
        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
        
        OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint()
    prints::
        [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']]
    """
    def __init__( self, expr ):
        super(FollowedBy,self).__init__(expr)
        self.mayReturnEmpty = True

    def parseImpl( self, instring, loc, doActions=True ):
        self.expr.tryParse( instring, loc )
        return loc, []


class NotAny(ParseElementEnhance):
    """
    Lookahead to disallow matching with the given parse expression.  C{NotAny}
    does I{not} advance the parsing position within the input string, it only
    verifies that the specified parse expression does I{not} match at the current
    position.  Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny}
    always returns a null token list.  May be constructed using the '~' operator.

    Example::
        
    """
    def __init__( self, expr ):
        super(NotAny,self).__init__(expr)
        #~ self.leaveWhitespace()
        self.skipWhitespace = False  # do NOT use self.leaveWhitespace(), don't want to propagate to exprs
        self.mayReturnEmpty = True
        self.errmsg = "Found unwanted token, "+_ustr(self.expr)

    def parseImpl( self, instring, loc, doActions=True ):
        if self.expr.canParseNext(instring, loc):
            raise ParseException(instring, loc, self.errmsg, self)
        return loc, []

    def __str__( self ):
        if hasattr(self,"name"):
            return self.name

        if self.strRepr is None:
            self.strRepr = "~{" + _ustr(self.expr) + "}"

        return self.strRepr

class _MultipleMatch(ParseElementEnhance):
    def __init__( self, expr, stopOn=None):
        super(_MultipleMatch, self).__init__(expr)
        self.saveAsList = True
        ender = stopOn
        if isinstance(ender, basestring):
            ender = ParserElement._literalStringClass(ender)
        self.not_ender = ~ender if ender is not None else None

    def parseImpl( self, instring, loc, doActions=True ):
        self_expr_parse = self.expr._parse
        self_skip_ignorables = self._skipIgnorables
        check_ender = self.not_ender is not None
        if check_ender:
            try_not_ender = self.not_ender.tryParse
        
        # must be at least one (but first see if we are the stopOn sentinel;
        # if so, fail)
        if check_ender:
            try_not_ender(instring, loc)
        loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False )
        try:
            hasIgnoreExprs = (not not self.ignoreExprs)
            while 1:
                if check_ender:
                    try_not_ender(instring, loc)
                if hasIgnoreExprs:
                    preloc = self_skip_ignorables( instring, loc )
                else:
                    preloc = loc
                loc, tmptokens = self_expr_parse( instring, preloc, doActions )
                if tmptokens or tmptokens.haskeys():
                    tokens += tmptokens
        except (ParseException,IndexError):
            pass

        return loc, tokens
        
class OneOrMore(_MultipleMatch):
    """
    Repetition of one or more of the given expression.
    
    Parameters:
     - expr - expression that must match one or more times
     - stopOn - (default=C{None}) - expression for a terminating sentinel
          (only required if the sentinel would ordinarily match the repetition 
          expression)          

    Example::
        data_word = Word(alphas)
        label = data_word + FollowedBy(':')
        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))

        text = "shape: SQUARE posn: upper left color: BLACK"
        OneOrMore(attr_expr).parseString(text).pprint()  # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']]

        # use stopOn attribute for OneOrMore to avoid reading label string as part of the data
        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
        OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']]
        
        # could also be written as
        (attr_expr * (1,)).parseString(text).pprint()
    """

    def __str__( self ):
        if hasattr(self,"name"):
            return self.name

        if self.strRepr is None:
            self.strRepr = "{" + _ustr(self.expr) + "}..."

        return self.strRepr

class ZeroOrMore(_MultipleMatch):
    """
    Optional repetition of zero or more of the given expression.
    
    Parameters:
     - expr - expression that must match zero or more times
     - stopOn - (default=C{None}) - expression for a terminating sentinel
          (only required if the sentinel would ordinarily match the repetition 
          expression)          

    Example: similar to L{OneOrMore}
    """
    def __init__( self, expr, stopOn=None):
        super(ZeroOrMore,self).__init__(expr, stopOn=stopOn)
        self.mayReturnEmpty = True
        
    def parseImpl( self, instring, loc, doActions=True ):
        try:
            return super(ZeroOrMore, self).parseImpl(instring, loc, doActions)
        except (ParseException,IndexError):
            return loc, []

    def __str__( self ):
        if hasattr(self,"name"):
            return self.name

        if self.strRepr is None:
            self.strRepr = "[" + _ustr(self.expr) + "]..."

        return self.strRepr

class _NullToken(object):
    def __bool__(self):
        return False
    __nonzero__ = __bool__
    def __str__(self):
        return ""

_optionalNotMatched = _NullToken()
class Optional(ParseElementEnhance):
    """
    Optional matching of the given expression.

    Parameters:
     - expr - expression that must match zero or more times
     - default (optional) - value to be returned if the optional expression is not found.

    Example::
        # US postal code can be a 5-digit zip, plus optional 4-digit qualifier
        zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4)))
        zip.runTests('''
            # traditional ZIP code
            12345
            
            # ZIP+4 form
            12101-0001
            
            # invalid ZIP
            98765-
            ''')
    prints::
        # traditional ZIP code
        12345
        ['12345']

        # ZIP+4 form
        12101-0001
        ['12101-0001']

        # invalid ZIP
        98765-
             ^
        FAIL: Expected end of text (at char 5), (line:1, col:6)
    """
    def __init__( self, expr, default=_optionalNotMatched ):
        super(Optional,self).__init__( expr, savelist=False )
        self.saveAsList = self.expr.saveAsList
        self.defaultValue = default
        self.mayReturnEmpty = True

    def parseImpl( self, instring, loc, doActions=True ):
        try:
            loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
        except (ParseException,IndexError):
            if self.defaultValue is not _optionalNotMatched:
                if self.expr.resultsName:
                    tokens = ParseResults([ self.defaultValue ])
                    tokens[self.expr.resultsName] = self.defaultValue
                else:
                    tokens = [ self.defaultValue ]
            else:
                tokens = []
        return loc, tokens

    def __str__( self ):
        if hasattr(self,"name"):
            return self.name

        if self.strRepr is None:
            self.strRepr = "[" + _ustr(self.expr) + "]"

        return self.strRepr

class SkipTo(ParseElementEnhance):
    """
    Token for skipping over all undefined text until the matched expression is found.

    Parameters:
     - expr - target expression marking the end of the data to be skipped
     - include - (default=C{False}) if True, the target expression is also parsed 
          (the skipped text and target expression are returned as a 2-element list).
     - ignore - (default=C{None}) used to define grammars (typically quoted strings and 
          comments) that might contain false matches to the target expression
     - failOn - (default=C{None}) define expressions that are not allowed to be 
          included in the skipped test; if found before the target expression is found, 
          the SkipTo is not a match

    Example::
        report = '''
            Outstanding Issues Report - 1 Jan 2000

               # | Severity | Description                               |  Days Open
            -----+----------+-------------------------------------------+-----------
             101 | Critical | Intermittent system crash                 |          6
              94 | Cosmetic | Spelling error on Login ('log|n')         |         14
              79 | Minor    | System slow when running too many reports |         47
            '''
        integer = Word(nums)
        SEP = Suppress('|')
        # use SkipTo to simply match everything up until the next SEP
        # - ignore quoted strings, so that a '|' character inside a quoted string does not match
        # - parse action will call token.strip() for each matched token, i.e., the description body
        string_data = SkipTo(SEP, ignore=quotedString)
        string_data.setParseAction(tokenMap(str.strip))
        ticket_expr = (integer("issue_num") + SEP 
                      + string_data("sev") + SEP 
                      + string_data("desc") + SEP 
                      + integer("days_open"))
        
        for tkt in ticket_expr.searchString(report):
            print tkt.dump()
    prints::
        ['101', 'Critical', 'Intermittent system crash', '6']
        - days_open: 6
        - desc: Intermittent system crash
        - issue_num: 101
        - sev: Critical
        ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14']
        - days_open: 14
        - desc: Spelling error on Login ('log|n')
        - issue_num: 94
        - sev: Cosmetic
        ['79', 'Minor', 'System slow when running too many reports', '47']
        - days_open: 47
        - desc: System slow when running too many reports
        - issue_num: 79
        - sev: Minor
    """
    def __init__( self, other, include=False, ignore=None, failOn=None ):
        super( SkipTo, self ).__init__( other )
        self.ignoreExpr = ignore
        self.mayReturnEmpty = True
        self.mayIndexError = False
        self.includeMatch = include
        self.asList = False
        if isinstance(failOn, basestring):
            self.failOn = ParserElement._literalStringClass(failOn)
        else:
            self.failOn = failOn
        self.errmsg = "No match found for "+_ustr(self.expr)

    def parseImpl( self, instring, loc, doActions=True ):
        startloc = loc
        instrlen = len(instring)
        expr = self.expr
        expr_parse = self.expr._parse
        self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None
        self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None
        
        tmploc = loc
        while tmploc <= instrlen:
            if self_failOn_canParseNext is not None:
                # break if failOn expression matches
                if self_failOn_canParseNext(instring, tmploc):
                    break
                    
            if self_ignoreExpr_tryParse is not None:
                # advance past ignore expressions
                while 1:
                    try:
                        tmploc = self_ignoreExpr_tryParse(instring, tmploc)
                    except ParseBaseException:
                        break
            
            try:
                expr_parse(instring, tmploc, doActions=False, callPreParse=False)
            except (ParseException, IndexError):
                # no match, advance loc in string
                tmploc += 1
            else:
                # matched skipto expr, done
                break

        else:
            # ran off the end of the input string without matching skipto expr, fail
            raise ParseException(instring, loc, self.errmsg, self)

        # build up return values
        loc = tmploc
        skiptext = instring[startloc:loc]
        skipresult = ParseResults(skiptext)
        
        if self.includeMatch:
            loc, mat = expr_parse(instring,loc,doActions,callPreParse=False)
            skipresult += mat

        return loc, skipresult

class Forward(ParseElementEnhance):
    """
    Forward declaration of an expression to be defined later -
    used for recursive grammars, such as algebraic infix notation.
    When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator.

    Note: take care when assigning to C{Forward} not to overlook precedence of operators.
    Specifically, '|' has a lower precedence than '<<', so that::
        fwdExpr << a | b | c
    will actually be evaluated as::
        (fwdExpr << a) | b | c
    thereby leaving b and c out as parseable alternatives.  It is recommended that you
    explicitly group the values inserted into the C{Forward}::
        fwdExpr << (a | b | c)
    Converting to use the '<<=' operator instead will avoid this problem.

    See L{ParseResults.pprint} for an example of a recursive parser created using
    C{Forward}.
    """
    def __init__( self, other=None ):
        super(Forward,self).__init__( other, savelist=False )

    def __lshift__( self, other ):
        if isinstance( other, basestring ):
            other = ParserElement._literalStringClass(other)
        self.expr = other
        self.strRepr = None
        self.mayIndexError = self.expr.mayIndexError
        self.mayReturnEmpty = self.expr.mayReturnEmpty
        self.setWhitespaceChars( self.expr.whiteChars )
        self.skipWhitespace = self.expr.skipWhitespace
        self.saveAsList = self.expr.saveAsList
        self.ignoreExprs.extend(self.expr.ignoreExprs)
        return self
        
    def __ilshift__(self, other):
        return self << other
    
    def leaveWhitespace( self ):
        self.skipWhitespace = False
        return self

    def streamline( self ):
        if not self.streamlined:
            self.streamlined = True
            if self.expr is not None:
                self.expr.streamline()
        return self

    def validate( self, validateTrace=[] ):
        if self not in validateTrace:
            tmp = validateTrace[:]+[self]
            if self.expr is not None:
                self.expr.validate(tmp)
        self.checkRecursion([])

    def __str__( self ):
        if hasattr(self,"name"):
            return self.name
        return self.__class__.__name__ + ": ..."

        # stubbed out for now - creates awful memory and perf issues
        self._revertClass = self.__class__
        self.__class__ = _ForwardNoRecurse
        try:
            if self.expr is not None:
                retString = _ustr(self.expr)
            else:
                retString = "None"
        finally:
            self.__class__ = self._revertClass
        return self.__class__.__name__ + ": " + retString

    def copy(self):
        if self.expr is not None:
            return super(Forward,self).copy()
        else:
            ret = Forward()
            ret <<= self
            return ret

class _ForwardNoRecurse(Forward):
    def __str__( self ):
        return "..."

class TokenConverter(ParseElementEnhance):
    """
    Abstract subclass of C{ParseExpression}, for converting parsed results.
    """
    def __init__( self, expr, savelist=False ):
        super(TokenConverter,self).__init__( expr )#, savelist )
        self.saveAsList = False

class Combine(TokenConverter):
    """
    Converter to concatenate all matching tokens to a single string.
    By default, the matching patterns must also be contiguous in the input string;
    this can be disabled by specifying C{'adjacent=False'} in the constructor.

    Example::
        real = Word(nums) + '.' + Word(nums)
        print(real.parseString('3.1416')) # -> ['3', '.', '1416']
        # will also erroneously match the following
        print(real.parseString('3. 1416')) # -> ['3', '.', '1416']

        real = Combine(Word(nums) + '.' + Word(nums))
        print(real.parseString('3.1416')) # -> ['3.1416']
        # no match when there are internal spaces
        print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...)
    """
    def __init__( self, expr, joinString="", adjacent=True ):
        super(Combine,self).__init__( expr )
        # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself
        if adjacent:
            self.leaveWhitespace()
        self.adjacent = adjacent
        self.skipWhitespace = True
        self.joinString = joinString
        self.callPreparse = True

    def ignore( self, other ):
        if self.adjacent:
            ParserElement.ignore(self, other)
        else:
            super( Combine, self).ignore( other )
        return self

    def postParse( self, instring, loc, tokenlist ):
        retToks = tokenlist.copy()
        del retToks[:]
        retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults)

        if self.resultsName and retToks.haskeys():
            return [ retToks ]
        else:
            return retToks

class Group(TokenConverter):
    """
    Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions.

    Example::
        ident = Word(alphas)
        num = Word(nums)
        term = ident | num
        func = ident + Optional(delimitedList(term))
        print(func.parseString("fn a,b,100"))  # -> ['fn', 'a', 'b', '100']

        func = ident + Group(Optional(delimitedList(term)))
        print(func.parseString("fn a,b,100"))  # -> ['fn', ['a', 'b', '100']]
    """
    def __init__( self, expr ):
        super(Group,self).__init__( expr )
        self.saveAsList = True

    def postParse( self, instring, loc, tokenlist ):
        return [ tokenlist ]

class Dict(TokenConverter):
    """
    Converter to return a repetitive expression as a list, but also as a dictionary.
    Each element can also be referenced using the first token in the expression as its key.
    Useful for tabular report scraping when the first column can be used as a item key.

    Example::
        data_word = Word(alphas)
        label = data_word + FollowedBy(':')
        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))

        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
        
        # print attributes as plain groups
        print(OneOrMore(attr_expr).parseString(text).dump())
        
        # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names
        result = Dict(OneOrMore(Group(attr_expr))).parseString(text)
        print(result.dump())
        
        # access named fields as dict entries, or output as dict
        print(result['shape'])        
        print(result.asDict())
    prints::
        ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap']

        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
        - color: light blue
        - posn: upper left
        - shape: SQUARE
        - texture: burlap
        SQUARE
        {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'}
    See more examples at L{ParseResults} of accessing fields by results name.
    """
    def __init__( self, expr ):
        super(Dict,self).__init__( expr )
        self.saveAsList = True

    def postParse( self, instring, loc, tokenlist ):
        for i,tok in enumerate(tokenlist):
            if len(tok) == 0:
                continue
            ikey = tok[0]
            if isinstance(ikey,int):
                ikey = _ustr(tok[0]).strip()
            if len(tok)==1:
                tokenlist[ikey] = _ParseResultsWithOffset("",i)
            elif len(tok)==2 and not isinstance(tok[1],ParseResults):
                tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i)
            else:
                dictvalue = tok.copy() #ParseResults(i)
                del dictvalue[0]
                if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()):
                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i)
                else:
                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i)

        if self.resultsName:
            return [ tokenlist ]
        else:
            return tokenlist


class Suppress(TokenConverter):
    """
    Converter for ignoring the results of a parsed expression.

    Example::
        source = "a, b, c,d"
        wd = Word(alphas)
        wd_list1 = wd + ZeroOrMore(',' + wd)
        print(wd_list1.parseString(source))

        # often, delimiters that are useful during parsing are just in the
        # way afterward - use Suppress to keep them out of the parsed output
        wd_list2 = wd + ZeroOrMore(Suppress(',') + wd)
        print(wd_list2.parseString(source))
    prints::
        ['a', ',', 'b', ',', 'c', ',', 'd']
        ['a', 'b', 'c', 'd']
    (See also L{delimitedList}.)
    """
    def postParse( self, instring, loc, tokenlist ):
        return []

    def suppress( self ):
        return self


class OnlyOnce(object):
    """
    Wrapper for parse actions, to ensure they are only called once.
    """
    def __init__(self, methodCall):
        self.callable = _trim_arity(methodCall)
        self.called = False
    def __call__(self,s,l,t):
        if not self.called:
            results = self.callable(s,l,t)
            self.called = True
            return results
        raise ParseException(s,l,"")
    def reset(self):
        self.called = False

def traceParseAction(f):
    """
    Decorator for debugging parse actions. 
    
    When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".}
    When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised.

    Example::
        wd = Word(alphas)

        @traceParseAction
        def remove_duplicate_chars(tokens):
            return ''.join(sorted(set(''.join(tokens))))

        wds = OneOrMore(wd).setParseAction(remove_duplicate_chars)
        print(wds.parseString("slkdjs sld sldd sdlf sdljf"))
    prints::
        >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {}))
        <3:
            thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc
        sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) )
        try:
            ret = f(*paArgs)
        except Exception as exc:
            sys.stderr.write( "< ['aa', 'bb', 'cc']
        delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE']
    """
    dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..."
    if combine:
        return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName)
    else:
        return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName)

def countedArray( expr, intExpr=None ):
    """
    Helper to define a counted list of expressions.
    This helper defines a pattern of the form::
        integer expr expr expr...
    where the leading integer tells how many expr expressions follow.
    The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed.
    
    If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value.

    Example::
        countedArray(Word(alphas)).parseString('2 ab cd ef')  # -> ['ab', 'cd']

        # in this parser, the leading integer value is given in binary,
        # '10' indicating that 2 values are in the array
        binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2))
        countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef')  # -> ['ab', 'cd']
    """
    arrayExpr = Forward()
    def countFieldParseAction(s,l,t):
        n = t[0]
        arrayExpr << (n and Group(And([expr]*n)) or Group(empty))
        return []
    if intExpr is None:
        intExpr = Word(nums).setParseAction(lambda t:int(t[0]))
    else:
        intExpr = intExpr.copy()
    intExpr.setName("arrayLen")
    intExpr.addParseAction(countFieldParseAction, callDuringTry=True)
    return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...')

def _flatten(L):
    ret = []
    for i in L:
        if isinstance(i,list):
            ret.extend(_flatten(i))
        else:
            ret.append(i)
    return ret

def matchPreviousLiteral(expr):
    """
    Helper to define an expression that is indirectly defined from
    the tokens matched in a previous expression, that is, it looks
    for a 'repeat' of a previous expression.  For example::
        first = Word(nums)
        second = matchPreviousLiteral(first)
        matchExpr = first + ":" + second
    will match C{"1:1"}, but not C{"1:2"}.  Because this matches a
    previous literal, will also match the leading C{"1:1"} in C{"1:10"}.
    If this is not desired, use C{matchPreviousExpr}.
    Do I{not} use with packrat parsing enabled.
    """
    rep = Forward()
    def copyTokenToRepeater(s,l,t):
        if t:
            if len(t) == 1:
                rep << t[0]
            else:
                # flatten t tokens
                tflat = _flatten(t.asList())
                rep << And(Literal(tt) for tt in tflat)
        else:
            rep << Empty()
    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
    rep.setName('(prev) ' + _ustr(expr))
    return rep

def matchPreviousExpr(expr):
    """
    Helper to define an expression that is indirectly defined from
    the tokens matched in a previous expression, that is, it looks
    for a 'repeat' of a previous expression.  For example::
        first = Word(nums)
        second = matchPreviousExpr(first)
        matchExpr = first + ":" + second
    will match C{"1:1"}, but not C{"1:2"}.  Because this matches by
    expressions, will I{not} match the leading C{"1:1"} in C{"1:10"};
    the expressions are evaluated first, and then compared, so
    C{"1"} is compared with C{"10"}.
    Do I{not} use with packrat parsing enabled.
    """
    rep = Forward()
    e2 = expr.copy()
    rep <<= e2
    def copyTokenToRepeater(s,l,t):
        matchTokens = _flatten(t.asList())
        def mustMatchTheseTokens(s,l,t):
            theseTokens = _flatten(t.asList())
            if  theseTokens != matchTokens:
                raise ParseException("",0,"")
        rep.setParseAction( mustMatchTheseTokens, callDuringTry=True )
    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
    rep.setName('(prev) ' + _ustr(expr))
    return rep

def _escapeRegexRangeChars(s):
    #~  escape these chars: ^-]
    for c in r"\^-]":
        s = s.replace(c,_bslash+c)
    s = s.replace("\n",r"\n")
    s = s.replace("\t",r"\t")
    return _ustr(s)

def oneOf( strs, caseless=False, useRegex=True ):
    """
    Helper to quickly define a set of alternative Literals, and makes sure to do
    longest-first testing when there is a conflict, regardless of the input order,
    but returns a C{L{MatchFirst}} for best performance.

    Parameters:
     - strs - a string of space-delimited literals, or a collection of string literals
     - caseless - (default=C{False}) - treat all literals as caseless
     - useRegex - (default=C{True}) - as an optimization, will generate a Regex
          object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or
          if creating a C{Regex} raises an exception)

    Example::
        comp_oper = oneOf("< = > <= >= !=")
        var = Word(alphas)
        number = Word(nums)
        term = var | number
        comparison_expr = term + comp_oper + term
        print(comparison_expr.searchString("B = 12  AA=23 B<=AA AA>12"))
    prints::
        [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']]
    """
    if caseless:
        isequal = ( lambda a,b: a.upper() == b.upper() )
        masks = ( lambda a,b: b.upper().startswith(a.upper()) )
        parseElementClass = CaselessLiteral
    else:
        isequal = ( lambda a,b: a == b )
        masks = ( lambda a,b: b.startswith(a) )
        parseElementClass = Literal

    symbols = []
    if isinstance(strs,basestring):
        symbols = strs.split()
    elif isinstance(strs, Iterable):
        symbols = list(strs)
    else:
        warnings.warn("Invalid argument to oneOf, expected string or iterable",
                SyntaxWarning, stacklevel=2)
    if not symbols:
        return NoMatch()

    i = 0
    while i < len(symbols)-1:
        cur = symbols[i]
        for j,other in enumerate(symbols[i+1:]):
            if ( isequal(other, cur) ):
                del symbols[i+j+1]
                break
            elif ( masks(cur, other) ):
                del symbols[i+j+1]
                symbols.insert(i,other)
                cur = other
                break
        else:
            i += 1

    if not caseless and useRegex:
        #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] ))
        try:
            if len(symbols)==len("".join(symbols)):
                return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols))
            else:
                return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols))
        except Exception:
            warnings.warn("Exception creating Regex for oneOf, building MatchFirst",
                    SyntaxWarning, stacklevel=2)


    # last resort, just use MatchFirst
    return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols))

def dictOf( key, value ):
    """
    Helper to easily and clearly define a dictionary by specifying the respective patterns
    for the key and value.  Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens
    in the proper order.  The key pattern can include delimiting markers or punctuation,
    as long as they are suppressed, thereby leaving the significant key text.  The value
    pattern can include named results, so that the C{Dict} results can include named token
    fields.

    Example::
        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
        print(OneOrMore(attr_expr).parseString(text).dump())
        
        attr_label = label
        attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)

        # similar to Dict, but simpler call format
        result = dictOf(attr_label, attr_value).parseString(text)
        print(result.dump())
        print(result['shape'])
        print(result.shape)  # object attribute access works too
        print(result.asDict())
    prints::
        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
        - color: light blue
        - posn: upper left
        - shape: SQUARE
        - texture: burlap
        SQUARE
        SQUARE
        {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'}
    """
    return Dict( ZeroOrMore( Group ( key + value ) ) )

def originalTextFor(expr, asString=True):
    """
    Helper to return the original, untokenized text for a given expression.  Useful to
    restore the parsed fields of an HTML start tag into the raw tag text itself, or to
    revert separate tokens with intervening whitespace back to the original matching
    input text. By default, returns astring containing the original parsed text.  
       
    If the optional C{asString} argument is passed as C{False}, then the return value is a 
    C{L{ParseResults}} containing any results names that were originally matched, and a 
    single token containing the original matched text from the input string.  So if 
    the expression passed to C{L{originalTextFor}} contains expressions with defined
    results names, you must set C{asString} to C{False} if you want to preserve those
    results name values.

    Example::
        src = "this is test  bold text  normal text "
        for tag in ("b","i"):
            opener,closer = makeHTMLTags(tag)
            patt = originalTextFor(opener + SkipTo(closer) + closer)
            print(patt.searchString(src)[0])
    prints::
        [' bold text ']
        ['text']
    """
    locMarker = Empty().setParseAction(lambda s,loc,t: loc)
    endlocMarker = locMarker.copy()
    endlocMarker.callPreparse = False
    matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end")
    if asString:
        extractText = lambda s,l,t: s[t._original_start:t._original_end]
    else:
        def extractText(s,l,t):
            t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]]
    matchExpr.setParseAction(extractText)
    matchExpr.ignoreExprs = expr.ignoreExprs
    return matchExpr

def ungroup(expr): 
    """
    Helper to undo pyparsing's default grouping of And expressions, even
    if all but one are non-empty.
    """
    return TokenConverter(expr).setParseAction(lambda t:t[0])

def locatedExpr(expr):
    """
    Helper to decorate a returned token with its starting and ending locations in the input string.
    This helper adds the following results names:
     - locn_start = location where matched expression begins
     - locn_end = location where matched expression ends
     - value = the actual parsed results

    Be careful if the input text contains C{} characters, you may want to call
    C{L{ParserElement.parseWithTabs}}

    Example::
        wd = Word(alphas)
        for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"):
            print(match)
    prints::
        [[0, 'ljsdf', 5]]
        [[8, 'lksdjjf', 15]]
        [[18, 'lkkjj', 23]]
    """
    locator = Empty().setParseAction(lambda s,l,t: l)
    return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end"))


# convenience constants for positional expressions
empty       = Empty().setName("empty")
lineStart   = LineStart().setName("lineStart")
lineEnd     = LineEnd().setName("lineEnd")
stringStart = StringStart().setName("stringStart")
stringEnd   = StringEnd().setName("stringEnd")

_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1])
_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16)))
_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8)))
_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1)
_charRange = Group(_singleChar + Suppress("-") + _singleChar)
_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]"

def srange(s):
    r"""
    Helper to easily define string ranges for use in Word construction.  Borrows
    syntax from regexp '[]' string range definitions::
        srange("[0-9]")   -> "0123456789"
        srange("[a-z]")   -> "abcdefghijklmnopqrstuvwxyz"
        srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_"
    The input string must be enclosed in []'s, and the returned string is the expanded
    character set joined into a single string.
    The values enclosed in the []'s may be:
     - a single character
     - an escaped character with a leading backslash (such as C{\-} or C{\]})
     - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) 
         (C{\0x##} is also supported for backwards compatibility) 
     - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character)
     - a range of any of the above, separated by a dash (C{'a-z'}, etc.)
     - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.)
    """
    _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1))
    try:
        return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body)
    except Exception:
        return ""

def matchOnlyAtCol(n):
    """
    Helper method for defining parse actions that require matching at a specific
    column in the input text.
    """
    def verifyCol(strg,locn,toks):
        if col(locn,strg) != n:
            raise ParseException(strg,locn,"matched token not at column %d" % n)
    return verifyCol

def replaceWith(replStr):
    """
    Helper method for common parse actions that simply return a literal value.  Especially
    useful when used with C{L{transformString}()}.

    Example::
        num = Word(nums).setParseAction(lambda toks: int(toks[0]))
        na = oneOf("N/A NA").setParseAction(replaceWith(math.nan))
        term = na | num
        
        OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234]
    """
    return lambda s,l,t: [replStr]

def removeQuotes(s,l,t):
    """
    Helper parse action for removing quotation marks from parsed quoted strings.

    Example::
        # by default, quotation marks are included in parsed results
        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"]

        # use removeQuotes to strip quotation marks from parsed results
        quotedString.setParseAction(removeQuotes)
        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"]
    """
    return t[0][1:-1]

def tokenMap(func, *args):
    """
    Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional 
    args are passed, they are forwarded to the given function as additional arguments after
    the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the
    parsed data to an integer using base 16.

    Example (compare the last to example in L{ParserElement.transformString}::
        hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16))
        hex_ints.runTests('''
            00 11 22 aa FF 0a 0d 1a
            ''')
        
        upperword = Word(alphas).setParseAction(tokenMap(str.upper))
        OneOrMore(upperword).runTests('''
            my kingdom for a horse
            ''')

        wd = Word(alphas).setParseAction(tokenMap(str.title))
        OneOrMore(wd).setParseAction(' '.join).runTests('''
            now is the winter of our discontent made glorious summer by this sun of york
            ''')
    prints::
        00 11 22 aa FF 0a 0d 1a
        [0, 17, 34, 170, 255, 10, 13, 26]

        my kingdom for a horse
        ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE']

        now is the winter of our discontent made glorious summer by this sun of york
        ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York']
    """
    def pa(s,l,t):
        return [func(tokn, *args) for tokn in t]

    try:
        func_name = getattr(func, '__name__', 
                            getattr(func, '__class__').__name__)
    except Exception:
        func_name = str(func)
    pa.__name__ = func_name

    return pa

upcaseTokens = tokenMap(lambda t: _ustr(t).upper())
"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}"""

downcaseTokens = tokenMap(lambda t: _ustr(t).lower())
"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}"""
    
def _makeTags(tagStr, xml):
    """Internal helper to construct opening and closing tag expressions, given a tag name"""
    if isinstance(tagStr,basestring):
        resname = tagStr
        tagStr = Keyword(tagStr, caseless=not xml)
    else:
        resname = tagStr.name

    tagAttrName = Word(alphas,alphanums+"_-:")
    if (xml):
        tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes )
        openTag = Suppress("<") + tagStr("tag") + \
                Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \
                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
    else:
        printablesLessRAbrack = "".join(c for c in printables if c not in ">")
        tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack)
        openTag = Suppress("<") + tagStr("tag") + \
                Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \
                Optional( Suppress("=") + tagAttrValue ) ))) + \
                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
    closeTag = Combine(_L("")

    openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname)
    closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("" % resname)
    openTag.tag = resname
    closeTag.tag = resname
    return openTag, closeTag

def makeHTMLTags(tagStr):
    """
    Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches
    tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values.

    Example::
        text = 'More info at the pyparsing wiki page'
        # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple
        a,a_end = makeHTMLTags("A")
        link_expr = a + SkipTo(a_end)("link_text") + a_end
        
        for link in link_expr.searchString(text):
            # attributes in the  tag (like "href" shown here) are also accessible as named results
            print(link.link_text, '->', link.href)
    prints::
        pyparsing -> http://pyparsing.wikispaces.com
    """
    return _makeTags( tagStr, False )

def makeXMLTags(tagStr):
    """
    Helper to construct opening and closing tag expressions for XML, given a tag name. Matches
    tags only in the given upper/lower case.

    Example: similar to L{makeHTMLTags}
    """
    return _makeTags( tagStr, True )

def withAttribute(*args,**attrDict):
    """
    Helper to create a validating parse action to be used with start tags created
    with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag
    with a required attribute value, to avoid false matches on common tags such as
    C{} or C{
}. Call C{withAttribute} with a series of attribute names and values. Specify the list of filter attributes names and values as: - keyword arguments, as in C{(align="right")}, or - as an explicit dict with C{**} operator, when an attribute name is also a Python reserved word, as in C{**{"class":"Customer", "align":"right"}} - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) For attribute names with a namespace prefix, you must use the second form. Attribute names are matched insensitive to upper/lower case. If just testing for C{class} (with or without a namespace), use C{L{withClass}}. To verify that the attribute exists, but without specifying a value, pass C{withAttribute.ANY_VALUE} as the value. Example:: html = '''
Some text
1 4 0 1 0
1,3 2,3 1,1
this has no type
''' div,div_end = makeHTMLTags("div") # only match div tag having a type attribute with value "grid" div_grid = div().setParseAction(withAttribute(type="grid")) grid_expr = div_grid + SkipTo(div | div_end)("body") for grid_header in grid_expr.searchString(html): print(grid_header.body) # construct a match with any div tag having a type attribute, regardless of the value div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) div_expr = div_any_type + SkipTo(div | div_end)("body") for div_header in div_expr.searchString(html): print(div_header.body) prints:: 1 4 0 1 0 1 4 0 1 0 1,3 2,3 1,1 """ if args: attrs = args[:] else: attrs = attrDict.items() attrs = [(k,v) for k,v in attrs] def pa(s,l,tokens): for attrName,attrValue in attrs: if attrName not in tokens: raise ParseException(s,l,"no matching attribute " + attrName) if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % (attrName, tokens[attrName], attrValue)) return pa withAttribute.ANY_VALUE = object() def withClass(classname, namespace=''): """ Simplified version of C{L{withAttribute}} when matching on a div class - made difficult because C{class} is a reserved word in Python. Example:: html = '''
Some text
1 4 0 1 0
1,3 2,3 1,1
this <div> has no class
''' div,div_end = makeHTMLTags("div") div_grid = div().setParseAction(withClass("grid")) grid_expr = div_grid + SkipTo(div | div_end)("body") for grid_header in grid_expr.searchString(html): print(grid_header.body) div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) div_expr = div_any_type + SkipTo(div | div_end)("body") for div_header in div_expr.searchString(html): print(div_header.body) prints:: 1 4 0 1 0 1 4 0 1 0 1,3 2,3 1,1 """ classattr = "%s:class" % namespace if namespace else "class" return withAttribute(**{classattr : classname}) opAssoc = _Constants() opAssoc.LEFT = object() opAssoc.RIGHT = object() def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): """ Helper method for constructing grammars of expressions made up of operators working in a precedence hierarchy. Operators may be unary or binary, left- or right-associative. Parse actions can also be attached to operator expressions. The generated parser will also recognize the use of parentheses to override operator precedences (see example below). Note: if you define a deep operator list, you may see performance issues when using infixNotation. See L{ParserElement.enablePackrat} for a mechanism to potentially improve your parser performance. Parameters: - baseExpr - expression representing the most basic element for the nested - opList - list of tuples, one for each operator precedence level in the expression grammar; each tuple is of the form (opExpr, numTerms, rightLeftAssoc, parseAction), where: - opExpr is the pyparsing expression for the operator; may also be a string, which will be converted to a Literal; if numTerms is 3, opExpr is a tuple of two expressions, for the two operators separating the 3 terms - numTerms is the number of terms for this operator (must be 1, 2, or 3) - rightLeftAssoc is the indicator whether the operator is right or left associative, using the pyparsing-defined constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. - parseAction is the parse action to be associated with expressions matching this operator expression (the parse action tuple member may be omitted); if the parse action is passed a tuple or list of functions, this is equivalent to calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) Example:: # simple example of four-function arithmetic with ints and variable names integer = pyparsing_common.signed_integer varname = pyparsing_common.identifier arith_expr = infixNotation(integer | varname, [ ('-', 1, opAssoc.RIGHT), (oneOf('* /'), 2, opAssoc.LEFT), (oneOf('+ -'), 2, opAssoc.LEFT), ]) arith_expr.runTests(''' 5+3*6 (5+3)*6 -2--11 ''', fullDump=False) prints:: 5+3*6 [[5, '+', [3, '*', 6]]] (5+3)*6 [[[5, '+', 3], '*', 6]] -2--11 [[['-', 2], '-', ['-', 11]]] """ ret = Forward() lastExpr = baseExpr | ( lpar + ret + rpar ) for i,operDef in enumerate(opList): opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr if arity == 3: if opExpr is None or len(opExpr) != 2: raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") opExpr1, opExpr2 = opExpr thisExpr = Forward().setName(termName) if rightLeftAssoc == opAssoc.LEFT: if arity == 1: matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) elif arity == 2: if opExpr is not None: matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) else: matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) elif arity == 3: matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) else: raise ValueError("operator must be unary (1), binary (2), or ternary (3)") elif rightLeftAssoc == opAssoc.RIGHT: if arity == 1: # try to avoid LR with this extra test if not isinstance(opExpr, Optional): opExpr = Optional(opExpr) matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) elif arity == 2: if opExpr is not None: matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) else: matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) elif arity == 3: matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) else: raise ValueError("operator must be unary (1), binary (2), or ternary (3)") else: raise ValueError("operator must indicate right or left associativity") if pa: if isinstance(pa, (tuple, list)): matchExpr.setParseAction(*pa) else: matchExpr.setParseAction(pa) thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) lastExpr = thisExpr ret <<= lastExpr return ret operatorPrecedence = infixNotation """(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release.""" dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): """ Helper method for defining nested lists enclosed in opening and closing delimiters ("(" and ")" are the default). Parameters: - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression - content - expression for items within the nested lists (default=C{None}) - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) If an expression is not provided for the content argument, the nested expression will capture all whitespace-delimited content between delimiters as a list of separate values. Use the C{ignoreExpr} argument to define expressions that may contain opening or closing characters that should not be treated as opening or closing characters for nesting, such as quotedString or a comment expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. The default is L{quotedString}, but if no expressions are to be ignored, then pass C{None} for this argument. Example:: data_type = oneOf("void int short long char float double") decl_data_type = Combine(data_type + Optional(Word('*'))) ident = Word(alphas+'_', alphanums+'_') number = pyparsing_common.number arg = Group(decl_data_type + ident) LPAR,RPAR = map(Suppress, "()") code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) c_function = (decl_data_type("type") + ident("name") + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + code_body("body")) c_function.ignore(cStyleComment) source_code = ''' int is_odd(int x) { return (x%2); } int dec_to_hex(char hchar) { if (hchar >= '0' && hchar <= '9') { return (ord(hchar)-ord('0')); } else { return (10+ord(hchar)-ord('A')); } } ''' for func in c_function.searchString(source_code): print("%(name)s (%(type)s) args: %(args)s" % func) prints:: is_odd (int) args: [['int', 'x']] dec_to_hex (int) args: [['char', 'hchar']] """ if opener == closer: raise ValueError("opening and closing strings cannot be the same") if content is None: if isinstance(opener,basestring) and isinstance(closer,basestring): if len(opener) == 1 and len(closer)==1: if ignoreExpr is not None: content = (Combine(OneOrMore(~ignoreExpr + CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) ).setParseAction(lambda t:t[0].strip())) else: content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS ).setParseAction(lambda t:t[0].strip())) else: if ignoreExpr is not None: content = (Combine(OneOrMore(~ignoreExpr + ~Literal(opener) + ~Literal(closer) + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) ).setParseAction(lambda t:t[0].strip())) else: content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) ).setParseAction(lambda t:t[0].strip())) else: raise ValueError("opening and closing arguments must be strings if no content expression is given") ret = Forward() if ignoreExpr is not None: ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) else: ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) ret.setName('nested %s%s expression' % (opener,closer)) return ret def indentedBlock(blockStatementExpr, indentStack, indent=True): """ Helper method for defining space-delimited indentation blocks, such as those used to define block statements in Python source code. Parameters: - blockStatementExpr - expression defining syntax of statement that is repeated within the indented block - indentStack - list created by caller to manage indentation stack (multiple statementWithIndentedBlock expressions within a single grammar should share a common indentStack) - indent - boolean indicating whether block must be indented beyond the the current level; set to False for block of left-most statements (default=C{True}) A valid block must contain at least one C{blockStatement}. Example:: data = ''' def A(z): A1 B = 100 G = A2 A2 A3 B def BB(a,b,c): BB1 def BBA(): bba1 bba2 bba3 C D def spam(x,y): def eggs(z): pass ''' indentStack = [1] stmt = Forward() identifier = Word(alphas, alphanums) funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") func_body = indentedBlock(stmt, indentStack) funcDef = Group( funcDecl + func_body ) rvalue = Forward() funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") rvalue << (funcCall | identifier | Word(nums)) assignment = Group(identifier + "=" + rvalue) stmt << ( funcDef | assignment | identifier ) module_body = OneOrMore(stmt) parseTree = module_body.parseString(data) parseTree.pprint() prints:: [['def', 'A', ['(', 'z', ')'], ':', [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], 'B', ['def', 'BB', ['(', 'a', 'b', 'c', ')'], ':', [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], 'C', 'D', ['def', 'spam', ['(', 'x', 'y', ')'], ':', [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] """ def checkPeerIndent(s,l,t): if l >= len(s): return curCol = col(l,s) if curCol != indentStack[-1]: if curCol > indentStack[-1]: raise ParseFatalException(s,l,"illegal nesting") raise ParseException(s,l,"not a peer entry") def checkSubIndent(s,l,t): curCol = col(l,s) if curCol > indentStack[-1]: indentStack.append( curCol ) else: raise ParseException(s,l,"not a subentry") def checkUnindent(s,l,t): if l >= len(s): return curCol = col(l,s) if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): raise ParseException(s,l,"not an unindent") indentStack.pop() NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') PEER = Empty().setParseAction(checkPeerIndent).setName('') UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') if indent: smExpr = Group( Optional(NL) + #~ FollowedBy(blockStatementExpr) + INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) else: smExpr = Group( Optional(NL) + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) blockStatementExpr.ignore(_bslash + LineEnd()) return smExpr.setName('indented block') alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) _htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) commonHTMLEntity = Regex('&(?P' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") def replaceHTMLEntity(t): """Helper parser action to replace common HTML entities with their special characters""" return _htmlEntityMap.get(t.entity) # it's easy to get these comment structures wrong - they're very common, so may as well make them available cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") "Comment of the form C{/* ... */}" htmlComment = Regex(r"").setName("HTML comment") "Comment of the form C{}" restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") "Comment of the form C{// ... (to end of line)}" cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") "Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" javaStyleComment = cppStyleComment "Same as C{L{cppStyleComment}}" pythonStyleComment = Regex(r"#.*").setName("Python style comment") "Comment of the form C{# ... (to end of line)}" _commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + Optional( Word(" \t") + ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") """(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" # some other useful expressions - using lower-case class name since we are really using this as a namespace class pyparsing_common: """ Here are some common low-level expressions that may be useful in jump-starting parser development: - numeric forms (L{integers}, L{reals}, L{scientific notation}) - common L{programming identifiers} - network addresses (L{MAC}, L{IPv4}, L{IPv6}) - ISO8601 L{dates} and L{datetime} - L{UUID} - L{comma-separated list} Parse actions: - C{L{convertToInteger}} - C{L{convertToFloat}} - C{L{convertToDate}} - C{L{convertToDatetime}} - C{L{stripHTMLTags}} - C{L{upcaseTokens}} - C{L{downcaseTokens}} Example:: pyparsing_common.number.runTests(''' # any int or real number, returned as the appropriate type 100 -100 +100 3.14159 6.02e23 1e-12 ''') pyparsing_common.fnumber.runTests(''' # any int or real number, returned as float 100 -100 +100 3.14159 6.02e23 1e-12 ''') pyparsing_common.hex_integer.runTests(''' # hex numbers 100 FF ''') pyparsing_common.fraction.runTests(''' # fractions 1/2 -3/4 ''') pyparsing_common.mixed_integer.runTests(''' # mixed fractions 1 1/2 -3/4 1-3/4 ''') import uuid pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) pyparsing_common.uuid.runTests(''' # uuid 12345678-1234-5678-1234-567812345678 ''') prints:: # any int or real number, returned as the appropriate type 100 [100] -100 [-100] +100 [100] 3.14159 [3.14159] 6.02e23 [6.02e+23] 1e-12 [1e-12] # any int or real number, returned as float 100 [100.0] -100 [-100.0] +100 [100.0] 3.14159 [3.14159] 6.02e23 [6.02e+23] 1e-12 [1e-12] # hex numbers 100 [256] FF [255] # fractions 1/2 [0.5] -3/4 [-0.75] # mixed fractions 1 [1] 1/2 [0.5] -3/4 [-0.75] 1-3/4 [1.75] # uuid 12345678-1234-5678-1234-567812345678 [UUID('12345678-1234-5678-1234-567812345678')] """ convertToInteger = tokenMap(int) """ Parse action for converting parsed integers to Python int """ convertToFloat = tokenMap(float) """ Parse action for converting parsed numbers to Python float """ integer = Word(nums).setName("integer").setParseAction(convertToInteger) """expression that parses an unsigned integer, returns an int""" hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) """expression that parses a hexadecimal integer, returns an int""" signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) """expression that parses an integer with optional leading sign, returns an int""" fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") """fractional expression of an integer divided by an integer, returns a float""" fraction.addParseAction(lambda t: t[0]/t[-1]) mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" mixed_integer.addParseAction(sum) real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) """expression that parses a floating point number and returns a float""" sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) """expression that parses a floating point number with optional scientific notation and returns a float""" # streamlining this expression makes the docs nicer-looking number = (sci_real | real | signed_integer).streamline() """any numeric expression, returns the corresponding Python type""" fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) """any int or real number, returned as float""" identifier = Word(alphas+'_', alphanums+'_').setName("identifier") """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") "IPv4 address (C{0.0.0.0 - 255.255.255.255})" _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") "IPv6 address (long, short, or mixed form)" mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" @staticmethod def convertToDate(fmt="%Y-%m-%d"): """ Helper to create a parse action for converting parsed date string to Python datetime.date Params - - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) Example:: date_expr = pyparsing_common.iso8601_date.copy() date_expr.setParseAction(pyparsing_common.convertToDate()) print(date_expr.parseString("1999-12-31")) prints:: [datetime.date(1999, 12, 31)] """ def cvt_fn(s,l,t): try: return datetime.strptime(t[0], fmt).date() except ValueError as ve: raise ParseException(s, l, str(ve)) return cvt_fn @staticmethod def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): """ Helper to create a parse action for converting parsed datetime string to Python datetime.datetime Params - - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) Example:: dt_expr = pyparsing_common.iso8601_datetime.copy() dt_expr.setParseAction(pyparsing_common.convertToDatetime()) print(dt_expr.parseString("1999-12-31T23:59:59.999")) prints:: [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] """ def cvt_fn(s,l,t): try: return datetime.strptime(t[0], fmt) except ValueError as ve: raise ParseException(s, l, str(ve)) return cvt_fn iso8601_date = Regex(r'(?P\d{4})(?:-(?P\d\d)(?:-(?P\d\d))?)?').setName("ISO8601 date") "ISO8601 date (C{yyyy-mm-dd})" iso8601_datetime = Regex(r'(?P\d{4})-(?P\d\d)-(?P\d\d)[T ](?P\d\d):(?P\d\d)(:(?P\d\d(\.\d*)?)?)?(?PZ|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() @staticmethod def stripHTMLTags(s, l, tokens): """ Parse action to remove HTML tags from web page HTML source Example:: # strip HTML links from normal text text = 'More info at the
pyparsing wiki page' td,td_end = makeHTMLTags("TD") table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page' """ return pyparsing_common._html_stripper.transformString(tokens[0]) _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') + Optional( White(" \t") ) ) ).streamline().setName("commaItem") comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) """Parse action to convert tokens to upper case.""" downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) """Parse action to convert tokens to lower case.""" if __name__ == "__main__": selectToken = CaselessLiteral("select") fromToken = CaselessLiteral("from") ident = Word(alphas, alphanums + "_$") columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) columnNameList = Group(delimitedList(columnName)).setName("columns") columnSpec = ('*' | columnNameList) tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) tableNameList = Group(delimitedList(tableName)).setName("tables") simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") # demo runTests method, including embedded comments in test string simpleSQL.runTests(""" # '*' as column list and dotted table name select * from SYS.XYZZY # caseless match on "SELECT", and casts back to "select" SELECT * from XYZZY, ABC # list of column names, and mixed case SELECT keyword Select AA,BB,CC from Sys.dual # multiple tables Select A, B, C from Sys.dual, Table2 # invalid SELECT keyword - should fail Xelect A, B, C from Sys.dual # incomplete command - should fail Select # invalid column name - should fail Select ^^^ frox Sys.dual """) pyparsing_common.number.runTests(""" 100 -100 +100 3.14159 6.02e23 1e-12 """) # any int or real number, returned as float pyparsing_common.fnumber.runTests(""" 100 -100 +100 3.14159 6.02e23 1e-12 """) pyparsing_common.hex_integer.runTests(""" 100 FF """) import uuid pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) pyparsing_common.uuid.runTests(""" 12345678-1234-5678-1234-567812345678 """) PKH];python3.10/site-packages/pip-21.3.1.dist-info/top_level.txtnu[pip PKH]"BB9python3.10/site-packages/pip-21.3.1.dist-info/LICENSE.txtnu[Copyright (c) 2008-2021 The pip developers (see AUTHORS.txt file) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PKH]ԍ1gg=python3.10/site-packages/pip-21.3.1.dist-info/direct_url.jsonnu[{"archive_info": {}, "url": "file:///builddir/build/BUILD/pip-21.3.1/dist/pip-21.3.1-py3-none-any.whl"}PKH]#7python3.10/site-packages/pip-21.3.1.dist-info/INSTALLERnu[rpm PKH]&+''4python3.10/site-packages/pip-21.3.1.dist-info/RECORDnu[../../../bin/pip,sha256=yH4SMgJWRL08-YBTdY73Jx4vSF7GW5vlKPOOFivVhzM,235 ../../../bin/pip3,sha256=yH4SMgJWRL08-YBTdY73Jx4vSF7GW5vlKPOOFivVhzM,235 ../../../bin/pip3.10,sha256=yH4SMgJWRL08-YBTdY73Jx4vSF7GW5vlKPOOFivVhzM,235 ../../../bin/pip3.10,sha256=yH4SMgJWRL08-YBTdY73Jx4vSF7GW5vlKPOOFivVhzM,235 pip-21.3.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 pip-21.3.1.dist-info/LICENSE.txt,sha256=I6c2HCsVgQKLxiO52ivSSZeryqR4Gs5q1ESjeUT42uE,1090 pip-21.3.1.dist-info/METADATA,sha256=PjWcvFEqJd4gOfiQam8il34_wPNKxf8ubyYI2wYm7tc,4216 pip-21.3.1.dist-info/RECORD,, pip-21.3.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip-21.3.1.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 pip-21.3.1.dist-info/direct_url.json,sha256=Vl58sluk6OBfGWPA_3cYakPqWvzPs77FuaR2htQJdG0,103 pip-21.3.1.dist-info/entry_points.txt,sha256=vUvIlB_ga0fFQuWvFEq6uJKftMG_HNuoe4kgXkb5rNY,126 pip-21.3.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 pip/__init__.py,sha256=798yhPIf6eMHi7R5Ogb3BJ5ALJ0Id8IwEuOSU2DFlp0,357 pip/__main__.py,sha256=mXwWDftNLMKfwVqKFWGE_uuBZvGSIiUELhLkeysIuZc,1198 pip/__pycache__/__init__.cpython-310.pyc,, pip/__pycache__/__main__.cpython-310.pyc,, pip/_internal/__init__.py,sha256=FU88-ODK1jGlVF2Qxp1gJqTwg0wujj12LayXQgFhlh8,587 pip/_internal/__pycache__/__init__.cpython-310.pyc,, pip/_internal/__pycache__/build_env.cpython-310.pyc,, pip/_internal/__pycache__/cache.cpython-310.pyc,, pip/_internal/__pycache__/configuration.cpython-310.pyc,, pip/_internal/__pycache__/exceptions.cpython-310.pyc,, pip/_internal/__pycache__/main.cpython-310.pyc,, pip/_internal/__pycache__/pyproject.cpython-310.pyc,, pip/_internal/__pycache__/self_outdated_check.cpython-310.pyc,, pip/_internal/__pycache__/wheel_builder.cpython-310.pyc,, pip/_internal/build_env.py,sha256=uIg4HJDgZK542FXVTl3jkPDNbklNgb8Rj6DeZef_oS8,9950 pip/_internal/cache.py,sha256=71eaYwrls34HJ6gzbmmYiotiKhPNFTM_tqYJXD5nf3s,9441 pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132 pip/_internal/cli/__pycache__/__init__.cpython-310.pyc,, pip/_internal/cli/__pycache__/autocompletion.cpython-310.pyc,, pip/_internal/cli/__pycache__/base_command.cpython-310.pyc,, pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pyc,, pip/_internal/cli/__pycache__/command_context.cpython-310.pyc,, pip/_internal/cli/__pycache__/main.cpython-310.pyc,, pip/_internal/cli/__pycache__/main_parser.cpython-310.pyc,, pip/_internal/cli/__pycache__/parser.cpython-310.pyc,, pip/_internal/cli/__pycache__/progress_bars.cpython-310.pyc,, pip/_internal/cli/__pycache__/req_command.cpython-310.pyc,, pip/_internal/cli/__pycache__/spinners.cpython-310.pyc,, pip/_internal/cli/__pycache__/status_codes.cpython-310.pyc,, pip/_internal/cli/autocompletion.py,sha256=NK5yqe49SgExZOCFVEUT5Bf0QV2CuITGK27WSo2MWg8,6399 pip/_internal/cli/base_command.py,sha256=oFuvjLsYE17V67L1dHeTo-YePZN97RKpOuGEXwCKwLc,7790 pip/_internal/cli/cmdoptions.py,sha256=o6hueHSc3VWZ-_do9eeoZKEaxqh18zlXKAzVZ00Kg-o,28391 pip/_internal/cli/command_context.py,sha256=a1pBBvvGLDiZ1Kw64_4tT6HmRTwYDoYy8JFgG5Czn7s,760 pip/_internal/cli/main.py,sha256=ioJ8IVlb2K1qLOxR-tXkee9lURhYV89CDM71MKag7YY,2472 pip/_internal/cli/main_parser.py,sha256=Q9TnytfuC5Z2JSjBFWVGtEdYLFy7rukNIb04movHdAo,2614 pip/_internal/cli/parser.py,sha256=CDXTuFr2UD8ozOlZYf1KDziQdo9-X_IaYOiUcyJQwrA,10788 pip/_internal/cli/progress_bars.py,sha256=ha8wowclY8_PaoM0cz4G6qK37zjnzuxQ-ydOtzx4EMI,8300 pip/_internal/cli/req_command.py,sha256=La6J8YonTxoPtJ8HMPN4RTKyzg0VS_R4vxfVf_HmFZw,17097 pip/_internal/cli/spinners.py,sha256=TFhjxtOnLeNJ5YmRvQm4eKPgPbJNkZiqO8jOXuxRaYU,5076 pip/_internal/cli/status_codes.py,sha256=sEFHUaUJbqv8iArL3HAtcztWZmGOFX01hTesSytDEh0,116 pip/_internal/commands/__init__.py,sha256=Vc1HjsLEtyCh7506OozPHPKXe2Hk-z9cFkFF3BMj1lM,3736 pip/_internal/commands/__pycache__/__init__.cpython-310.pyc,, pip/_internal/commands/__pycache__/cache.cpython-310.pyc,, pip/_internal/commands/__pycache__/check.cpython-310.pyc,, pip/_internal/commands/__pycache__/completion.cpython-310.pyc,, pip/_internal/commands/__pycache__/configuration.cpython-310.pyc,, pip/_internal/commands/__pycache__/debug.cpython-310.pyc,, pip/_internal/commands/__pycache__/download.cpython-310.pyc,, pip/_internal/commands/__pycache__/freeze.cpython-310.pyc,, pip/_internal/commands/__pycache__/hash.cpython-310.pyc,, pip/_internal/commands/__pycache__/help.cpython-310.pyc,, pip/_internal/commands/__pycache__/index.cpython-310.pyc,, pip/_internal/commands/__pycache__/install.cpython-310.pyc,, pip/_internal/commands/__pycache__/list.cpython-310.pyc,, pip/_internal/commands/__pycache__/search.cpython-310.pyc,, pip/_internal/commands/__pycache__/show.cpython-310.pyc,, pip/_internal/commands/__pycache__/uninstall.cpython-310.pyc,, pip/_internal/commands/__pycache__/wheel.cpython-310.pyc,, pip/_internal/commands/cache.py,sha256=p9gvc6W_xgxE2zO0o8NXqO1gGJEinEK42qEC-a7Cnuk,7524 pip/_internal/commands/check.py,sha256=0gjXR7j36xJT5cs2heYU_dfOfpnFfzX8OoPNNoKhqdM,1685 pip/_internal/commands/completion.py,sha256=kTG_I1VR3N5kGC4Ma9pQTSoY9Q1URCrNyseHSQ-rCL4,2958 pip/_internal/commands/configuration.py,sha256=arE8vLstjBg-Ar1krXF-bBmT1qBtnL7Fpk-NVh38a0U,8944 pip/_internal/commands/debug.py,sha256=krET-y45CnQzXwKR1qA3M_tJE4LE2vnQtm3yfGyDSnE,6629 pip/_internal/commands/download.py,sha256=p4lmYDgawRrwDFUpde_-1Gld45FnsMNHUFtOWFUCcSE,4904 pip/_internal/commands/freeze.py,sha256=gCjoD6foBZPBAAYx5t8zZLkJhsF_ZRtnb3dPuD7beO8,2951 pip/_internal/commands/hash.py,sha256=EVVOuvGtoPEdFi8SNnmdqlCQrhCxV-kJsdwtdcCnXGQ,1703 pip/_internal/commands/help.py,sha256=gcc6QDkcgHMOuAn5UxaZwAStsRBrnGSn_yxjS57JIoM,1132 pip/_internal/commands/index.py,sha256=1VVXXj5MsI2qH-N7uniQQyVkg-KCn_RdjiyiUmkUS5U,4762 pip/_internal/commands/install.py,sha256=HTWdTb72Bcrm2tA_d55_hX6yQbchnr_XRdA2Xs8uApU,27851 pip/_internal/commands/list.py,sha256=SnCh19e5zQKonNP7j25c_xru0Wm7wWWF8j49f-Dy9Bw,12203 pip/_internal/commands/search.py,sha256=sbBZiARRc050QquOKcCvOr2K3XLsoYebLKZGRi__iUI,5697 pip/_internal/commands/show.py,sha256=OREbPHF6UzvQiGLC1UIjG52Kc_jYDgcXZMYzgKXMbBI,8064 pip/_internal/commands/uninstall.py,sha256=DNTYAGJNljMO_YYBxrpcwj0FEl7lo_P55_98O6g2TNk,3526 pip/_internal/commands/wheel.py,sha256=xGSwLPYUM7jP_McD-wnM4D3zsP0n-NSkHFp4d0mAWIg,6168 pip/_internal/configuration.py,sha256=dKHBEl8aXnqVuRB0NW7Nz7lyYMwr7XCfkMZvUORaSRo,13153 pip/_internal/distributions/__init__.py,sha256=Hq6kt6gXBgjNit5hTTWLAzeCNOKoB-N0pGYSqehrli8,858 pip/_internal/distributions/__pycache__/__init__.cpython-310.pyc,, pip/_internal/distributions/__pycache__/base.cpython-310.pyc,, pip/_internal/distributions/__pycache__/installed.cpython-310.pyc,, pip/_internal/distributions/__pycache__/sdist.cpython-310.pyc,, pip/_internal/distributions/__pycache__/wheel.cpython-310.pyc,, pip/_internal/distributions/base.py,sha256=3FUYD8Gb4YuSu3pggC_FRctZBDbpm5ZK89tPksIUjoE,1172 pip/_internal/distributions/installed.py,sha256=QObf6KALGtwGx-Ap3Ua5FfcfaRMXWOk_wcrm7n5gYII,767 pip/_internal/distributions/sdist.py,sha256=3fsErGhAWdGzuO7Wea0F_8b9fKyUL1PoYet273OoAoM,5598 pip/_internal/distributions/wheel.py,sha256=-NgzdIs-w_hcer_U81yzgpVTljJRg5m79xufqvbjv0s,1115 pip/_internal/exceptions.py,sha256=XyfiRZn2X8WR61X-JF50BU72TdmVkneWPy9cnuKv2Rg,12762 pip/_internal/index/__init__.py,sha256=vpt-JeTZefh8a-FC22ZeBSXFVbuBcXSGiILhQZJaNpQ,30 pip/_internal/index/__pycache__/__init__.cpython-310.pyc,, pip/_internal/index/__pycache__/collector.cpython-310.pyc,, pip/_internal/index/__pycache__/package_finder.cpython-310.pyc,, pip/_internal/index/__pycache__/sources.cpython-310.pyc,, pip/_internal/index/collector.py,sha256=7rhUeH0IU_dUMk13-lBAN9czRuJ6dbG76Un7xuQ36Ck,17534 pip/_internal/index/package_finder.py,sha256=_N9LIcwAXbGDN3BUDlikSB93WI9PHv3MvkJ4YapfrPY,36344 pip/_internal/index/sources.py,sha256=SVyPitv08-Qalh2_Bk5diAJ9GAA_d-a93koouQodAG0,6557 pip/_internal/locations/__init__.py,sha256=CpH6Cz9HSZ0csN_KPtOcvS9TGYLb7ZNGtCAAmVtjXW0,14444 pip/_internal/locations/__pycache__/__init__.cpython-310.pyc,, pip/_internal/locations/__pycache__/_distutils.cpython-310.pyc,, pip/_internal/locations/__pycache__/_sysconfig.cpython-310.pyc,, pip/_internal/locations/__pycache__/base.cpython-310.pyc,, pip/_internal/locations/_distutils.py,sha256=Sk7tw8ZP1DWMYJ8MibABsa8IME2Ejv1PKeGlYQCBTZc,5871 pip/_internal/locations/_sysconfig.py,sha256=LQNKTJKyjVqxXaPntlBwdUqTG1xwYf6GVCKMbyRJx5M,7918 pip/_internal/locations/base.py,sha256=x5D1ONktmPJd8nnUTh-ELsAJ7fiXA-k-0a_vhfi2_Us,1579 pip/_internal/main.py,sha256=r-UnUe8HLo5XFJz8inTcOOTiu_sxNhgHb6VwlGUllOI,340 pip/_internal/metadata/__init__.py,sha256=HzTS3lRukzn-MJaEZkUQhAFe6ulxvNe7nNoBvUzy-DU,1660 pip/_internal/metadata/__pycache__/__init__.cpython-310.pyc,, pip/_internal/metadata/__pycache__/base.cpython-310.pyc,, pip/_internal/metadata/__pycache__/pkg_resources.cpython-310.pyc,, pip/_internal/metadata/base.py,sha256=gbNbb9blWO5hejmror-2n4_wLuYVrTyqwUluY9OmnMg,11103 pip/_internal/metadata/pkg_resources.py,sha256=-LiuojtAfl3yhNx8rnUKYN3ECBVCVcDWszCupithXAw,5089 pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63 pip/_internal/models/__pycache__/__init__.cpython-310.pyc,, pip/_internal/models/__pycache__/candidate.cpython-310.pyc,, pip/_internal/models/__pycache__/direct_url.cpython-310.pyc,, pip/_internal/models/__pycache__/format_control.cpython-310.pyc,, pip/_internal/models/__pycache__/index.cpython-310.pyc,, pip/_internal/models/__pycache__/link.cpython-310.pyc,, pip/_internal/models/__pycache__/scheme.cpython-310.pyc,, pip/_internal/models/__pycache__/search_scope.cpython-310.pyc,, pip/_internal/models/__pycache__/selection_prefs.cpython-310.pyc,, pip/_internal/models/__pycache__/target_python.cpython-310.pyc,, pip/_internal/models/__pycache__/wheel.cpython-310.pyc,, pip/_internal/models/candidate.py,sha256=6pcABsaR7CfIHlbJbr2_kMkVJFL_yrYjTx6SVWUnCPQ,990 pip/_internal/models/direct_url.py,sha256=7XtGQSLLDQb5ZywI2EMnnLcddtf5CJLx44lMtTHPxFw,6350 pip/_internal/models/format_control.py,sha256=DJpMYjxeYKKQdwNcML2_F0vtAh-qnKTYe-CpTxQe-4g,2520 pip/_internal/models/index.py,sha256=tYnL8oxGi4aSNWur0mG8DAP7rC6yuha_MwJO8xw0crI,1030 pip/_internal/models/link.py,sha256=hoT_qsOBAgLBm9GKqpBrNF_mrEXeGXQE-aH_RX2cGgg,9817 pip/_internal/models/scheme.py,sha256=3EFQp_ICu_shH1-TBqhl0QAusKCPDFOlgHFeN4XowWs,738 pip/_internal/models/search_scope.py,sha256=LwloG0PJAmtI1hFXIypsD95kWE9xfR5hf_a2v1Vw7sk,4520 pip/_internal/models/selection_prefs.py,sha256=KZdi66gsR-_RUXUr9uejssk3rmTHrQVJWeNA2sV-VSY,1907 pip/_internal/models/target_python.py,sha256=qKpZox7J8NAaPmDs5C_aniwfPDxzvpkrCKqfwndG87k,3858 pip/_internal/models/wheel.py,sha256=hN9Ub-m-cAJCajCcQHyQNsqpcDCbPPDlEzBDwaBMc14,3500 pip/_internal/network/__init__.py,sha256=jf6Tt5nV_7zkARBrKojIXItgejvoegVJVKUbhAa5Ioc,50 pip/_internal/network/__pycache__/__init__.cpython-310.pyc,, pip/_internal/network/__pycache__/auth.cpython-310.pyc,, pip/_internal/network/__pycache__/cache.cpython-310.pyc,, pip/_internal/network/__pycache__/download.cpython-310.pyc,, pip/_internal/network/__pycache__/lazy_wheel.cpython-310.pyc,, pip/_internal/network/__pycache__/session.cpython-310.pyc,, pip/_internal/network/__pycache__/utils.cpython-310.pyc,, pip/_internal/network/__pycache__/xmlrpc.cpython-310.pyc,, pip/_internal/network/auth.py,sha256=a3C7Xaa8kTJjXkdi_wrUjqaySc8Z9Yz7U6QIbXfzMyc,12190 pip/_internal/network/cache.py,sha256=HoprMCecwd4IS2wDZowc9B_OpaBlFjJYJl4xOxvtuwU,2100 pip/_internal/network/download.py,sha256=VmiR-KKIBugShZS4JlD7N8mq3hErx-0fK-D8aTYU3Og,6016 pip/_internal/network/lazy_wheel.py,sha256=1b8ZJ1w4bSBzpGzGwJR_CL2yQ6AFIwWQkS1vbPPw2XU,7627 pip/_internal/network/session.py,sha256=38IKGKC64MTVUIH5XOR1hr2pOCzp39RccykdmGAvqRU,16729 pip/_internal/network/utils.py,sha256=igLlTu_-q0LmL8FdJKq-Uj7AT_owrQ-T9FfyarkhK5U,4059 pip/_internal/network/xmlrpc.py,sha256=AzQgG4GgS152_cqmGr_Oz2MIXsCal-xfsis7fA7nmU0,1791 pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_internal/operations/__pycache__/__init__.cpython-310.pyc,, pip/_internal/operations/__pycache__/check.cpython-310.pyc,, pip/_internal/operations/__pycache__/freeze.cpython-310.pyc,, pip/_internal/operations/__pycache__/prepare.cpython-310.pyc,, pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_internal/operations/build/__pycache__/__init__.cpython-310.pyc,, pip/_internal/operations/build/__pycache__/metadata.cpython-310.pyc,, pip/_internal/operations/build/__pycache__/metadata_editable.cpython-310.pyc,, pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-310.pyc,, pip/_internal/operations/build/__pycache__/wheel.cpython-310.pyc,, pip/_internal/operations/build/__pycache__/wheel_editable.cpython-310.pyc,, pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-310.pyc,, pip/_internal/operations/build/metadata.py,sha256=KEsyrRFOBs2jhR-AcjyJyeV5GlsK1ubQqAB1j-b0Zu4,1119 pip/_internal/operations/build/metadata_editable.py,sha256=RnA8UgQqZwtBjBdqi1DW1gI3xaZ7qhKp1Xd-0YTktSk,1177 pip/_internal/operations/build/metadata_legacy.py,sha256=hjAJ75iKuJfKQYALZD0U6wJ7ElJ_BAEvjDxF8b9_l5k,1945 pip/_internal/operations/build/wheel.py,sha256=AO9XnTGhTgHtZmU8Dkbfo1OGr41rBuSDjIgAa4zUKgE,1063 pip/_internal/operations/build/wheel_editable.py,sha256=TVETY-L_M_dSEKBhTIcQOP75zKVXw8tuq1U354Mm30A,1405 pip/_internal/operations/build/wheel_legacy.py,sha256=aFMVOvyG-_CAIuXEVxuPJkz5UfCppSeu9FBPzn2tWvI,3047 pip/_internal/operations/check.py,sha256=ca4O9CkPt9Em9sLCf3H0iVt1GIcW7M8C0U5XooaBuT4,5109 pip/_internal/operations/freeze.py,sha256=ZiYw5GlUpLVx4VJHz4S1AP2JFNyvH0iq5kpcYj2ovyw,9770 pip/_internal/operations/install/__init__.py,sha256=mX7hyD2GNBO2mFGokDQ30r_GXv7Y_PLdtxcUv144e-s,51 pip/_internal/operations/install/__pycache__/__init__.cpython-310.pyc,, pip/_internal/operations/install/__pycache__/editable_legacy.cpython-310.pyc,, pip/_internal/operations/install/__pycache__/legacy.cpython-310.pyc,, pip/_internal/operations/install/__pycache__/wheel.cpython-310.pyc,, pip/_internal/operations/install/editable_legacy.py,sha256=J4VCOHvk_BgA_wG02WmlDtSWLwZJ5S_g9SXBkjYojaw,1298 pip/_internal/operations/install/legacy.py,sha256=YKrZvH894Iqf2oEkYqF9O7CK1DjTgfZCP3R9Azpjeqo,4158 pip/_internal/operations/install/wheel.py,sha256=QuQyCZE-XjuJjDYRixo40oUt2ucFhNmSrCbcXY7A9aE,27412 pip/_internal/operations/prepare.py,sha256=Dg-lFYsFhYeib8NuQvGOxd0wxcmTqXfe_c5zYb3ep64,23838 pip/_internal/pyproject.py,sha256=YgcyleTgyuh7NwGH9j8_21htqnF_VxgKiPc4ecLBWKk,7215 pip/_internal/req/__init__.py,sha256=A7mUvT1KAcCYP3H7gUOTx2GRMlgoDur3H68Q0OJqM5A,2793 pip/_internal/req/__pycache__/__init__.cpython-310.pyc,, pip/_internal/req/__pycache__/constructors.cpython-310.pyc,, pip/_internal/req/__pycache__/req_file.cpython-310.pyc,, pip/_internal/req/__pycache__/req_install.cpython-310.pyc,, pip/_internal/req/__pycache__/req_set.cpython-310.pyc,, pip/_internal/req/__pycache__/req_tracker.cpython-310.pyc,, pip/_internal/req/__pycache__/req_uninstall.cpython-310.pyc,, pip/_internal/req/constructors.py,sha256=FVWkWeGt3fK0DTC3Gurd2jglp_Z10CK-abd6yM3HD-A,15285 pip/_internal/req/req_file.py,sha256=5N8OTouPCof-305StC2YK9HBxQMw-xO46skRoBPbkZo,17421 pip/_internal/req/req_install.py,sha256=BLPPMm9obLThHs1Fp8mvaO02jHRrEZ6De4oAU_QDkx4,33866 pip/_internal/req/req_set.py,sha256=kHYiLvkKRx21WaLTwOI-54Ng0SSzZZ9SE7FD0PsfvYA,7584 pip/_internal/req/req_tracker.py,sha256=jK7JDu-Wt73X-gqozrFtgJVlUlnQo0P4IQ4x4_gPlfM,4117 pip/_internal/req/req_uninstall.py,sha256=Uf8Kx-PgoQIudFq9Y7sFP-uz_I6x1gEfPpJJxujOf14,23748 pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_internal/resolution/__pycache__/__init__.cpython-310.pyc,, pip/_internal/resolution/__pycache__/base.cpython-310.pyc,, pip/_internal/resolution/base.py,sha256=qlmh325SBVfvG6Me9gc5Nsh5sdwHBwzHBq6aEXtKsLA,583 pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_internal/resolution/legacy/__pycache__/__init__.cpython-310.pyc,, pip/_internal/resolution/legacy/__pycache__/resolver.cpython-310.pyc,, pip/_internal/resolution/legacy/resolver.py,sha256=IcQ57uIyki-hCBm4e5H8zZt840VzfxdWQFZNT9oYBH8,18449 pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-310.pyc,, pip/_internal/resolution/resolvelib/__pycache__/base.cpython-310.pyc,, pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-310.pyc,, pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-310.pyc,, pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-310.pyc,, pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-310.pyc,, pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-310.pyc,, pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-310.pyc,, pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-310.pyc,, pip/_internal/resolution/resolvelib/base.py,sha256=u1O4fkvCO4mhmu5i32xrDv9AX5NgUci_eYVyBDQhTIM,5220 pip/_internal/resolution/resolvelib/candidates.py,sha256=5q66J90AoMKKwy1HsdXvEeleOJG8QkAbo8OidFekee0,18210 pip/_internal/resolution/resolvelib/factory.py,sha256=fa97Ja0EbOYkyz5haXTUPbnR3H5MOLvouY6n8OjupSs,27391 pip/_internal/resolution/resolvelib/found_candidates.py,sha256=hvL3Hoa9VaYo-qEOZkBi2Iqw251UDxPz-uMHVaWmLpE,5705 pip/_internal/resolution/resolvelib/provider.py,sha256=HUMHvkU001rtlqvs11NPmMtlyMMLlVQfAl6qXdsLxZQ,9205 pip/_internal/resolution/resolvelib/reporter.py,sha256=3ZVVYrs5PqvLFJkGLcuXoMK5mTInFzl31xjUpDBpZZk,2526 pip/_internal/resolution/resolvelib/requirements.py,sha256=pcsnwz7txyDNZUEOWJOZEfivy3COWHPf_DIU7fwZ-Kk,5455 pip/_internal/resolution/resolvelib/resolver.py,sha256=bkrMZs_jJHP_KFAbg36-lcN4Ums7ESgllup8piHXOz0,9580 pip/_internal/self_outdated_check.py,sha256=nVLSc0nl4JZ9VI7GsZvblE-zzT-T5ofmMgplned8s_s,6393 pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_internal/utils/__pycache__/__init__.cpython-310.pyc,, pip/_internal/utils/__pycache__/_log.cpython-310.pyc,, pip/_internal/utils/__pycache__/appdirs.cpython-310.pyc,, pip/_internal/utils/__pycache__/compat.cpython-310.pyc,, pip/_internal/utils/__pycache__/compatibility_tags.cpython-310.pyc,, pip/_internal/utils/__pycache__/datetime.cpython-310.pyc,, pip/_internal/utils/__pycache__/deprecation.cpython-310.pyc,, pip/_internal/utils/__pycache__/direct_url_helpers.cpython-310.pyc,, pip/_internal/utils/__pycache__/distutils_args.cpython-310.pyc,, pip/_internal/utils/__pycache__/egg_link.cpython-310.pyc,, pip/_internal/utils/__pycache__/encoding.cpython-310.pyc,, pip/_internal/utils/__pycache__/entrypoints.cpython-310.pyc,, pip/_internal/utils/__pycache__/filesystem.cpython-310.pyc,, pip/_internal/utils/__pycache__/filetypes.cpython-310.pyc,, pip/_internal/utils/__pycache__/glibc.cpython-310.pyc,, pip/_internal/utils/__pycache__/hashes.cpython-310.pyc,, pip/_internal/utils/__pycache__/inject_securetransport.cpython-310.pyc,, pip/_internal/utils/__pycache__/logging.cpython-310.pyc,, pip/_internal/utils/__pycache__/misc.cpython-310.pyc,, pip/_internal/utils/__pycache__/models.cpython-310.pyc,, pip/_internal/utils/__pycache__/packaging.cpython-310.pyc,, pip/_internal/utils/__pycache__/parallel.cpython-310.pyc,, pip/_internal/utils/__pycache__/pkg_resources.cpython-310.pyc,, pip/_internal/utils/__pycache__/setuptools_build.cpython-310.pyc,, pip/_internal/utils/__pycache__/subprocess.cpython-310.pyc,, pip/_internal/utils/__pycache__/temp_dir.cpython-310.pyc,, pip/_internal/utils/__pycache__/unpacking.cpython-310.pyc,, pip/_internal/utils/__pycache__/urls.cpython-310.pyc,, pip/_internal/utils/__pycache__/virtualenv.cpython-310.pyc,, pip/_internal/utils/__pycache__/wheel.cpython-310.pyc,, pip/_internal/utils/_log.py,sha256=-jHLOE_THaZz5BFcCnoSL9EYAtJ0nXem49s9of4jvKw,1015 pip/_internal/utils/appdirs.py,sha256=swgcTKOm3daLeXTW6v5BUS2Ti2RvEnGRQYH_yDXklAo,1665 pip/_internal/utils/compat.py,sha256=ACyBfLgj3_XG-iA5omEDrXqDM0cQKzi8h8HRBInzG6Q,1884 pip/_internal/utils/compatibility_tags.py,sha256=ydin8QG8BHqYRsPY4OL6cmb44CbqXl1T0xxS97VhHkk,5377 pip/_internal/utils/datetime.py,sha256=m21Y3wAtQc-ji6Veb6k_M5g6A0ZyFI4egchTdnwh-pQ,242 pip/_internal/utils/deprecation.py,sha256=NKo8VqLioJ4nnXXGmW4KdasxF90EFHkZaHeX1fT08C8,3627 pip/_internal/utils/direct_url_helpers.py,sha256=6F1tc2rcKaCZmgfVwsE6ObIe_Pux23mUVYA-2D9wCFc,3206 pip/_internal/utils/distutils_args.py,sha256=mcAscyp80vTt3xAGTipnpgc83V-_wCvydNELVXLq7JI,1249 pip/_internal/utils/egg_link.py,sha256=5MVlpz5LirT4iLQq86OYzjXaYF0D4Qk1dprEI7ThST4,2203 pip/_internal/utils/encoding.py,sha256=bdZ3YgUpaOEBI5MP4-DEXiQarCW3V0rxw1kRz-TaU1Q,1169 pip/_internal/utils/entrypoints.py,sha256=g4QKi37JkZ2r6A9WbYLMwVzOiE3dn_lsqVhaFy0Erq0,1130 pip/_internal/utils/filesystem.py,sha256=rrl-rY1w8TYyKYndUyZlE9ffkQyA4-jI9x_59zXkn5s,5893 pip/_internal/utils/filetypes.py,sha256=i8XAQ0eFCog26Fw9yV0Yb1ygAqKYB1w9Cz9n0fj8gZU,716 pip/_internal/utils/glibc.py,sha256=tDfwVYnJCOC0BNVpItpy8CGLP9BjkxFHdl0mTS0J7fc,3110 pip/_internal/utils/hashes.py,sha256=anpZfFGIT6HcIj2td9NHtE8AWg6GeAIhwpP8GPvZE0E,4811 pip/_internal/utils/inject_securetransport.py,sha256=o-QRVMGiENrTJxw3fAhA7uxpdEdw6M41TjHYtSVRrcg,795 pip/_internal/utils/logging.py,sha256=oEkBvjj2A6NtVo75_Q-sL7qqH0bMFuY0pK4d8t40SKg,11532 pip/_internal/utils/misc.py,sha256=BmZJygU2e8NSUD-Iz4A1zzIL52GDhikAwCeZik7K7V4,20778 pip/_internal/utils/models.py,sha256=5GoYU586SrxURMvDn_jBMJInitviJg4O5-iOU-6I0WY,1193 pip/_internal/utils/packaging.py,sha256=wA29RPW_KkorI2PIfkm9cWCytpcVbk-wubwUE8YTmbQ,2952 pip/_internal/utils/parallel.py,sha256=Z-vNgYsyiAx8JfZYbD6ZSzkkPfpk0ANQI_YpCBE0Pxo,3196 pip/_internal/utils/pkg_resources.py,sha256=A7HUm5lSk7n1_7qypyI4QkXErXgb5iXDlKPXo8r_1Hk,987 pip/_internal/utils/setuptools_build.py,sha256=yDrfmxUgd0A9SDKV-7UuSTA3YLmVav5J86G9Fym-2FE,4697 pip/_internal/utils/subprocess.py,sha256=cy2c6XRuYkX3XJF_lIjY5nQL2XygBHLJr6WXwTsjfnc,10058 pip/_internal/utils/temp_dir.py,sha256=zob3PYMVevONkheOMUp_4jDofrEY3HIu5DHK78cSspI,7662 pip/_internal/utils/unpacking.py,sha256=HUFlMEyCa9dPwdLh6sWeh95DeKytV8rsOyKShEw9y6g,8906 pip/_internal/utils/urls.py,sha256=AhaesUGl-9it6uvG6fsFPOr9ynFpGaTMk4t5XTX7Z_Q,1759 pip/_internal/utils/virtualenv.py,sha256=4_48qMzCwB_F5jIK5BC_ua7uiAMVifmQWU9NdaGUoVA,3459 pip/_internal/utils/wheel.py,sha256=YwsLfuDzPJhFLuGotZ69i0bxJVGSweGuIHG2SxZvZtM,6163 pip/_internal/vcs/__init__.py,sha256=UAqvzpbi0VbZo3Ub6skEeZAw-ooIZR-zX_WpCbxyCoU,596 pip/_internal/vcs/__pycache__/__init__.cpython-310.pyc,, pip/_internal/vcs/__pycache__/bazaar.cpython-310.pyc,, pip/_internal/vcs/__pycache__/git.cpython-310.pyc,, pip/_internal/vcs/__pycache__/mercurial.cpython-310.pyc,, pip/_internal/vcs/__pycache__/subversion.cpython-310.pyc,, pip/_internal/vcs/__pycache__/versioncontrol.cpython-310.pyc,, pip/_internal/vcs/bazaar.py,sha256=pNMHrCLx1jSJzu1t1ycDVwhXQ23XI4Q483cvewaTUDs,2857 pip/_internal/vcs/git.py,sha256=Ph_hThbfTG040GpJRz1z0ByiNkj5eHgF_shCCbNnCw0,17804 pip/_internal/vcs/mercurial.py,sha256=Mtk-Bqjnp3wlaOdHfNSxq86vgCwNc3-df6UqgIXvMjE,4945 pip/_internal/vcs/subversion.py,sha256=h4_nYmYN9kcfeTPp9wjkHhIeTpFZwoCp1UVm4hbBq90,11596 pip/_internal/vcs/versioncontrol.py,sha256=W1zLW32PeuYiCV1I_dhqlk_n74B_GFTjNC5xdxs-1Ek,22414 pip/_internal/wheel_builder.py,sha256=ZakEA7CEJyp70yHoX0QLE8TAwM7vxF9PYPtjBxT3F1I,12247 pip/_vendor/__init__.py,sha256=xjcBX0EP50pkaMdCssrsBXoZgo2hTtYxlcH1CIyA3T4,4708 pip/_vendor/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/__pycache__/distro.cpython-310.pyc,, pip/_vendor/__pycache__/pyparsing.cpython-310.pyc,, pip/_vendor/__pycache__/six.cpython-310.pyc,, pip/_vendor/cachecontrol/__init__.py,sha256=pJtAaUxOsMPnytI1A3juAJkXYDr8krdSnsg4Yg3OBEg,302 pip/_vendor/cachecontrol/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-310.pyc,, pip/_vendor/cachecontrol/__pycache__/adapter.cpython-310.pyc,, pip/_vendor/cachecontrol/__pycache__/cache.cpython-310.pyc,, pip/_vendor/cachecontrol/__pycache__/compat.cpython-310.pyc,, pip/_vendor/cachecontrol/__pycache__/controller.cpython-310.pyc,, pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-310.pyc,, pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-310.pyc,, pip/_vendor/cachecontrol/__pycache__/serialize.cpython-310.pyc,, pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-310.pyc,, pip/_vendor/cachecontrol/_cmd.py,sha256=URGE0KrA87QekCG3SGPatlSPT571dZTDjNa-ZXX3pDc,1295 pip/_vendor/cachecontrol/adapter.py,sha256=sSwaSYd93IIfCFU4tOMgSo6b2LCt_gBSaQUj8ktJFOA,4882 pip/_vendor/cachecontrol/cache.py,sha256=1fc4wJP8HYt1ycnJXeEw5pCpeBL2Cqxx6g9Fb0AYDWQ,805 pip/_vendor/cachecontrol/caches/__init__.py,sha256=-gHNKYvaeD0kOk5M74eOrsSgIKUtC6i6GfbmugGweEo,86 pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-310.pyc,, pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-310.pyc,, pip/_vendor/cachecontrol/caches/file_cache.py,sha256=nYVKsJtXh6gJXvdn1iWyrhxvkwpQrK-eKoMRzuiwkKk,4153 pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=HxelMpNCo-dYr2fiJDwM3hhhRmxUYtB5tXm1GpAAT4Y,856 pip/_vendor/cachecontrol/compat.py,sha256=kHNvMRdt6s_Xwqq_9qJmr9ou3wYMOMUMxPPcwNxT8Mc,695 pip/_vendor/cachecontrol/controller.py,sha256=CWEX3pedIM9s60suf4zZPtm_JvVgnvogMGK_OiBG5F8,14149 pip/_vendor/cachecontrol/filewrapper.py,sha256=vACKO8Llzu_ZWyjV1Fxn1MA4TGU60N5N3GSrAFdAY2Q,2533 pip/_vendor/cachecontrol/heuristics.py,sha256=BFGHJ3yQcxvZizfo90LLZ04T_Z5XSCXvFotrp7Us0sc,4070 pip/_vendor/cachecontrol/serialize.py,sha256=vIa4jvq4x_KSOLdEIedoknX2aXYHQujLDFV4-F21Dno,7091 pip/_vendor/cachecontrol/wrapper.py,sha256=5LX0uJwkNQUtYSEw3aGmGu9WY8wGipd81mJ8lG0d0M4,690 pip/_vendor/certifi/__init__.py,sha256=-b78tXibbl0qtgCzv9tc9v6ozwcNX915lT9Tf4a9lds,62 pip/_vendor/certifi/__main__.py,sha256=1k3Cr95vCxxGRGDljrW3wMdpZdL3Nhf0u1n-k2qdsCY,255 pip/_vendor/certifi/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/certifi/__pycache__/__main__.cpython-310.pyc,, pip/_vendor/certifi/__pycache__/core.cpython-310.pyc,, pip/_vendor/certifi/core.py,sha256=xcXTRTzkcnYHuGFEjzUFUvg9MOnYkD1gjqhsWOUiB0Y,2846 pip/_vendor/chardet/__init__.py,sha256=mWZaWmvZkhwfBEAT9O1Y6nRTfKzhT7FHhQTTAujbqUA,3271 pip/_vendor/chardet/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/big5freq.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/big5prober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/chardistribution.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/charsetprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/compat.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/cp949prober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/enums.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/escprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/escsm.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/eucjpprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/euckrfreq.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/euckrprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/euctwfreq.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/euctwprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/gb2312freq.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/gb2312prober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/hebrewprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/jisfreq.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/jpcntx.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/langthaimodel.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/latin1prober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/mbcssm.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/sjisprober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/universaldetector.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/utf8prober.cpython-310.pyc,, pip/_vendor/chardet/__pycache__/version.cpython-310.pyc,, pip/_vendor/chardet/big5freq.py,sha256=D_zK5GyzoVsRes0HkLJziltFQX0bKCLOrFe9_xDvO_8,31254 pip/_vendor/chardet/big5prober.py,sha256=kBxHbdetBpPe7xrlb-e990iot64g_eGSLd32lB7_h3M,1757 pip/_vendor/chardet/chardistribution.py,sha256=3woWS62KrGooKyqz4zQSnjFbJpa6V7g02daAibTwcl8,9411 pip/_vendor/chardet/charsetgroupprober.py,sha256=GZLReHP6FRRn43hvSOoGCxYamErKzyp6RgOQxVeC3kg,3839 pip/_vendor/chardet/charsetprober.py,sha256=KSmwJErjypyj0bRZmC5F5eM7c8YQgLYIjZXintZNstg,5110 pip/_vendor/chardet/cli/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 pip/_vendor/chardet/cli/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-310.pyc,, pip/_vendor/chardet/cli/chardetect.py,sha256=XK5zqjUG2a4-y6eLHZ8ThYcp6WWUrdlmELxNypcc2SE,2747 pip/_vendor/chardet/codingstatemachine.py,sha256=VYp_6cyyki5sHgXDSZnXW4q1oelHc3cu9AyQTX7uug8,3590 pip/_vendor/chardet/compat.py,sha256=40zr6wICZwknxyuLGGcIOPyve8DTebBCbbvttvnmp5Q,1200 pip/_vendor/chardet/cp949prober.py,sha256=TZ434QX8zzBsnUvL_8wm4AQVTZ2ZkqEEQL_lNw9f9ow,1855 pip/_vendor/chardet/enums.py,sha256=Aimwdb9as1dJKZaFNUH2OhWIVBVd6ZkJJ_WK5sNY8cU,1661 pip/_vendor/chardet/escprober.py,sha256=kkyqVg1Yw3DIOAMJ2bdlyQgUFQhuHAW8dUGskToNWSc,3950 pip/_vendor/chardet/escsm.py,sha256=RuXlgNvTIDarndvllNCk5WZBIpdCxQ0kcd9EAuxUh84,10510 pip/_vendor/chardet/eucjpprober.py,sha256=iD8Jdp0ISRjgjiVN7f0e8xGeQJ5GM2oeZ1dA8nbSeUw,3749 pip/_vendor/chardet/euckrfreq.py,sha256=-7GdmvgWez4-eO4SuXpa7tBiDi5vRXQ8WvdFAzVaSfo,13546 pip/_vendor/chardet/euckrprober.py,sha256=MqFMTQXxW4HbzIpZ9lKDHB3GN8SP4yiHenTmf8g_PxY,1748 pip/_vendor/chardet/euctwfreq.py,sha256=No1WyduFOgB5VITUA7PLyC5oJRNzRyMbBxaKI1l16MA,31621 pip/_vendor/chardet/euctwprober.py,sha256=13p6EP4yRaxqnP4iHtxHOJ6R2zxHq1_m8hTRjzVZ95c,1747 pip/_vendor/chardet/gb2312freq.py,sha256=JX8lsweKLmnCwmk8UHEQsLgkr_rP_kEbvivC4qPOrlc,20715 pip/_vendor/chardet/gb2312prober.py,sha256=gGvIWi9WhDjE-xQXHvNIyrnLvEbMAYgyUSZ65HUfylw,1754 pip/_vendor/chardet/hebrewprober.py,sha256=c3SZ-K7hvyzGY6JRAZxJgwJ_sUS9k0WYkvMY00YBYFo,13838 pip/_vendor/chardet/jisfreq.py,sha256=vpmJv2Bu0J8gnMVRPHMFefTRvo_ha1mryLig8CBwgOg,25777 pip/_vendor/chardet/jpcntx.py,sha256=PYlNqRUQT8LM3cT5FmHGP0iiscFlTWED92MALvBungo,19643 pip/_vendor/chardet/langbulgarianmodel.py,sha256=Ys1irPhpi61ywJpv6a-6JQOLwn7Ed7YqTBpGZ7adhOk,105675 pip/_vendor/chardet/langgreekmodel.py,sha256=en5Np_mAnOAR1Akoh0562eSe7phGWuq7H2_KoEv4eQU,99549 pip/_vendor/chardet/langhebrewmodel.py,sha256=NHkt2JO49NbzkgPzgYgrGIKvpO040WOjUMEPRzkZVDo,98754 pip/_vendor/chardet/langhungarianmodel.py,sha256=IA_31i27hFJwCRhHQ_0CdUIeBr_qndYmj2SJqDdw1n4,102476 pip/_vendor/chardet/langrussianmodel.py,sha256=QzrKRvQInhNxnMkYTugNqEfvVFZl_WI1bj9rFLdjYgQ,131158 pip/_vendor/chardet/langthaimodel.py,sha256=Ju2fDTy26CdiZYkioD8I5ZzKEGe8Et-49zon1_OOZI4,103290 pip/_vendor/chardet/langturkishmodel.py,sha256=ycEZsKGFiLl-FgoZLiUmWeS8F7F2ts3RrNdgRzArDlU,95924 pip/_vendor/chardet/latin1prober.py,sha256=S2IoORhFk39FEFOlSFWtgVybRiP6h7BlLldHVclNkU8,5370 pip/_vendor/chardet/mbcharsetprober.py,sha256=AR95eFH9vuqSfvLQZN-L5ijea25NOBCoXqw8s5O9xLQ,3413 pip/_vendor/chardet/mbcsgroupprober.py,sha256=h6TRnnYq2OxG1WdD5JOyxcdVpn7dG0q-vB8nWr5mbh4,2012 pip/_vendor/chardet/mbcssm.py,sha256=SY32wVIF3HzcjY3BaEspy9metbNSKxIIB0RKPn7tjpI,25481 pip/_vendor/chardet/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/chardet/metadata/__pycache__/languages.cpython-310.pyc,, pip/_vendor/chardet/metadata/languages.py,sha256=Bn9KbnR_sctMbPDMw9IwxOyYeOGuE4tcVNjvE2FOEmA,19452 pip/_vendor/chardet/sbcharsetprober.py,sha256=nmyMyuxzG87DN6K3Rk2MUzJLMLR69MrWpdnHzOwVUwQ,6136 pip/_vendor/chardet/sbcsgroupprober.py,sha256=hqefQuXmiFyDBArOjujH6hd6WFXlOD1kWCsxDhjx5Vc,4309 pip/_vendor/chardet/sjisprober.py,sha256=IIt-lZj0WJqK4rmUZzKZP4GJlE8KUEtFYVuY96ek5MQ,3774 pip/_vendor/chardet/universaldetector.py,sha256=DpZTXCX0nUHXxkQ9sr4GZxGB_hveZ6hWt3uM94cgWKs,12503 pip/_vendor/chardet/utf8prober.py,sha256=IdD8v3zWOsB8OLiyPi-y_fqwipRFxV9Nc1eKBLSuIEw,2766 pip/_vendor/chardet/version.py,sha256=A4CILFAd8MRVG1HoXPp45iK9RLlWyV73a1EtwE8Tvn8,242 pip/_vendor/colorama/__init__.py,sha256=pCdErryzLSzDW5P-rRPBlPLqbBtIRNJB6cMgoeJns5k,239 pip/_vendor/colorama/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/colorama/__pycache__/ansi.cpython-310.pyc,, pip/_vendor/colorama/__pycache__/ansitowin32.cpython-310.pyc,, pip/_vendor/colorama/__pycache__/initialise.cpython-310.pyc,, pip/_vendor/colorama/__pycache__/win32.cpython-310.pyc,, pip/_vendor/colorama/__pycache__/winterm.cpython-310.pyc,, pip/_vendor/colorama/ansi.py,sha256=Top4EeEuaQdBWdteKMEcGOTeKeF19Q-Wo_6_Cj5kOzQ,2522 pip/_vendor/colorama/ansitowin32.py,sha256=yV7CEmCb19MjnJKODZEEvMH_fnbJhwnpzo4sxZuGXmA,10517 pip/_vendor/colorama/initialise.py,sha256=PprovDNxMTrvoNHFcL2NZjpH2XzDc8BLxLxiErfUl4k,1915 pip/_vendor/colorama/win32.py,sha256=bJ8Il9jwaBN5BJ8bmN6FoYZ1QYuMKv2j8fGrXh7TJjw,5404 pip/_vendor/colorama/winterm.py,sha256=2y_2b7Zsv34feAsP67mLOVc-Bgq51mdYGo571VprlrM,6438 pip/_vendor/distlib/__init__.py,sha256=HTGLP7dnTRTQCbEZNGUxBq-0sobr0KQUMn3yd6uEObA,581 pip/_vendor/distlib/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/compat.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/database.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/index.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/locators.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/manifest.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/markers.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/metadata.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/resources.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/scripts.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/util.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/version.cpython-310.pyc,, pip/_vendor/distlib/__pycache__/wheel.cpython-310.pyc,, pip/_vendor/distlib/_backport/__init__.py,sha256=bqS_dTOH6uW9iGgd0uzfpPjo6vZ4xpPZ7kyfZJ2vNaw,274 pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/distlib/_backport/__pycache__/misc.cpython-310.pyc,, pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-310.pyc,, pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-310.pyc,, pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-310.pyc,, pip/_vendor/distlib/_backport/misc.py,sha256=KWecINdbFNOxSOP1fGF680CJnaC6S4fBRgEtaYTw0ig,971 pip/_vendor/distlib/_backport/shutil.py,sha256=IX_G2NPqwecJibkIDje04bqu0xpHkfSQ2GaGdEVqM5Y,25707 pip/_vendor/distlib/_backport/sysconfig.cfg,sha256=swZKxq9RY5e9r3PXCrlvQPMsvOdiWZBTHLEbqS8LJLU,2617 pip/_vendor/distlib/_backport/sysconfig.py,sha256=BQHFlb6pubCl_dvT1NjtzIthylofjKisox239stDg0U,26854 pip/_vendor/distlib/_backport/tarfile.py,sha256=Ihp7rXRcjbIKw8COm9wSePV9ARGXbSF9gGXAMn2Q-KU,92628 pip/_vendor/distlib/compat.py,sha256=fbsxc5PfJ2wBx1K4k6mQ2goAYs-GZW0tcOPIlE_vf0I,41495 pip/_vendor/distlib/database.py,sha256=Kl0YvPQKc4OcpVi7k5cFziydM1xOK8iqdxLGXgbZHV4,51059 pip/_vendor/distlib/index.py,sha256=UfcimNW19AB7IKWam4VaJbXuCBvArKfSxhV16EwavzE,20739 pip/_vendor/distlib/locators.py,sha256=AKlB3oZvfOTg4E0CtfwOzujFL19X5V4XUA4eHdKOu44,51965 pip/_vendor/distlib/manifest.py,sha256=nQEhYmgoreaBZzyFzwYsXxJARu3fo4EkunU163U16iE,14811 pip/_vendor/distlib/markers.py,sha256=9c70ISEKwBjmUOHuIdOygVnRVESOKdNYp9a2TVn4qrI,4989 pip/_vendor/distlib/metadata.py,sha256=vatoxFdmBr6ie-sTVXVNPOPG3uwMDWJTnEECnm7xDCw,39109 pip/_vendor/distlib/resources.py,sha256=LwbPksc0A1JMbi6XnuPdMBUn83X7BPuFNWqPGEKI698,10820 pip/_vendor/distlib/scripts.py,sha256=tjSwENINeV91ROZxec5zTSMRg2jEeKc4enyCHDzNvEE,17720 pip/_vendor/distlib/util.py,sha256=0Uq_qa63FCLtdyNdWvMnmPbiSvVa-ykHM2E8HT7LSIU,67766 pip/_vendor/distlib/version.py,sha256=WG__LyAa2GwmA6qSoEJtvJE8REA1LZpbSizy8WvhJLk,23513 pip/_vendor/distlib/wheel.py,sha256=pj5VVCjqZMcHvgizORWwAFPS7hOk61CZ59dxP8laQ4E,42943 pip/_vendor/distro.py,sha256=O1EeHMq1-xAO373JI2_6pYEtd09yEkxtmrYkdY-9S-w,48414 pip/_vendor/html5lib/__init__.py,sha256=BYzcKCqeEii52xDrqBFruhnmtmkiuHXFyFh-cglQ8mk,1160 pip/_vendor/html5lib/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-310.pyc,, pip/_vendor/html5lib/__pycache__/_inputstream.cpython-310.pyc,, pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-310.pyc,, pip/_vendor/html5lib/__pycache__/_utils.cpython-310.pyc,, pip/_vendor/html5lib/__pycache__/constants.cpython-310.pyc,, pip/_vendor/html5lib/__pycache__/html5parser.cpython-310.pyc,, pip/_vendor/html5lib/__pycache__/serializer.cpython-310.pyc,, pip/_vendor/html5lib/_ihatexml.py,sha256=ifOwF7pXqmyThIXc3boWc96s4MDezqRrRVp7FwDYUFs,16728 pip/_vendor/html5lib/_inputstream.py,sha256=jErNASMlkgs7MpOM9Ve_VdLDJyFFweAjLuhVutZz33U,32353 pip/_vendor/html5lib/_tokenizer.py,sha256=04mgA2sNTniutl2fxFv-ei5bns4iRaPxVXXHh_HrV_4,77040 pip/_vendor/html5lib/_trie/__init__.py,sha256=nqfgO910329BEVJ5T4psVwQtjd2iJyEXQ2-X8c1YxwU,109 pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-310.pyc,, pip/_vendor/html5lib/_trie/__pycache__/py.cpython-310.pyc,, pip/_vendor/html5lib/_trie/_base.py,sha256=CaybYyMro8uERQYjby2tTeSUatnWDfWroUN9N7ety5w,1013 pip/_vendor/html5lib/_trie/py.py,sha256=wXmQLrZRf4MyWNyg0m3h81m9InhLR7GJ002mIIZh-8o,1775 pip/_vendor/html5lib/_utils.py,sha256=Dx9AKntksRjFT1veBj7I362pf5OgIaT0zglwq43RnfU,4931 pip/_vendor/html5lib/constants.py,sha256=Ll-yzLU_jcjyAI_h57zkqZ7aQWE5t5xA4y_jQgoUUhw,83464 pip/_vendor/html5lib/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-310.pyc,, pip/_vendor/html5lib/filters/__pycache__/base.cpython-310.pyc,, pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-310.pyc,, pip/_vendor/html5lib/filters/__pycache__/lint.cpython-310.pyc,, pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-310.pyc,, pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-310.pyc,, pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-310.pyc,, pip/_vendor/html5lib/filters/alphabeticalattributes.py,sha256=lViZc2JMCclXi_5gduvmdzrRxtO5Xo9ONnbHBVCsykU,919 pip/_vendor/html5lib/filters/base.py,sha256=z-IU9ZAYjpsVsqmVt7kuWC63jR11hDMr6CVrvuao8W0,286 pip/_vendor/html5lib/filters/inject_meta_charset.py,sha256=egDXUEHXmAG9504xz0K6ALDgYkvUrC2q15YUVeNlVQg,2945 pip/_vendor/html5lib/filters/lint.py,sha256=jk6q56xY0ojiYfvpdP-OZSm9eTqcAdRqhCoPItemPYA,3643 pip/_vendor/html5lib/filters/optionaltags.py,sha256=8lWT75J0aBOHmPgfmqTHSfPpPMp01T84NKu0CRedxcE,10588 pip/_vendor/html5lib/filters/sanitizer.py,sha256=m6oGmkBhkGAnn2nV6D4hE78SCZ6WEnK9rKdZB3uXBIc,26897 pip/_vendor/html5lib/filters/whitespace.py,sha256=8eWqZxd4UC4zlFGW6iyY6f-2uuT8pOCSALc3IZt7_t4,1214 pip/_vendor/html5lib/html5parser.py,sha256=anr-aXre_ImfrkQ35c_rftKXxC80vJCREKe06Tq15HA,117186 pip/_vendor/html5lib/serializer.py,sha256=_PpvcZF07cwE7xr9uKkZqh5f4UEaI8ltCU2xPJzaTpk,15759 pip/_vendor/html5lib/treeadapters/__init__.py,sha256=A0rY5gXIe4bJOiSGRO_j_tFhngRBO8QZPzPtPw5dFzo,679 pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-310.pyc,, pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-310.pyc,, pip/_vendor/html5lib/treeadapters/genshi.py,sha256=CH27pAsDKmu4ZGkAUrwty7u0KauGLCZRLPMzaO3M5vo,1715 pip/_vendor/html5lib/treeadapters/sax.py,sha256=BKS8woQTnKiqeffHsxChUqL4q2ZR_wb5fc9MJ3zQC8s,1776 pip/_vendor/html5lib/treebuilders/__init__.py,sha256=AysSJyvPfikCMMsTVvaxwkgDieELD5dfR8FJIAuq7hY,3592 pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-310.pyc,, pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-310.pyc,, pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-310.pyc,, pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-310.pyc,, pip/_vendor/html5lib/treebuilders/base.py,sha256=z-o51vt9r_l2IDG5IioTOKGzZne4Fy3_Fc-7ztrOh4I,14565 pip/_vendor/html5lib/treebuilders/dom.py,sha256=22whb0C71zXIsai5mamg6qzBEiigcBIvaDy4Asw3at0,8925 pip/_vendor/html5lib/treebuilders/etree.py,sha256=w5ZFpKk6bAxnrwD2_BrF5EVC7vzz0L3LMi9Sxrbc_8w,12836 pip/_vendor/html5lib/treebuilders/etree_lxml.py,sha256=9gqDjs-IxsPhBYa5cpvv2FZ1KZlG83Giusy2lFmvIkE,14766 pip/_vendor/html5lib/treewalkers/__init__.py,sha256=OBPtc1TU5mGyy18QDMxKEyYEz0wxFUUNj5v0-XgmYhY,5719 pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-310.pyc,, pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-310.pyc,, pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-310.pyc,, pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-310.pyc,, pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-310.pyc,, pip/_vendor/html5lib/treewalkers/base.py,sha256=ouiOsuSzvI0KgzdWP8PlxIaSNs9falhbiinAEc_UIJY,7476 pip/_vendor/html5lib/treewalkers/dom.py,sha256=EHyFR8D8lYNnyDU9lx_IKigVJRyecUGua0mOi7HBukc,1413 pip/_vendor/html5lib/treewalkers/etree.py,sha256=xo1L5m9VtkfpFJK0pFmkLVajhqYYVisVZn3k9kYpPkI,4551 pip/_vendor/html5lib/treewalkers/etree_lxml.py,sha256=_b0LAVWLcVu9WaU_-w3D8f0IRSpCbjf667V-3NRdhTw,6357 pip/_vendor/html5lib/treewalkers/genshi.py,sha256=4D2PECZ5n3ZN3qu3jMl9yY7B81jnQApBQSVlfaIuYbA,2309 pip/_vendor/idna/__init__.py,sha256=KJQN1eQBr8iIK5SKrJ47lXvxG0BJ7Lm38W4zT0v_8lk,849 pip/_vendor/idna/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/idna/__pycache__/codec.cpython-310.pyc,, pip/_vendor/idna/__pycache__/compat.cpython-310.pyc,, pip/_vendor/idna/__pycache__/core.cpython-310.pyc,, pip/_vendor/idna/__pycache__/idnadata.cpython-310.pyc,, pip/_vendor/idna/__pycache__/intranges.cpython-310.pyc,, pip/_vendor/idna/__pycache__/package_data.cpython-310.pyc,, pip/_vendor/idna/__pycache__/uts46data.cpython-310.pyc,, pip/_vendor/idna/codec.py,sha256=QsPFD3Je8gN17rfs14e7zTGRWlnL7bNf2ZqcHTRVYHs,3453 pip/_vendor/idna/compat.py,sha256=5A9xR04puRHCsyjBNewZlVSiarth7K1bZqyEOeob1fA,360 pip/_vendor/idna/core.py,sha256=icq2P13S6JMjoXgKhhd6ihhby7QsnZlNfniH6fLyf6U,12826 pip/_vendor/idna/idnadata.py,sha256=cl4x9RLdw1ZMtEEbvKwAsX-Id3AdIjO5U3HaoKM6VGs,42350 pip/_vendor/idna/intranges.py,sha256=EqgXwyATAn-CTACInqH9tYsYAitGB2VcQ50RZt_Cpjs,1933 pip/_vendor/idna/package_data.py,sha256=_028B4fvadRIaXMwMYjhuQPP3AxTIt1IRE7X6RDR4Mk,21 pip/_vendor/idna/uts46data.py,sha256=DGzwDQv8JijY17I_7ondo3stjFjNnjvVAbA-z0k1XOE,201849 pip/_vendor/msgpack/__init__.py,sha256=2gJwcsTIaAtCM0GMi2rU-_Y6kILeeQuqRkrQ22jSANc,1118 pip/_vendor/msgpack/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/msgpack/__pycache__/_version.cpython-310.pyc,, pip/_vendor/msgpack/__pycache__/exceptions.cpython-310.pyc,, pip/_vendor/msgpack/__pycache__/ext.cpython-310.pyc,, pip/_vendor/msgpack/__pycache__/fallback.cpython-310.pyc,, pip/_vendor/msgpack/_version.py,sha256=dFR03oACnj4lsKd1RnwD7BPMiVI_FMygdOL1TOBEw_U,20 pip/_vendor/msgpack/exceptions.py,sha256=dCTWei8dpkrMsQDcjQk74ATl9HsIBH0ybt8zOPNqMYc,1081 pip/_vendor/msgpack/ext.py,sha256=4l356Y4sVEcvCla2dh_cL57vh4GMhZfa3kuWHFHYz6A,6088 pip/_vendor/msgpack/fallback.py,sha256=Rpv1Ldey8f8ueRnQznD4ARKBn9dxM2PywVNkXI8IEeE,38026 pip/_vendor/packaging/__about__.py,sha256=p_OQloqH2saadcbUQmWEsWK857dI6_ff5E3aSiCqGFA,661 pip/_vendor/packaging/__init__.py,sha256=b9Kk5MF7KxhhLgcDmiUWukN-LatWFxPdNug0joPhHSk,497 pip/_vendor/packaging/__pycache__/__about__.cpython-310.pyc,, pip/_vendor/packaging/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc,, pip/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc,, pip/_vendor/packaging/__pycache__/_structures.cpython-310.pyc,, pip/_vendor/packaging/__pycache__/markers.cpython-310.pyc,, pip/_vendor/packaging/__pycache__/requirements.cpython-310.pyc,, pip/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc,, pip/_vendor/packaging/__pycache__/tags.cpython-310.pyc,, pip/_vendor/packaging/__pycache__/utils.cpython-310.pyc,, pip/_vendor/packaging/__pycache__/version.cpython-310.pyc,, pip/_vendor/packaging/_manylinux.py,sha256=XcbiXB-qcjv3bcohp6N98TMpOP4_j3m-iOA8ptK2GWY,11488 pip/_vendor/packaging/_musllinux.py,sha256=z5yeG1ygOPx4uUyLdqj-p8Dk5UBb5H_b0NIjW9yo8oA,4378 pip/_vendor/packaging/_structures.py,sha256=TMiAgFbdUOPmIfDIfiHc3KFhSJ8kMjof2QS5I-2NyQ8,1629 pip/_vendor/packaging/markers.py,sha256=AJBOcY8Oq0kYc570KuuPTkvuqjAlhufaE2c9sCUbm64,8487 pip/_vendor/packaging/requirements.py,sha256=NtDlPBtojpn1IUC85iMjPNsUmufjpSlwnNA-Xb4m5NA,4676 pip/_vendor/packaging/specifiers.py,sha256=MZ-fYcNL3u7pNrt-6g2EQO7AbRXkjc-SPEYwXMQbLmc,30964 pip/_vendor/packaging/tags.py,sha256=akIerYw8W0sz4OW9HHozgawWnbt2GGOPm3sviW0jowY,15714 pip/_vendor/packaging/utils.py,sha256=dJjeat3BS-TYn1RrUFVwufUMasbtzLfYRoy_HXENeFQ,4200 pip/_vendor/packaging/version.py,sha256=AOLsewGcHCskMRdz2ykO3Gv7U7YZwgzE5Pj9ifjd6S8,14479 pip/_vendor/pep517/__init__.py,sha256=Y1bATL2qbFNN6M_DQa4yyrwqjpIiL-j9T6kBmR0DS14,130 pip/_vendor/pep517/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/pep517/__pycache__/build.cpython-310.pyc,, pip/_vendor/pep517/__pycache__/check.cpython-310.pyc,, pip/_vendor/pep517/__pycache__/colorlog.cpython-310.pyc,, pip/_vendor/pep517/__pycache__/compat.cpython-310.pyc,, pip/_vendor/pep517/__pycache__/dirtools.cpython-310.pyc,, pip/_vendor/pep517/__pycache__/envbuild.cpython-310.pyc,, pip/_vendor/pep517/__pycache__/meta.cpython-310.pyc,, pip/_vendor/pep517/__pycache__/wrappers.cpython-310.pyc,, pip/_vendor/pep517/build.py,sha256=2bar6EdjwIz2Dlfy94qdxn3oA9mVnnny40mfoT5f-qI,3457 pip/_vendor/pep517/check.py,sha256=bCORq1WrHjhpTONa-zpAqG0EB9rHNuhO1ORu6DsDuL8,6084 pip/_vendor/pep517/colorlog.py,sha256=Tk9AuYm_cLF3BKTBoSTJt9bRryn0aFojIQOwbfVUTxQ,4098 pip/_vendor/pep517/compat.py,sha256=NmLImE5oiDT3gbEhJ4w7xeoMFcpAPrGu_NltBytSJUY,1253 pip/_vendor/pep517/dirtools.py,sha256=2mkAkAL0mRz_elYFjRKuekTJVipH1zTn4tbf1EDev84,1129 pip/_vendor/pep517/envbuild.py,sha256=zFde--rmzjXMLXcm7SA_3hDtgk5VCTA8hjpk88RbF6E,6100 pip/_vendor/pep517/in_process/__init__.py,sha256=MyWoAi8JHdcBv7yXuWpUSVADbx6LSB9rZh7kTIgdA8Y,563 pip/_vendor/pep517/in_process/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/pep517/in_process/__pycache__/_in_process.cpython-310.pyc,, pip/_vendor/pep517/in_process/_in_process.py,sha256=D3waguyNSGcwosociD5USfcycYr2RCzCjYtxX5UHQmQ,11201 pip/_vendor/pep517/meta.py,sha256=8mnM5lDnT4zXQpBTliJbRGfesH7iioHwozbDxALPS9Y,2463 pip/_vendor/pep517/wrappers.py,sha256=impq7Cz_LL1iDF1iiOzYWB4MaEu6O6Gps7TJ5qsJz1Q,13429 pip/_vendor/pkg_resources/__init__.py,sha256=NnpQ3g6BCHzpMgOR_OLBmYtniY4oOzdKpwqghfq_6ug,108287 pip/_vendor/pkg_resources/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-310.pyc,, pip/_vendor/pkg_resources/py31compat.py,sha256=CRk8fkiPRDLsbi5pZcKsHI__Pbmh_94L8mr9Qy9Ab2U,562 pip/_vendor/platformdirs/__init__.py,sha256=3iz938Grn-6IRg8gSuMxJtgiBfH0xqRqAlMBo-vPGUw,12859 pip/_vendor/platformdirs/__main__.py,sha256=SzGvNkYWuosrWXs2yL2VqcXEh-kivWq3-53-BpTco0o,1140 pip/_vendor/platformdirs/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/platformdirs/__pycache__/__main__.cpython-310.pyc,, pip/_vendor/platformdirs/__pycache__/android.cpython-310.pyc,, pip/_vendor/platformdirs/__pycache__/api.cpython-310.pyc,, pip/_vendor/platformdirs/__pycache__/macos.cpython-310.pyc,, pip/_vendor/platformdirs/__pycache__/unix.cpython-310.pyc,, pip/_vendor/platformdirs/__pycache__/version.cpython-310.pyc,, pip/_vendor/platformdirs/__pycache__/windows.cpython-310.pyc,, pip/_vendor/platformdirs/android.py,sha256=dadYfG2oc900YVi5AONQWw2WEvk-kmgkZs5iiNSiWiE,3994 pip/_vendor/platformdirs/api.py,sha256=yhRR6RkcZzPBfJD4Sn90vCHZbRMQ9nwtnRaa93X1wR8,4922 pip/_vendor/platformdirs/macos.py,sha256=vIowPYKkHksJcWVjqHQoa-oI1i2D0S7gsSdyFzZDJEA,2619 pip/_vendor/platformdirs/unix.py,sha256=7JdDnsyTFn2IHC8IFdiNYH7_R8VS-rPx8ivh4_dT1DU,6905 pip/_vendor/platformdirs/version.py,sha256=uUssQTtUqVP-PxbOSNBzNGRW27X5u1GvOllg--kzyuw,80 pip/_vendor/platformdirs/windows.py,sha256=91nNccR0CSxX_myMppSvUT1qtQao6kaO96e6ior8-Xw,6416 pip/_vendor/progress/__init__.py,sha256=1HejNZtv2ouUNQeStUDAtZrtwkz_3FmYKQ476hJ7zOs,5294 pip/_vendor/progress/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/progress/__pycache__/bar.cpython-310.pyc,, pip/_vendor/progress/__pycache__/colors.cpython-310.pyc,, pip/_vendor/progress/__pycache__/counter.cpython-310.pyc,, pip/_vendor/progress/__pycache__/spinner.cpython-310.pyc,, pip/_vendor/progress/bar.py,sha256=GbedY0oZ-Q1duXjmvVLO0tSf-uTSH7hJ3zzyI91Esws,2942 pip/_vendor/progress/colors.py,sha256=cCYXQnYFYVmQKKmYEbQ_lj6SPSFzdw4FN98F2x2kR-U,2655 pip/_vendor/progress/counter.py,sha256=zYt9DWH0_05s8Q9TrJwHVud-WwsyyaR3PwYtk5hxwwQ,1613 pip/_vendor/progress/spinner.py,sha256=u5ElzW94XEiLGH-aAlr54VJtKfeK745xr6UfGvvflzU,1461 pip/_vendor/pyparsing.py,sha256=J1b4z3S_KwyJW7hKGnoN-hXW9pgMIzIP6QThyY5yJq4,273394 pip/_vendor/requests/__init__.py,sha256=g4Bh1QYh6JKjMS4YLobx0uOLq-41sINaXjvbhX2VI8g,5113 pip/_vendor/requests/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/requests/__pycache__/__version__.cpython-310.pyc,, pip/_vendor/requests/__pycache__/_internal_utils.cpython-310.pyc,, pip/_vendor/requests/__pycache__/adapters.cpython-310.pyc,, pip/_vendor/requests/__pycache__/api.cpython-310.pyc,, pip/_vendor/requests/__pycache__/auth.cpython-310.pyc,, pip/_vendor/requests/__pycache__/certs.cpython-310.pyc,, pip/_vendor/requests/__pycache__/compat.cpython-310.pyc,, pip/_vendor/requests/__pycache__/cookies.cpython-310.pyc,, pip/_vendor/requests/__pycache__/exceptions.cpython-310.pyc,, pip/_vendor/requests/__pycache__/help.cpython-310.pyc,, pip/_vendor/requests/__pycache__/hooks.cpython-310.pyc,, pip/_vendor/requests/__pycache__/models.cpython-310.pyc,, pip/_vendor/requests/__pycache__/packages.cpython-310.pyc,, pip/_vendor/requests/__pycache__/sessions.cpython-310.pyc,, pip/_vendor/requests/__pycache__/status_codes.cpython-310.pyc,, pip/_vendor/requests/__pycache__/structures.cpython-310.pyc,, pip/_vendor/requests/__pycache__/utils.cpython-310.pyc,, pip/_vendor/requests/__version__.py,sha256=PZEyPTSIN_jRIAIB51wV7pw81m3qAw0InSR7OrKZUnE,441 pip/_vendor/requests/_internal_utils.py,sha256=Zx3PnEUccyfsB-ie11nZVAW8qClJy0gx1qNME7rgT18,1096 pip/_vendor/requests/adapters.py,sha256=e-bmKEApNVqFdylxuMJJfiaHdlmS_zhWhIMEzlHvGuc,21548 pip/_vendor/requests/api.py,sha256=hjuoP79IAEmX6Dysrw8t032cLfwLHxbI_wM4gC5G9t0,6402 pip/_vendor/requests/auth.py,sha256=OMoJIVKyRLy9THr91y8rxysZuclwPB-K1Xg1zBomUhQ,10207 pip/_vendor/requests/certs.py,sha256=nXRVq9DtGmv_1AYbwjTu9UrgAcdJv05ZvkNeaoLOZxY,465 pip/_vendor/requests/compat.py,sha256=LQWuCR4qXk6w7-qQopXyz0WNHUdAD40k0mKnaAEf1-g,2045 pip/_vendor/requests/cookies.py,sha256=Y-bKX6TvW3FnYlE6Au0SXtVVWcaNdFvuAwQxw-G0iTI,18430 pip/_vendor/requests/exceptions.py,sha256=dwIi512RCDqXJ2T81nLC88mqPNhUFnOI_CgKKDXhTO8,3250 pip/_vendor/requests/help.py,sha256=dyhe3lcmHXnFCzDiZVjcGmVvvO_jtsfAm-AC542ndw8,3972 pip/_vendor/requests/hooks.py,sha256=QReGyy0bRcr5rkwCuObNakbYsc7EkiKeBwG4qHekr2Q,757 pip/_vendor/requests/models.py,sha256=9_LS_t1t6HbbaWFE3ZkxGmmHN2V8BgxziiOU84rrQ50,34924 pip/_vendor/requests/packages.py,sha256=njJmVifY4aSctuW3PP5EFRCxjEwMRDO6J_feG2dKWsI,695 pip/_vendor/requests/sessions.py,sha256=57O4ud9yRL6eLYh-dtFbqC1kO4d_EwZcCgYXEkujlfs,30168 pip/_vendor/requests/status_codes.py,sha256=gT79Pbs_cQjBgp-fvrUgg1dn2DQO32bDj4TInjnMPSc,4188 pip/_vendor/requests/structures.py,sha256=msAtr9mq1JxHd-JRyiILfdFlpbJwvvFuP3rfUQT_QxE,3005 pip/_vendor/requests/utils.py,sha256=U_-i6WxLw-67KEij43xHbcvL0DdeQ5Jbd4hfifWJzQY,31394 pip/_vendor/resolvelib/__init__.py,sha256=fzWkeoLV8ol6l2fvBVRZZLylOePc9w9tKRvUb8RJsCY,537 pip/_vendor/resolvelib/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/resolvelib/__pycache__/providers.cpython-310.pyc,, pip/_vendor/resolvelib/__pycache__/reporters.cpython-310.pyc,, pip/_vendor/resolvelib/__pycache__/resolvers.cpython-310.pyc,, pip/_vendor/resolvelib/__pycache__/structs.cpython-310.pyc,, pip/_vendor/resolvelib/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-310.pyc,, pip/_vendor/resolvelib/compat/collections_abc.py,sha256=uy8xUZ-NDEw916tugUXm8HgwCGiMO0f-RcdnpkfXfOs,156 pip/_vendor/resolvelib/providers.py,sha256=roVmFBItQJ0TkhNua65h8LdNny7rmeqVEXZu90QiP4o,5872 pip/_vendor/resolvelib/reporters.py,sha256=hQvvXuuEBOyEWO8KDfLsWKVjX55UFMAUwO0YZMNpzAw,1364 pip/_vendor/resolvelib/resolvers.py,sha256=UjFUEVrUa1hCzfEEakmjHEjYAL9J5ACJmwZyHFdmzvE,17540 pip/_vendor/resolvelib/structs.py,sha256=IVIYof6sA_N4ZEiE1C1UhzTX495brCNnyCdgq6CYq28,4794 pip/_vendor/six.py,sha256=TOOfQi7nFGfMrIvtdr6wX4wyHH8M7aknmuLfo2cBBrM,34549 pip/_vendor/tenacity/__init__.py,sha256=GLLsTFD4Bd5VDgTR6mU_FxyOsrxc48qONorVaRebeD4,18257 pip/_vendor/tenacity/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/tenacity/__pycache__/_asyncio.cpython-310.pyc,, pip/_vendor/tenacity/__pycache__/_utils.cpython-310.pyc,, pip/_vendor/tenacity/__pycache__/after.cpython-310.pyc,, pip/_vendor/tenacity/__pycache__/before.cpython-310.pyc,, pip/_vendor/tenacity/__pycache__/before_sleep.cpython-310.pyc,, pip/_vendor/tenacity/__pycache__/nap.cpython-310.pyc,, pip/_vendor/tenacity/__pycache__/retry.cpython-310.pyc,, pip/_vendor/tenacity/__pycache__/stop.cpython-310.pyc,, pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-310.pyc,, pip/_vendor/tenacity/__pycache__/wait.cpython-310.pyc,, pip/_vendor/tenacity/_asyncio.py,sha256=HEb0BVJEeBJE9P-m9XBxh1KcaF96BwoeqkJCL5sbVcQ,3314 pip/_vendor/tenacity/_utils.py,sha256=-y68scDcyoqvTJuJJ0GTfjdSCljEYlbCYvgk7nM4NdM,1944 pip/_vendor/tenacity/after.py,sha256=dlmyxxFy2uqpLXDr838DiEd7jgv2AGthsWHGYcGYsaI,1496 pip/_vendor/tenacity/before.py,sha256=7XtvRmO0dRWUp8SVn24OvIiGFj8-4OP5muQRUiWgLh0,1376 pip/_vendor/tenacity/before_sleep.py,sha256=ThyDvqKU5yle_IvYQz_b6Tp6UjUS0PhVp6zgqYl9U6Y,1908 pip/_vendor/tenacity/nap.py,sha256=fRWvnz1aIzbIq9Ap3gAkAZgDH6oo5zxMrU6ZOVByq0I,1383 pip/_vendor/tenacity/retry.py,sha256=62R71W59bQjuNyFKsDM7hE2aEkEPtwNBRA0tnsEvgSk,6645 pip/_vendor/tenacity/stop.py,sha256=sKHmHaoSaW6sKu3dTxUVKr1-stVkY7lw4Y9yjZU30zQ,2790 pip/_vendor/tenacity/tornadoweb.py,sha256=E8lWO2nwe6dJgoB-N2HhQprYLDLB_UdSgFnv-EN6wKE,2145 pip/_vendor/tenacity/wait.py,sha256=e_Saa6I2tsNLpCL1t9897wN2fGb0XQMQlE4bU2t9V2w,6691 pip/_vendor/tomli/__init__.py,sha256=z1Elt0nLAqU5Y0DOn9p__8QnLWavlEOpRyQikdYgKro,230 pip/_vendor/tomli/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/tomli/__pycache__/_parser.cpython-310.pyc,, pip/_vendor/tomli/__pycache__/_re.cpython-310.pyc,, pip/_vendor/tomli/_parser.py,sha256=50BD4o9YbzFAGAYyZLqZC8F81DQ7iWWyJnrHNwBKa6A,22415 pip/_vendor/tomli/_re.py,sha256=5GPfgXKteg7wRFCF-DzlkAPI2ilHbkMK2-JC49F-AJQ,2681 pip/_vendor/urllib3/__init__.py,sha256=j3yzHIbmW7CS-IKQJ9-PPQf_YKO8EOAey_rMW0UR7us,2763 pip/_vendor/urllib3/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/urllib3/__pycache__/_collections.cpython-310.pyc,, pip/_vendor/urllib3/__pycache__/_version.cpython-310.pyc,, pip/_vendor/urllib3/__pycache__/connection.cpython-310.pyc,, pip/_vendor/urllib3/__pycache__/connectionpool.cpython-310.pyc,, pip/_vendor/urllib3/__pycache__/exceptions.cpython-310.pyc,, pip/_vendor/urllib3/__pycache__/fields.cpython-310.pyc,, pip/_vendor/urllib3/__pycache__/filepost.cpython-310.pyc,, pip/_vendor/urllib3/__pycache__/poolmanager.cpython-310.pyc,, pip/_vendor/urllib3/__pycache__/request.cpython-310.pyc,, pip/_vendor/urllib3/__pycache__/response.cpython-310.pyc,, pip/_vendor/urllib3/_collections.py,sha256=Rp1mVyBgc_UlAcp6M3at1skJBXR5J43NawRTvW2g_XY,10811 pip/_vendor/urllib3/_version.py,sha256=CA4bKbKLwUBfKitbVR-44Whe53HWyInIVElDQQniAJU,63 pip/_vendor/urllib3/connection.py,sha256=8TiEbQrJMgySqOllKNeX5tMv8nluKRjNj5j9hyzS6x0,20080 pip/_vendor/urllib3/connectionpool.py,sha256=FQoodlNAP1KeUi4htGdl5TJEvKL5LWisCbmFNewxRpg,37587 pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-310.pyc,, pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-310.pyc,, pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-310.pyc,, pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-310.pyc,, pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-310.pyc,, pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-310.pyc,, pip/_vendor/urllib3/contrib/_appengine_environ.py,sha256=bDbyOEhW2CKLJcQqAKAyrEHN-aklsyHFKq6vF8ZFsmk,957 pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-310.pyc,, pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-310.pyc,, pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=eRy1Mj-wpg7sR6-OSvnSV4jUbjMT464dLN_CWxbIRVw,17649 pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=B2JBB2_NRP02xK6DCa1Pa9IuxrPwxzDzZbixQkb7U9M,13922 pip/_vendor/urllib3/contrib/appengine.py,sha256=lfzpHFmJiO82shClLEm3QB62SYgHWnjpZOH_2JhU5Tc,11034 pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=ej9gGvfAb2Gt00lafFp45SIoRz-QwrQ4WChm6gQmAlM,4538 pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=DD4pInv_3OEEGffEFynBoirc8ldR789sLmGSKukzA0E,16900 pip/_vendor/urllib3/contrib/securetransport.py,sha256=4qUKo7PUV-vVIqXmr2BD-sH7qplB918jiD5eNsRI9vU,34449 pip/_vendor/urllib3/contrib/socks.py,sha256=aRi9eWXo9ZEb95XUxef4Z21CFlnnjbEiAo9HOseoMt4,7097 pip/_vendor/urllib3/exceptions.py,sha256=0Mnno3KHTNfXRfY7638NufOPkUb6mXOm-Lqj-4x2w8A,8217 pip/_vendor/urllib3/fields.py,sha256=kvLDCg_JmH1lLjUUEY_FLS8UhY7hBvDPuVETbY8mdrM,8579 pip/_vendor/urllib3/filepost.py,sha256=5b_qqgRHVlL7uLtdAYBzBh-GHmU5AfJVt_2N0XS3PeY,2440 pip/_vendor/urllib3/packages/__init__.py,sha256=h4BLhD4tLaBx1adaDtKXfupsgqY0wWLXb_f1_yVlV6A,108 pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/urllib3/packages/__pycache__/six.cpython-310.pyc,, pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-310.pyc,, pip/_vendor/urllib3/packages/backports/makefile.py,sha256=nbzt3i0agPVP07jqqgjhaYjMmuAi_W5E0EywZivVO8E,1417 pip/_vendor/urllib3/packages/six.py,sha256=1LVW7ljqRirFlfExjwl-v1B7vSAUNTmzGMs-qays2zg,34666 pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py,sha256=ZVMwCkHx-py8ERsxxM3Il-MiREZktV-8iLBmCfRRHI4,927 pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-310.pyc,, pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py,sha256=6dZ-q074g7XhsJ27MFCgkct8iVNZB3sMZvKhf-KUVy0,5679 pip/_vendor/urllib3/poolmanager.py,sha256=whzlX6UTEgODMOCy0ZDMUONRBCz5wyIM8Z9opXAY-Lk,19763 pip/_vendor/urllib3/request.py,sha256=ZFSIqX0C6WizixecChZ3_okyu7BEv0lZu1VT0s6h4SM,5985 pip/_vendor/urllib3/response.py,sha256=hGhGBh7TkEkh_IQg5C1W_xuPNrgIKv5BUXPyE-q0LuE,28203 pip/_vendor/urllib3/util/__init__.py,sha256=JEmSmmqqLyaw8P51gUImZh8Gwg9i1zSe-DoqAitn2nc,1155 pip/_vendor/urllib3/util/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/urllib3/util/__pycache__/connection.cpython-310.pyc,, pip/_vendor/urllib3/util/__pycache__/proxy.cpython-310.pyc,, pip/_vendor/urllib3/util/__pycache__/queue.cpython-310.pyc,, pip/_vendor/urllib3/util/__pycache__/request.cpython-310.pyc,, pip/_vendor/urllib3/util/__pycache__/response.cpython-310.pyc,, pip/_vendor/urllib3/util/__pycache__/retry.cpython-310.pyc,, pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-310.pyc,, pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-310.pyc,, pip/_vendor/urllib3/util/__pycache__/timeout.cpython-310.pyc,, pip/_vendor/urllib3/util/__pycache__/url.cpython-310.pyc,, pip/_vendor/urllib3/util/__pycache__/wait.cpython-310.pyc,, pip/_vendor/urllib3/util/connection.py,sha256=KykjNIXzUZEzeKEOpl5xvKs6IsESXP9o9eTrjE0W_Ys,4920 pip/_vendor/urllib3/util/proxy.py,sha256=zUvPPCJrp6dOF0N4GAVbOcl6o-4uXKSrGiTkkr5vUS4,1605 pip/_vendor/urllib3/util/queue.py,sha256=nRgX8_eX-_VkvxoX096QWoz8Ps0QHUAExILCY_7PncM,498 pip/_vendor/urllib3/util/request.py,sha256=NnzaEKQ1Pauw5MFMV6HmgEMHITf0Aua9fQuzi2uZzGc,4123 pip/_vendor/urllib3/util/response.py,sha256=GJpg3Egi9qaJXRwBh5wv-MNuRWan5BIu40oReoxWP28,3510 pip/_vendor/urllib3/util/retry.py,sha256=tOWfZpLsuc7Vbk5nWpMwkHdMoXCp90IAvH4xtjSDRqQ,21391 pip/_vendor/urllib3/util/ssl_.py,sha256=X4-AqW91aYPhPx6-xbf66yHFQKbqqfC_5Zt4WkLX1Hc,17177 pip/_vendor/urllib3/util/ssltransport.py,sha256=F_UncOXGcc-MgeWFTA1H4QCt_RRNQXRbF6onje3SyHY,6931 pip/_vendor/urllib3/util/timeout.py,sha256=QSbBUNOB9yh6AnDn61SrLQ0hg5oz0I9-uXEG91AJuIg,10003 pip/_vendor/urllib3/util/url.py,sha256=QVEzcbHipbXyCWwH6R4K4TR-N8T4LM55WEMwNUTBmLE,14047 pip/_vendor/urllib3/util/wait.py,sha256=3MUKRSAUJDB2tgco7qRUskW0zXGAWYvRRE4Q1_6xlLs,5404 pip/_vendor/vendor.txt,sha256=vux9Tgc3pSRZZnXz9TNDdn514NdkDdnb-QPC0LCHkK4,432 pip/_vendor/webencodings/__init__.py,sha256=qOBJIuPy_4ByYH6W_bNgJF-qYQ2DoU-dKsDu5yRWCXg,10579 pip/_vendor/webencodings/__pycache__/__init__.cpython-310.pyc,, pip/_vendor/webencodings/__pycache__/labels.cpython-310.pyc,, pip/_vendor/webencodings/__pycache__/mklabels.cpython-310.pyc,, pip/_vendor/webencodings/__pycache__/tests.cpython-310.pyc,, pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-310.pyc,, pip/_vendor/webencodings/labels.py,sha256=4AO_KxTddqGtrL9ns7kAPjb0CcN6xsCIxbK37HY9r3E,8979 pip/_vendor/webencodings/mklabels.py,sha256=GYIeywnpaLnP0GSic8LFWgd0UVvO_l1Nc6YoF-87R_4,1305 pip/_vendor/webencodings/tests.py,sha256=OtGLyjhNY1fvkW1GvLJ_FV9ZoqC9Anyjr7q3kxTbzNs,6563 pip/_vendor/webencodings/x_user_defined.py,sha256=yOqWSdmpytGfUgh_Z6JYgDNhoc-BAHyyeeT15Fr42tM,4307 pip/py.typed,sha256=EBVvvPRTn_eIpz5e5QztSCdrMX7Qwd7VP93RSoIlZ2I,286 PKH]xx6python3.10/site-packages/pip-21.3.1.dist-info/METADATAnu[Metadata-Version: 2.1 Name: pip Version: 21.3.1 Summary: The PyPA recommended tool for installing Python packages. Home-page: https://pip.pypa.io/ Author: The pip developers Author-email: distutils-sig@python.org License: MIT Project-URL: Documentation, https://pip.pypa.io Project-URL: Source, https://github.com/pypa/pip Project-URL: Changelog, https://pip.pypa.io/en/stable/news/ Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Topic :: Software Development :: Build Tools Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Requires-Python: >=3.6 License-File: LICENSE.txt pip - The Python Package Installer ================================== .. image:: https://img.shields.io/pypi/v/pip.svg :target: https://pypi.org/project/pip/ .. image:: https://readthedocs.org/projects/pip/badge/?version=latest :target: https://pip.pypa.io/en/latest pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes. Please take a look at our documentation for how to install and use pip: * `Installation`_ * `Usage`_ We release updates regularly, with a new version every 3 months. Find more details in our documentation: * `Release notes`_ * `Release process`_ In pip 20.3, we've `made a big improvement to the heart of pip`_; `learn more`_. We want your input, so `sign up for our user experience research studies`_ to help us do it right. **Note**: pip 21.0, in January 2021, removed Python 2 support, per pip's `Python 2 support policy`_. Please migrate to Python 3. If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms: * `Issue tracking`_ * `Discourse channel`_ * `User IRC`_ If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms: * `GitHub page`_ * `Development documentation`_ * `Development mailing list`_ * `Development IRC`_ Code of Conduct --------------- Everyone interacting in the pip project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_. .. _package installer: https://packaging.python.org/guides/tool-recommendations/ .. _Python Package Index: https://pypi.org .. _Installation: https://pip.pypa.io/en/stable/installation/ .. _Usage: https://pip.pypa.io/en/stable/ .. _Release notes: https://pip.pypa.io/en/stable/news.html .. _Release process: https://pip.pypa.io/en/latest/development/release-process/ .. _GitHub page: https://github.com/pypa/pip .. _Development documentation: https://pip.pypa.io/en/latest/development .. _made a big improvement to the heart of pip: https://pyfound.blogspot.com/2020/11/pip-20-3-new-resolver.html .. _learn more: https://pip.pypa.io/en/latest/user_guide/#changes-to-the-pip-dependency-resolver-in-20-3-2020 .. _sign up for our user experience research studies: https://pyfound.blogspot.com/2020/03/new-pip-resolver-to-roll-out-this-year.html .. _Python 2 support policy: https://pip.pypa.io/en/latest/development/release-process/#python-2-support .. _Issue tracking: https://github.com/pypa/pip/issues .. _Discourse channel: https://discuss.python.org/c/packaging .. _Development mailing list: https://mail.python.org/mailman3/lists/distutils-sig.python.org/ .. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa .. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev .. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md PKH]P2\\3python3.10/site-packages/pip-21.3.1.dist-info/WHEELnu[Wheel-Version: 1.0 Generator: bdist_wheel (0.37.0) Root-Is-Purelib: true Tag: py3-none-any PKH]7python3.10/site-packages/pip-21.3.1.dist-info/REQUESTEDnu[PKH]Sܝ~~>python3.10/site-packages/pip-21.3.1.dist-info/entry_points.txtnu[[console_scripts] pip = pip._internal.cli.main:main pip3 = pip._internal.cli.main:main pip3.10 = pip._internal.cli.main:main PKH]#㿮(python3.10/site-packages/pip/__main__.pynu[import os import sys import warnings # Remove '' and current working directory from the first entry # of sys.path, if present to avoid using current directory # in pip commands check, freeze, install, list and show, # when invoked as python -m pip if sys.path[0] in ("", os.getcwd()): sys.path.pop(0) # If we are running from a wheel, add the wheel to sys.path # This allows the usage python pip-*.whl/pip install pip-*.whl if __package__ == "": # __file__ is pip-*.whl/pip/__main__.py # first dirname call strips of '/__main__.py', second strips off '/pip' # Resulting path is the name of the wheel itself # Add that to sys.path so we can import pip path = os.path.dirname(os.path.dirname(__file__)) sys.path.insert(0, path) if __name__ == "__main__": # Work around the error reported in #9540, pending a proper fix. # Note: It is essential the warning filter is set *before* importing # pip, as the deprecation happens at import time, not runtime. warnings.filterwarnings( "ignore", category=DeprecationWarning, module=".*packaging\\.version" ) from pip._internal.cli.main import main as _main sys.exit(_main()) PKH]DZ}}Apython3.10/site-packages/pip/__pycache__/__main__.cpython-310.pycnu[o ai@sddlZddlZddlZejddefvrejdedkr2ejejeZej dee dkrLej de ddddl mZeedSdS)N__main__ignorez.*packaging\.version)categorymodule)main)ossyswarningspathgetcwdpop __package__dirname__file__insert__name__filterwarningsDeprecationWarningpip._internal.cli.mainr_mainexitrr~/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/__main__.pys  PKH]?<Apython3.10/site-packages/pip/__pycache__/__init__.cpython-310.pycnu[o aie@s4ddlmZmZdZddeeedefddZdS) )ListOptionalz21.3.1NargsreturncCsddlm}||S)zThis is an internal API only meant for use by pip's own console scripts. For additional details, see https://github.com/pypa/pip/issues/7498. r)_wrapper)pip._internal.utils.entrypointsr)rrr~/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/__init__.pymains r )N)typingrr __version__strintr rrrr s PKH]jO++Ppython3.10/site-packages/pip/_internal/__pycache__/configuration.cpython-310.pycnu[o aia3@sBdZddlZddlZddlZddlZddlmZmZmZm Z m Z m Z m Z ddl mZmZddlmZddlmZddlmZddlmZmZejZe d eZerRd nd Zd Zed dddddZejej ej!ej"ej#fZ$ej ejej!fZ%ee&Z'dedefddZ(dede efddZ)deee effddZ*GdddZ+dS)a Configuration management setup Some terminology: - name As written in config files. - value Value associated with a name - key Name combined with it's section (section.name) - variant A single word describing where the configuration key-value pair came from N)AnyDictIterableListNewTypeOptionalTuple)ConfigurationError!ConfigurationFileCouldNotBeLoaded)appdirs)WINDOWS) getLogger) ensure_direnumKindzpip.inizpip.conf)versionhelpuserglobalsiteenvzenv-var)USERGLOBALSITEENVENV_VARnamereturncCs*|dd}|dr|dd}|S)zAMake a name consistent regardless of source (environment or file)_-z--N)lowerreplace startswith)rr$/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/configuration.py_normalize_name2s  r&cCs&d|vr d|}t||ddS)N.zbKey does not contain dot separated section and key. Perhaps you wanted to use 'global.{}' instead?)formatr split)r error_messager$r$r%_disassemble_key:s  r,cCstddtdD}tjtjt}tjtjdt rdndt}tjt dt}t j |t j |gt j||giS)NcSsg|] }tj|tqSr$)ospathjoinCONFIG_BASENAME).0r.r$r$r% Esz+get_configuration_files..pip~z.pip)r site_config_dirsr-r.r/sysprefixr0 expanduserr user_config_dirkindsrrr)global_config_filessite_config_filelegacy_config_filenew_config_filer$r$r%get_configuration_filesDs   r?cseZdZdZd7dedeeddffdd Zd8dd Zdee fd d Z de e e e ffd d Zde de fddZde de ddfddZde ddfddZd8ddZd8ddZedee e ffddZd8ddZdede defd d!Zde defd"d#Zd8d$d%Zd&e d'e e e e fdee e ffd(d)Zde e e e ffd*d+Zde e eee ffd,d-Zdedee e ffd.d/Z de e effd0d1Z!de d2eddfd3d4Z"de fd5d6Z#Z$S)9 ConfigurationaHandles management of configuration. Provides an interface to accessing and managing configuration files. This class converts provides an API that takes "section.key-name" style keys and stores the value associated with it as "key-name" under the section "section". This allows for a clean interface wherein the both the section and the key-name are preserved in an easy to manage form in the configuration files and the data stored is also nice. Nisolated load_onlyrcsjt|dur|tvrtddttt||_||_ ddt D|_ ddt D|_ g|_ dS)Nz5Got invalid value for load_only - should be one of {}z, cSsi|]}|gqSr$r$r1variantr$r$r% rz*Configuration.__init__..cSsi|]}|iqSr$r$rCr$r$r%rEurF)super__init__VALID_LOAD_ONLYr r)r/mapreprrArBOVERRIDE_ORDER_parsers_config_modified_parsers)selfrArB __class__r$r%rHes  zConfiguration.__init__cCs||js |dSdS)ztj |tj fVtj |tj fVdS)zYields variant and configuration files associated with it. This should be treated like items of a dictionary. PIP_CONFIG_FILEN) r-rgetr:rr?rrAr.rrr)rP config_filer}should_load_user_configr$r$r%ry9s zConfiguration.iter_config_filescCs |j|S)z#Get values present in a config file)rN)rPrDr$r$r%get_values_in_configWs z"Configuration.get_values_in_configcCs*|jsJ|j|j}|std|dS)Nz4Fatal Internal error [id=2]. Please report as a bug.)rBrMr )rPparsersr$r$r%rW[s  z#Configuration._get_parser_to_modifyrgcCs&||f}||jvr|j|dSdSN)rOr|)rPrfrgfile_parser_tupler$r$r%reis zConfiguration._mark_as_modifiedcCs|jjd|jdS)N())rR__name__rZrUr$r$r%__repr__nszConfiguration.__repr__r)rN)%r __module__ __qualname____doc__boolrrrHrVstrrYrrrr[r_rirlrtrapropertyrrZrSrr{rrTrrrryrrWrer __classcell__r$r$rQr%r@Ws<         r@),rrrr-r6typingrrrrrrrpip._internal.exceptionsr r pip._internal.utilsr pip._internal.utils.compatr pip._internal.utils.loggingr pip._internal.utils.miscrrrrrr0rr:rrrrrrLrIrrnr&r,r?r@r$r$r$r%s: $      PKH],,Kpython3.10/site-packages/pip/_internal/__pycache__/__init__.cpython-310.pycnu[o aiK@sLddlmZmZddlZddlmZeddeeede fddZ dS) )ListOptionalN)_logargsreturncCsddlm}||ddS)zThis is preserved for old console scripts that may still be referencing it. For additional details, see https://github.com/pypa/pip/issues/7498. r)_wrapperT)_nowarn)pip._internal.utils.entrypointsr)rrr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/__init__.pymain s  r )N) typingrr*pip._internal.utils.inject_securetransportpippip._internal.utilsr init_loggingstrintr r r r r s   PKH]* gGpython3.10/site-packages/pip/_internal/__pycache__/main.cpython-310.pycnu[o aiT@s0ddlmZmZddeeedefddZdS))ListOptionalNargsreturncCsddlm}||S)zThis is preserved for old console scripts that may still be referencing it. For additional details, see https://github.com/pypa/pip/issues/7498. r)_wrapper)pip._internal.utils.entrypointsr)rrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/main.pymains r )N)typingrrstrintr rrrr s PKH]"??Mpython3.10/site-packages/pip/_internal/__pycache__/exceptions.cpython-310.pycnu[o ai1@s4dZddlZddlmZmZmZddlmZmZm Z m Z m Z ddl m Z ddlmZmZer@ddlmZddlmZdd lmZGd d d eZGd d d eZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZ GdddeZ!GdddeZ"Gd d!d!eZ#Gd"d#d#eZ$Gd$d%d%eZ%Gd&d'd'eZ&Gd(d)d)eZ'Gd*d+d+eZ(Gd,d-d-eZ)Gd.d/d/eZ*Gd0d1d1eZ+Gd2d3d3e+Z,Gd4d5d5e+Z-Gd6d7d7e+Z.Gd8d9d9e+Z/Gd:d;d;e+Z0Gdd?d?eZ2dS)@z"Exceptions used throughout packageN)chaingroupbyrepeat) TYPE_CHECKINGDictListOptionalUnion) Distribution)RequestResponse)_Hash)BaseDistribution)InstallRequirementc@eZdZdZdS)PipErrorzBase pip exceptionN__name__ __module__ __qualname____doc__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/exceptions.pyrrc@r)ConfigurationErrorz"General exception in configurationNrrrrrrrrc@r)InstallationErrorz%General exception during installationNrrrrrrrrc@r)UninstallationErrorz'General exception during uninstallationNrrrrrrrrc@s<eZdZdZdeedfdeddfddZdefd d ZdS) NoneMetadataErrora Raised when accessing "METADATA" or "PKG-INFO" metadata for a pip._vendor.pkg_resources.Distribution object and `dist.has_metadata('METADATA')` returns True but `dist.get_metadata('METADATA')` returns None (and similarly for "PKG-INFO"). distr metadata_namereturnNcC||_||_dS)z :param dist: A Distribution object. :param metadata_name: The name of the metadata being accessed (can be "METADATA" or "PKG-INFO"). N)rr)selfrrrrr__init__*s zNoneMetadataError.__init__cCd|j|jS)Nz+None {} metadata found for distribution: {})formatrrr"rrr__str__7szNoneMetadataError.__str__) rrrrr r strr#r'rrrrr!s   rc@seZdZdZdefddZdS)UserInstallationInvalidzBA --user install is requested on an environment without user site.r cCsdS)Nz$User base directory is not specifiedrr&rrrr'CszUserInstallationInvalid.__str__N)rrrrr(r'rrrrr)@sr)c@seZdZdefddZdS)InvalidSchemeCombinationr cCs6ddd|jddD}d|d|jddS)Nz, css|]}t|VqdSN)r().0arrr Iz3InvalidSchemeCombination.__str__..z Cannot set z and z together)joinargs)r"beforerrrr'Hsz InvalidSchemeCombination.__str__N)rrrr(r'rrrrr*Gsr*c@r)DistributionNotFoundzCRaised when a distribution cannot be found to satisfy a requirementNrrrrrr4Mrr4c@r)RequirementsFileParseErrorzDRaised when a general error occurs parsing a requirements file line.Nrrrrrr5Qrr5c@r)BestVersionAlreadyInstalledzNRaised when the most up-to-date version of a package is already installed.Nrrrrrr6Urr6c@r) BadCommandz0Raised when virtualenv or a command is not foundNrrrrrr7Zrr7c@r) CommandErrorz7Raised when there is an error in command-line argumentsNrrrrrr8^rr8c@r)PreviousBuildDirErrorz:Raised when there's a previous conflicting build directoryNrrrrrr9brr9c sDeZdZdZ d dedededdffdd Zdefd d ZZ S) NetworkConnectionErrorzHTTP connection errorN error_msgresponserequestr csJ||_||_||_|jdur|jst|dr|jj|_t|||dS)zc Initialize NetworkConnectionError with `request` and `response` objects. Nr=)r<r=r;hasattrsuperr#)r"r;r<r= __class__rrr#is  zNetworkConnectionError.__init__cC t|jSr+)r(r;r&rrrr'{ zNetworkConnectionError.__str__)NN) rrrrr(r r r#r' __classcell__rrr@rr:fsr:c@r)InvalidWheelFilenamezInvalid wheel filename.NrrrrrrErrEc@r)UnsupportedWheelzUnsupported wheel.NrrrrrrFrrFc @s<eZdZdZdddedededdf d d Zdefd d ZdS) MetadataInconsistentzBuilt metadata contains inconsistent information. This is raised when the metadata contains values (e.g. name and version) that do not match the information previously obtained from sdist filename or user-supplied ``#egg=`` value. ireqrfieldf_valm_valr NcCs||_||_||_||_dSr+)rHrIrJrK)r"rHrIrJrKrrrr#s zMetadataInconsistent.__init__cCsd}||j|j|j|jS)NzJRequested {} has inconsistent {}: filename has {!r}, but metadata has {!r})r%rHrIrJrK)r"templaterrrr'szMetadataInconsistent.__str__)rrrrr(r#r'rrrrrGs rGc@s4eZdZdZdededdfddZdefdd ZdS) InstallationSubprocessErrorz-A subprocess call failed during installation. returncode descriptionr NcCs||_||_dSr+)rNrO)r"rNrOrrrr#s z$InstallationSubprocessError.__init__cCr$)NzSCommand errored out with exit status {}: {} Check the logs for full command output.)r%rNrOr&rrrr's z#InstallationSubprocessError.__str__)rrrrintr(r#r'rrrrrMsrMc@s@eZdZdZdddZddd Zdefd d Zdefd d Z dS) HashErrorsz:Multiple HashError instances rolled into one for reportingr NcCs g|_dSr+)errorsr&rrrr#rCzHashErrors.__init__error HashErrorcCs|j|dSr+)rRappend)r"rSrrrrUszHashErrors.appendcCsbg}|jjdddt|jddD]\}}||j|dd|Dq|r/d|SdS) NcS|jSr+)ordererrrz$HashErrors.__str__..)keycSrVr+r@rXrrrrZr[css|]}|VqdSr+)bodyr,rYrrrr.r/z%HashErrors.__str__.. )rRsortrrUheadextendr1)r"linescls errors_of_clsrrrr's  zHashErrors.__str__cCrBr+)boolrRr&rrr__bool__rCzHashErrors.__bool__)r N)rSrTr N) rrrrr#rUr(r'rgrhrrrrrQs    rQc@s\eZdZUdZdZeded<dZdZe ed<de fd d Z de fd d Z de fd dZ dS)rTa A failure to verify a package against known-good hashes :cvar order: An int sorting hash exception classes by difficulty of recovery (lower being harder), so the user doesn't bother fretting about unpinned packages when he has deeper issues, like VCS dependencies, to deal with. Also keeps error reports in a deterministic order. :cvar head: A section heading for display above potentially many exceptions of this kind :ivar req: The InstallRequirement that triggered this error. This is pasted on after the exception is instantiated, because it's not typically available earlier. Nrreqr`r0rWr cCsd|S)a=Return a summary of me for display under the heading. This default implementation simply prints a description of the triggering requirement. :param req: The InstallRequirement that provoked this error, with its link already populated by the resolver's _populate_link(). z )_requirement_namer&rrrr]s zHashError.bodycCs|jd|S)Nr_)rbr]r&rrrr'zHashError.__str__cCs|jrt|jSdS)zReturn a description of the requirement that triggered me. This default implementation returns long description of the req, with line numbers unknown package)rir(r&rrrrjszHashError._requirement_name)rrrrrir__annotations__rbrWrPr(r]r'rjrrrrrTs   rTc@eZdZdZdZdZdS)VcsHashUnsupporteduA hash was provided for a version-control-system-based requirement, but we don't have a method for hashing those.rzlCan't verify hashes for these requirements because we don't have a way to hash version control repositories:NrrrrrWrbrrrrro roc@rn)DirectoryUrlHashUnsupportedrpzUCan't verify hashes for these file:// requirements because they point to directories:Nrqrrrrrsrrrsc@s8eZdZdZdZdZdeddfddZdefd d ZdS) HashMissingz2A hash was needed for a requirement but is absent.awHashes are required in --require-hashes mode, but they are missing from some requirements. Here is a list of those requirements along with the hashes their downloaded archives actually had. Add lines like these to your requirements files to prevent tampering. (If you did not enable --require-hashes manually, note that it turns on automatically when any package has a hash.) gotten_hashr NcCs ||_dS)zq :param gotten_hash: The hash of the (possibly malicious) archive we just downloaded N)rw)r"rwrrrr#s zHashMissing.__init__cCsHddlm}d}|jr|jjr|jjnt|jdd}d|pd||jS)Nr) FAVORITE_HASHriz {} --hash={}:{}rl)pip._internal.utils.hashesrxri original_linkgetattrr%rw)r"rxpackagerrrr]s   zHashMissing.body) rrrrrWrbr(r#r]rrrrrus ruc@rn) HashUnpinnedzPA requirement had a hash specified but was not pinned to a specific version.zaIn --require-hashes mode, all requirements must have their versions pinned with ==. These do not:Nrqrrrrr}2rrr}c@s^eZdZdZdZdZdeeeefdeedfddfd d Z defd d Z defd dZ dS) HashMismatchz Distribution file hash values don't match. :ivar package_name: The name of the package that triggered the hash mismatch. Feel free to write to this after the exception is raise to improve its error message. zTHESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.allowedgotsr r NcCr!)z :param allowed: A dict of algorithm names pointing to lists of allowed hex digests :param gots: A dict of algorithm names pointing to hashes we actually got from the files under suspicion N)rr)r"rrrrrr#Os zHashMismatch.__init__cCsd||S)Nz {}: {})r%rj_hash_comparisonr&rrrr]YrkzHashMismatch.bodycsndtddfdd}g}|jD]!\}}|||fdd|D|d|j|qd |S) aE Return a comparison of actual and expected hash values. Example:: Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde or 123451234512345123451234512345123451234512345 Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef hash_namer z chain[str]cSst|gtdS)Nz or)rr)rrrr hash_then_orhsz3HashMismatch._hash_comparison..hash_then_orc3s |] }dt|VqdS)z Expected {} {}N)r%nextr^prefixrrr.ps z0HashMismatch._hash_comparison..z Got {} r_) r(ritemsrcrUr%r hexdigestr1)r"rrdr expectedsrrrr\s  zHashMismatch._hash_comparison) rrrrrWrbrr(rr#r]rrrrrr=s * rc@r)UnsupportedPythonVersionzMUnsupported python version according to Requires-Python package metadata.Nrrrrrryrrc sReZdZdZ   d dedeedeejddffdd Zdefd d Z Z S) !ConfigurationFileCouldNotBeLoadedz8When there are errors while loading a configuration filecould not be loadedNreasonfnamerSr cs"t|||_||_||_dSr+)r?r#rrrS)r"rrrSr@rrr#s  z*ConfigurationFileCouldNotBeLoaded.__init__cCsF|jdur d|jd}n|jdusJd|jd}d|j|S)Nz in .z. r_zConfiguration file )rrSr)r" message_partrrrr's z)ConfigurationFileCouldNotBeLoaded.__str__)rNN) rrrrr(r configparserErrorr#r'rDrrr@rr~s r)3rr itertoolsrrrtypingrrrrr pip._vendor.pkg_resourcesr pip._vendor.requests.modelsr r hashlibr pip._internal.metadatarpip._internal.req.req_installr Exceptionrrrrrr)r*r4r5r6r7r8r9r:rErFrGrMrQrTrorsrur}rrrrrrrsJ    .  * <PKH]{)`Vpython3.10/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-310.pycnu[o ai@s ddlZddlZddlZddlZddlZddlZddlZddlm Z m Z ddl m Z ddlmZddlmZddlmZddlmZddlmZdd lmZmZmZdd lmZd Zee Z!d e"d e"fddZ#GdddZ$de"d e%fddZ&dedej'd dfddZ(dS)N)AnyDict)parse) LinkCollector) PackageFinder)get_default_environment)SelectionPreferences) PipSession)adjacent_tmp_filecheck_path_ownerreplace) ensure_dirz%Y-%m-%dT%H:%M:%SZkeyreturncCs|}t|}|SN)encodehashlibsha224 hexdigest)r key_bytesnamer/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/self_outdated_check.py_get_statefile_namesrc@sHeZdZdeddfddZedefddZded ejddfd d ZdS) SelfCheckState cache_dirrNc Csi|_d|_|rDtj|dt|j|_z"t|jdd}t ||_WdWdS1s/wYWdSt t t fyCYdSwdS)N selfcheckzutf-8)encoding) statestatefile_pathospathjoinrropenjsonloadOSError ValueErrorKeyError)selfr statefilerrr__init__!s &zSelfCheckState.__init__cCstjSr)sysprefix)r)rrrr2szSelfCheckState.key pypi_version current_timecCs|jsdSttj|jsdSttj|j|j|t|d}t j |ddd}t |j}| | Wdn1sBwYz t|j|jWdSty[YdSw)N)r last_checkr.T),:) sort_keys separators)rr r r!dirnamer rstrftimeSELFCHECK_DATE_FMTr$dumpsr writerr rr&)r)r.r/rtextfrrrsave6s$  zSelfCheckState.save) __name__ __module__ __qualname__strr+propertyrdatetimer<rrrrr s rpkgcCst|}|duod|jkS)zChecks whether pkg was installed by pip This is used not to display the upgrade message when pip is in fact installed by system package manager, such as dnf on Fedora. Npip)rget_distribution installer)rCdistrrrwas_installed_by_pipYs rHsessionoptionscCsLtd}|s dS|j}d}zt|jd}tj}d|jvrs,        9 PKH]Aʸƃ%%Lpython3.10/site-packages/pip/_internal/__pycache__/build_env.cpython-310.pycnu[o ai&@sbdZddlZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z ddl m Z ddlmZmZmZmZmZmZmZmZddlmZddlmZdd lmZdd lmZdd l m!Z!dd l"m#Z#m$Z$m%Z%dd l&m'Z'ddl(m)Z)ddl*m+Z+m,Z,erddl-m.Z.e/e0Z1GdddZ2ej3dee4fddZ5GdddZ6Gddde6Z7dS)z;Build Environment used for isolation during sdist building N) OrderedDict) get_paths) TracebackType) TYPE_CHECKINGIterableIteratorListOptionalSetTupleType)where) Requirement)Version)__file__) open_spinner) get_platlibget_prefixed_libs get_purelib)get_environment)call_subprocess) TempDirectory tempdir_kinds) PackageFinderc@seZdZdeddfddZdS)_PrefixpathreturnNcCs@||_d|_ttjdkrdnd||ddd|_t||_dS)NFnt posix_prefix)baseplatbase)varsscripts)rsetuprosnamebin_dirrlib_dirs)selfrr)/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/build_env.py__init__"sz_Prefix.__init__)__name__ __module__ __qualname__strr+r)r)r)r*r!srrc csttj}|st|VdStddR}tj |j d}i}t j dkr-d|d<t j|dfi|}|d D]}||||jq=Wdn1sVwYtj |d VWddS1snwYdS) zCreate a "standalone pip" zip file. The zip file's content is identical to the currently-running pip. It will be used to install requirements into the build environment. Nzstandalone-pip)kindz__env_pip__.zip)Fstrict_timestampsw*pip)pathlibPath pip_locationresolveparentis_dirr/rr$rjoinsys version_infozipfileZipFilerglobwrite relative_toas_posix)sourcetmp_dirpip_zipkwargszfchildr)r)r*_create_standalone_pip,s"   "rLc @seZdZdZdddZdddZdeeed eed ee ddfd d Z d e e de ee e e fee ffddZddde e de de ddf ddZede ddde e dede ddf ddZdS)BuildEnvironmentzACreates and manages an isolated environment to install build depsrNcsttjddtfdddD|_g|_g|_tt|j D]}|j |j |j |j q"ddttfD}tjjd|_tj|jsTt|jttj|jd d }|td j||jd WddS1sywYdS) NT)r0globally_managedc3s(|]}|ttjj|fVqdSN)rr$rr=.0r%temp_dirr)r* Ls  z,BuildEnvironment.__init__..)normaloverlaycSsh|]}tj|qSr))r$rnormcase)rQsiter)r)r* Zs z,BuildEnvironment.__init__..rXzsitecustomize.pyr4a import os, site, sys # First, drop system-sites related paths. original_sys_path = sys.path[:] known_paths = set() for path in {system_sites!r}: site.addsitedir(path, known_paths=known_paths) system_paths = set( os.path.normcase(path) for path in sys.path[len(original_sys_path):] ) original_sys_path = [ path for path in original_sys_path if os.path.normcase(path) not in system_paths ] sys.path = original_sys_path # Second, add lib directories. # ensuring .pth file are processed. for path in {lib_dirs!r}: assert not path in sys.path site.addsitedir(path) ) system_sitesr')rr BUILD_ENVr _prefixes _bin_dirs _lib_dirsreversedlistvaluesappendr&extendr'rrr$rr= _site_direxistsmkdiropenrCtextwrapdedentformat)r(prefixrZfpr)rRr*r+Is0    "zBuildEnvironment.__init__cCsndddD|_|jdd}|jd}|r||tj|jg}tjtj |dtj |ddS)NcSsi|] }|tj|dqSrO)r$environgetrPr)r)r* sz.BuildEnvironment.__enter__..)PATHPYTHONNOUSERSITE PYTHONPATHrp1) _save_envr]rcsplitr$pathseprdrmupdater=)r(rold_path pythonpathr)r)r* __enter__~s   zBuildEnvironment.__enter__exc_typeexc_valexc_tbcCs:|jD]\}}|durtj|dq|tj|<qdSrO)rtitemsr$rmpop)r(r{r|r}varname old_valuer)r)r*__exit__s  zBuildEnvironment.__exit__reqsc Cst}t}|rJt|j}|D]:}t|}||j}|s#||qt|jt r3|jd|j}n |jd|j}|j|j vrI|||fq||fS)zReturn 2 sets: - conflicting requirements: set of (installed, wanted) reqs tuples - missing requirements: set of reqs z==z===) setrr^rget_distributionr%add isinstanceversionr specifier) r(rmissing conflictingenvreq_strreqdistinstalled_req_strr)r)r*check_requirementss"     z#BuildEnvironment.check_requirementsfinderr requirementsprefix_as_stringmessagecCs|j|}|jr Jd|_|sdSt$}tjdkr"tjt }n| t }| |||||WddS1sr?r$rdirnamer9 enter_contextrL_install_requirements)r(rrrrrkctx pip_runnabler)r)r*install_requirementss"     "z%BuildEnvironment.install_requirementsrrkcCsftj|dddd|jdg}ttjkr|ddD]}t|j |}| d| d d d t |p2d hfq|j}|rW| d |dg|ddD] } | d| gqLn|d|jD] } | d| gq_|jD] } | d| gql|jr~|d|jr|d|d| |dti} t|} t|| | dWddS1swYdS)Ninstallz--ignore-installedz --no-userz--prefixz--no-warn-script-locationz-v) no_binary only_binaryz--_-,z:none:z-irz--extra-index-urlz --no-indexz --find-linksz--trusted-hostz--prez--prefer-binary_PIP_STANDALONE_CERT)spinner extra_environ)r> executablerloggergetEffectiveLevelloggingDEBUGrbgetattrformat_controlrcreplacer=sorted index_urls find_links trusted_hostsallow_all_prereleases prefer_binaryr rr)rrrrkrargsrformatsr extra_indexlinkhostrrr)r)r*rsN            "z&BuildEnvironment._install_requirementsrN)r,r-r.__doc__r+rzr r BaseExceptionrrrr/r r rr staticmethodrrr)r)r)r*rMFsV  5     rMc @szeZdZdZdddZdddZdeeed eed ee ddfd d Z dd dZ ddde e de de ddf ddZdS)NoOpBuildEnvironmentz0A no-op drop-in replacement for BuildEnvironmentrNcCdSrOr)r(r)r)r*r+ zNoOpBuildEnvironment.__init__cCrrOr)rr)r)r*rzrzNoOpBuildEnvironment.__enter__r{r|r}cCrrOr))r(r{r|r}r)r)r*rszNoOpBuildEnvironment.__exit__cCrrOr)rr)r)r*cleanuprzNoOpBuildEnvironment.cleanuprrrrrcCstrO)NotImplementedError)r(rrrrr)r)r*rsz)NoOpBuildEnvironment.install_requirementsr)r,r-r.rr+rzr r rrrrrr/rr)r)r)r*r s2    r)8rrrr$r7r>rhr@ collectionsr sysconfigrtypesrtypingrrrrr r r r pip._vendor.certifir Z"pip._vendor.packaging.requirementsrZpip._vendor.packaging.versionrr6rr9pip._internal.cli.spinnersrpip._internal.locationsrrrpip._internal.metadatarpip._internal.utils.subprocessrpip._internal.utils.temp_dirrr"pip._internal.index.package_finderr getLoggerr,rrcontextmanagerr/rLrMrr)r)r)r*s<   (          EPKH]O Hpython3.10/site-packages/pip/_internal/__pycache__/cache.cpython-310.pycnu[o ai$@s dZddlZddlZddlZddlZddlmZmZmZm Z m Z ddl m Z m Z mZddlmZddlmZddlmZddlmZdd lmZdd lmZmZdd lmZeeZ d ee!e!fd e!fddZ"GdddZ#Gddde#Z$Gddde$Z%GdddZ&Gddde#Z'dS)zCache Management N)AnyDictListOptionalSet)Taginterpreter_nameinterpreter_version)canonicalize_name)InvalidWheelFilename) FormatControl)Link)Wheel) TempDirectory tempdir_kinds) path_to_urldreturncCs&tj|dddd}t|dS)z'Return a stable sha224 of a dictionary.T),:) sort_keys separators ensure_asciiascii)jsondumpshashlibsha224encode hexdigest)rsr!/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cache.py _hash_dictsr#cseZdZdZdededeeddffdd Zd ede efd d Z d ed ede e fd dZ d edefddZ d edeede edefddZZS)CacheanAn abstract class - provides cache directories for data from links :param cache_dir: The root of the cache. :param format_control: An object of FormatControl class to limit binaries being read from the cache. :param allowed_formats: which formats of files the cache should store. ('binary' and 'source' are the only allowed values) cache_dirformat_controlallowed_formatsrNcsTt|rtj|sJ|pd|_||_||_ddh}|j||ks(JdS)Nsourcebinary) super__init__ospathisabsr%r&r'union)selfr%r&r'_valid_formats __class__r!r"r+(s  zCache.__init__linkcCsd|ji}|jdur|jdur|j||j<|jr|j|d<t|d<t|d<t|}|dd|dd|dd|ddg}|S) zs*       XF  PKH]c##Ppython3.10/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-310.pycnu[o ai/@sdZddlZddlZddlZddlZddlmZmZm Z m Z m Z m Z ddl mZmZddlmZmZddlmZddlmZmZddlmZmZdd lmZdd lmZdd lm Z dd l!m"Z"dd l#m$Z$ddl%m&Z&ddl'm(Z(ddl)m*Z*m+Z+m,Z,ddl-m.Z.ddl/m0Z0ddl1m2Z2ddl3m4Z4ddl5m6Z6e7e8Z9e:dej;Ze e e&e e&fZ?de@de=fddZAde&de=de>de=fddZBde&de=fd d!ZCde&de>de=fd"d#ZDde&de e=fd$d%ZEde&d&ede@fd'd(ZFd)ede=fd*d+ZGde&d,e@ddfd-d.ZHde&d/e@d0e=d1e e@d2e e@d3e=de e@fd4d5ZIde&d/e@d1e e@d2e e@d3e=de e@f d6d7ZJde&d2e e@de=fd8d9ZKd:e e&d&ed0e=d1e e@d2e e@de?f d;d<ZLdS)=z;Orchestrator for building wheels from InstallRequirements. N)AnyCallableIterableListOptionalTuple)canonicalize_namecanonicalize_version)InvalidVersionVersion) WheelCache)InvalidWheelFilenameUnsupportedWheel)FilesystemWheelget_wheel_distribution)Link)Wheel)build_wheel_pep517)build_wheel_editable)build_wheel_legacy)InstallRequirement) indent_log) ensure_dir hash_fileis_wheel_installed)make_setuptools_clean_args)call_subprocess) TempDirectory) path_to_url)vcsz([a-z0-9_.]+)-([a-z0-9_.!+-]+)sreturncCstt|S)zjDetermine whether the string looks like an egg_info. :param s: The string to parse. E.g. foo-2.1 )bool _egg_info_research)r r%/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/wheel_builder.py_contains_egg_info&sr'req need_wheelcheck_binary_allowedcCs|jrdS|jr|rtd|jdS|rdS|jsdS|jr#|S|jr(dS||s5td|jdSt sAtd|jdSdS)zBReturn whether an InstallRequirement should be built into a wheel.Fz(Skipping %s, due to already being wheel.TzCSkipping wheel build for %s, due to binaries being disabled for it.zOUsing legacy 'setup.py install' for %s, since package 'wheel' is not installed.) constraintis_wheelloggerinfoname source_direditablesupports_pyproject_editable use_pep517r)r(r)r*r%r%r& _should_build.s<r4cCst|dtdS)NTr)r*)r4 _always_true)r(r%r%r&should_build_for_wheel_commandcsr7cCst|d|dS)NFr5)r4)r(r*r%r%r& should_build_for_install_commandisr8cCs|js|jsdS|jr1|jjr1|jrJ|jsJt|jj}|s$J||jj|jr/dSdS|js6J|j \}}t |rCdSdS)z Return whether a built InstallRequirement can be stored in the persistent wheel cache, assuming the wheel cache is available, and _should_build() has determined a wheel needs to be built. FT) r1r0linkis_vcsrget_backend_for_schemeschemeis_immutable_rev_checkouturlsplitextr')r( vcs_backendbaseextr%r%r& _should_cachers    rC wheel_cachecCs@t|j}|js J|rt|r||j}|S||j}|S)zdReturn the persistent or temporary cache directory where the built wheel need to be stored. )r" cache_dirr9rCget_path_for_linkget_ephem_path_for_link)r(rDcache_availablerEr%r%r&_get_cache_dirs     rI_cCsdS)NTr%)rJr%r%r&r6sr6 wheel_pathc Cst|jpd}ttj|}t|j|krtd||jtt ||}t |j }t |t |j kr=td||j |j }|durHtdzt|}Wnty^d|}t|w|tdkrrt|j tsttd|dSdS)Nz7Wheel has unexpected file name: expected {!r}, got {!r}zMissing Metadata-VersionzInvalid Metadata-Version: z1.2z6Metadata 1.2 mandates PEP 440 version, but {!r} is not)rr/rospathbasenamer formatrrstrversionr metadata_versionrr r isinstance) r(rKcanonical_namewdist dist_verstrmetadata_version_valuerSmsgr%r%r& _verify_ones:      r[ output_dirverify build_optionsglobal_optionsr1c Cs|rdnd}zt|Wnty(}ztd||j|WYd}~dSd}~ww|jt|||||}Wdn1s?wY|ro|rozt||W|Stt fyn}ztd||j|WYd}~dSd}~ww|S)zaBuild one wheel. :return: The filename of the built wheel, or None if the build failed. r1wheelzBuilding %s for %s failed: %sNzBuilt %s for %s is invalid: %s) rOSErrorr-warningr/ build_env_build_one_inside_envr[r r) r(r\r]r^r_r1artifacterKr%r%r& _build_ones8     rgc Cstdd}|js J|jrF|jsJ|jsJ|r!td|j|r*td|j|r9t|j|j|j|jd}nt |j|j|j|jd}nt |j|j |j |||jd}|durt j|}t j||}z(t|\} } t||td|j|| | td||WWdSty} ztd |j| WYd} ~ nd} ~ ww|jst|| WddS1swYdS) Nr`)kindz7Ignoring --global-option when building %s using PEP 517z6Ignoring --build-option when building %s using PEP 517)r/backendmetadata_directorytempd)r/ setup_py_pathr0r_r^rkz3Created wheel for %s: filename=%s size=%d sha256=%szStored in directory: %sz Building wheel for %s failed: %s)rr/r3rjpep517_backendr-rbrrNrrrlunpacked_source_directoryrMrOjoinrshutilmover. hexdigest Exception_clean_one_legacy) r(r\r^r_r1temp_dirrK wheel_name dest_path wheel_hashlengthrfr%r%r&rds|        4 $rdcCsTt|j|d}td|jz t||jdWdSty)td|jYdSw)N)r_zRunning setup.py clean for %s)cwdTz Failed cleaning build dir for %sF) rrlr-r.r/rr0rserror)r(r_ clean_argsr%r%r&rt1s rt requirementsc Cs|sggfStdddd|DtHgg}}|D]8}|js&Jt||}t||||||jo6|j} | rRt t | |_ |j j |_ |j jsLJ||q||qWdn1sbwY|rwtdddd |D|rtd dd d |D||fS) zBuild wheels. :return: The list of InstallRequirement that succeeded to build and the list of InstallRequirement that failed to build. z*Building wheels for collected packages: %sz, css|]}|jVqdS)Nr/.0r(r%r%r& Rszbuild..NzSuccessfully built %s cSg|]}|jqSr%r~rr%r%r& ozbuild..zFailed to build %scSrr%r~rr%r%r&rtr)r-r.rorr/rIrgr1permit_editable_wheelsrrr9 file_pathlocal_file_pathr,append) r}rDr]r^r_build_successesbuild_failuresr(rE wheel_filer%r%r&build@sL         r)M__doc__loggingos.pathrMrerptypingrrrrrrpip._vendor.packaging.utilsrr Zpip._vendor.packaging.versionr r pip._internal.cacher pip._internal.exceptionsr rpip._internal.metadatarrpip._internal.models.linkrpip._internal.models.wheelr$pip._internal.operations.build.wheelr-pip._internal.operations.build.wheel_editabler+pip._internal.operations.build.wheel_legacyrpip._internal.req.req_installrpip._internal.utils.loggingrpip._internal.utils.miscrrr$pip._internal.utils.setuptools_buildrpip._internal.utils.subprocessrpip._internal.utils.temp_dirrpip._internal.utils.urlsrpip._internal.vcsr getLogger__name__r-compile IGNORECASEr#r"BinaryAllowedPredicate BuildResultrQr'r4r7r8rCrIr6r[rgrdrtrr%r%r%r&s                5       & GPKH]Lpython3.10/site-packages/pip/_internal/__pycache__/pyproject.cpython-310.pycnu[o ai/ @sddlZddlmZddlmZmZmZddlmZddl m Z m Z ddl m Z dedefd d Zd edefd d ZedgdZdeededededeef ddZdS)N) namedtuple)AnyListOptional)tomli)InvalidRequirement Requirement)InstallationErrorobjreturncCst|to tdd|DS)Ncss|]}t|tVqdS)N) isinstancestr).0itemr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/pyproject.py sz"_is_list_of_str..)r listall)r rrr_is_list_of_str srunpacked_source_directorycCstj|dS)Nzpyproject.toml)ospathjoin)rrrrmake_pyproject_pathsrBuildSystemDetails)requiresbackendcheck backend_path use_pep517pyproject_tomlsetup_pyreq_namec Cstj|}tj|}|s|st|d|r:t|dd }t|}Wdn1s/wY|d}nd}|rM|sM|durJ|sJtdd}n|red|vre|durb|sbtd |dd}n|durk|}|dusqJ|sudS|durd d gd d }|dusJd} d|vrt| j|dd|d} t | st| j|dd| D]} zt | Wqt yt| j|d| dw|d} |dg} g}| durd } d d g}t | | || S)aBLoad the pyproject.toml file. Parameters: use_pep517 - Has the user requested PEP 517 processing? None means the user hasn't explicitly specified. pyproject_toml - Location of the project's pyproject.toml file setup_py - Location of the project's setup.py file req_name - The name of the requirement we're processing (for error reporting) Returns: None if we should use the legacy code path, otherwise a tuple ( requirements from pyproject.toml, name of PEP 517 backend, requirements we should check are installed after setting up the build environment directory paths to import the backend from (backend-path), relative to the project root. ) zW does not appear to be a Python project: neither 'setup.py' nor 'pyproject.toml' found.zutf-8)encodingNz build-systemzIDisabling PEP 517 processing is invalid: project does not have a setup.pyT build-backendzbDisabling PEP 517 processing is invalid: project specifies a build backend of {} in pyproject.tomlzsetuptools>=40.8.0wheelz setuptools.build_meta:__legacy__)rr%zO{package} has a pyproject.toml file that does not comply with PEP 518: {reason}rz]it has a 'build-system' table but not 'build-system.requires' which is mandatory in the table)packagereasonz1'build-system.requires' is not a list of strings.z='build-system.requires' contains an invalid requirement: {!r}z backend-path) rrisfiler openrloadgetformatrrrr)r r!r"r# has_pyproject has_setupfpp_toml build_systemerror_templater requirementrrrrrrload_pyproject_tomls                r5)r collectionsrtypingrrr pip._vendorrZ"pip._vendor.packaging.requirementsrrpip._internal.exceptionsr boolrr rrr5rrrrs,   PKH]Օ$$/python3.10/site-packages/pip/_internal/cache.pynu["""Cache Management """ import hashlib import json import logging import os from typing import Any, Dict, List, Optional, Set from pip._vendor.packaging.tags import Tag, interpreter_name, interpreter_version from pip._vendor.packaging.utils import canonicalize_name from pip._internal.exceptions import InvalidWheelFilename from pip._internal.models.format_control import FormatControl from pip._internal.models.link import Link from pip._internal.models.wheel import Wheel from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds from pip._internal.utils.urls import path_to_url logger = logging.getLogger(__name__) def _hash_dict(d: Dict[str, str]) -> str: """Return a stable sha224 of a dictionary.""" s = json.dumps(d, sort_keys=True, separators=(",", ":"), ensure_ascii=True) return hashlib.sha224(s.encode("ascii")).hexdigest() class Cache: """An abstract class - provides cache directories for data from links :param cache_dir: The root of the cache. :param format_control: An object of FormatControl class to limit binaries being read from the cache. :param allowed_formats: which formats of files the cache should store. ('binary' and 'source' are the only allowed values) """ def __init__( self, cache_dir: str, format_control: FormatControl, allowed_formats: Set[str] ) -> None: super().__init__() assert not cache_dir or os.path.isabs(cache_dir) self.cache_dir = cache_dir or None self.format_control = format_control self.allowed_formats = allowed_formats _valid_formats = {"source", "binary"} assert self.allowed_formats.union(_valid_formats) == _valid_formats def _get_cache_path_parts(self, link: Link) -> List[str]: """Get parts of part that must be os.path.joined with cache_dir""" # We want to generate an url to use as our cache key, we don't want to # just re-use the URL because it might have other items in the fragment # and we don't care about those. key_parts = {"url": link.url_without_fragment} if link.hash_name is not None and link.hash is not None: key_parts[link.hash_name] = link.hash if link.subdirectory_fragment: key_parts["subdirectory"] = link.subdirectory_fragment # Include interpreter name, major and minor version in cache key # to cope with ill-behaved sdists that build a different wheel # depending on the python version their setup.py is being run on, # and don't encode the difference in compatibility tags. # https://github.com/pypa/pip/issues/7296 key_parts["interpreter_name"] = interpreter_name() key_parts["interpreter_version"] = interpreter_version() # Encode our key url with sha224, we'll use this because it has similar # security properties to sha256, but with a shorter total output (and # thus less secure). However the differences don't make a lot of # difference for our use case here. hashed = _hash_dict(key_parts) # We want to nest the directories some to prevent having a ton of top # level directories where we might run out of sub directories on some # FS. parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] return parts def _get_candidates(self, link: Link, canonical_package_name: str) -> List[Any]: can_not_cache = not self.cache_dir or not canonical_package_name or not link if can_not_cache: return [] formats = self.format_control.get_allowed_formats(canonical_package_name) if not self.allowed_formats.intersection(formats): return [] candidates = [] path = self.get_path_for_link(link) if os.path.isdir(path): for candidate in os.listdir(path): candidates.append((candidate, path)) return candidates def get_path_for_link(self, link: Link) -> str: """Return a directory to store cached items in for link.""" raise NotImplementedError() def get( self, link: Link, package_name: Optional[str], supported_tags: List[Tag], ) -> Link: """Returns a link to a cached item if it exists, otherwise returns the passed link. """ raise NotImplementedError() class SimpleWheelCache(Cache): """A cache of wheels for future installs.""" def __init__(self, cache_dir: str, format_control: FormatControl) -> None: super().__init__(cache_dir, format_control, {"binary"}) def get_path_for_link(self, link: Link) -> str: """Return a directory to store cached wheels for link Because there are M wheels for any one sdist, we provide a directory to cache them in, and then consult that directory when looking up cache hits. We only insert things into the cache if they have plausible version numbers, so that we don't contaminate the cache with things that were not unique. E.g. ./package might have dozens of installs done for it and build a version of 0.0...and if we built and cached a wheel, we'd end up using the same wheel even if the source has been edited. :param link: The link of the sdist for which this will cache wheels. """ parts = self._get_cache_path_parts(link) assert self.cache_dir # Store wheels within the root cache_dir return os.path.join(self.cache_dir, "wheels", *parts) def get( self, link: Link, package_name: Optional[str], supported_tags: List[Tag], ) -> Link: candidates = [] if not package_name: return link canonical_package_name = canonicalize_name(package_name) for wheel_name, wheel_dir in self._get_candidates(link, canonical_package_name): try: wheel = Wheel(wheel_name) except InvalidWheelFilename: continue if canonicalize_name(wheel.name) != canonical_package_name: logger.debug( "Ignoring cached wheel %s for %s as it " "does not match the expected distribution name %s.", wheel_name, link, package_name, ) continue if not wheel.supported(supported_tags): # Built for a different python/arch/etc continue candidates.append( ( wheel.support_index_min(supported_tags), wheel_name, wheel_dir, ) ) if not candidates: return link _, wheel_name, wheel_dir = min(candidates) return Link(path_to_url(os.path.join(wheel_dir, wheel_name))) class EphemWheelCache(SimpleWheelCache): """A SimpleWheelCache that creates it's own temporary cache directory""" def __init__(self, format_control: FormatControl) -> None: self._temp_dir = TempDirectory( kind=tempdir_kinds.EPHEM_WHEEL_CACHE, globally_managed=True, ) super().__init__(self._temp_dir.path, format_control) class CacheEntry: def __init__( self, link: Link, persistent: bool, ): self.link = link self.persistent = persistent class WheelCache(Cache): """Wraps EphemWheelCache and SimpleWheelCache into a single Cache This Cache allows for gracefully degradation, using the ephem wheel cache when a certain link is not found in the simple wheel cache first. """ def __init__(self, cache_dir: str, format_control: FormatControl) -> None: super().__init__(cache_dir, format_control, {"binary"}) self._wheel_cache = SimpleWheelCache(cache_dir, format_control) self._ephem_cache = EphemWheelCache(format_control) def get_path_for_link(self, link: Link) -> str: return self._wheel_cache.get_path_for_link(link) def get_ephem_path_for_link(self, link: Link) -> str: return self._ephem_cache.get_path_for_link(link) def get( self, link: Link, package_name: Optional[str], supported_tags: List[Tag], ) -> Link: cache_entry = self.get_cache_entry(link, package_name, supported_tags) if cache_entry is None: return link return cache_entry.link def get_cache_entry( self, link: Link, package_name: Optional[str], supported_tags: List[Tag], ) -> Optional[CacheEntry]: """Returns a CacheEntry with a link to a cached item if it exists or None. The cache entry indicates if the item was found in the persistent or ephemeral cache. """ retval = self._wheel_cache.get( link=link, package_name=package_name, supported_tags=supported_tags, ) if retval is not link: return CacheEntry(retval, persistent=True) retval = self._ephem_cache.get( link=link, package_name=package_name, supported_tags=supported_tags, ) if retval is not link: return CacheEntry(retval, persistent=False) return None PKH]- gš8python3.10/site-packages/pip/_internal/commands/index.pynu[import logging from optparse import Values from typing import Any, Iterable, List, Optional, Union from pip._vendor.packaging.version import LegacyVersion, Version from pip._internal.cli import cmdoptions from pip._internal.cli.req_command import IndexGroupCommand from pip._internal.cli.status_codes import ERROR, SUCCESS from pip._internal.commands.search import print_dist_installation_info from pip._internal.exceptions import CommandError, DistributionNotFound, PipError from pip._internal.index.collector import LinkCollector from pip._internal.index.package_finder import PackageFinder from pip._internal.models.selection_prefs import SelectionPreferences from pip._internal.models.target_python import TargetPython from pip._internal.network.session import PipSession from pip._internal.utils.misc import write_output logger = logging.getLogger(__name__) class IndexCommand(IndexGroupCommand): """ Inspect information available from package indexes. """ usage = """ %prog versions """ def add_options(self) -> None: cmdoptions.add_target_python_options(self.cmd_opts) self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) self.cmd_opts.add_option(cmdoptions.pre()) self.cmd_opts.add_option(cmdoptions.no_binary()) self.cmd_opts.add_option(cmdoptions.only_binary()) index_opts = cmdoptions.make_option_group( cmdoptions.index_group, self.parser, ) self.parser.insert_option_group(0, index_opts) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options: Values, args: List[str]) -> int: handlers = { "versions": self.get_available_package_versions, } logger.warning( "pip index is currently an experimental command. " "It may be removed/changed in a future release " "without prior warning." ) # Determine action if not args or args[0] not in handlers: logger.error( "Need an action (%s) to perform.", ", ".join(sorted(handlers)), ) return ERROR action = args[0] # Error handling happens here, not in the action-handlers. try: handlers[action](options, args[1:]) except PipError as e: logger.error(e.args[0]) return ERROR return SUCCESS def _build_package_finder( self, options: Values, session: PipSession, target_python: Optional[TargetPython] = None, ignore_requires_python: Optional[bool] = None, ) -> PackageFinder: """ Create a package finder appropriate to the index command. """ link_collector = LinkCollector.create(session, options=options) # Pass allow_yanked=False to ignore yanked versions. selection_prefs = SelectionPreferences( allow_yanked=False, allow_all_prereleases=options.pre, ignore_requires_python=ignore_requires_python, ) return PackageFinder.create( link_collector=link_collector, selection_prefs=selection_prefs, target_python=target_python, ) def get_available_package_versions(self, options: Values, args: List[Any]) -> None: if len(args) != 1: raise CommandError("You need to specify exactly one argument") target_python = cmdoptions.make_target_python(options) query = args[0] with self._build_session(options) as session: finder = self._build_package_finder( options=options, session=session, target_python=target_python, ignore_requires_python=options.ignore_requires_python, ) versions: Iterable[Union[LegacyVersion, Version]] = ( candidate.version for candidate in finder.find_all_candidates(query) ) if not options.pre: # Remove prereleases versions = ( version for version in versions if not version.is_prerelease ) versions = set(versions) if not versions: raise DistributionNotFound( "No matching distribution found for {}".format(query) ) formatted_versions = [str(ver) for ver in sorted(versions, reverse=True)] latest = formatted_versions[0] write_output("{} ({})".format(query, latest)) write_output("Available versions: {}".format(", ".join(formatted_versions))) print_dist_installation_info(query, latest) PKH]Z]8python3.10/site-packages/pip/_internal/commands/debug.pynu[import locale import logging import os import sys from optparse import Values from types import ModuleType from typing import Any, Dict, List, Optional import pip._vendor from pip._vendor.certifi import where from pip._vendor.packaging.version import parse as parse_version from pip import __file__ as pip_location from pip._internal.cli import cmdoptions from pip._internal.cli.base_command import Command from pip._internal.cli.cmdoptions import make_target_python from pip._internal.cli.status_codes import SUCCESS from pip._internal.configuration import Configuration from pip._internal.metadata import get_environment from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import get_pip_version logger = logging.getLogger(__name__) def show_value(name: str, value: Any) -> None: logger.info("%s: %s", name, value) def show_sys_implementation() -> None: logger.info("sys.implementation:") implementation_name = sys.implementation.name with indent_log(): show_value("name", implementation_name) def create_vendor_txt_map() -> Dict[str, str]: vendor_txt_path = os.path.join( os.path.dirname(pip_location), "_vendor", "vendor.txt" ) with open(vendor_txt_path) as f: # Purge non version specifying lines. # Also, remove any space prefix or suffixes (including comments). lines = [ line.strip().split(" ", 1)[0] for line in f.readlines() if "==" in line ] # Transform into "module" -> version dict. return dict(line.split("==", 1) for line in lines) # type: ignore def get_module_from_module_name(module_name: str) -> ModuleType: # Module name can be uppercase in vendor.txt for some reason... module_name = module_name.lower() # PATCH: setuptools is actually only pkg_resources. if module_name == "setuptools": module_name = "pkg_resources" __import__(f"pip._vendor.{module_name}", globals(), locals(), level=0) return getattr(pip._vendor, module_name) def get_vendor_version_from_module(module_name: str) -> Optional[str]: module = get_module_from_module_name(module_name) version = getattr(module, "__version__", None) if not version: # Try to find version in debundled module info. env = get_environment([os.path.dirname(module.__file__)]) dist = env.get_distribution(module_name) if dist: version = str(dist.version) return version def show_actual_vendor_versions(vendor_txt_versions: Dict[str, str]) -> None: """Log the actual version and print extra info if there is a conflict or if the actual version could not be imported. """ for module_name, expected_version in vendor_txt_versions.items(): extra_message = "" actual_version = get_vendor_version_from_module(module_name) if not actual_version: extra_message = ( " (Unable to locate actual module version, using" " vendor.txt specified version)" ) actual_version = expected_version elif parse_version(actual_version) != parse_version(expected_version): extra_message = ( " (CONFLICT: vendor.txt suggests version should" " be {})".format(expected_version) ) logger.info("%s==%s%s", module_name, actual_version, extra_message) def show_vendor_versions() -> None: logger.info("vendored library versions:") vendor_txt_versions = create_vendor_txt_map() with indent_log(): show_actual_vendor_versions(vendor_txt_versions) def show_tags(options: Values) -> None: tag_limit = 10 target_python = make_target_python(options) tags = target_python.get_tags() # Display the target options that were explicitly provided. formatted_target = target_python.format_given() suffix = "" if formatted_target: suffix = f" (target: {formatted_target})" msg = "Compatible tags: {}{}".format(len(tags), suffix) logger.info(msg) if options.verbose < 1 and len(tags) > tag_limit: tags_limited = True tags = tags[:tag_limit] else: tags_limited = False with indent_log(): for tag in tags: logger.info(str(tag)) if tags_limited: msg = ( "...\n[First {tag_limit} tags shown. Pass --verbose to show all.]" ).format(tag_limit=tag_limit) logger.info(msg) def ca_bundle_info(config: Configuration) -> str: levels = set() for key, _ in config.items(): levels.add(key.split(".")[0]) if not levels: return "Not specified" levels_that_override_global = ["install", "wheel", "download"] global_overriding_level = [ level for level in levels if level in levels_that_override_global ] if not global_overriding_level: return "global" if "global" in levels: levels.remove("global") return ", ".join(levels) class DebugCommand(Command): """ Display debug information. """ usage = """ %prog """ ignore_require_venv = True def add_options(self) -> None: cmdoptions.add_target_python_options(self.cmd_opts) self.parser.insert_option_group(0, self.cmd_opts) self.parser.config.load() def run(self, options: Values, args: List[str]) -> int: logger.warning( "This command is only meant for debugging. " "Do not use this with automation for parsing and getting these " "details, since the output and options of this command may " "change without notice." ) show_value("pip version", get_pip_version()) show_value("sys.version", sys.version) show_value("sys.executable", sys.executable) show_value("sys.getdefaultencoding", sys.getdefaultencoding()) show_value("sys.getfilesystemencoding", sys.getfilesystemencoding()) show_value( "locale.getpreferredencoding", locale.getpreferredencoding(), ) show_value("sys.platform", sys.platform) show_sys_implementation() show_value("'cert' config value", ca_bundle_info(self.parser.config)) show_value("REQUESTS_CA_BUNDLE", os.environ.get("REQUESTS_CA_BUNDLE")) show_value("CURL_CA_BUNDLE", os.environ.get("CURL_CA_BUNDLE")) show_value("pip._vendor.certifi.where()", where()) show_value("pip._vendor.DEBUNDLED", pip._vendor.DEBUNDLED) show_vendor_versions() show_tags(options) return SUCCESS PKH]9 Ypython3.10/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-310.pycnu[o ai"@sddlZddlZddlZddlmZddlmZmZmZddl m Z ddl m Z m Z ddlmZmZmZmZddlmZddlmZdd lmZmZeeZGd d d e ZdS) N)Values)AnyListOptional)Command)ERRORSUCCESS) ConfigurationKindget_configuration_fileskinds)PipError) indent_log)get_prog write_outputc@sHeZdZdZdZdZd(ddZded ee de fd d Z ded e de efd dZded ee ddfddZded ee ddfddZded ee ddfddZded ee ddfddZded ee ddfddZdeddfddZd(ddZded ee ddfddZd ee d e d!e defd"d#Zd(d$d%Zdede fd&d'ZdS))ConfigurationCommandaa Manage local and global configuration. Subcommands: - list: List the active configuration (or from the file specified) - edit: Edit the configuration file in an editor - get: Get the value associated with name - set: Set the name=value - unset: Unset the value associated with name - debug: List the configuration files and values defined under them If none of --user, --global and --site are passed, a virtual environment configuration file is used if one is active and the file exists. Otherwise, all modifications happen to the user file by default. Ta %prog [] list %prog [] [--editor ] edit %prog [] get name %prog [] set name value %prog [] unset name %prog [] debug returnNcCsl|jjdddddd|jjdddd d d|jjd d dd d d|jjdddd dd|jd|jdS)Nz--editoreditorstorez\Editor to use to edit the file. Uses VISUAL or EDITOR environment variables if not provided.)destactiondefaulthelpz--global global_file store_trueFz+Use the system-wide configuration file onlyz--user user_filez$Use the user configuration file onlyz--site site_filez3Use the current environment configuration file onlyr)cmd_opts add_optionparserinsert_option_groupselfr#/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/configuration.py add_options4s: z ConfigurationCommand.add_optionsoptionsargsc Cs|j|j|j|j|j|jd}|r|d|vr$tddt |t S|d}z |j ||dvd}Wnt yO}zt|j dt WYd}~Sd}~wwt|j|d|_|jz||||ddWtSt y}zt|j dt WYd}~Sd}~ww) N)listeditgetsetunsetdebugrzNeed an action (%s) to perform.z, )r*r+r,r)) need_value)isolated load_only) list_valuesopen_in_editorget_nameset_name_value unset_namelist_config_valuesloggererrorjoinsortedr_determine_filer r'r isolated_mode configurationloadr)r"r&r'handlersrr0er#r#r$runZsF    zConfigurationCommand.runr.cCszddtj|jftj|jftj|jffD}|s/|sdStddttjDr,tjStjSt |dkr9|dSt d)NcSsg|]\}}|r|qSr#r#).0keyvaluer#r#r$ s z8ConfigurationCommand._determine_file..css|] }tj|VqdS)N)ospathexists)rCsite_config_filer#r#r$ s  z7ConfigurationCommand._determine_file..r1rzLNeed exactly one file to operate upon (--user, --site, --global) to perform.) r USERrGLOBALrSITEranyr lenr )r"r&r.Z file_optionsr#r#r$r<s&      z$ConfigurationCommand._determine_filecCs8|j|dddt|jD] \}}td||qdS)Nr(rn%s=%r) _get_n_argsr;r>itemsrr"r&r'rDrEr#r#r$r2sz ConfigurationCommand.list_valuescCs*|j|ddd}|j|}td|dS)Nz get [name]r1rQz%s)rTr> get_valuerrVr#r#r$r4s zConfigurationCommand.get_namecCs.|j|ddd\}}|j|||dS)Nzset [name] [value]rQ)rTr> set_value_save_configurationrVr#r#r$r5s z#ConfigurationCommand.set_name_valuecCs(|j|ddd}|j||dS)Nz unset [name]r1rQ)rTr> unset_valuerZ)r"r&r'rDr#r#r$r6s  zConfigurationCommand.unset_namec Cs|j|ddd|t|jD]4\}}td||D](}ttj |}td|||r7| |Wdn1sAwYqqdS)z9List config key-value pairs across different config filesr-rrQ%s:z%s, exists: %rN) rTprint_env_var_valuesr;r>iter_config_filesrrrGrHrIprint_config_file_values)r"r&r'variantfilesfnameZ file_existsr#r#r$r7s    z'ConfigurationCommand.list_config_valuesr`c CsP|j|D]\}}ttd||Wdn1s wYqdS)z.Get key-value pairs from the file of a variantz%s: %sN)r>get_values_in_configrUrr)r"r`namerEr#r#r$r_s z-ConfigurationCommand.print_config_file_valuescCshtddt"t|jD]\}}d|}td||qWddS1s-wYdS)z5Get key-values pairs present as environment variablesr\env_varPIP_rSN)rrr;r>get_environ_varsupper)r"rDrErer#r#r$r]s "z)ConfigurationCommand.print_env_var_valuesc Csd||}|j}|durtdz t||gWdStjy1}ztd|jd}~ww)Nz%Could not determine appropriate file.z*Editor Subprocess exited with exit code {}) _determine_editorr>get_file_to_editr subprocess check_callCalledProcessErrorformat returncode)r"r&r'rrbrAr#r#r$r3s   z#ConfigurationCommand.open_in_editorexamplerRcCs8t||krd|t|}t||dkr|dS|S)zAHelper to make sure the command got the right number of argumentszJGot unexpected number of arguments, expected {}. (example: "{} config {}")r1r)rPrnrr )r"r'rprRmsgr#r#r$rTs  z ConfigurationCommand._get_n_argscCs2z|jWdStytdtdw)Nz:Unable to save configuration. Please report this as a bug.zInternal Error.)r>save Exceptionr8 exceptionr r!r#r#r$rZs z(ConfigurationCommand._save_configurationcCs@|jdur|jSdtjvrtjdSdtjvrtjdStd)NZVISUALZEDITORz"Could not determine editor to use.)rrGenvironr )r"r&r#r#r$ris     z&ConfigurationCommand._determine_editor)rN)__name__ __module__ __qualname____doc__ignore_require_venvusager%rrstrintrBboolrr r<r2r4r5r6r7r_r]r3rrTrZrir#r#r#r$rs$ &-   r)loggingrGrkoptparsertypingrrrpip._internal.cli.base_commandrpip._internal.cli.status_codesrrpip._internal.configurationr r r r pip._internal.exceptionsr pip._internal.utils.loggingrpip._internal.utils.miscrr getLoggerrvr8rr#r#r#r$s     PKH]> Tpython3.10/site-packages/pip/_internal/commands/__pycache__/download.cpython-310.pycnu[o ai(@sddlZddlZddlmZddlmZddlmZddlm Z ddl m Z m Z ddl mZddlmZdd lmZmZmZdd lmZeeZGd d d e ZdS) N)Values)List) cmdoptions)make_target_python)RequirementCommand with_cleanup)SUCCESS)get_requirement_tracker) ensure_dirnormalize_path write_output) TempDirectoryc@s<eZdZdZdZd ddZededee de fd d Z dS) DownloadCommandaL Download packages from: - PyPI (and other indexes) using requirement specifiers. - VCS project urls. - Local project directories. - Local or remote source archives. pip also supports downloading from "requirements files", which provide an easy way to specify a whole environment to be downloaded. a %prog [options] [package-index-options] ... %prog [options] -r [package-index-options] ... %prog [options] ... %prog [options] ... %prog [options] ...returnNc CsL|jt|jt|jt|jt|jt|jt|jt |jt |jt |jt |jt |jt|jt|jt|jt|jjddddddtjddt|jttj|j}|jd ||jd |jdS) Nz-dz--destz--destination-dirz--destination-directory download_dirdirzDownload packages into .)destmetavardefaulthelpr)cmd_opts add_optionr constraints requirementsno_depsglobal_options no_binary only_binary prefer_binarysrcprerequire_hashes progress_barno_build_isolation use_pep517 no_use_pep517ignore_requires_pythonoscurdiradd_target_python_optionsmake_option_group index_groupparserinsert_option_group)self index_optsr0/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/download.py add_options%s@ zDownloadCommand.add_optionsoptionsargsc Cs$d|_g|_t|t|j|_t|j||}t|}|j ||||j d}| t }t |j ddd}|||||}|j||||||jdd} |j| |||j |jd} ||| j|dd} g} | jD]} | jdur| jduszJ| | | | jql| rtd d | tS) NT)r3session target_pythonr&download)deletekindglobally_managedF)temp_build_dirr3 req_trackerr5finderr use_user_site)preparerr=r3r&py_version_info)check_supported_wheelszSuccessfully downloaded %s )ignore_installed editablesrcheck_dist_restrictionr rr get_default_sessionr_build_package_finderr& enter_contextr r no_cleanget_requirementsmake_requirement_preparer make_resolverpython_versiontrace_basic_inforesolvervalues satisfied_bynamesave_linked_requirementappendr joinr)r.r3r4r5r6r=r< directoryreqsr?resolverrequirement_set downloadedreqr0r0r1runKs`          zDownloadCommand.run)rN) __name__ __module__ __qualname____doc__usager2rrrstrintr\r0r0r0r1rs  & r)loggingr'optparsertypingrpip._internal.clirZpip._internal.cli.cmdoptionsrpip._internal.cli.req_commandrrpip._internal.cli.status_codesrpip._internal.req.req_trackerr pip._internal.utils.miscr r r pip._internal.utils.temp_dirr getLoggerr]loggerrr0r0r0r1s        PKH]9%Qpython3.10/site-packages/pip/_internal/commands/__pycache__/index.cpython-310.pycnu[o ai@sddlZddlmZddlmZmZmZmZmZddl m Z m Z ddl m Z ddlmZddlmZmZddlmZdd lmZmZmZdd lmZdd lmZdd lmZdd lm Z ddl!m"Z"ddl#m$Z$e%e&Z'GdddeZ(dS)N)Values)AnyIterableListOptionalUnion) LegacyVersionVersion) cmdoptions)IndexGroupCommand)ERRORSUCCESS)print_dist_installation_info) CommandErrorDistributionNotFoundPipError) LinkCollector) PackageFinder)SelectionPreferences) TargetPython) PipSession) write_outputc @s~eZdZdZdZdddZdedeede fd d Z  dded e d e e d e edef ddZdedeeddfddZdS) IndexCommandz= Inspect information available from package indexes. z& %prog versions returnNcCs~t|j|jt|jt|jt|jtttj |j }|j d||j d|jdS)Nr) r add_target_python_optionscmd_opts add_optionignore_requires_pythonpre no_binary only_binarymake_option_group index_groupparserinsert_option_group)self index_optsr'/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/index.py add_optionss zIndexCommand.add_optionsoptionsargsc Csd|ji}td|r|d|vrtddt|tS|d}z||||ddWt StyM}zt|jdtWYd}~Sd}~ww)Nversionsztpip index is currently an experimental command. It may be removed/changed in a future release without prior warning.rzNeed an action (%s) to perform., ) get_available_package_versionsloggerwarningerrorjoinsortedr rr+r )r%r*r+handlersactioner'r'r(run/s( zIndexCommand.runsession target_pythonrcCs.tj||d}td|j|d}tj|||dS)zK Create a package finder appropriate to the index command. )r*F) allow_yankedallow_all_prereleasesr)link_collectorselection_prefsr:)rcreaterrr)r%r*r9r:rr=r>r'r'r(_build_package_finderMs z"IndexCommand._build_package_finderc Cst|dkr tdt|}|d}||B}|j||||jd}dd||D}|js7dd|D}t |}|sDt d |d d t |d d D}|d} Wdn1s]wYt d || t d d|t|| dS)Nr.z(You need to specify exactly one argumentr)r*r9r:rcss|]}|jVqdSN)version).0 candidater'r'r( us z>IndexCommand.get_available_package_versions..css|]}|js|VqdSrA) is_prerelease)rCrBr'r'r(rE{s  z%No matching distribution found for {}cSsg|]}t|qSr')str)rCverr'r'r( sz?IndexCommand.get_available_package_versions..T)reversez{} ({})zAvailable versions: {}r-)lenrr make_target_python_build_sessionr@rfind_all_candidatesrsetrformatr4rr3r) r%r*r+r:queryr9finderr,Zformatted_versionsZlatestr'r'r(r/fs:    z+IndexCommand.get_available_package_versions)rN)NN)__name__ __module__ __qualname____doc__usager)rrrGintr8rrrboolrr@rr/r'r'r'r(rs& " r))loggingoptparsertypingrrrrrZpip._vendor.packaging.versionrr pip._internal.clir pip._internal.cli.req_commandr pip._internal.cli.status_codesr r Zpip._internal.commands.searchrpip._internal.exceptionsrrrpip._internal.index.collectorr"pip._internal.index.package_finderr$pip._internal.models.selection_prefsr"pip._internal.models.target_pythonrpip._internal.network.sessionrpip._internal.utils.miscr getLoggerrSr0rr'r'r'r(s"           PKH]euv v Rpython3.10/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-310.pycnu[o ai @sxddlZddlmZddlmZddlmZddlmZddl m Z ddl m Z ddl mZhd ZGd d d eZdS) N)Values)List) cmdoptions)Command)SUCCESS)freeze) stdlib_pkgs> setuptoolspipwheelZ distributec@s<eZdZdZdZdZd ddZded ee de fd d Z dS) FreezeCommandzx Output installed packages in requirements format. packages are listed in a case-insensitive sorted order. z %prog [options])ext://sys.stderrr returnNc Cs|jjddddgddd|jjdd d d d d d|jjddd d dd|jt|jjddd ddtd|jjddd dd|jt|j d|jdS)Nz-rz --requirement requirementsappendfilez}Use the order in the given requirements file and its comments when generating output. This option can be used multiple times.)destactiondefaultmetavarhelpz-lz--locallocal store_trueFzUIf in a virtualenv that has global access, do not output globally-installed packages.)rrrrz--useruserz,Only output packages installed in user-site.z--all freeze_allz,Do not skip these packages in the output: {}z, )rrrz--exclude-editableexclude_editablez%Exclude editable package from output.r) cmd_opts add_optionr list_pathformatjoinDEV_PKGS list_excludeparserinsert_option_group)selfr&/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/freeze.py add_optionssP    zFreezeCommand.add_optionsoptionsargsc Csptt}|js |t|jr||jt|t|j |j |j |j |j ||jdD] }tj|dq+tS)N) requirement local_only user_onlypathsisolatedskipr )setrrupdater!excludesrcheck_list_path_optionrrrrpath isolated_modersysstdoutwriter)r%r)r*r0liner&r&r'runMs"     zFreezeCommand.run)rN) __name__ __module__ __qualname____doc__usage log_streamsr(rrstrintr<r&r&r&r'r s  4r )r8optparsertypingrpip._internal.clirpip._internal.cli.base_commandrpip._internal.cli.status_codesrZpip._internal.operations.freezerpip._internal.utils.compatrr!r r&r&r&r's       PKH][/Rpython3.10/site-packages/pip/_internal/commands/__pycache__/search.cpython-310.pycnu[o aiA @sddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z m Z m Z mZddlmZddlmZddlmZddlmZmZdd lmZdd lmZdd lmZdd lm Z dd l!m"Z"ddl#m$Z$e rzddl m%Z%Gddde%Z&e'e(Z)GdddeeZ*de e e+e+fde dfddZ,de+de+ddfddZ-  d#de ddee.dee.ddfddZ/d e e+de+fd!d"Z0dS)$N) OrderedDict)Values) TYPE_CHECKINGDictListOptional)parse)Command)SessionCommandMixin)NO_MATCHES_FOUNDSUCCESS) CommandError)get_default_environment)PyPI)PipXmlrpcTransport) indent_log) write_output) TypedDictc@s*eZdZUeed<eed<eeed<dS)TransformedHitnamesummaryversionsN)__name__ __module__ __qualname__str__annotations__rrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/search.pyrs rc @sbeZdZdZdZdZdddZded ee de fd d Z d ee dedee e e ffd dZ dS) SearchCommandz@Search for PyPI packages whose name or summary contains .z %prog [options] TreturnNcCs.|jjddddtjdd|jd|jdS)Nz-iz--indexindexURLz3Base URL of Python Package Index (default %default))destmetavardefaulthelpr)cmd_opts add_optionrpypi_urlparserinsert_option_group)selfrrr add_options)s zSearchCommand.add_optionsoptionsargscCsV|std|}|||}t|}d}tjrtd}t||d|r)t St S)Nz)Missing required argument (search query).r)terminal_width) r searchtransform_hitssysstdoutisattyshutilget_terminal_size print_resultsr r )r,r.r/queryZ pypi_hitshitsr0rrrrun5s    zSearchCommand.runr9c Cs|j}||}t||}tj||}z |||dd}Wntjjy:}z dj|j |j d} t | d}~wwt |t sBJ|S)N)rrorz-XMLRPC request failed [code: {code}] {string})codestring)r!get_default_sessionrxmlrpcclient ServerProxyr1Faultformat faultCode faultStringr isinstancelist) r,r9r. index_urlsession transportpypir:faultmessagerrrr1Es   zSearchCommand.search)r N)rrr__doc__usageignore_require_venvr-rrrintr;rr1rrrrr"s  *rr:r cCst}|D]7}|d}|d}|d}||vr#|||gd||<q||d||t||dkr<|||d<qt|S)z The list from pypi is really a list of versions. We want a list of packages with the list of versions stored inline. This converts the list from pypi into one we can use. rrversion)rrrr)rkeysappendhighest_versionrHvalues)r:packageshitrrrSrrrr2Xs    r2rlatestcCst}||}|durTt;|j|krtd|jntd|jt|jr-td|ntd|WddSWddSWddS1sMwYdSdS)NzINSTALLED: %s (latest)z INSTALLED: %sz=LATEST: %s (pre-release; install with `pip install --pre`)z LATEST: %s)rget_distributionrrSr parse_versionpre)rrZenvdistrrrprint_dist_installation_infots&     "r`name_column_widthr0c Cs|sdS|durtdd|Dd}|D]Y}|d}|dp d}t|ddg}|durI||d }|d krIt||}d d |d |}|d|d} | |d|} z t| t||WqtynYqwdS)Nc Ss.g|]}t|dtt|ddgqS)rr-)lenrVget).0rYrrr s z!print_results..rrrrb   z ()z - ) maxrVrdtextwrapwrapjoinrr`UnicodeEncodeError) r:rar0rYrrrZZ target_widthZ summary_linesZ name_latestlinerrrr8s:     r8rcCs t|tdS)N)key)ror\)rrrrrVs rV)NN)1loggingr6r3rp xmlrpc.clientr@ collectionsroptparsertypingrrrrZpip._vendor.packaging.versionrr\pip._internal.cli.base_commandr pip._internal.cli.req_commandr pip._internal.cli.status_codesr r pip._internal.exceptionsr pip._internal.metadatarpip._internal.models.indexrZpip._internal.network.xmlrpcrpip._internal.utils.loggingrpip._internal.utils.miscrrr getLoggerrloggerrrr2r`rRr8rVrrrrsJ             "6 &PKH]8k k Tpython3.10/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-310.pycnu[o ai@shUdZddlZddlmZddlmZmZmZddlm Z eddZ ide d d d d e d ddde dddde dddde dddde dddd e d!d"d#d$e d%d&d'd(e d)d*d+d,e d-d.d/d0e d1d2d3d4e d5d6d7d8e d9d:d;dd?d@e dAdBdCdDe dEdFdGZ ee e fe dH<dIe dJedKe fdLdMZdIe dKee fdNdOZdS)Pz% Package containing all pip commands N) namedtuple)AnyDictOptional)Command CommandInfoz module_path, class_name, summaryinstallzpip._internal.commands.installInstallCommandzInstall packages.downloadzpip._internal.commands.downloadDownloadCommandzDownload packages. uninstallz pip._internal.commands.uninstallUninstallCommandzUninstall packages.freezezpip._internal.commands.freeze FreezeCommandz1Output installed packages in requirements format.listzpip._internal.commands.list ListCommandzList installed packages.showzpip._internal.commands.show ShowCommandz*Show information about installed packages.checkzpip._internal.commands.check CheckCommandz7Verify installed packages have compatible dependencies.configz$pip._internal.commands.configurationConfigurationCommandz&Manage local and global configuration.searchzpip._internal.commands.search SearchCommandzSearch PyPI for packages.cachezpip._internal.commands.cache CacheCommandz%Inspect and manage pip's wheel cache.indexzpip._internal.commands.index IndexCommandz3Inspect information available from package indexes.wheelzpip._internal.commands.wheel WheelCommandz$Build wheels from your requirements.hashzpip._internal.commands.hash HashCommandz#Compute hashes of package archives. completionz!pip._internal.commands.completionCompletionCommandz-A helper command used for command completion.debugzpip._internal.commands.debug DebugCommandz&Show information useful for debugging.helpzpip._internal.commands.help HelpCommandzShow help for commands. commands_dictnamekwargsreturncKs:t|\}}}t|}t||}|d||d|}|S)zF Create an instance of the Command class with the given name. )r)summaryN)r( importlib import_modulegetattr)r)r* module_path class_namer,module command_classcommandr-r-/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/__init__.pycreate_commandhs   r7cCs2ddlm}|}||t}|r|dSdS)zCommand name auto-correct.r)get_close_matchesN)difflibr8lowerr(keys)r)r8close_commandsr-r-r6get_similar_commandsts r=)__doc__r. collectionsrtypingrrrpip._internal.cli.base_commandrrr(str__annotations__r7r=r-r-r-r6s     $).38=BGLT PKH]`oaNv!v!Ppython3.10/site-packages/pip/_internal/commands/__pycache__/show.cpython-310.pycnu[o ai@sddlZddlZddlZddlmZddlmZmZmZm Z m Z ddl m Z ddl mZddlmZmZddlmZmZddlmZeeZGd d d eZGd d d eZd e edfde edfdefddZdeedeefddZdeedededefddZ dS)N)Values)IteratorList NamedTupleOptionalTuplecanonicalize_name)Command)ERRORSUCCESS)BaseDistributionget_default_environment) write_outputc@s<eZdZdZdZdZd ddZded ee de fd d Z dS) ShowCommandzx Show information about one or more installed packages. The output is in RFC-compliant mail header format. z$ %prog [options] ...TreturnNcCs,|jjddddddd|jd|jdS) Nz-fz--filesfiles store_trueFz7Show the full list of installed files for each package.)destactiondefaulthelpr)cmd_opts add_optionparserinsert_option_group)selfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/show.py add_optionss zShowCommand.add_optionsoptionsargscCs8|s tdtS|}t|}t||j|jdstStS)Nz.ERROR: Please provide a package name or names.) list_filesverbose)loggerwarningr search_packages_info print_resultsrr#r )rr r!queryresultsrrrrun(s  zShowCommand.run)rN) __name__ __module__ __qualname____doc__usageignore_require_venvrrrstrintr*rrrrrs   rc@seZdZUeed<eed<eed<eeed<eeed<eed<eed<eeed<eed <eed <eed <eed <eed <eeed<eeeed<dS) _PackageInfonameversionlocationrequires required_by installermetadata_version classifierssummaryhomepageauthor author_emaillicense entry_pointsrN)r+r,r-r1__annotations__rrrrrrr36s     r3entry.inforcCsj|r)|ddkr)|r|ddkr|d7}n|dd}|dd}|r)|ddksttjg||RS)aConvert a legacy installed-files.txt path into modern RECORD path. The legacy format stores paths relative to the info directory, while the modern format stores paths relative to the package root, e.g. the site-packages directory. :param entry: Path parts of the installed-files.txt entry. :param info: Path parts of the egg-info directory relative to package root. :returns: The converted entry. For best compatibility with symlinks, this does not use ``abspath()`` or ``Path.resolve()``, but tries to work with path parts: 1. While ``entry`` starts with ``..``, remove the equal amounts of parts from ``info``; if ``info`` is empty, start appending ``..`` instead. 2. Join the two directly. r..)rENr1pathlibPath)rCrDrrr_convert_legacy_entryHs   rKr(c#st}dd|Ddd|D}tfddt||D}|r-tdd|dtd tt ffd d }d td t tt fd d}d td t tt fdd}|D]}z|}Wn t ygYqVwtdd| Dt j d} t||t j d} z |d} | jdd} Wn tyg} Ynw||p||} | durd}nt| }|j}t|jt |j|jpd| | |j|jpd|dg|dd|dd|dd|dd|dd| |dVqVdS) z Gather details from installed distributions. Print distribution name, version, location, and installed files. Installed files requires a pip generated 'installed-files.txt' in the distributions '.egg-info' directory. cSsi|]}|j|qSr)canonical_name.0distrrr lz(search_packages_info..cSsg|]}t|qSrr)rNr4rrr mrQz(search_packages_info..csg|] \}}|vr|qSrr)rNr4pkg installedrrrRoszPackage(s) not found: %s, current_distrcsfddDS)Nc3s6|]}jdd|Dvr|jdpdVqdS)cSsh|]}t|jqSr)r r4)rNdrrr yszRsearch_packages_info.._get_requiring_packages...NameUNKNOWNN)rLiter_dependenciesmetadatarMrWrr us zHsearch_packages_info.._get_requiring_packages..)valuesr^rTr^r_get_requiring_packagests z5search_packages_info.._get_requiring_packagesrOcSs<z|d}Wn tyYdSwddt|DS)NRECORDcss"|] }tt|dVqdS)rNrH)rNrowrrrr_s zCsearch_packages_info.._files_from_record..) read_textFileNotFoundErrorcsvreader splitlines)rOtextrrr_files_from_record|s  z0search_packages_info.._files_from_recordcsz|d}Wn tyYdSwdd|jddD}|j}|j}|dus+|dur-|Sz t||Wn tyB|YSwj sH|Sfdd|DS)Nzinstalled-files.txtcss|]}|r|VqdSNrrNprrrr_szCsearch_packages_info.._files_from_legacy..Fkeependsc3s$|] }tt|jjVqdSrk)rKrIrJpartsrlZinfo_relrrr_s ) rdrerhr6info_directoryrIrJ relative_to ValueErrorrp)rOripathsrootrDrrqr_files_from_legacys(   z0search_packages_info.._files_from_legacycss|]}|jVqdSrk)r4)rNreqrrrr_sz'search_packages_info..)keyzentry_points.txtFrnN ClassifierZSummaryz Home-pageZAuthorz Author-emailZLicense)r4r5r6r7r8r9r:r;r<r=r>r?r@rAr)riter_distributionssortedzipr$r%joinr rr1rKeyErrorr\lowerrdrhrer]r3raw_namer5r6r9r:get_allget)r(envZ query_namesmissingrarjrwZ query_namerOr7r8Zentry_points_textrAZ files_iterrr]rrTrr&csb           r& distributionsr"r#c CsHd}t|D]\}}d}|dkrtdtd|jtd|jtd|jtd|jtd |jtd |jtd |jtd |j td d |j tdd |j |rtd|j td|jtd|jD]}td|qktd|jD] }td|qz|rtd|jdurtdq|jD] }td|qq|S)zC Print the information from installed distributions found. FTrz---zName: %sz Version: %sz Summary: %sz Home-page: %sz Author: %szAuthor-email: %sz License: %sz Location: %sz Requires: %srVzRequired-by: %szMetadata-Version: %sz Installer: %sz Classifiers:z %sz Entry-points:zFiles:Nz+Cannot locate RECORD or installed-files.txt) enumeraterr4r5r<r=r>r?r@r6rr7r8r:r9r;rAstripr) rr"r#Zresults_printedirO classifierrClinerrrr's@                r')!rfloggingrIoptparsertypingrrrrrpip._vendor.packaging.utilsr pip._internal.cli.base_commandr pip._internal.cli.status_codesr r pip._internal.metadatar rpip._internal.utils.miscr getLoggerr+r$rr3r1rKr&boolr'rrrrs0     %&_PKH]qPpython3.10/site-packages/pip/_internal/commands/__pycache__/hash.cpython-310.pycnu[o ai@sddlZddlZddlZddlmZddlmZddlmZddl m Z m Z ddl m Z mZddlmZmZeeZGdd d eZd ed ed efd dZdS)N)Values)List)Command)ERRORSUCCESS) FAVORITE_HASH STRONG_HASHES) read_chunks write_outputc@s<eZdZdZdZdZd ddZded ee de fd d Z dS) HashCommandz Compute a hash of a local package archive. These can be used with --hash in a requirements file to do repeatable installs. z%prog [options] ...TreturnNc Cs:|jjdddtdtddtd|jd|jdS) Nz-az --algorithm algorithmstorez$The hash algorithm to use: one of {}z, )destchoicesactiondefaulthelpr)cmd_opts add_optionrrformatjoinparserinsert_option_group)selfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/hash.py add_optionss zHashCommand.add_optionsoptionsargscCs>|s |jtjtS|j}|D] }td||t||qtS)Nz%s: --hash=%s:%s) r print_usagesysstderrrr r _hash_of_filer)rrrr pathrrrrun(szHashCommand.run)r N) __name__ __module__ __qualname____doc__usageignore_require_venvrrrstrintr%rrrrr s  r r$r r cCsZt|d}t|}t|D]}||qWd|S1s$wY|S)z!Return the hash digest of a file.rbN)openhashlibnewr update hexdigest)r$r archivehashchunkrrrr#5s     r#)r0loggingr!optparsertypingrpip._internal.cli.base_commandrpip._internal.cli.status_codesrrpip._internal.utils.hashesrrpip._internal.utils.miscr r getLoggerr&loggerr r,r#rrrrs    &PKH]֐`LLQpython3.10/site-packages/pip/_internal/commands/__pycache__/cache.cpython-310.pycnu[o aid@sddlZddlZddlmZddlmZmZddlmm m Z ddl m Z ddl mZmZddlmZmZddlmZeeZGdd d e ZdS) N)Values)AnyList)Command)ERRORSUCCESS) CommandErrorPipError) getLoggerc@s0eZdZdZdZdZd#ddZded ee de fd d Z ded ee ddfd d Z ded ee ddfddZded ee ddfddZdee ddfddZdee ddfddZded ee ddfddZded ee ddfddZdede de fddZdedee fddZded e dee fd!d"ZdS)$ CacheCommandaw Inspect and manage pip's wheel cache. Subcommands: - dir: Show the cache directory. - info: Show information about the cache. - list: List filenames of packages stored in the cache. - remove: Remove one or more package from the cache. - purge: Remove all items from the cache. ```` can be a glob expression or a package name. Tz %prog dir %prog info %prog list [] [--format=[human, abspath]] %prog remove %prog purge returnNcCs,|jjddddddd|jd|jdS) Nz--formatstore list_formathuman)rabspathz:Select the output format among: human (default) or abspath)actiondestdefaultchoiceshelpr)cmd_opts add_optionparserinsert_option_group)selfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/cache.py add_options's zCacheCommand.add_optionsoptionsargsc Cs|j|j|j|j|jd}|jstdtS|r|d|vr,tdd t |tS|d}z||||ddWt St yZ}zt|j dtWYd}~Sd}~ww)N)dirinfolistremovepurgezrEr,warningrNunlinkverboser!)rrrrKZno_matching_msgrTrrrr)s    zCacheCommand.remove_cache_itemscCs|rtd||dgS)Nr3r5)rr)r4rrrr*szCacheCommand.purge_cachesubdircCstj|j|S)N)rNrOr.r+)rrrZrrrr@szCacheCommand._cache_dircCs||d}t|dS)Nr6r5r@rA find_files)rrZhttp_dirrrrr>s  zCacheCommand._find_http_filesrJcCs,||d}|d|vr dnd}t||S)Nr7-z*.whlz-*.whlr[)rrrJ wheel_dirrrrr?s  zCacheCommand._find_wheels)r N)__name__ __module__ __qualname____doc__ignore_require_venvusagerrrstrintr2rr&r'r(rHrIr)r*r@r>r?rrrrr s    $  r )rNrCoptparsertypingrrpip._internal.utils.filesystem _internalutilsrApip._internal.cli.base_commandrpip._internal.cli.status_codesrrpip._internal.exceptionsrr pip._internal.utils.loggingr r_r,r rrrrs   PKH]Y7(7(Ppython3.10/site-packages/pip/_internal/commands/__pycache__/list.cpython-310.pycnu[o ai/ @sjddlZddlZddlmZddlmZmZmZmZm Z m Z m Z ddl m Z ddlmZddlmZddlmZddlmZdd lmZdd lmZdd lmZmZdd lmZdd lm Z ddl!m"Z"ddl#m$Z$m%Z%ddl&m'Z'erddl(m)Z)GdddeZ*e e*Z+e,e-Z.GdddeZ/dddede eee0ee0ffddZ1dddede0fddZ2dS)N)Values) TYPE_CHECKINGIteratorListOptionalSequenceTuplecastcanonicalize_name) cmdoptions)IndexGroupCommand)SUCCESS) CommandError) LinkCollector) PackageFinder)BaseDistributionget_environment)SelectionPreferences) PipSession) stdlib_pkgs)tabulate write_output)map_multithread)DistributionVersionc@s"eZdZUdZeed<eed<dS)_DistWithLatestInfozGive the distribution object a couple of extra fields. These will be populated during ``get_outdated()``. This is dirty but makes the rest of the code much cleaner. latest_versionlatest_filetypeN)__name__ __module__ __qualname____doc__r__annotations__strr$r$/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/list.pyrs  rc@seZdZdZdZdZd ddZded ede fd d Z ded e e de fd dZdddeddfddZdddeddfddZdddeddfddZdddededfddZdddeddfddZde e e de e ddfddZdS)! ListCommandzt List installed packages, including editables. Packages are listed in a case-insensitive sorted order. Tz %prog [options]returnNcCs*|jjdddddd|jjddddd d|jjd d ddd d|jjd ddddd|jjdddddd|jt|jjddddd|jjddddddd|jjddddd |jjd!d"d#d$d |jjd%dd#d&d'd(|jtttj|j}|jd)||jd)|jdS)*Nz-oz --outdated store_trueFzList outdated packages)actiondefaulthelpz-uz --uptodatezList uptodate packagesz-ez --editablezList editable projects.z-lz--localzSIf in a virtualenv that has global access, do not list globally-installed packages.z--useruserz,Only output packages installed in user-site.)destr)r*r+z--prezYInclude pre-release and development versions. By default, pip only finds stable versions.z--formatstore list_formatcolumns)r0freezejsonzBSelect the output format among: columns (default), freeze, or json)r)r-r*choicesr+z--not-required not_requiredz>List packages that are not dependencies of installed packages.)r)r-r+z--exclude-editable store_falseinclude_editablez%Exclude editable package from output.z--include-editablez%Include editable package from output.T)r)r-r+r*r) cmd_opts add_optionr list_path list_excludemake_option_group index_groupparserinsert_option_group)self index_optsr$r$r% add_options3s   zListCommand.add_optionsoptionssessioncCs*tj||d}td|jd}tj||dS)zK Create a package finder appropriate to this list command. )rBF) allow_yankedallow_all_prereleases)link_collectorselection_prefs)rcreaterprer)r?rBrCrFrGr$r$r%_build_package_findersz!ListCommand._build_package_finderargscCs|jr |jr tdt|tt}|jr!|dd|jDddt |j j |j |j |j|j|dD}|jr@|||}|jrJ|||}n |jrS|||}|||tS)Nz5Options --outdated and --uptodate cannot be combined.css|]}t|VqdSNr ).0nr$r$r% sz"ListCommand.run..cSsg|]}td|qS)r)r )rMdr$r$r% sz#ListCommand.run..) local_only user_onlyeditables_onlyinclude_editablesskip)outdatedZuptodaterr check_list_path_optionsetrexcludesupdaterpathiter_installed_distributionslocalr,editabler6r4get_not_required get_outdated get_uptodateoutput_package_listingr)r?rBrKrVpackagesr$r$r%runs.      zListCommand.runrd_ProcessedDistscCdd|||DS)NcSsg|] }|j|jkr|qSr$rversionrMdistr$r$r%rQ  z,ListCommand.get_outdated..iter_packages_latest_infosr?rdrBr$r$r%ra zListCommand.get_outdatedcCrg)NcSsg|] }|j|jkr|qSr$rhrjr$r$r%rQrlz,ListCommand.get_uptodate..rmror$r$r%rbrpzListCommand.get_uptodatecs$dd|Dtfdd|DS)NcSs(h|]}|p dD]}t|jq qS)r$)iter_dependenciesr name)rMrkdepr$r$r% s z/ListCommand.get_not_required..csh|] }|jvr|qSr$canonical_name)rMpkgZdep_keysr$r%rts)listror$rxr%r`s zListCommand.get_not_requiredrc#sx|,}||dddtdffdd }t||D] }|dur)|Vq WddS1s5wYdS)Nrkrr'csl|j}jsdd|D}j|jd}||}|dur"dS|j}|jjr,d}nd}||_||_ |S)NcSsg|]}|jjs|qSr$)ri is_prerelease)rM candidater$r$r%rQs zOListCommand.iter_packages_latest_infos..latest_info..) project_namewheelsdist) find_all_candidatesrvrImake_candidate_evaluatorsort_best_candidaterilinkis_wheelrr)rkZall_candidatesZ evaluatorbest_candidateremote_versiontypfinderrBr$r% latest_infos$  z;ListCommand.iter_packages_latest_infos..latest_info)_build_sessionrJrr)r?rdrBrCrrkr$rr%rns  "z&ListCommand.iter_packages_latest_infoscCst|ddd}|jdkr|rt||\}}|||dS|jdkrB|D]}|jdkr7td|j|j|jq%td|j|jq%dS|jd krPtt ||dSdS) NcSs|jSrLru)rkr$r$r% sz4ListCommand.output_package_listing..)keyr0r1z %s==%s (%s)z%s==%sr2) sortedr/format_for_columnsoutput_package_listing_columnsverboserraw_namerilocationformat_for_json)r?rdrBdataheaderrkr$r$r%rcs$   z"ListCommand.output_package_listingrrcCsbt|dkr |d|t|\}}t|dkr&|ddtdd||D]}t|q(dS)Nrr cSsd|S)N-r$)xr$r$r%r%sz.)leninsertrjoinmapr)r?rrZ pkg_stringssizesvalr$r$r%rs     z*ListCommand.output_package_listing_columns)r'N)rrr r!ignore_require_venvusagerArrrrJrr#intrerarbr`rrnrcrr$r$r$r%r&(sn U $      &  r&pkgsrfrBr'cCsddg}|j}|r|ddgtdd|D}|r |d|jdkr*|d |jdkr4|d g}|D]A}|jt|jg}|rR|t|j||j |r\||j pZd |jdkri||j pgd |jdkrt||j ||q8||fS) z_ Convert the package data into something usable by output_package_listing_columns. PackageVersionZLatestTypecss|]}|jVqdSrL)r_)rMrr$r$r%rO8sz%format_for_columns..zEditable project locationrZLocationZ Installer) rWextendanyappendrrr#rirreditable_project_locationr installer)rrBrZrunning_outdatedZ has_editablesrZprojrowr$r$r%r+s2          rrdcCsg}|D]9}|jt|jd}|jdkr |jpd|d<|j|d<|jr/t|j|d<|j|d<|j }|r8||d<| |qt |S) N)rrrirrrrrrr) rr#rirrrrWrrrrr2dumps)rdrBrrkinforr$r$r%rXs      r)3r2loggingoptparsertypingrrrrrrr pip._vendor.packaging.utilsr pip._internal.clir pip._internal.cli.req_commandr pip._internal.cli.status_codesrpip._internal.exceptionsrpip._internal.index.collectorr"pip._internal.index.package_finderrpip._internal.metadatarr$pip._internal.models.selection_prefsrpip._internal.network.sessionrpip._internal.utils.compatrpip._internal.utils.miscrrZpip._internal.utils.parallelrZpip._internal.metadata.baserrrf getLoggerrloggerr&r#rrr$r$r$r%sB $              -PKH]xol l Vpython3.10/site-packages/pip/_internal/commands/__pycache__/completion.cpython-310.pycnu[o ai @spddlZddlZddlmZddlmZddlmZddlm Z ddl m Z dZ dd d d Z Gd d d eZdS)N)Values)List)Command)SUCCESS)get_progzD # pip {shell} completion start{script}# pip {shell} completion end a _pip_completion() {{ COMPREPLY=( $( COMP_WORDS="${{COMP_WORDS[*]}}" \ COMP_CWORD=$COMP_CWORD \ PIP_AUTO_COMPLETE=1 $1 2>/dev/null ) ) }} complete -o default -F _pip_completion {prog} aM function _pip_completion {{ local words cword read -Ac words read -cn cword reply=( $( COMP_WORDS="$words[*]" \ COMP_CWORD=$(( cword-1 )) \ PIP_AUTO_COMPLETE=1 $words[1] 2>/dev/null )) }} compctl -K _pip_completion {prog} au function __fish_complete_pip set -lx COMP_WORDS (commandline -o) "" set -lx COMP_CWORD ( \ math (contains -i -- (commandline -t) $COMP_WORDS)-1 \ ) set -lx PIP_AUTO_COMPLETE 1 string split \ -- (eval $COMP_WORDS[1]) end complete -fa "(__fish_complete_pip)" -c {prog} )bashzshfishc@s8eZdZdZdZd ddZdedeede fd d Z dS) CompletionCommandz3A helper command to be used for command completion.TreturnNcCs\|jjddddddd|jjdd dd dd d|jjd d ddddd|jd|jdS)Nz--bashz-b store_constrshellzEmit completion code for bash)actionconstdesthelpz--zshz-zrzEmit completion code for zshz--fishz-fr zEmit completion code for fishr)cmd_opts add_optionparserinsert_option_group)selfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/completion.py add_options6s2 zCompletionCommand.add_optionsoptionsargscCsvt}ddt|D}|j|vr-tt|jdjtd}t t j||jdt St j dd|t S)z-Prints the completion code of the given shellcSsg|]}d|qS)z--r).0r rrr Usz)CompletionCommand.run..)prog)scriptr zERROR: You must pass {} z or )COMPLETION_SCRIPTSkeyssortedr textwrapdedentgetformatrprintBASE_COMPLETIONrsysstderrwritejoin)rrrZshellsZ shell_optionsr rrrrunRs zCompletionCommand.run)r N) __name__ __module__ __qualname____doc__ignore_require_venvrrrstrintr.rrrrr 1s  r )r*r$optparsertypingrpip._internal.cli.base_commandrpip._internal.cli.status_codesrpip._internal.utils.miscrr)r!r rrrrs       #PKH]DPMMQpython3.10/site-packages/pip/_internal/commands/__pycache__/check.cpython-310.pycnu[o ai@svddlZddlmZddlmZddlmZddlmZm Z ddl m Z m Z ddl mZeeZGdd d eZdS) N)Values)List)Command)ERRORSUCCESS)check_package_set!create_package_set_from_installed) write_outputc@s.eZdZdZdZdedeedefddZ dS) CheckCommandz7Verify installed packages have compatible dependencies.z %prog [options]optionsargsreturnc Cst\}}t|\}}|D]}||j}||D] } td||| dqq |D]}||j}||D]\} } } td||| | | q2q'|sH|sH|rJtStdtS)Nz*%s %s requires %s, which is not installed.rz-%s %s has requirement %s, but you have %s %s.zNo broken requirements found.)rrversionr rr) selfr r package_setZ parsing_probsmissing conflicting project_namer dependencydep_name dep_versionreqr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/check.pyruns8      zCheckCommand.runN) __name__ __module__ __qualname____doc__usagerrstrintrrrrrr sr )loggingoptparsertypingrpip._internal.cli.base_commandrpip._internal.cli.status_codesrrpip._internal.operations.checkrrpip._internal.utils.miscr getLoggerrloggerr rrrrs     PKH]Od_==Qpython3.10/site-packages/pip/_internal/commands/__pycache__/debug.cpython-310.pycnu[o ai@sddlZddlZddlZddlZddlmZddlmZddlm Z m Z m Z m Z ddl ZddlmZddlmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd l m!Z!ddl"m#Z#ddl$m%Z%e&e'Z(de)de ddfddZ*d+ddZ+de e)e)ffddZ,de)defddZ-de)de e)fddZ.de e)e)fddfdd Z/d+d!d"Z0d#eddfd$d%Z1d&ede)fd'd(Z2Gd)d*d*eZ3dS),N)Values) ModuleType)AnyDictListOptional)where)parse)__file__) cmdoptions)Command)make_target_python)SUCCESS) Configuration)get_environment) indent_log)get_pip_versionnamevaluereturncCstd||dS)Nz%s: %s)loggerinfo)rrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/debug.py show_valuesrcCsHtdtjj}ttd|WddS1swYdS)Nzsys.implementation:r)rrsysimplementationrrr)implementation_namerrrshow_sys_implementations  "rcCsdtjtjtdd}t|}dd|D}Wdn1s$wYtdd|DS)N_vendorz vendor.txtcSs(g|]}d|vr|dddqS)== r)stripsplit.0linerrr -s"z)create_vendor_txt_map..css|] }|ddVqdS)r r"N)r$r%rrr 2sz(create_vendor_txt_map..)ospathjoindirname pip_locationopen readlinesdict)Zvendor_txt_pathflinesrrrcreate_vendor_txt_map%s r4 module_namecCs:|}|dkr d}td|ttddttj|S)N setuptools pkg_resourcesz pip._vendor.r)level)lower __import__globalslocalsgetattrpipr)r5rrrget_module_from_module_name5s  r?cCsHt|}t|dd}|s"ttj|jg}||}|r"t|j }|S)N __version__) r?r=rr*r+r-r get_distributionstrversion)r5modulerCenvdistrrrget_vendor_version_from_module@s   rGvendor_txt_versionscCsZ|D]&\}}d}t|}|sd}|}n t|t|kr"d|}td|||qdS)z{Log the actual version and print extra info if there is a conflict or if the actual version could not be imported. zM (Unable to locate actual module version, using vendor.txt specified version)z5 (CONFLICT: vendor.txt suggests version should be {})z%s==%s%sN)itemsrG parse_versionformatrr)rHr5Zexpected_versionZ extra_messageZactual_versionrrrshow_actual_vendor_versionsNsrMcCsDtdt}t t|WddS1swYdS)Nzvendored library versions:)rrr4rrM)rHrrrshow_vendor_versionscs  "rNoptionsc Csd}t|}|}|}d}|rd|d}dt||}t||jdkr9t||kr9d}|d|}nd}t*|D] }tt |qA|r`d j|d }t|WddSWddS1skwYdS) N rIz (target: )zCompatible tags: {}{}r"TFz?... [First {tag_limit} tags shown. Pass --verbose to show all.]) tag_limit) r get_tags format_givenrLlenrrverboserrB) rOrR target_pythontagsZformatted_targetsuffixmsgZ tags_limitedtagrrr show_tagsks0   "r\configcsrt}|D]\}}||ddq|sdSgdfdd|D}|s+dSd|vr4|dd|S) N.rz Not specified)installwheeldownloadcsg|]}|vr|qSrr)r&r8Zlevels_that_override_globalrrr(sz"ca_bundle_info..globalz, )setrJaddr$remover,)r]Zlevelskey_Zglobal_overriding_levelrrbrca_bundle_infos   ric@s<eZdZdZdZdZd ddZded ee de fd d Z dS) DebugCommandz$ Display debug information. z %prog TrNcCs,t|j|jd|j|jjdS)Nr)r add_target_python_optionscmd_optsparserinsert_option_groupr]load)selfrrr add_optionss zDebugCommand.add_optionsrOargscCstdtdttdtjtdtjtdttdttdt tdtj t td t |jjtd tjd td tjd td ttd tjjtt|tS)NzThis command is only meant for debugging. Do not use this with automation for parsing and getting these details, since the output and options of this command may change without notice.z pip versionz sys.versionzsys.executablezsys.getdefaultencodingzsys.getfilesystemencodingzlocale.getpreferredencodingz sys.platformz'cert' config valueREQUESTS_CA_BUNDLECURL_CA_BUNDLEzpip._vendor.certifi.where()zpip._vendor.DEBUNDLED)rwarningrrrrC executablegetdefaultencodinggetfilesystemencodinglocalegetpreferredencodingplatformrrirmr]r*environgetrr>r DEBUNDLEDrNr\r)rprOrrrrrruns,     zDebugCommand.runrN) __name__ __module__ __qualname____doc__usageignore_require_venvrqrrrBintrrrrrrjs  rjr)4ryloggingr*roptparsertypesrtypingrrrr pip._vendorr>pip._vendor.certifirZpip._vendor.packaging.versionr rKr r.pip._internal.clir pip._internal.cli.base_commandr Zpip._internal.cli.cmdoptionsr pip._internal.cli.status_codesrpip._internal.configurationrpip._internal.metadatarpip._internal.utils.loggingrpip._internal.utils.miscr getLoggerrrrBrrr4r?rGrMrNr\rirjrrrrs<                  PKH]*aLN N Upython3.10/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-310.pycnu[o ai @sddlZddlmZddlmZddlmZddlmZddl m Z m Z ddl m Z ddlmZdd lmZdd lmZmZdd lmZeeZGd d d ee ZdS)N)Values)List)canonicalize_name)Command)SessionCommandMixinwarn_if_run_as_root)SUCCESS)InstallationError)parse_requirements)install_req_from_line#install_req_from_parsed_requirement)(protect_pip_from_modification_on_windowsc@s8eZdZdZdZd ddZdedeede fd d Z dS) UninstallCommandaB Uninstall packages. pip is able to uninstall most installed packages. Known exceptions are: - Pure distutils packages installed with ``python setup.py install``, which leave behind no metadata to determine what files were installed. - Script wrappers installed by ``python setup.py develop``. zU %prog [options] ... %prog [options] -r ...returnNc CsD|jjddddgddd|jjdd d d d d |jd|jdS)Nz-rz --requirement requirementsappendfilezjUninstall all the packages listed in the given requirements file. This option can be used multiple times.)destactiondefaultmetavarhelpz-yz--yesyes store_truez2Don't ask for confirmation of uninstall deletions.)rrrr)cmd_opts add_optionparserinsert_option_group)selfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/uninstall.py add_options$s" zUninstallCommand.add_optionsoptionsargsc Cs||}i}|D]}t||jd}|jr||t|j<q td|q |jD]}t|||dD]}t ||jd}|jrC||t|j<q0q'|sTt d|jd|jdt d|vd| D]}|j |j|jd kd } | rr| q_ttS) N)isolatedzSInvalid requirement: %r ignored - the uninstall command expects named requirements.)r"sessionz*You must give at least one requirement to z (see "pip help z")pip) modifying_pipr) auto_confirmverbose)get_default_sessionr isolated_modenamerloggerwarningrr r r r values uninstallr verbositycommitrr) rr"r#r%Zreqs_to_uninstallr,reqfilename parsed_reqZuninstall_pathsetrrr run;sV     zUninstallCommand.run)rN) __name__ __module__ __qualname____doc__usager!rrstrintr6rrrr rs  r)loggingoptparsertypingrpip._vendor.packaging.utilsrpip._internal.cli.base_commandrpip._internal.cli.req_commandrrpip._internal.cli.status_codesrpip._internal.exceptionsr pip._internal.reqr pip._internal.req.constructorsr r pip._internal.utils.miscr getLoggerr7r-rrrrr s         PKH]P'Qpython3.10/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-310.pycnu[o ai@sddlZddlZddlZddlmZddlmZddlmZddl m Z ddl m Z m Z ddlmZddlmZdd lmZdd lmZdd lmZmZdd lmZdd lmZmZeeZ Gddde Z!dS)N)Values)List) WheelCache) cmdoptions)RequirementCommand with_cleanup)SUCCESS) CommandError)InstallRequirement)get_requirement_tracker) ensure_dirnormalize_path) TempDirectory)buildshould_build_for_wheel_commandc@s<eZdZdZdZd ddZededee de fd d Z dS) WheelCommanda Build Wheel archives for your requirements and dependencies. Wheel is a built-package format, and offers the advantage of not recompiling your software during every install. For more details, see the wheel docs: https://wheel.readthedocs.io/en/latest/ Requirements: setuptools>=0.8, and wheel. 'pip wheel' uses the bdist_wheel setuptools extension from the wheel package to build individual wheels. z %prog [options] ... %prog [options] -r ... %prog [options] [-e] ... %prog [options] [-e] ... %prog [options] ...returnNcCsv|jjddddtjdd|jt|jt|jt|jt|jt |jt |jt |jt |jt |jt|jt|jt|jt|jjddd d d d |jt|jt|jjd d d dd|jtttj|j}|jd||jd|jdS)Nz-wz --wheel-dir wheel_dirdirzLBuild wheels into , where the default is the current working directory.)destmetavardefaulthelpz --no-verify no_verify store_trueFz%Don't verify if built wheel is valid.)ractionrrz--prezYInclude pre-release and development versions. By default, pip only finds stable versions.)rrrr)cmd_opts add_optionoscurdirr no_binary only_binary prefer_binaryno_build_isolation use_pep517 no_use_pep517 constraintseditable requirementssrcignore_requires_pythonno_deps progress_bar build_optionsglobal_optionsrequire_hashesmake_option_group index_groupparserinsert_option_group)self index_optsr6/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/wheel.py add_options+sV  zWheelCommand.add_optionsoptionsargsc Cst|||}|||}t|j|j}t|j|_t |j| t }t |j ddd}|||||}|j||||||jdd} |j| ||||j|jd} ||| j|dd} g} | jD]} | jrq| | qft| rz| | qft| ||j |jpg|jpgd\}}|D]9} | jr| jjsJ| j sJz t!"| j |jWqt#y}zt$%d | j&||| WYd}~qd}~wwt'|d krt(d t)S) NwheelT)deletekindglobally_managedF)temp_build_dirr9 req_trackersessionfinder download_dir use_user_site)preparerrBr9 wheel_cacher*r$)check_supported_wheels)rFverifyr-r.z Building wheel for %s failed: %srz"Failed to build one or more wheels)*rcheck_install_build_globalget_default_session_build_package_finderr cache_dirformat_controlr rr enter_contextr rno_cleanget_requirementsmake_requirement_preparer make_resolverr*r$trace_basic_inforesolver(valuesis_wheelsave_linked_requirementrappendrrr-r.linklocal_file_pathshutilcopyOSErrorloggerwarningnamelenr r)r4r9r:rArBrFr@ directoryreqsrEresolverrequirement_set reqs_to_buildreqbuild_successesbuild_failureser6r6r7runes~             zWheelCommand.run)rN) __name__ __module__ __qualname____doc__usager8rrrstrintrkr6r6r6r7rs  : r)"loggingrr[optparsertypingrpip._internal.cacherpip._internal.clirpip._internal.cli.req_commandrrpip._internal.cli.status_codesrpip._internal.exceptionsr pip._internal.req.req_installr pip._internal.req.req_trackerr pip._internal.utils.miscr r pip._internal.utils.temp_dirrpip._internal.wheel_builderrr getLoggerrlr^rr6r6r6r7s"          PKH]UEESpython3.10/site-packages/pip/_internal/commands/__pycache__/install.cpython-310.pycnu[o ail@s~ddlZddlZddlZddlZddlZddlmZmZddlm Z m Z m Z ddl m Z ddlmZddlmZddlmZddlmZmZmZdd lmZmZdd lmZmZdd lmZdd l m!Z!dd l"m#Z#ddl$m%Z%m&Z&ddl'm(Z(ddl)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0ddl1m2Z2ddl3m4Z4ddl5m6Z6m7Z7m8Z8m9Z9ddl:m;Z;ddlZ>ddl?m@Z@mAZAmBZBe4eCZDde#de@fddZEGdddeZF   d:d!eGd"e eHd#e eHd$eGd%e eHde eHf d&d'ZId#e eHd$eGdeGfd(d)ZJ    d;d*e eGd+e eHd,e eHd-e eHd.eGdeGf d/d0ZKd1e e*d2e e eHddfd3d4ZLd5eMd6eGd7eGdeHfd8d9ZNdS)<N) SUPPRESS_HELPValues)IterableListOptional)canonicalize_name) WheelCache) cmdoptions)make_target_python)RequirementCommandwarn_if_run_as_root with_cleanup)ERRORSUCCESS) CommandErrorInstallationError) get_scheme)get_environment) FormatControl)ConflictDetailscheck_install_conflicts)install_given_reqs)InstallRequirement)get_requirement_tracker)WINDOWS)parse_distutils_argstest_writable_dir) getLogger) ensure_dirget_pip_version(protect_pip_from_modification_on_windows write_output) TempDirectory)running_under_virtualenvvirtualenv_no_global)BinaryAllowedPredicatebuild should_build_for_install_commandformat_controlreturncsdtdtffdd }|S)Nreqr*cs t|jpd}|}d|vS)Nbinary)rnameget_allowed_formats)r+canonical_nameallowed_formatsr)/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/install.pycheck_binary_allowed5s z6get_check_binary_allowed..check_binary_allowed)rbool)r)r5r3r2r4get_check_binary_allowed4sr7c@seZdZdZdZdddZededee de fd d Z d e d e d e ddfddZdeedeefddZdede ddfddZdS)InstallCommandaI Install packages from: - PyPI (and other indexes) using requirement specifiers. - VCS project urls. - Local project directories. - Local or remote source archives. pip also supports installing from "requirements files", which provide an easy way to specify a whole environment to be installed. a% %prog [options] [package-index-options] ... %prog [options] -r [package-index-options] ... %prog [options] [-e] ... %prog [options] [-e] ... %prog [options] ...r*NcCsj|jt|jt|jt|jt|jt|jjdddddddt|j|jjddd d d |jjd dd t d |jjdddddd|jjdddddd|jt |jjdddd dd |jjdddddgdd|jjddd d d |jjd!d"d#d d$d |jt |jt |jt |jt|jt|jt|jjd%d d&d'd(d)|jjd*d d&d+d,|jjd-d d.d'd/d)|jjd0d d1d'd2d)|jt|jt|jt|jt|jtttj|j}|jd3||jd3|jdS)4Nz-tz--target target_dirdirzInstall packages into . By default this will not replace existing files/folders in . Use --upgrade to replace existing packages in with new versions.)destmetavardefaulthelpz--user use_user_site store_truezInstall to the Python user install directory for your platform. Typically ~/.local/, or %APPDATA%\Python on Windows. (See the Python documentation for site.USER_BASE for full details.))r;actionr>z --no-user store_falsez--root root_pathz=Install everything relative to this alternate root directory.z--prefix prefix_pathzIInstallation prefix where lib, bin and other top-level folders are placedz-Uz --upgradeupgradezUpgrade all specified packages to the newest available version. The handling of dependencies depends on the upgrade-strategy used.z--upgrade-strategyupgrade_strategyzonly-if-neededeageraGDetermines how dependency upgrading should be handled [default: %default]. "eager" - dependencies are upgraded regardless of whether the currently installed version satisfies the requirements of the upgraded package(s). "only-if-needed" - are upgraded only when they do not satisfy the requirements of the upgraded package(s).)r;r=choicesr>z--force-reinstallforce_reinstallz;Reinstall all packages even if they are already up-to-date.z-Iz--ignore-installedignore_installedzIgnore the installed packages, overwriting them. This can break your system if the existing package is of a different version or was installed with a different package manager!z --compilecompileTz'Compile Python source files to bytecode)rAr;r=r>z --no-compilez.Do not compile Python source files to bytecode)rAr;r>z--no-warn-script-locationwarn_script_locationz0Do not warn when installing scripts outside PATHz--no-warn-conflictswarn_about_conflictsz%Do not warn about broken dependenciesr)cmd_opts add_optionr requirements constraintsno_depspreeditableadd_target_python_optionsrsrcignore_requires_pythonno_build_isolation use_pep517 no_use_pep517install_optionsglobal_options no_binary only_binary prefer_binaryrequire_hashes progress_barmake_option_group index_groupparserinsert_option_group)self index_optsr3r3r4 add_optionsQs     zInstallCommand.add_optionsoptionsargsc) s*|jr |jdur tdt|d}|jr|j}tj|dd|jp$g}t dt t |j|j |j|j|jd|_d}d}|jrld|_tj|j|_tj|jr_tj|js_tdtdd }|j}|||jppg}||}t|} |j||| |jd } t|j|j} |t } t|j! d dd } z:|"||| |}|D]}d|_#qt$||j|j%| || || |jd }|j&|| || |j|j|j|j'||j(d }|)| |j*||j d}z|+d}Wn t,yd}Ynw|j-du}t.|dt/| jfdd|j01D}t2|| dggd\}}dd|D}|r-t3d4d5||D] }|j(s8d|_6q/|7|}d}|j8 oH|j9}|rQ|:|}|j;}|js\|j r^d}t<||||j||j ||j|j=d }t>|j||j|j |jd}t?|} |j@tABddg}!|D]*}"|"jC}#z| D|#}$|$dur|#d|$jE}#Wn tFyYnw|!G|#q|dur|jH||I|dd 5|!}%|%rtJd!|%Wn(tKy}&z|jLd"k}'tM|&|'|j}(t jN|(|'d#tOWYd}&~&Sd}&~&ww|jr|sJ|P|j||jtQtRS)$Nz'Can not combine '--user' and '--target'zto-satisfy-onlyT) check_targetzUsing %s)rDr9rC isolated_modez=Target path exists but is not a directory, will not continue.target)kind)risession target_pythonrWinstall)deleternglobally_managed)temp_build_dirri req_trackerrofinderr?) preparerrvri wheel_cacher?rJrWrIrFrY)check_supported_wheelspipF) modifying_pipcsg|] }t|r|qSr3)r(.0rr5r3r4 bs z&InstallCommand.run..)rxverify build_optionsr\cSsg|]}|jr|jqSr3)rYr.r|r3r3r4rrs zYCould not build wheels for {}, which is required to install pyproject.toml-based projectsz, i )roothomeprefixrLr? pycompile)userrrrisolatedr.)key-)resolver_variant zSuccessfully installed %s)exc_info)Sr?r9rr check_install_build_globalrErFcheck_dist_restrictionr[loggerverboser decide_user_installrDrCrlrJospathabspathexistsisdirr# enter_contextr\get_default_sessionr _build_package_finderrWr cache_dirr)rno_cleanget_requirementspermit_editable_wheels'reject_location_related_install_optionsmake_requirement_preparer make_resolverrIrYtrace_basic_inforesolveget_requirementKeyError satisfied_byr!r7rPvaluesr'rformatjoinlegacy_install_reasonget_installation_orderignore_dependenciesrM_determine_conflictsrLrrKget_lib_location_guessesrsortoperator attrgetterr.get_distributionversion Exceptionappend_warn_about_conflictsdetermine_resolver_variantr"OSError verbositycreate_os_error_messageerrorr_handle_target_dirr r))rfrirjrFr[target_temp_dirtarget_temp_dir_pathr\rorprvrxru directoryreqsr+rwresolverrequirement_setpip_reqr{ reqs_to_build_build_failurespep517_build_failure_namesr~ to_install conflictsshould_warn_about_conflictsrL installed lib_locationsenvitemsresultiteminstalled_distinstalled_descrshow_tracebackmessager3rr4runsf                             zInstallCommand.runr9rrEc sHt|g}td|jd}|j}|j}|j}tj|r!||tj|r0||kr0||tj|r;|||D]d} t | D]\} | |kratj || t fdd|ddDraqDtj || } tj| r|swt d| qDtj| rt d| qDtj| rt| nt| ttj | | | qDq=dS)Nr,)rc3s|]}|VqdSN) startswith)r}sddirr3r4 sz4InstallCommand._handle_target_dir..zKTarget directory %s already exists. Specify --upgrade to force replacement.zTarget directory %s already exists and is a link. pip will not automatically replace links, please remove if replacement is desired.)rrrpurelibplatlibdatarrrlistdirranyrwarningislinkrshutilrmtreeremovemove) rfr9rrE lib_dir_listscheme purelib_dir platlib_dirdata_dirlib_dirrtarget_item_dirr3rr4rsL          z!InstallCommand._handle_target_dirrcCs*zt|WStytdYdSw)NzwError while checking for conflicts. Please file an issue on pip's issue tracker: https://github.com/pypa/pip/issues/new)rrr exception)rfrr3r3r4r s  z#InstallCommand._determine_conflictsconflict_detailsrc Cs|\}\}}|s |s dSg}|dkr|dn |dksJ|d|D]}||d}||D]} dj||| dd} || q1q%|D](}||d}||D]\} } } d j||| | | |dkrdd nd d } || qRqFtd |dS)Nlegacyzpip's legacy dependency resolver does not consider dependency conflicts when selecting packages. This behaviour is the source of the following dependency conflicts.z 2020-resolverzpip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.rz@{name} {version} requires {requirement}, which is not installed.r)r.r requirementzg{name} {version} requires {requirement}, but {you} have {dep_name} {dep_version} which is incompatible.youzyou'll)r.rrdep_name dep_versionr )rrrcriticalr)rfrr package_setmissing conflictingparts project_namer dependencyrrrr+r3r3r4rsL       z$InstallCommand._warn_about_conflicts)r*N)__name__ __module__ __qualname____doc__usagerhr rrstrintrr#r6rrrrrrr3r3r3r4r8=s:  f 6  r8FrrrrrcCs td|||||d}|j|jgS)Nr,)rrrrr)rrr)rrrrrrr3r3r4rOs rcCstddtt||dDS)Ncss|]}t|VqdSrr)r}dr3r3r4rbs  z)site_packages_writable..rr)allsetrrr3r3r4site_packages_writableasr r?rDr9rCrlcCs|dur |s tddS|r#|rtdtrtdtddS|dus)J|s-|r4tddStjs>td dSt||d rKtd dStd dS) aZDetermine whether to do a user install based on the input options. If use_user_site is False, no additional checks are done. If use_user_site is True, it is checked for compatibility with other options. If use_user_site is None, the default behaviour depends on the environment, which is provided by the other arguments. Nz$Non-user install by explicit requestFzVCan not combine '--user' and '--prefix' as they imply different installation locationszZCan not perform a '--user' install. User site-packages are not visible in this virtualenv.z User install by explicit requestTz3Non-user install due to --prefix or --target optionz4Non-user install because user site-packages disabledrz0Non-user install because site-packages writeablezMDefaulting to user installation because normal site-packages is not writeable) rdebugrr%rsiteENABLE_USER_SITEr info)r?rDr9rCrlr3r3r4rhs8        rrPricCsdttdttfdd}g}|D]}|j}t|}|r)|d|||q|r>t|}|r>|d|||sBdStdd |) zIf any location-changing --install-option arguments were passed for requirements or on the command-line, then show a deprecation warning. option_namesr*cSsdd|DS)NcSsg|] }d|ddqS)z--{}rr)rreplace)r}r.r3r3r4rszSreject_location_related_install_options..format_options..r3)rr3r3r4format_optionssz?reject_location_related_install_options..format_optionsz {!r} from {}z{!r} from command lineNzLocation-changing options found in --install-option: {}. This is unsupported, use pip-level options like --user, --prefix, --root, and --target instead.z; ) rrrr[rrrkeysrr)rPrir offendersrr[location_optionsr3r3r4rs0  rrrusing_user_sitecCsg}|d|s|d|t|n|d|dd7<|jtjkrGd}d}ts=|s=||d|gn|||d tr^|jtjkr^|j r^t |j d kr^|d d | dS) zrFormat an error message for an OSError It may occur anytime during the execution of the install command. z,Could not install packages due to an OSErrorz: .rrz"Consider using the `--user` optionzCheck the permissionsz or z. izHINT: This error might have occurred since this system does not have Windows Long Path support enabled. You can find information on how to enable this at https://pip.pypa.io/warnings/enable-long-paths r,) rrerrnoEACCESr$extendlowerrENOENTfilenamelenrstrip)rrrruser_option_partpermissions_partr3r3r4rs:        r)FNNFN)NNNF)Orrrrr optparserrtypingrrrpip._vendor.packaging.utilsrpip._internal.cacherpip._internal.clir Zpip._internal.cli.cmdoptionsr pip._internal.cli.req_commandr r r pip._internal.cli.status_codesrrpip._internal.exceptionsrrpip._internal.locationsrpip._internal.metadatar#pip._internal.models.format_controlrpip._internal.operations.checkrrpip._internal.reqrpip._internal.req.req_installrpip._internal.req.req_trackerrpip._internal.utils.compatr"pip._internal.utils.distutils_argsrpip._internal.utils.filesystemrpip._internal.utils.loggingrpip._internal.utils.miscrr r!r"pip._internal.utils.temp_dirr#pip._internal.utils.virtualenvr$r%pip._internal.wheel_builderr&r'r(rrr7r8r6rrr rrrrr3r3r3r4s                   =  'PKH]:IIPpython3.10/site-packages/pip/_internal/commands/__pycache__/help.cpython-310.pycnu[o ail@sPddlmZddlmZddlmZddlmZddlm Z GdddeZ dS) )Values)List)Command)SUCCESS) CommandErrorc@s2eZdZdZdZdZdedeede fddZ d S) HelpCommandzShow help for commandsz %prog Toptionsargsreturnc Csddlm}m}m}z|d}Wn tytYSw||vr=||}d|dg}|r6|d|dtd|||} | j tS)Nr) commands_dictcreate_commandget_similar_commandszunknown command ""zmaybe you meant "z - ) pip._internal.commandsr r r IndexErrorrappendrjoinparser print_help) selfrr r r r cmd_nameguessmsgcommandr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/commands/help.pyruns   zHelpCommand.runN) __name__ __module__ __qualname____doc__usageignore_require_venvrrstrintrrrrrr s rN) optparsertypingrpip._internal.cli.base_commandrpip._internal.cli.status_codesrpip._internal.exceptionsrrrrrrs    PKH]8dd8python3.10/site-packages/pip/_internal/commands/cache.pynu[import os import textwrap from optparse import Values from typing import Any, List import pip._internal.utils.filesystem as filesystem from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import ERROR, SUCCESS from pip._internal.exceptions import CommandError, PipError from pip._internal.utils.logging import getLogger logger = getLogger(__name__) class CacheCommand(Command): """ Inspect and manage pip's wheel cache. Subcommands: - dir: Show the cache directory. - info: Show information about the cache. - list: List filenames of packages stored in the cache. - remove: Remove one or more package from the cache. - purge: Remove all items from the cache. ```` can be a glob expression or a package name. """ ignore_require_venv = True usage = """ %prog dir %prog info %prog list [] [--format=[human, abspath]] %prog remove %prog purge """ def add_options(self) -> None: self.cmd_opts.add_option( "--format", action="store", dest="list_format", default="human", choices=("human", "abspath"), help="Select the output format among: human (default) or abspath", ) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options: Values, args: List[str]) -> int: handlers = { "dir": self.get_cache_dir, "info": self.get_cache_info, "list": self.list_cache_items, "remove": self.remove_cache_items, "purge": self.purge_cache, } if not options.cache_dir: logger.error("pip cache commands can not function since cache is disabled.") return ERROR # Determine action if not args or args[0] not in handlers: logger.error( "Need an action (%s) to perform.", ", ".join(sorted(handlers)), ) return ERROR action = args[0] # Error handling happens here, not in the action-handlers. try: handlers[action](options, args[1:]) except PipError as e: logger.error(e.args[0]) return ERROR return SUCCESS def get_cache_dir(self, options: Values, args: List[Any]) -> None: if args: raise CommandError("Too many arguments") logger.info(options.cache_dir) def get_cache_info(self, options: Values, args: List[Any]) -> None: if args: raise CommandError("Too many arguments") num_http_files = len(self._find_http_files(options)) num_packages = len(self._find_wheels(options, "*")) http_cache_location = self._cache_dir(options, "http") wheels_cache_location = self._cache_dir(options, "wheels") http_cache_size = filesystem.format_directory_size(http_cache_location) wheels_cache_size = filesystem.format_directory_size(wheels_cache_location) message = ( textwrap.dedent( """ Package index page cache location: {http_cache_location} Package index page cache size: {http_cache_size} Number of HTTP files: {num_http_files} Wheels location: {wheels_cache_location} Wheels size: {wheels_cache_size} Number of wheels: {package_count} """ ) .format( http_cache_location=http_cache_location, http_cache_size=http_cache_size, num_http_files=num_http_files, wheels_cache_location=wheels_cache_location, package_count=num_packages, wheels_cache_size=wheels_cache_size, ) .strip() ) logger.info(message) def list_cache_items(self, options: Values, args: List[Any]) -> None: if len(args) > 1: raise CommandError("Too many arguments") if args: pattern = args[0] else: pattern = "*" files = self._find_wheels(options, pattern) if options.list_format == "human": self.format_for_human(files) else: self.format_for_abspath(files) def format_for_human(self, files: List[str]) -> None: if not files: logger.info("Nothing cached.") return results = [] for filename in files: wheel = os.path.basename(filename) size = filesystem.format_file_size(filename) results.append(f" - {wheel} ({size})") logger.info("Cache contents:\n") logger.info("\n".join(sorted(results))) def format_for_abspath(self, files: List[str]) -> None: if not files: return results = [] for filename in files: results.append(filename) logger.info("\n".join(sorted(results))) def remove_cache_items(self, options: Values, args: List[Any]) -> None: if len(args) > 1: raise CommandError("Too many arguments") if not args: raise CommandError("Please provide a pattern") files = self._find_wheels(options, args[0]) no_matching_msg = "No matching packages" if args[0] == "*": # Only fetch http files if no specific pattern given files += self._find_http_files(options) else: # Add the pattern to the log message no_matching_msg += ' for pattern "{}"'.format(args[0]) if not files: logger.warning(no_matching_msg) for filename in files: os.unlink(filename) logger.verbose("Removed %s", filename) logger.info("Files removed: %s", len(files)) def purge_cache(self, options: Values, args: List[Any]) -> None: if args: raise CommandError("Too many arguments") return self.remove_cache_items(options, ["*"]) def _cache_dir(self, options: Values, subdir: str) -> str: return os.path.join(options.cache_dir, subdir) def _find_http_files(self, options: Values) -> List[str]: http_dir = self._cache_dir(options, "http") return filesystem.find_files(http_dir, "*") def _find_wheels(self, options: Values, pattern: str) -> List[str]: wheel_dir = self._cache_dir(options, "wheels") # The wheel filename format, as specified in PEP 427, is: # {distribution}-{version}(-{build})?-{python}-{abi}-{platform}.whl # # Additionally, non-alphanumeric values in the distribution are # normalized to underscores (_), meaning hyphens can never occur # before `-{version}`. # # Given that information: # - If the pattern we're given contains a hyphen (-), the user is # providing at least the version. Thus, we can just append `*.whl` # to match the rest of it. # - If the pattern we're given doesn't contain a hyphen (-), the # user is only providing the name. Thus, we append `-*.whl` to # match the hyphen before the version, followed by anything else. # # PEP 427: https://www.python.org/dev/peps/pep-0427/ pattern = pattern + ("*.whl" if "-" in pattern else "-*.whl") return filesystem.find_files(wheel_dir, pattern) PKH]7python3.10/site-packages/pip/_internal/commands/hash.pynu[import hashlib import logging import sys from optparse import Values from typing import List from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import ERROR, SUCCESS from pip._internal.utils.hashes import FAVORITE_HASH, STRONG_HASHES from pip._internal.utils.misc import read_chunks, write_output logger = logging.getLogger(__name__) class HashCommand(Command): """ Compute a hash of a local package archive. These can be used with --hash in a requirements file to do repeatable installs. """ usage = "%prog [options] ..." ignore_require_venv = True def add_options(self) -> None: self.cmd_opts.add_option( "-a", "--algorithm", dest="algorithm", choices=STRONG_HASHES, action="store", default=FAVORITE_HASH, help="The hash algorithm to use: one of {}".format( ", ".join(STRONG_HASHES) ), ) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options: Values, args: List[str]) -> int: if not args: self.parser.print_usage(sys.stderr) return ERROR algorithm = options.algorithm for path in args: write_output( "%s:\n--hash=%s:%s", path, algorithm, _hash_of_file(path, algorithm) ) return SUCCESS def _hash_of_file(path: str, algorithm: str) -> str: """Return the hash digest of a file.""" with open(path, "rb") as archive: hash = hashlib.new(algorithm) for chunk in read_chunks(archive): hash.update(chunk) return hash.hexdigest() PKH]W/AA9python3.10/site-packages/pip/_internal/commands/search.pynu[import logging import shutil import sys import textwrap import xmlrpc.client from collections import OrderedDict from optparse import Values from typing import TYPE_CHECKING, Dict, List, Optional from pip._vendor.packaging.version import parse as parse_version from pip._internal.cli.base_command import Command from pip._internal.cli.req_command import SessionCommandMixin from pip._internal.cli.status_codes import NO_MATCHES_FOUND, SUCCESS from pip._internal.exceptions import CommandError from pip._internal.metadata import get_default_environment from pip._internal.models.index import PyPI from pip._internal.network.xmlrpc import PipXmlrpcTransport from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import write_output if TYPE_CHECKING: from typing import TypedDict class TransformedHit(TypedDict): name: str summary: str versions: List[str] logger = logging.getLogger(__name__) class SearchCommand(Command, SessionCommandMixin): """Search for PyPI packages whose name or summary contains .""" usage = """ %prog [options] """ ignore_require_venv = True def add_options(self) -> None: self.cmd_opts.add_option( "-i", "--index", dest="index", metavar="URL", default=PyPI.pypi_url, help="Base URL of Python Package Index (default %default)", ) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options: Values, args: List[str]) -> int: if not args: raise CommandError("Missing required argument (search query).") query = args pypi_hits = self.search(query, options) hits = transform_hits(pypi_hits) terminal_width = None if sys.stdout.isatty(): terminal_width = shutil.get_terminal_size()[0] print_results(hits, terminal_width=terminal_width) if pypi_hits: return SUCCESS return NO_MATCHES_FOUND def search(self, query: List[str], options: Values) -> List[Dict[str, str]]: index_url = options.index session = self.get_default_session(options) transport = PipXmlrpcTransport(index_url, session) pypi = xmlrpc.client.ServerProxy(index_url, transport) try: hits = pypi.search({"name": query, "summary": query}, "or") except xmlrpc.client.Fault as fault: message = "XMLRPC request failed [code: {code}]\n{string}".format( code=fault.faultCode, string=fault.faultString, ) raise CommandError(message) assert isinstance(hits, list) return hits def transform_hits(hits: List[Dict[str, str]]) -> List["TransformedHit"]: """ The list from pypi is really a list of versions. We want a list of packages with the list of versions stored inline. This converts the list from pypi into one we can use. """ packages: Dict[str, "TransformedHit"] = OrderedDict() for hit in hits: name = hit["name"] summary = hit["summary"] version = hit["version"] if name not in packages.keys(): packages[name] = { "name": name, "summary": summary, "versions": [version], } else: packages[name]["versions"].append(version) # if this is the highest version, replace summary and score if version == highest_version(packages[name]["versions"]): packages[name]["summary"] = summary return list(packages.values()) def print_dist_installation_info(name: str, latest: str) -> None: env = get_default_environment() dist = env.get_distribution(name) if dist is not None: with indent_log(): if dist.version == latest: write_output("INSTALLED: %s (latest)", dist.version) else: write_output("INSTALLED: %s", dist.version) if parse_version(latest).pre: write_output( "LATEST: %s (pre-release; install" " with `pip install --pre`)", latest, ) else: write_output("LATEST: %s", latest) def print_results( hits: List["TransformedHit"], name_column_width: Optional[int] = None, terminal_width: Optional[int] = None, ) -> None: if not hits: return if name_column_width is None: name_column_width = ( max( [ len(hit["name"]) + len(highest_version(hit.get("versions", ["-"]))) for hit in hits ] ) + 4 ) for hit in hits: name = hit["name"] summary = hit["summary"] or "" latest = highest_version(hit.get("versions", ["-"])) if terminal_width is not None: target_width = terminal_width - name_column_width - 5 if target_width > 10: # wrap and indent summary to fit terminal summary_lines = textwrap.wrap(summary, target_width) summary = ("\n" + " " * (name_column_width + 3)).join(summary_lines) name_latest = f"{name} ({latest})" line = f"{name_latest:{name_column_width}} - {summary}" try: write_output(line) print_dist_installation_info(name, latest) except UnicodeEncodeError: pass def highest_version(versions: List[str]) -> str: return max(versions, key=parse_version) PKH]6l8python3.10/site-packages/pip/_internal/commands/check.pynu[import logging from optparse import Values from typing import List from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import ERROR, SUCCESS from pip._internal.operations.check import ( check_package_set, create_package_set_from_installed, ) from pip._internal.utils.misc import write_output logger = logging.getLogger(__name__) class CheckCommand(Command): """Verify installed packages have compatible dependencies.""" usage = """ %prog [options]""" def run(self, options: Values, args: List[str]) -> int: package_set, parsing_probs = create_package_set_from_installed() missing, conflicting = check_package_set(package_set) for project_name in missing: version = package_set[project_name].version for dependency in missing[project_name]: write_output( "%s %s requires %s, which is not installed.", project_name, version, dependency[0], ) for project_name in conflicting: version = package_set[project_name].version for dep_name, dep_version, req in conflicting[project_name]: write_output( "%s %s has requirement %s, but you have %s %s.", project_name, version, req, dep_name, dep_version, ) if missing or conflicting or parsing_probs: return ERROR else: write_output("No broken requirements found.") return SUCCESS PKH] 9python3.10/site-packages/pip/_internal/commands/freeze.pynu[import sys from optparse import Values from typing import List from pip._internal.cli import cmdoptions from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import SUCCESS from pip._internal.operations.freeze import freeze from pip._internal.utils.compat import stdlib_pkgs DEV_PKGS = {"pip", "setuptools", "distribute", "wheel"} class FreezeCommand(Command): """ Output installed packages in requirements format. packages are listed in a case-insensitive sorted order. """ usage = """ %prog [options]""" log_streams = ("ext://sys.stderr", "ext://sys.stderr") def add_options(self) -> None: self.cmd_opts.add_option( "-r", "--requirement", dest="requirements", action="append", default=[], metavar="file", help=( "Use the order in the given requirements file and its " "comments when generating output. This option can be " "used multiple times." ), ) self.cmd_opts.add_option( "-l", "--local", dest="local", action="store_true", default=False, help=( "If in a virtualenv that has global access, do not output " "globally-installed packages." ), ) self.cmd_opts.add_option( "--user", dest="user", action="store_true", default=False, help="Only output packages installed in user-site.", ) self.cmd_opts.add_option(cmdoptions.list_path()) self.cmd_opts.add_option( "--all", dest="freeze_all", action="store_true", help=( "Do not skip these packages in the output:" " {}".format(", ".join(DEV_PKGS)) ), ) self.cmd_opts.add_option( "--exclude-editable", dest="exclude_editable", action="store_true", help="Exclude editable package from output.", ) self.cmd_opts.add_option(cmdoptions.list_exclude()) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options: Values, args: List[str]) -> int: skip = set(stdlib_pkgs) if not options.freeze_all: skip.update(DEV_PKGS) if options.excludes: skip.update(options.excludes) cmdoptions.check_list_path_option(options) for line in freeze( requirement=options.requirements, local_only=options.local, user_only=options.user, paths=options.path, isolated=options.isolated_mode, skip=skip, exclude_editable=options.exclude_editable, ): sys.stdout.write(line + "\n") return SUCCESS PKH]qC =python3.10/site-packages/pip/_internal/commands/completion.pynu[import sys import textwrap from optparse import Values from typing import List from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import SUCCESS from pip._internal.utils.misc import get_prog BASE_COMPLETION = """ # pip {shell} completion start{script}# pip {shell} completion end """ COMPLETION_SCRIPTS = { "bash": """ _pip_completion() {{ COMPREPLY=( $( COMP_WORDS="${{COMP_WORDS[*]}}" \\ COMP_CWORD=$COMP_CWORD \\ PIP_AUTO_COMPLETE=1 $1 2>/dev/null ) ) }} complete -o default -F _pip_completion {prog} """, "zsh": """ function _pip_completion {{ local words cword read -Ac words read -cn cword reply=( $( COMP_WORDS="$words[*]" \\ COMP_CWORD=$(( cword-1 )) \\ PIP_AUTO_COMPLETE=1 $words[1] 2>/dev/null )) }} compctl -K _pip_completion {prog} """, "fish": """ function __fish_complete_pip set -lx COMP_WORDS (commandline -o) "" set -lx COMP_CWORD ( \\ math (contains -i -- (commandline -t) $COMP_WORDS)-1 \\ ) set -lx PIP_AUTO_COMPLETE 1 string split \\ -- (eval $COMP_WORDS[1]) end complete -fa "(__fish_complete_pip)" -c {prog} """, } class CompletionCommand(Command): """A helper command to be used for command completion.""" ignore_require_venv = True def add_options(self) -> None: self.cmd_opts.add_option( "--bash", "-b", action="store_const", const="bash", dest="shell", help="Emit completion code for bash", ) self.cmd_opts.add_option( "--zsh", "-z", action="store_const", const="zsh", dest="shell", help="Emit completion code for zsh", ) self.cmd_opts.add_option( "--fish", "-f", action="store_const", const="fish", dest="shell", help="Emit completion code for fish", ) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options: Values, args: List[str]) -> int: """Prints the completion code of the given shell""" shells = COMPLETION_SCRIPTS.keys() shell_options = ["--" + shell for shell in sorted(shells)] if options.shell in shells: script = textwrap.dedent( COMPLETION_SCRIPTS.get(options.shell, "").format(prog=get_prog()) ) print(BASE_COMPLETION.format(script=script, shell=options.shell)) return SUCCESS else: sys.stderr.write( "ERROR: You must pass {}\n".format(" or ".join(shell_options)) ) return SUCCESS PKH]Ô""" ignore_require_venv = True def run(self, options: Values, args: List[str]) -> int: from pip._internal.commands import ( commands_dict, create_command, get_similar_commands, ) try: # 'pip help' with no args is handled by pip.__init__.parseopt() cmd_name = args[0] # the command we need help for except IndexError: return SUCCESS if cmd_name not in commands_dict: guess = get_similar_commands(cmd_name) msg = [f'unknown command "{cmd_name}"'] if guess: msg.append(f'maybe you meant "{guess}"') raise CommandError(" - ".join(msg)) command = create_command(cmd_name) command.parser.print_help() return SUCCESS PKH] wy8python3.10/site-packages/pip/_internal/commands/wheel.pynu[import logging import os import shutil from optparse import Values from typing import List from pip._internal.cache import WheelCache from pip._internal.cli import cmdoptions from pip._internal.cli.req_command import RequirementCommand, with_cleanup from pip._internal.cli.status_codes import SUCCESS from pip._internal.exceptions import CommandError from pip._internal.req.req_install import InstallRequirement from pip._internal.req.req_tracker import get_requirement_tracker from pip._internal.utils.misc import ensure_dir, normalize_path from pip._internal.utils.temp_dir import TempDirectory from pip._internal.wheel_builder import build, should_build_for_wheel_command logger = logging.getLogger(__name__) class WheelCommand(RequirementCommand): """ Build Wheel archives for your requirements and dependencies. Wheel is a built-package format, and offers the advantage of not recompiling your software during every install. For more details, see the wheel docs: https://wheel.readthedocs.io/en/latest/ Requirements: setuptools>=0.8, and wheel. 'pip wheel' uses the bdist_wheel setuptools extension from the wheel package to build individual wheels. """ usage = """ %prog [options] ... %prog [options] -r ... %prog [options] [-e] ... %prog [options] [-e] ... %prog [options] ...""" def add_options(self) -> None: self.cmd_opts.add_option( "-w", "--wheel-dir", dest="wheel_dir", metavar="dir", default=os.curdir, help=( "Build wheels into , where the default is the " "current working directory." ), ) self.cmd_opts.add_option(cmdoptions.no_binary()) self.cmd_opts.add_option(cmdoptions.only_binary()) self.cmd_opts.add_option(cmdoptions.prefer_binary()) self.cmd_opts.add_option(cmdoptions.no_build_isolation()) self.cmd_opts.add_option(cmdoptions.use_pep517()) self.cmd_opts.add_option(cmdoptions.no_use_pep517()) self.cmd_opts.add_option(cmdoptions.constraints()) self.cmd_opts.add_option(cmdoptions.editable()) self.cmd_opts.add_option(cmdoptions.requirements()) self.cmd_opts.add_option(cmdoptions.src()) self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) self.cmd_opts.add_option(cmdoptions.no_deps()) self.cmd_opts.add_option(cmdoptions.progress_bar()) self.cmd_opts.add_option( "--no-verify", dest="no_verify", action="store_true", default=False, help="Don't verify if built wheel is valid.", ) self.cmd_opts.add_option(cmdoptions.build_options()) self.cmd_opts.add_option(cmdoptions.global_options()) self.cmd_opts.add_option( "--pre", action="store_true", default=False, help=( "Include pre-release and development versions. By default, " "pip only finds stable versions." ), ) self.cmd_opts.add_option(cmdoptions.require_hashes()) index_opts = cmdoptions.make_option_group( cmdoptions.index_group, self.parser, ) self.parser.insert_option_group(0, index_opts) self.parser.insert_option_group(0, self.cmd_opts) @with_cleanup def run(self, options: Values, args: List[str]) -> int: cmdoptions.check_install_build_global(options) session = self.get_default_session(options) finder = self._build_package_finder(options, session) wheel_cache = WheelCache(options.cache_dir, options.format_control) options.wheel_dir = normalize_path(options.wheel_dir) ensure_dir(options.wheel_dir) req_tracker = self.enter_context(get_requirement_tracker()) directory = TempDirectory( delete=not options.no_clean, kind="wheel", globally_managed=True, ) reqs = self.get_requirements(args, options, finder, session) preparer = self.make_requirement_preparer( temp_build_dir=directory, options=options, req_tracker=req_tracker, session=session, finder=finder, download_dir=options.wheel_dir, use_user_site=False, ) resolver = self.make_resolver( preparer=preparer, finder=finder, options=options, wheel_cache=wheel_cache, ignore_requires_python=options.ignore_requires_python, use_pep517=options.use_pep517, ) self.trace_basic_info(finder) requirement_set = resolver.resolve(reqs, check_supported_wheels=True) reqs_to_build: List[InstallRequirement] = [] for req in requirement_set.requirements.values(): if req.is_wheel: preparer.save_linked_requirement(req) elif should_build_for_wheel_command(req): reqs_to_build.append(req) # build wheels build_successes, build_failures = build( reqs_to_build, wheel_cache=wheel_cache, verify=(not options.no_verify), build_options=options.build_options or [], global_options=options.global_options or [], ) for req in build_successes: assert req.link and req.link.is_wheel assert req.local_file_path # copy from cache to target directory try: shutil.copy(req.local_file_path, options.wheel_dir) except OSError as e: logger.warning( "Building wheel for %s failed: %s", req.name, e, ) build_failures.append(req) if len(build_failures) != 0: raise CommandError("Failed to build one or more wheels") return SUCCESS PKH]`+ll:python3.10/site-packages/pip/_internal/commands/install.pynu[import errno import operator import os import shutil import site from optparse import SUPPRESS_HELP, Values from typing import Iterable, List, Optional from pip._vendor.packaging.utils import canonicalize_name from pip._internal.cache import WheelCache from pip._internal.cli import cmdoptions from pip._internal.cli.cmdoptions import make_target_python from pip._internal.cli.req_command import ( RequirementCommand, warn_if_run_as_root, with_cleanup, ) from pip._internal.cli.status_codes import ERROR, SUCCESS from pip._internal.exceptions import CommandError, InstallationError from pip._internal.locations import get_scheme from pip._internal.metadata import get_environment from pip._internal.models.format_control import FormatControl from pip._internal.operations.check import ConflictDetails, check_install_conflicts from pip._internal.req import install_given_reqs from pip._internal.req.req_install import InstallRequirement from pip._internal.req.req_tracker import get_requirement_tracker from pip._internal.utils.compat import WINDOWS from pip._internal.utils.distutils_args import parse_distutils_args from pip._internal.utils.filesystem import test_writable_dir from pip._internal.utils.logging import getLogger from pip._internal.utils.misc import ( ensure_dir, get_pip_version, protect_pip_from_modification_on_windows, write_output, ) from pip._internal.utils.temp_dir import TempDirectory from pip._internal.utils.virtualenv import ( running_under_virtualenv, virtualenv_no_global, ) from pip._internal.wheel_builder import ( BinaryAllowedPredicate, build, should_build_for_install_command, ) logger = getLogger(__name__) def get_check_binary_allowed(format_control: FormatControl) -> BinaryAllowedPredicate: def check_binary_allowed(req: InstallRequirement) -> bool: canonical_name = canonicalize_name(req.name or "") allowed_formats = format_control.get_allowed_formats(canonical_name) return "binary" in allowed_formats return check_binary_allowed class InstallCommand(RequirementCommand): """ Install packages from: - PyPI (and other indexes) using requirement specifiers. - VCS project urls. - Local project directories. - Local or remote source archives. pip also supports installing from "requirements files", which provide an easy way to specify a whole environment to be installed. """ usage = """ %prog [options] [package-index-options] ... %prog [options] -r [package-index-options] ... %prog [options] [-e] ... %prog [options] [-e] ... %prog [options] ...""" def add_options(self) -> None: self.cmd_opts.add_option(cmdoptions.requirements()) self.cmd_opts.add_option(cmdoptions.constraints()) self.cmd_opts.add_option(cmdoptions.no_deps()) self.cmd_opts.add_option(cmdoptions.pre()) self.cmd_opts.add_option(cmdoptions.editable()) self.cmd_opts.add_option( "-t", "--target", dest="target_dir", metavar="dir", default=None, help=( "Install packages into . " "By default this will not replace existing files/folders in " ". Use --upgrade to replace existing packages in " "with new versions." ), ) cmdoptions.add_target_python_options(self.cmd_opts) self.cmd_opts.add_option( "--user", dest="use_user_site", action="store_true", help=( "Install to the Python user install directory for your " "platform. Typically ~/.local/, or %APPDATA%\\Python on " "Windows. (See the Python documentation for site.USER_BASE " "for full details.)" ), ) self.cmd_opts.add_option( "--no-user", dest="use_user_site", action="store_false", help=SUPPRESS_HELP, ) self.cmd_opts.add_option( "--root", dest="root_path", metavar="dir", default=None, help="Install everything relative to this alternate root directory.", ) self.cmd_opts.add_option( "--prefix", dest="prefix_path", metavar="dir", default=None, help=( "Installation prefix where lib, bin and other top-level " "folders are placed" ), ) self.cmd_opts.add_option(cmdoptions.src()) self.cmd_opts.add_option( "-U", "--upgrade", dest="upgrade", action="store_true", help=( "Upgrade all specified packages to the newest available " "version. The handling of dependencies depends on the " "upgrade-strategy used." ), ) self.cmd_opts.add_option( "--upgrade-strategy", dest="upgrade_strategy", default="only-if-needed", choices=["only-if-needed", "eager"], help=( "Determines how dependency upgrading should be handled " "[default: %default]. " '"eager" - dependencies are upgraded regardless of ' "whether the currently installed version satisfies the " "requirements of the upgraded package(s). " '"only-if-needed" - are upgraded only when they do not ' "satisfy the requirements of the upgraded package(s)." ), ) self.cmd_opts.add_option( "--force-reinstall", dest="force_reinstall", action="store_true", help="Reinstall all packages even if they are already up-to-date.", ) self.cmd_opts.add_option( "-I", "--ignore-installed", dest="ignore_installed", action="store_true", help=( "Ignore the installed packages, overwriting them. " "This can break your system if the existing package " "is of a different version or was installed " "with a different package manager!" ), ) self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) self.cmd_opts.add_option(cmdoptions.no_build_isolation()) self.cmd_opts.add_option(cmdoptions.use_pep517()) self.cmd_opts.add_option(cmdoptions.no_use_pep517()) self.cmd_opts.add_option(cmdoptions.install_options()) self.cmd_opts.add_option(cmdoptions.global_options()) self.cmd_opts.add_option( "--compile", action="store_true", dest="compile", default=True, help="Compile Python source files to bytecode", ) self.cmd_opts.add_option( "--no-compile", action="store_false", dest="compile", help="Do not compile Python source files to bytecode", ) self.cmd_opts.add_option( "--no-warn-script-location", action="store_false", dest="warn_script_location", default=True, help="Do not warn when installing scripts outside PATH", ) self.cmd_opts.add_option( "--no-warn-conflicts", action="store_false", dest="warn_about_conflicts", default=True, help="Do not warn about broken dependencies", ) self.cmd_opts.add_option(cmdoptions.no_binary()) self.cmd_opts.add_option(cmdoptions.only_binary()) self.cmd_opts.add_option(cmdoptions.prefer_binary()) self.cmd_opts.add_option(cmdoptions.require_hashes()) self.cmd_opts.add_option(cmdoptions.progress_bar()) index_opts = cmdoptions.make_option_group( cmdoptions.index_group, self.parser, ) self.parser.insert_option_group(0, index_opts) self.parser.insert_option_group(0, self.cmd_opts) @with_cleanup def run(self, options: Values, args: List[str]) -> int: if options.use_user_site and options.target_dir is not None: raise CommandError("Can not combine '--user' and '--target'") cmdoptions.check_install_build_global(options) upgrade_strategy = "to-satisfy-only" if options.upgrade: upgrade_strategy = options.upgrade_strategy cmdoptions.check_dist_restriction(options, check_target=True) install_options = options.install_options or [] logger.verbose("Using %s", get_pip_version()) options.use_user_site = decide_user_install( options.use_user_site, prefix_path=options.prefix_path, target_dir=options.target_dir, root_path=options.root_path, isolated_mode=options.isolated_mode, ) target_temp_dir: Optional[TempDirectory] = None target_temp_dir_path: Optional[str] = None if options.target_dir: options.ignore_installed = True options.target_dir = os.path.abspath(options.target_dir) if ( # fmt: off os.path.exists(options.target_dir) and not os.path.isdir(options.target_dir) # fmt: on ): raise CommandError( "Target path exists but is not a directory, will not continue." ) # Create a target directory for using with the target option target_temp_dir = TempDirectory(kind="target") target_temp_dir_path = target_temp_dir.path self.enter_context(target_temp_dir) global_options = options.global_options or [] session = self.get_default_session(options) target_python = make_target_python(options) finder = self._build_package_finder( options=options, session=session, target_python=target_python, ignore_requires_python=options.ignore_requires_python, ) wheel_cache = WheelCache(options.cache_dir, options.format_control) req_tracker = self.enter_context(get_requirement_tracker()) directory = TempDirectory( delete=not options.no_clean, kind="install", globally_managed=True, ) try: reqs = self.get_requirements(args, options, finder, session) # Only when installing is it permitted to use PEP 660. # In other circumstances (pip wheel, pip download) we generate # regular (i.e. non editable) metadata and wheels. for req in reqs: req.permit_editable_wheels = True reject_location_related_install_options(reqs, options.install_options) preparer = self.make_requirement_preparer( temp_build_dir=directory, options=options, req_tracker=req_tracker, session=session, finder=finder, use_user_site=options.use_user_site, ) resolver = self.make_resolver( preparer=preparer, finder=finder, options=options, wheel_cache=wheel_cache, use_user_site=options.use_user_site, ignore_installed=options.ignore_installed, ignore_requires_python=options.ignore_requires_python, force_reinstall=options.force_reinstall, upgrade_strategy=upgrade_strategy, use_pep517=options.use_pep517, ) self.trace_basic_info(finder) requirement_set = resolver.resolve( reqs, check_supported_wheels=not options.target_dir ) try: pip_req = requirement_set.get_requirement("pip") except KeyError: modifying_pip = False else: # If we're not replacing an already installed pip, # we're not modifying it. modifying_pip = pip_req.satisfied_by is None protect_pip_from_modification_on_windows(modifying_pip=modifying_pip) check_binary_allowed = get_check_binary_allowed(finder.format_control) reqs_to_build = [ r for r in requirement_set.requirements.values() if should_build_for_install_command(r, check_binary_allowed) ] _, build_failures = build( reqs_to_build, wheel_cache=wheel_cache, verify=True, build_options=[], global_options=[], ) # If we're using PEP 517, we cannot do a legacy setup.py install # so we fail here. pep517_build_failure_names: List[str] = [ r.name for r in build_failures if r.use_pep517 # type: ignore ] if pep517_build_failure_names: raise InstallationError( "Could not build wheels for {}, which is required to " "install pyproject.toml-based projects".format( ", ".join(pep517_build_failure_names) ) ) # For now, we just warn about failures building legacy # requirements, as we'll fall through to a setup.py install for # those. for r in build_failures: if not r.use_pep517: r.legacy_install_reason = 8368 to_install = resolver.get_installation_order(requirement_set) # Check for conflicts in the package set we're installing. conflicts: Optional[ConflictDetails] = None should_warn_about_conflicts = ( not options.ignore_dependencies and options.warn_about_conflicts ) if should_warn_about_conflicts: conflicts = self._determine_conflicts(to_install) # Don't warn about script install locations if # --target or --prefix has been specified warn_script_location = options.warn_script_location if options.target_dir or options.prefix_path: warn_script_location = False installed = install_given_reqs( to_install, install_options, global_options, root=options.root_path, home=target_temp_dir_path, prefix=options.prefix_path, warn_script_location=warn_script_location, use_user_site=options.use_user_site, pycompile=options.compile, ) lib_locations = get_lib_location_guesses( user=options.use_user_site, home=target_temp_dir_path, root=options.root_path, prefix=options.prefix_path, isolated=options.isolated_mode, ) env = get_environment(lib_locations) installed.sort(key=operator.attrgetter("name")) items = [] for result in installed: item = result.name try: installed_dist = env.get_distribution(item) if installed_dist is not None: item = f"{item}-{installed_dist.version}" except Exception: pass items.append(item) if conflicts is not None: self._warn_about_conflicts( conflicts, resolver_variant=self.determine_resolver_variant(options), ) installed_desc = " ".join(items) if installed_desc: write_output( "Successfully installed %s", installed_desc, ) except OSError as error: show_traceback = self.verbosity >= 1 message = create_os_error_message( error, show_traceback, options.use_user_site, ) logger.error(message, exc_info=show_traceback) # noqa return ERROR if options.target_dir: assert target_temp_dir self._handle_target_dir( options.target_dir, target_temp_dir, options.upgrade ) warn_if_run_as_root() return SUCCESS def _handle_target_dir( self, target_dir: str, target_temp_dir: TempDirectory, upgrade: bool ) -> None: ensure_dir(target_dir) # Checking both purelib and platlib directories for installed # packages to be moved to target directory lib_dir_list = [] # Checking both purelib and platlib directories for installed # packages to be moved to target directory scheme = get_scheme("", home=target_temp_dir.path) purelib_dir = scheme.purelib platlib_dir = scheme.platlib data_dir = scheme.data if os.path.exists(purelib_dir): lib_dir_list.append(purelib_dir) if os.path.exists(platlib_dir) and platlib_dir != purelib_dir: lib_dir_list.append(platlib_dir) if os.path.exists(data_dir): lib_dir_list.append(data_dir) for lib_dir in lib_dir_list: for item in os.listdir(lib_dir): if lib_dir == data_dir: ddir = os.path.join(data_dir, item) if any(s.startswith(ddir) for s in lib_dir_list[:-1]): continue target_item_dir = os.path.join(target_dir, item) if os.path.exists(target_item_dir): if not upgrade: logger.warning( "Target directory %s already exists. Specify " "--upgrade to force replacement.", target_item_dir, ) continue if os.path.islink(target_item_dir): logger.warning( "Target directory %s already exists and is " "a link. pip will not automatically replace " "links, please remove if replacement is " "desired.", target_item_dir, ) continue if os.path.isdir(target_item_dir): shutil.rmtree(target_item_dir) else: os.remove(target_item_dir) shutil.move(os.path.join(lib_dir, item), target_item_dir) def _determine_conflicts( self, to_install: List[InstallRequirement] ) -> Optional[ConflictDetails]: try: return check_install_conflicts(to_install) except Exception: logger.exception( "Error while checking for conflicts. Please file an issue on " "pip's issue tracker: https://github.com/pypa/pip/issues/new" ) return None def _warn_about_conflicts( self, conflict_details: ConflictDetails, resolver_variant: str ) -> None: package_set, (missing, conflicting) = conflict_details if not missing and not conflicting: return parts: List[str] = [] if resolver_variant == "legacy": parts.append( "pip's legacy dependency resolver does not consider dependency " "conflicts when selecting packages. This behaviour is the " "source of the following dependency conflicts." ) else: assert resolver_variant == "2020-resolver" parts.append( "pip's dependency resolver does not currently take into account " "all the packages that are installed. This behaviour is the " "source of the following dependency conflicts." ) # NOTE: There is some duplication here, with commands/check.py for project_name in missing: version = package_set[project_name][0] for dependency in missing[project_name]: message = ( "{name} {version} requires {requirement}, " "which is not installed." ).format( name=project_name, version=version, requirement=dependency[1], ) parts.append(message) for project_name in conflicting: version = package_set[project_name][0] for dep_name, dep_version, req in conflicting[project_name]: message = ( "{name} {version} requires {requirement}, but {you} have " "{dep_name} {dep_version} which is incompatible." ).format( name=project_name, version=version, requirement=req, dep_name=dep_name, dep_version=dep_version, you=("you" if resolver_variant == "2020-resolver" else "you'll"), ) parts.append(message) logger.critical("\n".join(parts)) def get_lib_location_guesses( user: bool = False, home: Optional[str] = None, root: Optional[str] = None, isolated: bool = False, prefix: Optional[str] = None, ) -> List[str]: scheme = get_scheme( "", user=user, home=home, root=root, isolated=isolated, prefix=prefix, ) return [scheme.purelib, scheme.platlib] def site_packages_writable(root: Optional[str], isolated: bool) -> bool: return all( test_writable_dir(d) for d in set(get_lib_location_guesses(root=root, isolated=isolated)) ) def decide_user_install( use_user_site: Optional[bool], prefix_path: Optional[str] = None, target_dir: Optional[str] = None, root_path: Optional[str] = None, isolated_mode: bool = False, ) -> bool: """Determine whether to do a user install based on the input options. If use_user_site is False, no additional checks are done. If use_user_site is True, it is checked for compatibility with other options. If use_user_site is None, the default behaviour depends on the environment, which is provided by the other arguments. """ # In some cases (config from tox), use_user_site can be set to an integer # rather than a bool, which 'use_user_site is False' wouldn't catch. if (use_user_site is not None) and (not use_user_site): logger.debug("Non-user install by explicit request") return False if use_user_site: if prefix_path: raise CommandError( "Can not combine '--user' and '--prefix' as they imply " "different installation locations" ) if virtualenv_no_global(): raise InstallationError( "Can not perform a '--user' install. User site-packages " "are not visible in this virtualenv." ) logger.debug("User install by explicit request") return True # If we are here, user installs have not been explicitly requested/avoided assert use_user_site is None # user install incompatible with --prefix/--target if prefix_path or target_dir: logger.debug("Non-user install due to --prefix or --target option") return False # If user installs are not enabled, choose a non-user install if not site.ENABLE_USER_SITE: logger.debug("Non-user install because user site-packages disabled") return False # If we have permission for a non-user install, do that, # otherwise do a user install. if site_packages_writable(root=root_path, isolated=isolated_mode): logger.debug("Non-user install because site-packages writeable") return False logger.info( "Defaulting to user installation because normal site-packages " "is not writeable" ) return True def reject_location_related_install_options( requirements: List[InstallRequirement], options: Optional[List[str]] ) -> None: """If any location-changing --install-option arguments were passed for requirements or on the command-line, then show a deprecation warning. """ def format_options(option_names: Iterable[str]) -> List[str]: return ["--{}".format(name.replace("_", "-")) for name in option_names] offenders = [] for requirement in requirements: install_options = requirement.install_options location_options = parse_distutils_args(install_options) if location_options: offenders.append( "{!r} from {}".format( format_options(location_options.keys()), requirement ) ) if options: location_options = parse_distutils_args(options) if location_options: offenders.append( "{!r} from command line".format(format_options(location_options.keys())) ) if not offenders: return raise CommandError( "Location-changing options found in --install-option: {}." " This is unsupported, use pip-level options like --user," " --prefix, --root, and --target instead.".format("; ".join(offenders)) ) def create_os_error_message( error: OSError, show_traceback: bool, using_user_site: bool ) -> str: """Format an error message for an OSError It may occur anytime during the execution of the install command. """ parts = [] # Mention the error if we are not going to show a traceback parts.append("Could not install packages due to an OSError") if not show_traceback: parts.append(": ") parts.append(str(error)) else: parts.append(".") # Spilt the error indication from a helper message (if any) parts[-1] += "\n" # Suggest useful actions to the user: # (1) using user site-packages or (2) verifying the permissions if error.errno == errno.EACCES: user_option_part = "Consider using the `--user` option" permissions_part = "Check the permissions" if not running_under_virtualenv() and not using_user_site: parts.extend( [ user_option_part, " or ", permissions_part.lower(), ] ) else: parts.append(permissions_part) parts.append(".\n") # Suggest the user to enable Long Paths if path length is # more than 260 if ( WINDOWS and error.errno == errno.ENOENT and error.filename and len(error.filename) > 260 ): parts.append( "HINT: This error might have occurred since " "this system does not have Windows Long Path " "support enabled. You can find information on " "how to enable this at " "https://pip.pypa.io/warnings/enable-long-paths\n" ) return "".join(parts).strip() + "\n" PKH]BI7python3.10/site-packages/pip/_internal/commands/show.pynu[import csv import logging import pathlib from optparse import Values from typing import Iterator, List, NamedTuple, Optional, Tuple from pip._vendor.packaging.utils import canonicalize_name from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import ERROR, SUCCESS from pip._internal.metadata import BaseDistribution, get_default_environment from pip._internal.utils.misc import write_output logger = logging.getLogger(__name__) class ShowCommand(Command): """ Show information about one or more installed packages. The output is in RFC-compliant mail header format. """ usage = """ %prog [options] ...""" ignore_require_venv = True def add_options(self) -> None: self.cmd_opts.add_option( "-f", "--files", dest="files", action="store_true", default=False, help="Show the full list of installed files for each package.", ) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options: Values, args: List[str]) -> int: if not args: logger.warning("ERROR: Please provide a package name or names.") return ERROR query = args results = search_packages_info(query) if not print_results( results, list_files=options.files, verbose=options.verbose ): return ERROR return SUCCESS class _PackageInfo(NamedTuple): name: str version: str location: str requires: List[str] required_by: List[str] installer: str metadata_version: str classifiers: List[str] summary: str homepage: str author: str author_email: str license: str entry_points: List[str] files: Optional[List[str]] def _convert_legacy_entry(entry: Tuple[str, ...], info: Tuple[str, ...]) -> str: """Convert a legacy installed-files.txt path into modern RECORD path. The legacy format stores paths relative to the info directory, while the modern format stores paths relative to the package root, e.g. the site-packages directory. :param entry: Path parts of the installed-files.txt entry. :param info: Path parts of the egg-info directory relative to package root. :returns: The converted entry. For best compatibility with symlinks, this does not use ``abspath()`` or ``Path.resolve()``, but tries to work with path parts: 1. While ``entry`` starts with ``..``, remove the equal amounts of parts from ``info``; if ``info`` is empty, start appending ``..`` instead. 2. Join the two directly. """ while entry and entry[0] == "..": if not info or info[-1] == "..": info += ("..",) else: info = info[:-1] entry = entry[1:] return str(pathlib.Path(*info, *entry)) def search_packages_info(query: List[str]) -> Iterator[_PackageInfo]: """ Gather details from installed distributions. Print distribution name, version, location, and installed files. Installed files requires a pip generated 'installed-files.txt' in the distributions '.egg-info' directory. """ env = get_default_environment() installed = {dist.canonical_name: dist for dist in env.iter_distributions()} query_names = [canonicalize_name(name) for name in query] missing = sorted( [name for name, pkg in zip(query, query_names) if pkg not in installed] ) if missing: logger.warning("Package(s) not found: %s", ", ".join(missing)) def _get_requiring_packages(current_dist: BaseDistribution) -> Iterator[str]: return ( dist.metadata["Name"] or "UNKNOWN" for dist in installed.values() if current_dist.canonical_name in {canonicalize_name(d.name) for d in dist.iter_dependencies()} ) def _files_from_record(dist: BaseDistribution) -> Optional[Iterator[str]]: try: text = dist.read_text("RECORD") except FileNotFoundError: return None # This extra Path-str cast normalizes entries. return (str(pathlib.Path(row[0])) for row in csv.reader(text.splitlines())) def _files_from_legacy(dist: BaseDistribution) -> Optional[Iterator[str]]: try: text = dist.read_text("installed-files.txt") except FileNotFoundError: return None paths = (p for p in text.splitlines(keepends=False) if p) root = dist.location info = dist.info_directory if root is None or info is None: return paths try: info_rel = pathlib.Path(info).relative_to(root) except ValueError: # info is not relative to root. return paths if not info_rel.parts: # info *is* root. return paths return ( _convert_legacy_entry(pathlib.Path(p).parts, info_rel.parts) for p in paths ) for query_name in query_names: try: dist = installed[query_name] except KeyError: continue requires = sorted((req.name for req in dist.iter_dependencies()), key=str.lower) required_by = sorted(_get_requiring_packages(dist), key=str.lower) try: entry_points_text = dist.read_text("entry_points.txt") entry_points = entry_points_text.splitlines(keepends=False) except FileNotFoundError: entry_points = [] files_iter = _files_from_record(dist) or _files_from_legacy(dist) if files_iter is None: files: Optional[List[str]] = None else: files = sorted(files_iter) metadata = dist.metadata yield _PackageInfo( name=dist.raw_name, version=str(dist.version), location=dist.location or "", requires=requires, required_by=required_by, installer=dist.installer, metadata_version=dist.metadata_version or "", classifiers=metadata.get_all("Classifier", []), summary=metadata.get("Summary", ""), homepage=metadata.get("Home-page", ""), author=metadata.get("Author", ""), author_email=metadata.get("Author-email", ""), license=metadata.get("License", ""), entry_points=entry_points, files=files, ) def print_results( distributions: Iterator[_PackageInfo], list_files: bool, verbose: bool, ) -> bool: """ Print the information from installed distributions found. """ results_printed = False for i, dist in enumerate(distributions): results_printed = True if i > 0: write_output("---") write_output("Name: %s", dist.name) write_output("Version: %s", dist.version) write_output("Summary: %s", dist.summary) write_output("Home-page: %s", dist.homepage) write_output("Author: %s", dist.author) write_output("Author-email: %s", dist.author_email) write_output("License: %s", dist.license) write_output("Location: %s", dist.location) write_output("Requires: %s", ", ".join(dist.requires)) write_output("Required-by: %s", ", ".join(dist.required_by)) if verbose: write_output("Metadata-Version: %s", dist.metadata_version) write_output("Installer: %s", dist.installer) write_output("Classifiers:") for classifier in dist.classifiers: write_output(" %s", classifier) write_output("Entry-points:") for entry in dist.entry_points: write_output(" %s", entry.strip()) if list_files: write_output("Files:") if dist.files is None: write_output("Cannot locate RECORD or installed-files.txt") else: for line in dist.files: write_output(" %s", line.strip()) return results_printed PKH]m((;python3.10/site-packages/pip/_internal/commands/download.pynu[import logging import os from optparse import Values from typing import List from pip._internal.cli import cmdoptions from pip._internal.cli.cmdoptions import make_target_python from pip._internal.cli.req_command import RequirementCommand, with_cleanup from pip._internal.cli.status_codes import SUCCESS from pip._internal.req.req_tracker import get_requirement_tracker from pip._internal.utils.misc import ensure_dir, normalize_path, write_output from pip._internal.utils.temp_dir import TempDirectory logger = logging.getLogger(__name__) class DownloadCommand(RequirementCommand): """ Download packages from: - PyPI (and other indexes) using requirement specifiers. - VCS project urls. - Local project directories. - Local or remote source archives. pip also supports downloading from "requirements files", which provide an easy way to specify a whole environment to be downloaded. """ usage = """ %prog [options] [package-index-options] ... %prog [options] -r [package-index-options] ... %prog [options] ... %prog [options] ... %prog [options] ...""" def add_options(self) -> None: self.cmd_opts.add_option(cmdoptions.constraints()) self.cmd_opts.add_option(cmdoptions.requirements()) self.cmd_opts.add_option(cmdoptions.no_deps()) self.cmd_opts.add_option(cmdoptions.global_options()) self.cmd_opts.add_option(cmdoptions.no_binary()) self.cmd_opts.add_option(cmdoptions.only_binary()) self.cmd_opts.add_option(cmdoptions.prefer_binary()) self.cmd_opts.add_option(cmdoptions.src()) self.cmd_opts.add_option(cmdoptions.pre()) self.cmd_opts.add_option(cmdoptions.require_hashes()) self.cmd_opts.add_option(cmdoptions.progress_bar()) self.cmd_opts.add_option(cmdoptions.no_build_isolation()) self.cmd_opts.add_option(cmdoptions.use_pep517()) self.cmd_opts.add_option(cmdoptions.no_use_pep517()) self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) self.cmd_opts.add_option( "-d", "--dest", "--destination-dir", "--destination-directory", dest="download_dir", metavar="dir", default=os.curdir, help="Download packages into .", ) cmdoptions.add_target_python_options(self.cmd_opts) index_opts = cmdoptions.make_option_group( cmdoptions.index_group, self.parser, ) self.parser.insert_option_group(0, index_opts) self.parser.insert_option_group(0, self.cmd_opts) @with_cleanup def run(self, options: Values, args: List[str]) -> int: options.ignore_installed = True # editable doesn't really make sense for `pip download`, but the bowels # of the RequirementSet code require that property. options.editables = [] cmdoptions.check_dist_restriction(options) options.download_dir = normalize_path(options.download_dir) ensure_dir(options.download_dir) session = self.get_default_session(options) target_python = make_target_python(options) finder = self._build_package_finder( options=options, session=session, target_python=target_python, ignore_requires_python=options.ignore_requires_python, ) req_tracker = self.enter_context(get_requirement_tracker()) directory = TempDirectory( delete=not options.no_clean, kind="download", globally_managed=True, ) reqs = self.get_requirements(args, options, finder, session) preparer = self.make_requirement_preparer( temp_build_dir=directory, options=options, req_tracker=req_tracker, session=session, finder=finder, download_dir=options.download_dir, use_user_site=False, ) resolver = self.make_resolver( preparer=preparer, finder=finder, options=options, ignore_requires_python=options.ignore_requires_python, py_version_info=options.python_version, ) self.trace_basic_info(finder) requirement_set = resolver.resolve(reqs, check_supported_wheels=True) downloaded: List[str] = [] for req in requirement_set.requirements.values(): if req.satisfied_by is None: assert req.name is not None preparer.save_linked_requirement(req) downloaded.append(req.name) if downloaded: write_output("Successfully downloaded %s", " ".join(downloaded)) return SUCCESS PKH]җ""@python3.10/site-packages/pip/_internal/commands/configuration.pynu[import logging import os import subprocess from optparse import Values from typing import Any, List, Optional from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import ERROR, SUCCESS from pip._internal.configuration import ( Configuration, Kind, get_configuration_files, kinds, ) from pip._internal.exceptions import PipError from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import get_prog, write_output logger = logging.getLogger(__name__) class ConfigurationCommand(Command): """ Manage local and global configuration. Subcommands: - list: List the active configuration (or from the file specified) - edit: Edit the configuration file in an editor - get: Get the value associated with name - set: Set the name=value - unset: Unset the value associated with name - debug: List the configuration files and values defined under them If none of --user, --global and --site are passed, a virtual environment configuration file is used if one is active and the file exists. Otherwise, all modifications happen to the user file by default. """ ignore_require_venv = True usage = """ %prog [] list %prog [] [--editor ] edit %prog [] get name %prog [] set name value %prog [] unset name %prog [] debug """ def add_options(self) -> None: self.cmd_opts.add_option( "--editor", dest="editor", action="store", default=None, help=( "Editor to use to edit the file. Uses VISUAL or EDITOR " "environment variables if not provided." ), ) self.cmd_opts.add_option( "--global", dest="global_file", action="store_true", default=False, help="Use the system-wide configuration file only", ) self.cmd_opts.add_option( "--user", dest="user_file", action="store_true", default=False, help="Use the user configuration file only", ) self.cmd_opts.add_option( "--site", dest="site_file", action="store_true", default=False, help="Use the current environment configuration file only", ) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options: Values, args: List[str]) -> int: handlers = { "list": self.list_values, "edit": self.open_in_editor, "get": self.get_name, "set": self.set_name_value, "unset": self.unset_name, "debug": self.list_config_values, } # Determine action if not args or args[0] not in handlers: logger.error( "Need an action (%s) to perform.", ", ".join(sorted(handlers)), ) return ERROR action = args[0] # Determine which configuration files are to be loaded # Depends on whether the command is modifying. try: load_only = self._determine_file( options, need_value=(action in ["get", "set", "unset", "edit"]) ) except PipError as e: logger.error(e.args[0]) return ERROR # Load a new configuration self.configuration = Configuration( isolated=options.isolated_mode, load_only=load_only ) self.configuration.load() # Error handling happens here, not in the action-handlers. try: handlers[action](options, args[1:]) except PipError as e: logger.error(e.args[0]) return ERROR return SUCCESS def _determine_file(self, options: Values, need_value: bool) -> Optional[Kind]: file_options = [ key for key, value in ( (kinds.USER, options.user_file), (kinds.GLOBAL, options.global_file), (kinds.SITE, options.site_file), ) if value ] if not file_options: if not need_value: return None # Default to user, unless there's a site file. elif any( os.path.exists(site_config_file) for site_config_file in get_configuration_files()[kinds.SITE] ): return kinds.SITE else: return kinds.USER elif len(file_options) == 1: return file_options[0] raise PipError( "Need exactly one file to operate upon " "(--user, --site, --global) to perform." ) def list_values(self, options: Values, args: List[str]) -> None: self._get_n_args(args, "list", n=0) for key, value in sorted(self.configuration.items()): write_output("%s=%r", key, value) def get_name(self, options: Values, args: List[str]) -> None: key = self._get_n_args(args, "get [name]", n=1) value = self.configuration.get_value(key) write_output("%s", value) def set_name_value(self, options: Values, args: List[str]) -> None: key, value = self._get_n_args(args, "set [name] [value]", n=2) self.configuration.set_value(key, value) self._save_configuration() def unset_name(self, options: Values, args: List[str]) -> None: key = self._get_n_args(args, "unset [name]", n=1) self.configuration.unset_value(key) self._save_configuration() def list_config_values(self, options: Values, args: List[str]) -> None: """List config key-value pairs across different config files""" self._get_n_args(args, "debug", n=0) self.print_env_var_values() # Iterate over config files and print if they exist, and the # key-value pairs present in them if they do for variant, files in sorted(self.configuration.iter_config_files()): write_output("%s:", variant) for fname in files: with indent_log(): file_exists = os.path.exists(fname) write_output("%s, exists: %r", fname, file_exists) if file_exists: self.print_config_file_values(variant) def print_config_file_values(self, variant: Kind) -> None: """Get key-value pairs from the file of a variant""" for name, value in self.configuration.get_values_in_config(variant).items(): with indent_log(): write_output("%s: %s", name, value) def print_env_var_values(self) -> None: """Get key-values pairs present as environment variables""" write_output("%s:", "env_var") with indent_log(): for key, value in sorted(self.configuration.get_environ_vars()): env_var = f"PIP_{key.upper()}" write_output("%s=%r", env_var, value) def open_in_editor(self, options: Values, args: List[str]) -> None: editor = self._determine_editor(options) fname = self.configuration.get_file_to_edit() if fname is None: raise PipError("Could not determine appropriate file.") try: subprocess.check_call([editor, fname]) except subprocess.CalledProcessError as e: raise PipError( "Editor Subprocess exited with exit code {}".format(e.returncode) ) def _get_n_args(self, args: List[str], example: str, n: int) -> Any: """Helper to make sure the command got the right number of arguments""" if len(args) != n: msg = ( "Got unexpected number of arguments, expected {}. " '(example: "{} config {}")' ).format(n, get_prog(), example) raise PipError(msg) if n == 1: return args[0] else: return args def _save_configuration(self) -> None: # We successfully ran a modifying command. Need to save the # configuration. try: self.configuration.save() except Exception: logger.exception( "Unable to save configuration. Please report this as a bug." ) raise PipError("Internal Error.") def _determine_editor(self, options: Values) -> str: if options.editor is not None: return options.editor elif "VISUAL" in os.environ: return os.environ["VISUAL"] elif "EDITOR" in os.environ: return os.environ["EDITOR"] else: raise PipError("Could not determine editor to use.") PKH]/# <python3.10/site-packages/pip/_internal/commands/uninstall.pynu[import logging from optparse import Values from typing import List from pip._vendor.packaging.utils import canonicalize_name from pip._internal.cli.base_command import Command from pip._internal.cli.req_command import SessionCommandMixin, warn_if_run_as_root from pip._internal.cli.status_codes import SUCCESS from pip._internal.exceptions import InstallationError from pip._internal.req import parse_requirements from pip._internal.req.constructors import ( install_req_from_line, install_req_from_parsed_requirement, ) from pip._internal.utils.misc import protect_pip_from_modification_on_windows logger = logging.getLogger(__name__) class UninstallCommand(Command, SessionCommandMixin): """ Uninstall packages. pip is able to uninstall most installed packages. Known exceptions are: - Pure distutils packages installed with ``python setup.py install``, which leave behind no metadata to determine what files were installed. - Script wrappers installed by ``python setup.py develop``. """ usage = """ %prog [options] ... %prog [options] -r ...""" def add_options(self) -> None: self.cmd_opts.add_option( "-r", "--requirement", dest="requirements", action="append", default=[], metavar="file", help=( "Uninstall all the packages listed in the given requirements " "file. This option can be used multiple times." ), ) self.cmd_opts.add_option( "-y", "--yes", dest="yes", action="store_true", help="Don't ask for confirmation of uninstall deletions.", ) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options: Values, args: List[str]) -> int: session = self.get_default_session(options) reqs_to_uninstall = {} for name in args: req = install_req_from_line( name, isolated=options.isolated_mode, ) if req.name: reqs_to_uninstall[canonicalize_name(req.name)] = req else: logger.warning( "Invalid requirement: %r ignored -" " the uninstall command expects named" " requirements.", name, ) for filename in options.requirements: for parsed_req in parse_requirements( filename, options=options, session=session ): req = install_req_from_parsed_requirement( parsed_req, isolated=options.isolated_mode ) if req.name: reqs_to_uninstall[canonicalize_name(req.name)] = req if not reqs_to_uninstall: raise InstallationError( f"You must give at least one requirement to {self.name} (see " f'"pip help {self.name}")' ) protect_pip_from_modification_on_windows( modifying_pip="pip" in reqs_to_uninstall ) for req in reqs_to_uninstall.values(): uninstall_pathset = req.uninstall( auto_confirm=options.yes, verbose=self.verbosity > 0, ) if uninstall_pathset: uninstall_pathset.commit() warn_if_run_as_root() return SUCCESS PKH]Xǫ//7python3.10/site-packages/pip/_internal/commands/list.pynu[import json import logging from optparse import Values from typing import TYPE_CHECKING, Iterator, List, Optional, Sequence, Tuple, cast from pip._vendor.packaging.utils import canonicalize_name from pip._internal.cli import cmdoptions from pip._internal.cli.req_command import IndexGroupCommand from pip._internal.cli.status_codes import SUCCESS from pip._internal.exceptions import CommandError from pip._internal.index.collector import LinkCollector from pip._internal.index.package_finder import PackageFinder from pip._internal.metadata import BaseDistribution, get_environment from pip._internal.models.selection_prefs import SelectionPreferences from pip._internal.network.session import PipSession from pip._internal.utils.compat import stdlib_pkgs from pip._internal.utils.misc import tabulate, write_output from pip._internal.utils.parallel import map_multithread if TYPE_CHECKING: from pip._internal.metadata.base import DistributionVersion class _DistWithLatestInfo(BaseDistribution): """Give the distribution object a couple of extra fields. These will be populated during ``get_outdated()``. This is dirty but makes the rest of the code much cleaner. """ latest_version: DistributionVersion latest_filetype: str _ProcessedDists = Sequence[_DistWithLatestInfo] logger = logging.getLogger(__name__) class ListCommand(IndexGroupCommand): """ List installed packages, including editables. Packages are listed in a case-insensitive sorted order. """ ignore_require_venv = True usage = """ %prog [options]""" def add_options(self) -> None: self.cmd_opts.add_option( "-o", "--outdated", action="store_true", default=False, help="List outdated packages", ) self.cmd_opts.add_option( "-u", "--uptodate", action="store_true", default=False, help="List uptodate packages", ) self.cmd_opts.add_option( "-e", "--editable", action="store_true", default=False, help="List editable projects.", ) self.cmd_opts.add_option( "-l", "--local", action="store_true", default=False, help=( "If in a virtualenv that has global access, do not list " "globally-installed packages." ), ) self.cmd_opts.add_option( "--user", dest="user", action="store_true", default=False, help="Only output packages installed in user-site.", ) self.cmd_opts.add_option(cmdoptions.list_path()) self.cmd_opts.add_option( "--pre", action="store_true", default=False, help=( "Include pre-release and development versions. By default, " "pip only finds stable versions." ), ) self.cmd_opts.add_option( "--format", action="store", dest="list_format", default="columns", choices=("columns", "freeze", "json"), help="Select the output format among: columns (default), freeze, or json", ) self.cmd_opts.add_option( "--not-required", action="store_true", dest="not_required", help="List packages that are not dependencies of installed packages.", ) self.cmd_opts.add_option( "--exclude-editable", action="store_false", dest="include_editable", help="Exclude editable package from output.", ) self.cmd_opts.add_option( "--include-editable", action="store_true", dest="include_editable", help="Include editable package from output.", default=True, ) self.cmd_opts.add_option(cmdoptions.list_exclude()) index_opts = cmdoptions.make_option_group(cmdoptions.index_group, self.parser) self.parser.insert_option_group(0, index_opts) self.parser.insert_option_group(0, self.cmd_opts) def _build_package_finder( self, options: Values, session: PipSession ) -> PackageFinder: """ Create a package finder appropriate to this list command. """ link_collector = LinkCollector.create(session, options=options) # Pass allow_yanked=False to ignore yanked versions. selection_prefs = SelectionPreferences( allow_yanked=False, allow_all_prereleases=options.pre, ) return PackageFinder.create( link_collector=link_collector, selection_prefs=selection_prefs, ) def run(self, options: Values, args: List[str]) -> int: if options.outdated and options.uptodate: raise CommandError("Options --outdated and --uptodate cannot be combined.") cmdoptions.check_list_path_option(options) skip = set(stdlib_pkgs) if options.excludes: skip.update(canonicalize_name(n) for n in options.excludes) packages: "_ProcessedDists" = [ cast("_DistWithLatestInfo", d) for d in get_environment(options.path).iter_installed_distributions( local_only=options.local, user_only=options.user, editables_only=options.editable, include_editables=options.include_editable, skip=skip, ) ] # get_not_required must be called firstly in order to find and # filter out all dependencies correctly. Otherwise a package # can't be identified as requirement because some parent packages # could be filtered out before. if options.not_required: packages = self.get_not_required(packages, options) if options.outdated: packages = self.get_outdated(packages, options) elif options.uptodate: packages = self.get_uptodate(packages, options) self.output_package_listing(packages, options) return SUCCESS def get_outdated( self, packages: "_ProcessedDists", options: Values ) -> "_ProcessedDists": return [ dist for dist in self.iter_packages_latest_infos(packages, options) if dist.latest_version > dist.version ] def get_uptodate( self, packages: "_ProcessedDists", options: Values ) -> "_ProcessedDists": return [ dist for dist in self.iter_packages_latest_infos(packages, options) if dist.latest_version == dist.version ] def get_not_required( self, packages: "_ProcessedDists", options: Values ) -> "_ProcessedDists": dep_keys = { canonicalize_name(dep.name) for dist in packages for dep in (dist.iter_dependencies() or ()) } # Create a set to remove duplicate packages, and cast it to a list # to keep the return type consistent with get_outdated and # get_uptodate return list({pkg for pkg in packages if pkg.canonical_name not in dep_keys}) def iter_packages_latest_infos( self, packages: "_ProcessedDists", options: Values ) -> Iterator["_DistWithLatestInfo"]: with self._build_session(options) as session: finder = self._build_package_finder(options, session) def latest_info( dist: "_DistWithLatestInfo", ) -> Optional["_DistWithLatestInfo"]: all_candidates = finder.find_all_candidates(dist.canonical_name) if not options.pre: # Remove prereleases all_candidates = [ candidate for candidate in all_candidates if not candidate.version.is_prerelease ] evaluator = finder.make_candidate_evaluator( project_name=dist.canonical_name, ) best_candidate = evaluator.sort_best_candidate(all_candidates) if best_candidate is None: return None remote_version = best_candidate.version if best_candidate.link.is_wheel: typ = "wheel" else: typ = "sdist" dist.latest_version = remote_version dist.latest_filetype = typ return dist for dist in map_multithread(latest_info, packages): if dist is not None: yield dist def output_package_listing( self, packages: "_ProcessedDists", options: Values ) -> None: packages = sorted( packages, key=lambda dist: dist.canonical_name, ) if options.list_format == "columns" and packages: data, header = format_for_columns(packages, options) self.output_package_listing_columns(data, header) elif options.list_format == "freeze": for dist in packages: if options.verbose >= 1: write_output( "%s==%s (%s)", dist.raw_name, dist.version, dist.location ) else: write_output("%s==%s", dist.raw_name, dist.version) elif options.list_format == "json": write_output(format_for_json(packages, options)) def output_package_listing_columns( self, data: List[List[str]], header: List[str] ) -> None: # insert the header first: we need to know the size of column names if len(data) > 0: data.insert(0, header) pkg_strings, sizes = tabulate(data) # Create and add a separator. if len(data) > 0: pkg_strings.insert(1, " ".join(map(lambda x: "-" * x, sizes))) for val in pkg_strings: write_output(val) def format_for_columns( pkgs: "_ProcessedDists", options: Values ) -> Tuple[List[List[str]], List[str]]: """ Convert the package data into something usable by output_package_listing_columns. """ header = ["Package", "Version"] running_outdated = options.outdated if running_outdated: header.extend(["Latest", "Type"]) has_editables = any(x.editable for x in pkgs) if has_editables: header.append("Editable project location") if options.verbose >= 1: header.append("Location") if options.verbose >= 1: header.append("Installer") data = [] for proj in pkgs: # if we're working on the 'outdated' list, separate out the # latest_version and type row = [proj.raw_name, str(proj.version)] if running_outdated: row.append(str(proj.latest_version)) row.append(proj.latest_filetype) if has_editables: row.append(proj.editable_project_location or "") if options.verbose >= 1: row.append(proj.location or "") if options.verbose >= 1: row.append(proj.installer) data.append(row) return data, header def format_for_json(packages: "_ProcessedDists", options: Values) -> str: data = [] for dist in packages: info = { "name": dist.raw_name, "version": str(dist.version), } if options.verbose >= 1: info["location"] = dist.location or "" info["installer"] = dist.installer if options.outdated: info["latest_version"] = str(dist.latest_version) info["latest_filetype"] = dist.latest_filetype editable_project_location = dist.editable_project_location if editable_project_location: info["editable_project_location"] = editable_project_location data.append(info) return json.dumps(data) PKH]AC;python3.10/site-packages/pip/_internal/commands/__init__.pynu[""" Package containing all pip commands """ import importlib from collections import namedtuple from typing import Any, Dict, Optional from pip._internal.cli.base_command import Command CommandInfo = namedtuple("CommandInfo", "module_path, class_name, summary") # This dictionary does a bunch of heavy lifting for help output: # - Enables avoiding additional (costly) imports for presenting `--help`. # - The ordering matters for help display. # # Even though the module path starts with the same "pip._internal.commands" # prefix, the full path makes testing easier (specifically when modifying # `commands_dict` in test setup / teardown). commands_dict: Dict[str, CommandInfo] = { "install": CommandInfo( "pip._internal.commands.install", "InstallCommand", "Install packages.", ), "download": CommandInfo( "pip._internal.commands.download", "DownloadCommand", "Download packages.", ), "uninstall": CommandInfo( "pip._internal.commands.uninstall", "UninstallCommand", "Uninstall packages.", ), "freeze": CommandInfo( "pip._internal.commands.freeze", "FreezeCommand", "Output installed packages in requirements format.", ), "list": CommandInfo( "pip._internal.commands.list", "ListCommand", "List installed packages.", ), "show": CommandInfo( "pip._internal.commands.show", "ShowCommand", "Show information about installed packages.", ), "check": CommandInfo( "pip._internal.commands.check", "CheckCommand", "Verify installed packages have compatible dependencies.", ), "config": CommandInfo( "pip._internal.commands.configuration", "ConfigurationCommand", "Manage local and global configuration.", ), "search": CommandInfo( "pip._internal.commands.search", "SearchCommand", "Search PyPI for packages.", ), "cache": CommandInfo( "pip._internal.commands.cache", "CacheCommand", "Inspect and manage pip's wheel cache.", ), "index": CommandInfo( "pip._internal.commands.index", "IndexCommand", "Inspect information available from package indexes.", ), "wheel": CommandInfo( "pip._internal.commands.wheel", "WheelCommand", "Build wheels from your requirements.", ), "hash": CommandInfo( "pip._internal.commands.hash", "HashCommand", "Compute hashes of package archives.", ), "completion": CommandInfo( "pip._internal.commands.completion", "CompletionCommand", "A helper command used for command completion.", ), "debug": CommandInfo( "pip._internal.commands.debug", "DebugCommand", "Show information useful for debugging.", ), "help": CommandInfo( "pip._internal.commands.help", "HelpCommand", "Show help for commands.", ), } def create_command(name: str, **kwargs: Any) -> Command: """ Create an instance of the Command class with the given name. """ module_path, class_name, summary = commands_dict[name] module = importlib.import_module(module_path) command_class = getattr(module, class_name) command = command_class(name=name, summary=summary, **kwargs) return command def get_similar_commands(name: str) -> Optional[str]: """Command name auto-correct.""" from difflib import get_close_matches name = name.lower() close_commands = get_close_matches(name, commands_dict.keys()) if close_commands: return close_commands[0] else: return None PKH]1Rpython3.10/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-310.pycnu[o ai@sddlZddlZddlZddlZddlmZddlmZmZm Z m Z m Z m Z ddl mZddlmZddlmZeeZejdededfd d Zejded fd d ZGdd d ZdS)N) TracebackType)DictIteratorOptionalSetTypeUnion)Link)InstallRequirement) TempDirectorychangesreturnc kstj}t}i}|D]\}}z||||<Wn ty&|||<Ynw|||<q z"dVW|D]\}}||urA||=q5t|tsHJ|||<q5dS|D]\}}||ur_||=qSt|tsfJ|||<qSwN)osenvironobjectitemsKeyError isinstancestr)r targetnon_existent_marker saved_valuesname new_valueoriginal_valuer/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/req/req_tracker.pyupdate_env_context_managers0     rRequirementTrackerc cstjd}tC}|dur'|tddj}|t|dt d|t | }|VWdn1s9wYWddSWddS1sQwYdS)NPIP_REQ_TRACKERz req-tracker)kind)r z Initialized build tracking at %s) rrget contextlib ExitStack enter_contextr pathrloggerdebugr)rootctxtrackerrrrget_requirement_tracker)s    "r,c@seZdZdeddfddZdddZdeeed eed ee ddfd d Z d e defddZ de ddfddZde ddfddZdddZejde dedfddZdS)rr)r NcCs ||_t|_td|jdS)NzCreated build tracker: %s)_rootset_entriesr'r()selfr)rrr__init__7szRequirementTracker.__init__cCstd|j|S)NzEntered build tracker: %s)r'r(r-)r0rrr __enter__<szRequirementTracker.__enter__exc_typeexc_valexc_tbcCs |dSr)cleanup)r0r3r4r5rrr__exit__@s zRequirementTracker.__exit__linkcCs$t|j}tj|j|Sr) hashlibsha224url_without_fragmentencode hexdigestrr&joinr-)r0r8hashedrrr _entry_pathHszRequirementTracker._entry_pathreqcCs|jsJ||j}zt| }|}Wdn1swYWn ty.Yn wd|j|}t|||jvsAJt|ddd}|t |Wdn1sZwY|j |t d||j dS)z,Add an InstallRequirement to build tracking.Nz{} is already being built: {}wzutf-8)encodingzAdded %s to build tracker %r)r8r@openreadFileNotFoundErrorformat LookupErrorr/writeraddr'r(r-)r0rA entry_pathfpcontentsmessagerrrrJLs$      zRequirementTracker.addcCs<|jsJt||j|j|td||jdS)z1Remove an InstallRequirement from build tracking.z Removed %s from build tracker %rN) r8runlinkr@r/remover'r(r-r0rArrrrPhs  zRequirementTracker.removecCs,t|jD]}||qtd|jdS)NzRemoved build tracker: %r)r.r/rPr'r(r-rQrrrr6rs zRequirementTracker.cleanupccs ||dV||dSr)rJrPrQrrrtrackxs zRequirementTracker.track)r r)r N)__name__ __module__ __qualname__rr1r2rr BaseExceptionrr7r r@r rJrPr6r#contextmanagerrrRrrrrr6s$    )r#r9loggingrtypesrtypingrrrrrrpip._internal.models.linkr pip._internal.req.req_installr pip._internal.utils.temp_dirr getLoggerrSr'rWrrr,rrrrrs       PKH]P P Opython3.10/site-packages/pip/_internal/req/__pycache__/__init__.cpython-310.pycnu[o ai @sddlZddlZddlmZmZmZmZmZddlm Z ddl m Z ddl m Z ddlmZgdZeeZGd d d Zd ee d eeee ffd dZd ee deedeedeedeedeedededed eefddZdS)N)IteratorListOptionalSequenceTuple) indent_log)parse_requirements)InstallRequirement)RequirementSet)r r r install_given_reqsc@s,eZdZdeddfddZdefddZdS)InstallationResultnamereturnNcCs ||_dS)Nr)selfrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/req/__init__.py__init__s zInstallationResult.__init__cCsd|jdS)NzInstallationResult(name=)r)rrrr__repr__szInstallationResult.__repr__)__name__ __module__ __qualname__strrrrrrrr sr requirementsrccs0|D]}|jsJd||j|fVqdS)Nz%invalid to-be-installed requirement: r)rreqrrr_validate_requirementss rinstall_optionsglobal_optionsroothomeprefixwarn_script_location use_user_site pycompilec  Cstt|} | rtdd| g} th| D]Z\} } | j rEtd| t| j dd} Wdn1s?wYnd} z| j ||||||||dWnt yg| rf| j sf| w| rq| j rq| | t| qWd| S1swY| S)zu Install everything in the given list. (to be called after having downloaded and unpacked the packages) z!Installing collected packages: %sz, zAttempting uninstall: %sT) auto_confirmN)r r!r"r#r$r%) collections OrderedDictrloggerinfojoinkeysritemsshould_reinstall uninstallinstall Exceptioninstall_succeededrollbackcommitappendr )rrrr r!r"r#r$r% to_install installedreq_name requirementuninstalled_pathsetrrrr %sP     r )r'loggingtypingrrrrrpip._internal.utils.loggingrreq_filer req_installr req_setr __all__ getLoggerrr)r rrboolr rrrrsH        PKH]#`Npython3.10/site-packages/pip/_internal/req/__pycache__/req_set.cpython-310.pycnu[o ai@sddlZddlmZddlmZmZmZmZmZddl m Z ddl m Z ddl mZddlmZddlmZeeZGd d d ZdS) N) OrderedDict)DictIterableListOptionalTuple)canonicalize_name)InstallationError)Wheel)InstallRequirement)compatibility_tagsc @seZdZddeddfddZdefddZdefd d Zd eddfd d Z d eddfddZ  dd ede ede e ede eee effddZdedefddZdedefddZedeefddZdS)RequirementSetTcheck_supported_wheelsreturnNcCst|_||_g|_dS)zCreate a RequirementSet.N)r requirementsrunnamed_requirements)selfrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/req/req_set.py__init__s zRequirementSet.__init__cCs4tdd|jDddd}ddd|DS)Ncss|]}|js|VqdSN) comes_from.0reqrrr z)RequirementSet.__str__..cSt|jpdSNrnamerrrrz(RequirementSet.__str__..key cs|]}t|jVqdSrstrrrrrrrr)sortedrvaluesjoin)rrrrr__str__s zRequirementSet.__str__cCsBt|jddd}d}|j|jjt|ddd|DdS) NcSrrr r"rrrr#"r$z)RequirementSet.__repr__..r%z4<{classname} object; {count} requirement(s): {reqs}>z, csr(rr)rrrrr)rz*RequirementSet.__repr__..) classnamecountreqs)r+rr,format __class____name__lenr-)rr format_stringrrr__repr__szRequirementSet.__repr__ install_reqcCs|jrJ|j|dSr)r!rappend)rr8rrradd_unnamed_requirement,s z&RequirementSet.add_unnamed_requirementcCs"|jsJt|j}||j|<dSr)r!rr)rr8 project_namerrradd_named_requirement0s  z$RequirementSet.add_named_requirementparent_req_nameextras_requestedc Cs||std|j|jgdfS|jr3|jjr3t|jj}t }|j r3| |s3t d|j|jr>|dus>Jd|jsK|||gdfSz||j}Wn ty^d}Ynw|duo||o||j o||j|jko||jo||jo||jj|jjk}|rt d|||j|s|||g|fS|js|jsg|fS|jo|jo|jj|jjk }|rt d|jd|_|jrd|_ttt|jt|jB|_td ||j|g|fS) a&Add install_req as a requirement to install. :param parent_req_name: The name of the requirement that needed this added. The name is used because when multiple unnamed requirements resolve to the same name, we could otherwise end up with dependency links that point outside the Requirements set. parent_req must already be added. Note that None implies that this is a user supplied requirement, vs an inferred one. :param extras_requested: an iterable of extras used to evaluate the environment markers. :return: Additional requirements to scan. That is either [] if the requirement is not applicable, or [install_req] if the requirement is applicable and has just been added. z6Ignoring %s: markers '%s' don't match your environmentNz-{} is not a supported wheel on this platform.z+a user supplied req shouldn't have a parentz7Double requirement given: {} (already in {}, name={!r})zhCould not satisfy constraints for '{}': installation from path or url cannot be constrained to a versionFTzSetting %s extras to: %s) match_markersloggerinfor!markerslinkis_wheelr filenamer get_supportedr supportedr r2 user_suppliedr:get_requirementKeyError constraintextrasr specifierr<pathtupler+setdebug) rr8r=r>wheeltags existing_reqhas_conflicting_requirementdoes_not_satisfy_constraintrrradd_requirement6s            zRequirementSet.add_requirementr!cCs t|}||jvo|j|j Sr)rrrKrr!r;rrrhas_requirements  zRequirementSet.has_requirementcCs*t|}||jvr|j|Std|)NzNo project with the name )rrrJrXrrrrIs  zRequirementSet.get_requirementcCs|jt|jSr)rlistrr,)rrrrall_requirementsszRequirementSet.all_requirements)T)NN)r4 __module__ __qualname__boolrr*r.r7r r:r<rrrrrWrYrIpropertyr[rrrrr s*    ur )logging collectionsrtypingrrrrrpip._vendor.packaging.utilsrpip._internal.exceptionsr pip._internal.models.wheelr pip._internal.req.req_installr pip._internal.utilsr getLoggerr4r@r rrrrs       PKH]OkIITpython3.10/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-310.pycnu[o ai\ @sddlZddlZddlZddlZddlZddlmZddlmZm Z m Z m Z m Z m Z mZmZmZddlmZddlmZddlmZddlmZmZddlmZdd lmZdd lmZm Z dd l!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(dd l)m*Z*m+Z+ee,Z-d ede.de/de e.fddZ0de de efde de effddZ1e1d ede e.fddZ2de e.dee.fddZ3de e.dee.fddZ4de e.deee.ee.ffddZ5Gd d!d!Z6Gd"d#d#Z7Gd$d%d%Z8dS)&N)cache_from_source) AnyCallableDictIterableIteratorListOptionalSetTuple) pkg_resources) Distribution)UninstallationError)get_bin_prefix get_bin_user)WINDOWS)egg_link_path_from_location) getLogger indent_log)askdist_in_usersite dist_is_localis_localnormalize_pathrenamesrmtree)AdjacentTempDirectory TempDirectorydist script_nameis_guireturncCsrt|rt}nt}tj||}|g}tr7||d||d|r0||d|S||d|S)zCreate the fully qualified name of the files created by {console,gui}_scripts for the given ``dist``. Returns the list of file names z.exez .exe.manifestz -script.pywz -script.py)rrrospathjoinrappend)rrr bin_direxe_namepaths_to_remover)/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/req/req_uninstall.py _script_namessr+fn.cs,tdtdtdttffdd }|S)Nargskwr!c?s8t}|i|D]}||vr|||Vq dSN)setadd)r-r.seenitemr,r)r*unique5s z_unique..unique) functoolswrapsrr)r,r5r)r4r*_unique4s r8c cs.z t|d}WnLtyW}z@dj|d}zt|d}|r'|dkr*tWntttfyFd|j |j }|d|7}Ynw|d|7}t ||d }~ww|D]:}t j |j|d }|V|d rt j |\}} | d d } t j || d }|Vt j || d}|VqZd S)a Yield all the uninstallation paths for dist based on RECORD-without-.py[co] Yield paths to all the files in RECORD. For each .py file in RECORD, add the .pyc and .pyo in the same directory. UninstallPathSet.add() takes care of the __pycache__ .py[co]. If RECORD is not found, raises UninstallationError, with possible information from the INSTALLER file. https://packaging.python.org/specifications/recording-installed-packages/ RECORDz/Cannot uninstall {dist}, RECORD file not found.)r INSTALLERpipz{}=={}zZ You might be able to recover from this via: 'pip install --force-reinstall --no-deps {}'.z' Hint: The package was installed by {}.Nr.py.pyc.pyo)csvreaderget_metadata_linesFileNotFoundErrorformatnext ValueErrorOSError StopIteration project_nameversionrr"r#r$locationendswithsplit) rrmissing_record_exceptionmsg installerdeprowr#dnr,baser)r)r*uninstallation_paths@sB     rVpathscsJtjjt}t|tdD]tfdd|D}|s"|q |S)zCompact a path set to contain the minimal number of paths necessary to contain all paths in the set. If /a/path/ and /a/path/to/a/file.txt are both in the set, leave only the shorter path.keyc3s<|]}|dot|dkVqdS)*N) startswithrstriplen).0 shortpathr#sepr)r* us  zcompact..)r"r#rar0sortedr]anyr1)rW short_paths should_skipr)r`r*compactls rgc sdd|D}t|}tdd|Dtd}t}dtdtfdd |D]Ltfd d |Dr4q&t}t}tD]!\}}|fd d |D|fd d |Dq?||sr| || tj q&tt |j ||BS)zReturns a set containing the paths that need to be renamed. This set may include directories when the original sequence of paths included every file on disk. cSsi|] }tj||qSr))r"r#normcaser^pr)r)r* z'compress_for_rename..cSsh|] }tj|dqS)r)r"r#rMrir)r)r* sz&compress_for_rename..rXar!cWstjtjj|Sr/)r"r#rhr$)rnr)r)r* norm_joinsz&compress_for_rename..norm_joinc3s"|] }tj|VqdSr/)r"r#rhr[)r^w)rootr)r*rbs z&compress_for_rename..c3|] }|VqdSr/r))r^ddirnamerorqr)r*rbc3rrr/r))r^frtr)r*rbrv)r0rcvaluesr]strrdr"walkupdatedifference_updater1ramap __getitem__) rWcase_map remaining unchecked wildcards all_files all_subdirssubdirsfilesr)rtr*compress_for_renames$ rc Cst|}t}t}t}|D]}|drq|ds d|vr)|tj|||qtttjj|}t|}|D]2}t |D]*\}} } | D]"} | drTqLtj || } tj | rntj| |vrn|| qLqEq>|dd|DB}||fS)asReturns a tuple of 2 sets of which paths to display to user The first set contains paths that would be deleted. Files of a package are not added and the top-level directory of the package has a '*' added at the end - to signify that all it's contents are removed. The second set contains files that would have been skipped in the above folders. r>z __init__.py .dist-infocSsh|] }tj|dqS)rZ)r"r#r$)r^folderr)r)r*rmrlz.compress_for_output_listing..) r0rLr1r"r#rur}rhrgrzr$isfile) rW will_remove will_skipfoldersrr#_normcased_filesrdirpath_dirfilesfnamefile_r)r)r*compress_for_output_listings6       rc@sveZdZdZdddZdedefddZdedefd d Zdedefd d Zdd dZ dddZ e de fddZ dS)StashedUninstallPathSetzWA set of file rename operations to stash files while tentatively uninstalling them.r!NcCsi|_g|_dSr/) _save_dirs_movesselfr)r)r*__init__s z StashedUninstallPathSet.__init__r#cCsBzt|}Wntytdd}Ynw||jtj|<|jS)zStashes a directory. Directories are stashed adjacent to their original location if possible, or else moved/copied into the user's temp dir. uninstallkind)rrGrrr"r#rh)rr#save_dirr)r)r*_get_directory_stashs  z,StashedUninstallPathSet._get_directory_stashcCstj|}tj|d}}d}||kr3z|j|}Wn&ty%Ynwtj||}}||kstj|}tdd}||j|<tj||}|rZ|tjjkrZtj |j|S|jS)zStashes a file. If no root has been provided, one will be created for the directory in the user's temp directory.Nrr) r"r#rhrurKeyErrorrrelpathcurdirr$)rr#headold_headrrr)r)r*_get_file_stashs&     z'StashedUninstallPathSet._get_file_stashcCsltj|o tj| }|r||}n||}|j||f|r/tj|r/t|t |||S)zStashes the directory or file and returns its new location. Handle symlinks as files to avoid modifying the symlink targets. ) r"r#isdirislinkrrrr%rmdirr)rr# path_is_dirnew_pathr)r)r*stashs    zStashedUninstallPathSet.stashcCs,|jD]\}}|qg|_i|_dS)z0Commits the uninstall by removing stashed files.N)ritemscleanupr)rrrr)r)r*commits  zStashedUninstallPathSet.commitc Cs|jD] }tjdg|Rq|jD]L\}}z*td||tj|s*tj|r0t|n tj |r:t |t ||Wqt y^}zt d|td|WYd}~qd}~ww|dS)z2Undoes the uninstall by moving stashed files back.zMoving to %s from %szReplacing %s from %szFailed to restore %sz Exception: %sN)rloggerinfodebugr"r#rrunlinkrrrrGerrorr)rrjrr#exr)r)r*rollback$s     z StashedUninstallPathSet.rollbackcCs t|jSr/)boolrrr)r)r* can_rollback7s z$StashedUninstallPathSet.can_rollbackr!N)__name__ __module__ __qualname____doc__rryrrrrrpropertyrrr)r)r)r*rs   rc@seZdZdZdeddfddZdedefdd Zdeddfd d Z d ed eddfddZ ddededdfddZ dedefddZ dddZ dddZededdfddZdS)UninstallPathSetzMA set of file paths to be removed in the uninstallation of a requirement.rr!NcCs(t|_t|_i|_||_t|_dSr/)r0rW_refusepthrr _moved_paths)rrr)r)r*r@s  zUninstallPathSet.__init__r#cCst|S)zs Return True if the given path is one we are permitted to remove/modify, False otherwise. )r)rr#r)r)r* _permittedGszUninstallPathSet._permittedcCstj|\}}tjt|tj|}tj|sdS||r)|j |n|j |tj |ddkrB| t |dSdS)Nr<) r"r#rMr$rrhexistsrrWr1rsplitextr)rr#rtailr)r)r*r1Os   zUninstallPathSet.addpth_fileentrycCsNt|}||r||jvrt||j|<|j||dS|j|dSr/)rrrUninstallPthEntriesr1r)rrrr)r)r*add_pthbs   zUninstallPathSet.add_pthF auto_confirmverbosecCs|js td|jjdS|jjd|jj}td|tF|s(||r^|j}t |j}t t |D] }| |t d|q6|jD]}|qItd|WddSWddS1siwYdS)z[Remove paths in ``self.paths`` with confirmation (unless ``auto_confirm`` is True).z7Can't uninstall '%s'. No files were found to uninstall.N-zUninstalling %s:zRemoving file or directory %szSuccessfully uninstalled %s)rWrrrrIrJr_allowed_to_proceedrrrcrgrrrrxremove)rrrdist_name_versionmoved for_renamer#rr)r)r*rks*    "zUninstallPathSet.removecCsdtdttddfdd}|st|j\}}nt|j}t}|d||d||d |j|r9|d t|jtd d d kS)z@Display which files would be deleted and prompt for confirmationrPrWr!NcSsZ|sdSt|ttt|D]}t|qWddS1s&wYdSr/)rrrrcrg)rPrWr#r)r)r*_displays  "z6UninstallPathSet._allowed_to_proceed.._displayz Would remove:z+Would not remove (might be manually added):z%Would not remove (outside of prefix):zWill actually move:zProceed (Y/n)? )ynr)ryrrrWr0rrr)rrrrrr)r)r*rs     z$UninstallPathSet._allowed_to_proceedcCsR|jjstd|jjdStd|jj|j|j D]}|q dS)z1Rollback the changes previously made by remove().z'Can't roll back %s; was not uninstalledNzRolling back uninstall of %s) rrrrrrIrrrrx)rrr)r)r*rs  zUninstallPathSet.rollbackcCs|jdS)z?Remove temporary save dir: rollback will no longer be possible.N)rrrr)r)r*rszUninstallPathSet.commitcst|j}t|std|j|tj||S|ddt dt dhDvr4td|j|||S||}t |j }d t |j }|joOtj|j}t|jdd}|r|jd r|j|s||j|d r|d D]}tjtj|j|} || qwn|d r|d r|d ngfd d|d DD]$} tj|j| } || || d|| d|| dqn|rtd |j |jdr||jtj|jd} tjtj|jd} || d| nk|r|jdrt |D]} || qnS|rjt!|} tj"| #$}Wdn 1s.stdlib platstdlibzsz.UninstallPathSet.from_dist..r<r>r?zCannot uninstall {!r}. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.z.eggrzeasy-install.pthz./rz;Egg-link {} does not match installed location of {} (at {})z)Not sure how to uninstall: %s - Check: %sscriptsz.batconsole_scripts)groupF gui_scriptsT)0rrKrrrrYsysprefix sysconfigget_pathrrIrDr to_filenameegg_infor"r#rgetattr _providerrLr1 has_metadata get_metadata splitlinesnormpathr$rrMrurrVopenrhreadlinestriprmetadata_isdirmetadata_listdirrrrr get_entry_mapkeysextendr+)clsr dist_pathr(develop_egg_linkdevelop_egg_link_egg_infoegg_info_existsdistutils_egg_infoinstalled_filer# top_level_pkgeasy_install_eggeasy_install_pthfh link_pointerscriptr&_scripts_to_removernamersr)rr* from_dists                          zUninstallPathSet.from_dist)FFr)rrrrr rryrrr1rrrrr classmethodrr)r)r)r*r<s   rc@sHeZdZdeddfddZdeddfddZd d d Zdefd d ZdS)rrr!NcCs||_t|_d|_dSr/)filer0entries _saved_lines)rrr)r)r*rCs zUninstallPthEntries.__init__rcCs<tj|}trtj|ds|dd}|j|dS)Nr\/)r"r#rhr splitdrivereplacerr1)rrr)r)r*r1Hs  zUninstallPthEntries.addc Cs0td|jtj|jstd|jdSt|jd}|}||_ Wdn1s/wYt dd|Dr@d}nd}|rY|d | d sY|d| d |d<|j D]}ztd |||| d Wq\tyyYq\wt|jd }||WddS1swYdS) NzRemoving pth entries from %s:z.Cannot remove entries from nonexistent file %srbcss|]}d|vVqdS)s Nr))r^liner)r)r*rbbsz-UninstallPthEntries.remove..z  zutf-8zRemoving entry: %swb)rrrr"r#rwarningr readlinesrrdrLencoderrrF writelines)rrlinesendlinerr)r)r*rWs.    "zUninstallPthEntries.removecCsh|jdurtd|jdStd|jt|jd}||jWddS1s-wYdS)Nz.Cannot roll back changes to %s, none were madeFz!Rolling %s back to previous staterT)rrrrrrr)rrr)r)r*rrs  zUninstallPthEntries.rollbackr) rrrryrr1rrrr)r)r)r*rBs  r)9r@r6r"rrimportlib.utilrtypingrrrrrrr r r pip._vendorr pip._vendor.pkg_resourcesr pip._internal.exceptionsrpip._internal.locationsrrpip._internal.utils.compatrpip._internal.utils.egg_linkrpip._internal.utils.loggingrrpip._internal.utils.miscrrrrrrrpip._internal.utils.temp_dirrrrrryrr+r8rVrgrrrrrr)r)r)r*s: ,     $ * +&"2iPKH]744Opython3.10/site-packages/pip/_internal/req/__pycache__/req_file.cpython-310.pycnu[o ai D@s^UdZddlZddlZddlZddlZddlZddlmZddlm Z m Z m Z m Z m Z mZmZmZmZddlmZddlmZmZddlmZddlmZdd lmZdd lmZdd lm Z e rmdd lm!Z!dd l"m#Z#dgZ$e ee%e&fZ'e e&gee&effZ(e)dej*Z+e)dZ,e)dZ-ej.ej/ej0ej1ej2ej3ej4ej5ej6ej7ej8ej9ej:ej;gZd<ej?ej@ejAgZBee dej=fe>d<ddeBDZCGdddZDGdddZE   dDde&dededd eejd!eFd"eeDf d#dZGd$e&d"e'fd%d&ZH dEd'eEd eejd"eDfd(d)ZI   dFd*ede&d+e%dedd eejdeed"dfd,d-ZJ   dFd'eEd eejdeddeed"eeDf d.d/ZKGd0d1d1ZLdedd"e(fd2d3ZMd'e&d"ee&e&ffd4d5ZNGd6d7d7eOZPd"ejQfd8d9ZRd:e'd"e'fd;d<ZSd:e'd"e'fd=d>ZTd:e'd"e'fd?d@ZUdAe&ded"ee&e&ffdBdCZVdS)Gz Requirements file parsing N)Values) TYPE_CHECKINGAnyCallableDictIterableIteratorListOptionalTuple) cmdoptions)InstallationErrorRequirementsFileParseError) SearchScope) PipSession)raise_for_status) auto_decode)get_url_scheme)NoReturn) PackageFinderparse_requirementsz^(http|https|file):z (^|\s+)#.*$z#(?P\$\{(?P[A-Z0-9_]+)\}).SUPPORTED_OPTIONSSUPPORTED_OPTIONS_REQcCsg|]}t|jqS)strdest).0orr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/req/req_file.py Nsrc@sHeZdZ  d dededededeeeefdeeddfd d ZdS) ParsedRequirementN requirement is_editable comes_from constraintoptions line_sourcereturncCs(||_||_||_||_||_||_dSN)r!r"r#r%r$r&)selfr!r"r#r$r%r&rrr__init__Rs   zParsedRequirement.__init__)NN) __name__ __module__ __qualname__rboolr rrr*rrrrr Qs$r c @s.eZdZdedededededdf dd ZdS) ParsedLinefilenamelinenoargsoptsr$r'NcCs^||_||_||_||_|rd|_d|_||_dS|jr*d|_d|_|jd|_dSd|_dS)NTFr)r0r1r3r$is_requirementr"r! editables)r)r0r1r2r3r$rrrr*ds  zParsedLine.__init__)r+r,r-rintrr.r*rrrrr/csr/Fr0sessionfinderrr%r$r'c csHt|}t||}|||D]}t||||d}|dur!|VqdS)aqParse a requirements file and yield ParsedRequirement instances. :param filename: Path or url of requirements file. :param session: PipSession instance. :param finder: Instance of pip.index.PackageFinder. :param options: cli options. :param constraint: If true, parsing a constraint file rather than requirements file. )r%r8r7N)get_line_parserRequirementsFileParserparse handle_line) r0r7r8r%r$ line_parserparser parsed_line parsed_reqrrrr~s contentcCs,t|dd}t|}t|}t|}|S)zxSplit, filter, and join lines, and return a line iterator :param content: the content of the requirements file )start) enumerate splitlines join_linesignore_commentsexpand_env_variables)rA lines_enumrrr preprocesss rJlinecCsd|jrdnd|j|j}|jsJ|jr!t|j|j||jdS|r*t ||j i}t D]}||j j vrD|j j |rD|j j |||<q.d|jd|j}t|j|j||j||dS)Nz{} {} (line {})z-cz-r)r!r"r#r$line  of )r!r"r#r$r%r&) formatr$r0r1r4r"r r!r check_install_build_globalr3SUPPORTED_OPTIONS_REQ_DEST__dict__)rKr%line_comes_from req_optionsrr&rrrhandle_requirement_lines:  rTr3r1cs8r|jr |j_|jrjfdd|jD|r|j}|j}|jr)|jg}|jdur0g}|jr9||j|jr_|jd}tj tj |} tj | |} tj | rZ| }|||rf||t||d} | |_|jrv||jr}||r|jpgD]} d|d|} |j| | dqdSdSdS) Nc3s|] }|jvr|VqdSr()features_enabled)rfr%rr sz%handle_option_line..Tr) find_links index_urlsrLrM)source)require_hashesrUextendrYrZ index_urlno_indexextra_index_urlsospathdirnameabspathjoinexistsappendupdate_index_urlsr search_scopepreset_allow_all_prereleases prefer_binaryset_prefer_binary trusted_hostsadd_trusted_host)r3r0r1r8r%r7rYrZvaluereq_dirrelative_to_reqs_filerihostr[rrWrhandle_option_linesR       $rtcCs0|jr t||}|St|j|j|j|||dS)aHandle a single parsed requirements line; This can result in creating/yielding requirements, or updating the finder. :param line: The parsed line to be processed. :param options: CLI options. :param finder: The finder - updated by non-requirement lines. :param session: The session - updated by non-requirement lines. Returns a ParsedRequirement object if the line is a requirement line, otherwise returns None. For lines that contain requirements, the only options that have an effect are from SUPPORTED_OPTIONS_REQ, and they are scoped to the requirement. Other options from SUPPORTED_OPTIONS may be present, but are ignored. For lines that do not contain requirements, the only options that have an effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may be present, but are ignored. These lines may contain multiple options (although our docs imply only one is supported), and all our parsed and affect the finder. N)r4rTrtr3r0r1)rKr%r8r7r@rrrr<s r<c@speZdZdededdfddZdededee fd d Z dededee fd d Z dededee fd dZ dS)r:r7r=r'NcCs||_||_dSr()_session _line_parser)r)r7r=rrrr*<s zRequirementsFileParser.__init__r0r$ccs|||EdHdS)z*Parse a given file, yielding parsed lines.N)_parse_and_recurse)r)r0r$rrrr;DszRequirementsFileParser.parseccs|||D]L}|jsP|jjs|jjrP|jjr!|jjd}d}n|jjd}d}t|r6tj ||}nt|sFt j t j ||}|||EdHq|VqdS)NrFT) _parse_filer4r3 requirements constraints SCHEME_REsearchurllibr;urljoinrarbrercrw)r)r0r$rKreq_pathnested_constraintrrrrwHs,     z)RequirementsFileParser._parse_and_recursec cst||j\}}t|}|D]0\}}z ||\}} Wnty5} z d|d| j} t| d} ~ wwt|||| |VqdS)NzInvalid requirement:  )get_file_contentrurJrvOptionParsingErrormsgrr/) r)r0r$_rArI line_numberrKargs_strr3errrrrxgs& z"RequirementsFileParser._parse_file) r+r,r-r LineParserr*rr.rr/r;rwrxrrrrr:;s"  r:cs"dtdtttfffdd }|S)NrKr'csJt}|}d|_rj|_t|\}}|t||\}}||fSr() build_parserget_default_valuesr^format_controlbreak_args_options parse_argsshlexsplit)rKr>defaultsr options_strr3rr8rr parse_line~s z#get_line_parser..parse_line)rr r)r8rrrrr9}sr9cCsd|d}g}|dd}|D]}|ds|drn |||dqd|d|fS)zBreak up the line into an args and options string. We only want to shlex (and then optparse) the options, not the args. args can contain markers which are corrupted by shlex.  N-z--r)r startswithrgpopre)rKtokensr2r%tokenrrrrs    rc@seZdZdeddfddZdS)rrr'NcCs ||_dSr()rr)rrrrr*s zOptionParsingError.__init__)r+r,r-rr*rrrrrsrcCsNtjdd}tt}|D] }|}||q dtdtddfdd}||_|S) z7 Return a parser for parsing requirement lines F)add_help_optionr)rr'rcSst|r()rrrrr parser_exitsz!build_parser..parser_exit)optparse OptionParserrr add_optionrrexit)r>option_factoriesoption_factoryoptionrrrrrs  rrIccsd}g}|D]A\}}|drt|r`_. Valid characters in variable names follow the `POSIX standard `_ and are limited to uppercase letter, digits and the `_` (underscore). N) ENV_VAR_REfindallragetenvreplace)rIrrKenv_varvar_namerprrrrHs   rHurlc Cst|}|dvr||}t||j|jfSz%t|d}t|}Wdn 1s.wYW||fSW||fStyO}zt d|d}~ww)aGets the content of a file; it may be a filename, file: URL, or http: URL. Returns (location, content). Content is unicode. Respects # -*- coding: declarations on the retrieved files. :param url: File path or url. :param session: PipSession instance. )httphttpsfilerbNz"Could not open requirements file: ) rgetrrtextopenrreadOSErrorr )rr7schemeresprVrAexcrrrrs    r)NNFr()NNN)W__doc__rrarer urllib.parser}rtypingrrrrrrr r r pip._internal.clir pip._internal.exceptionsr r!pip._internal.models.search_scoperpip._internal.network.sessionrpip._internal.network.utilsrpip._internal.utils.encodingrpip._internal.utils.urlsrr"pip._internal.index.package_finderr__all__r6r ReqFileLinesrcompileIr{rrr^extra_index_urlr_rzryeditablerY no_binary only_binaryrlr\rj trusted_hostuse_new_featurerOption__annotations__install_optionsglobal_optionshashrrPr r/r.rrJrTrtr<r:r9r ExceptionrrrrFrGrHrrrrrs ,            1 ? ,B "PKH].\yYyYRpython3.10/site-packages/pip/_internal/req/__pycache__/req_install.cpython-310.pycnu[o aiJ@sDddlZddlZddlZddlZddlZddlZddlZddlmZm Z m Z m Z m Z m Z mZmZddlmZddlmZddlmZddlmZddlmZddlmZdd lmZdd lmZdd l m!Z!dd l"m#Z#m$Z$dd l%m&Z&ddl'm(Z(ddl)m*Z*ddl+m,Z,ddl-m.Z.ddl/m,Z0ddl1m2Z3ddl4m5Z5ddl4m6Z7ddl8m9Z9ddl:m;Z;mZ>ddl?m@Z@ddlAmBZBmCZCddlDmEZEddlFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOddlPmQZQddlRmSZSddlTmUZUmVZVddlWmXZXdd lYmZZZe[e\Z]d!e^d"e!fd#d$Z_Gd%d&d&Z`d'e`d"e^fd(d)ZadS)*N)Any CollectionDictIterableListOptionalSequenceUnion) pkg_resources)Marker) Requirement) SpecifierSet)canonicalize_name)Version)parse)Pep517HookCaller) Distribution)BuildEnvironmentNoOpBuildEnvironment)InstallationError) get_scheme)Link)generate_metadata)generate_editable_metadata)install_editable)LegacyInstallFailure)install) install_wheel)load_pyproject_tomlmake_pyproject_path)UninstallPathSet) deprecated)direct_url_for_editabledirect_url_from_link)Hashes) ask_path_exists backup_dir display_pathdist_in_install_pathdist_in_site_packagesdist_in_usersiteget_distributionhide_urlredact_auth_from_url) get_metadata)runner_with_spinner_message) TempDirectory tempdir_kinds)running_under_virtualenv)vcsmetadata_directoryreturncCs|tj}tj|\}}t||}|dr%tj}tj |d}n|ds,Jtj }tj |ddd}||||dS)zQReturn a pkg_resources.Distribution for the provided metadata directory. z .egg-inforz .dist-info-) project_namemetadata) rstriposseppathsplitr PathMetadataendswithrsplitextDistInfoDistribution)r4dist_dirbase_dir dist_dir_namer8dist_cls dist_namerG/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/req/req_install.py _get_distBs   rIc@s.eZdZdZ            dhdeedeeedfdedee d ee d eed ed ee ed ee edee ee efdede edededdfddZdefddZdefddZdefddZedeefddZedefddZedefd d!Zedefd"d#Zdid$eeedefd%d&Zedefd'd(Zdjd*edefd+d,Zdeefd-d.Zd/ed0ed1edefd2d3Z dkd4d5Z!dkd6d7Z"d8eddfd9d:Z#edefd;d<Z$edefd=d>Z%edefd?d@Z&edefdAdBZ'edefdCdDZ(dkdEdFZ)dkdGdHZ*dkdIdJZ+ede,fdKdLZ-de.fdMdNZ/dkdOdPZ0  dldQed0ed1eddfdRdSZ1dkdTdUZ2 dldVedWedee3fdXdYZ4dZed[ed\edefd]d^Z5d/eeddfd_d`Z6     )  )dmd e ed ee7edaeedbeedceedded8edeeddfdfdgZ8dS)nInstallRequirementz Represents something that may be installed later on, may have information about where to fetch the relevant requirement and also contains logic for installing the said requirement. FNrGreq comes_fromeditablelinkmarkers use_pep517isolatedinstall_optionsglobal_options hash_options constraintextras user_suppliedpermit_editable_wheelsr5cCs|dus t|ts J|||_||_| |_||_||_d|_d|_|jr8|s)J|j r8t j t j |j|_|durF|rF|jrFt|j}||_|_d|_d|_|jr^|jj r^|jj|_| rd| |_n|rpdd|jD|_nt|_|dur}|r}|j}||_d|_d|_d|_d|_|r|ng|_| r| ng|_| r| ni|_d|_ | |_!||_"t#|_$d|_%d|_&g|_'d|_(||_)d|_*dS)NFcSsh|]}t|qSrG)r safe_extra.0extrarGrGrH sz.InstallRequirement.__init__..)+ isinstancer rKrLrUrMrXlegacy_install_reason source_diris_filer:r<normpathabspath file_pathurlrrN original_linkoriginal_link_is_in_wheel_cachelocal_file_pathrVsetmarkerrO satisfied_byshould_reinstall_temp_build_dirinstall_succeededrRrSrTpreparedrWrQr build_envr4pyproject_requiresrequirements_to_checkpep517_backendrPneeds_more_preparation)selfrKrLrMrNrOrPrQrRrSrTrUrVrWrXrGrGrH__init__csX     zInstallRequirement.__init__cCs|jrt|j}|jr|dt|jj7}n |jr!t|jj}nd}|jdur3|dt|jj7}|j rOt |j tr@|j }n|j }|rO|d|d7}|S)Nz from {}zz in {}z (from )) rKstrrNformatr-rerkr'locationrLr^ from_pathrusrLrGrGrH__str__s"    zInstallRequirement.__str__cCsd|jjt||jS)Nz<{} object: {} editable={!r}>)ry __class____name__rxrMrurGrGrH__repr__szInstallRequirement.__repr__cs>t|t}fddt|D}dj|jjd|dS)z5An un-tested helper for getting state, for debugging.c3s |] }d||VqdS)z{}={!r}N)ry)r[attr attributesrGrH sz2InstallRequirement.format_debug..z<{name} object: {{{state}}}>z, )namestate)varssortedryrrjoin)runamesrrGrrH format_debugszInstallRequirement.format_debugcCs|jdurdSt|jjSN)rKr safe_namerrrGrGrHrs zInstallRequirement.namec Cs|jsdS|js J|j1td}|j|d|jvWdWdS1s1wYWddS1sAwYdS)NFz1Checking if build backend supports build_editablebuild_editable)rPrsrpr/subprocess_runner_supported_features)rurunnerrGrGrHsupports_pyproject_editables  "z.InstallRequirement.supports_pyproject_editablecCs|jjSr)rK specifierrrGrGrHrszInstallRequirement.specifiercCs$|j}t|dkott|jdvS)zReturn whether I am pinned to an exact version. For example, some-package==1.2 is pinned; some-package>1.2 is not. >=====)rlennextiteroperator)ru specifiersrGrGrH is_pinnedszInstallRequirement.is_pinnedextras_requestedcs,|sd}jdurtfdd|DSdS)N)c3s |] }jd|iVqdS)r\N)rOevaluaterZrrGrHrs z3InstallRequirement.match_markers..T)rOany)rurrGrrH match_markerss  z InstallRequirement.match_markerscC t|jS)zReturn whether any known-good hashes are specified as options. These activate --require-hashes mode; hashes specified as part of a URL do not. )boolrTrrGrGrHhas_hash_optionss z#InstallRequirement.has_hash_optionsTtrust_internetcCsB|j}|r |jn|j}|r|jr||jg|jt|S)aReturn a hash-comparer that considers my option- and URL-based hashes to be known-good. Hashes in URLs--ones embedded in the requirements file, not ones downloaded from an index server--are almost peers with ones from flags. They satisfy --require-hashes (whether it was implicitly or explicitly activated) but do not activate it. md5 and sha224 are not allowed in flags, which should nudge people toward good algos. We always OR all hashes together, even ones from URLs. :param trust_internet: Whether to trust URL-based (#md5=...) hashes downloaded from the internet, as by populate_link() ) rTcopyrNrfhash setdefault hash_nameappendr$)rur good_hashesrNrGrGrHhashes's  zInstallRequirement.hashescCsP|jdurdSt|j}|jr&t|jtr|j}n|j}|r&|d|7}|S)z8Format a nice indicator to show where this "comes from" Nz->)rKrxrLr^r{r|rGrGrHr{<s     zInstallRequirement.from_path build_dir autodeleteparallel_buildscCs|dusJ|jdur|jjsJ|jjS|jdur&ttjdd|_|jjSt|j}|r7|dt j }t j |sHt d|t |t j||}|rSdnd}t||tjddjS)NT)kindglobally_managed_zCreating directory %sF)r<deleterr)rmr<rKr0r1 REQ_BUILDrruuiduuid4hexr:existsloggerdebugmakedirsr)rurrrdir_nameactual_build_dir delete_argrGrGrHensure_build_locationJs2         z(InstallRequirement.ensure_build_locationcCsn|jdusJ|jdusJ|jdusJtt|jdtr"d}nd}td|jd||jdg|_dS)z*Set requirement after generating metadata.NrrrrName)rKr8r`r^ parse_versionrr r)ruoprGrGrH_set_requirementus z#InstallRequirement._set_requirementcCsDt|jd}t|jj|krdStd|j||jt||_dS)NrzeGenerating metadata for package %s produced metadata for project name %s. Fix your #egg=%s fragments.)rr8rKrrwarningr )ru metadata_namerGrGrHwarn_on_mismatching_namesz+InstallRequirement.warn_on_mismatching_name use_user_sitecCs|jdurdSt|jj}|sdS|j}|duo |jjj|dd}|sQd|_|rFt|r1d|_dSt rBt |rDt d |j |jdSdSt|rOd|_dSdS|jr\d|_d|_dS||_dS)zFind an installed distribution that satisfies or conflicts with this requirement, and set self.satisfied_by or self.should_reinstall appropriately. NT) prereleaseszVWill not install to the user site because it will lack sys.path precedence to {} in {})rKr+rversionrcontainsrkr*rlr2r)rryr7rzr(rM)rur existing_distexisting_versionversion_compatiblerGrGrHcheck_if_existss>      z"InstallRequirement.check_if_existscCs|jsdS|jjS)NF)rNis_wheelrrGrGrHrszInstallRequirement.is_wheelcCstj|j|jr |jjp dS)Nr)r:r<rr`rNsubdirectory_fragmentrrGrGrHunpacked_source_directorysz,InstallRequirement.unpacked_source_directorycC(|js Jd|tj|jd}|S)NNo source dir for zsetup.pyr`r:r<rr)rusetup_pyrGrGrH setup_py_pathz InstallRequirement.setup_py_pathcCr)Nrz setup.cfgr)ru setup_cfgrGrGrHsetup_cfg_pathrz!InstallRequirement.setup_cfg_pathcCs|js Jd|t|jS)Nr)r`rrrrGrGrHpyproject_toml_paths z&InstallRequirement.pyproject_toml_pathcCs^t|j|j|jt|}|durd|_dSd|_|\}}}}||_||_t|j||d|_ dS)aALoad the pyproject.toml file. After calling this routine, all of the attributes related to PEP 517 processing for this requirement have been set. In particular, the use_pep517 attribute can be used to determine whether we should follow the PEP 517 or legacy (setup.py) code path. NFT) backend_path) rrPrrrxrrrqrrrs)rupyproject_toml_datarequiresbackendcheckrrGrGrHrs  z&InstallRequirement.load_pyproject_tomlcCsT|jr |jr"|s$tj|js&tj|js(td|ddSdSdSdSdS)zCheck that an editable requirement if valid for use with PEP 517/518. This verifies that an editable that has a pyproject.toml either supports PEP 660 or as a setup.py or a setup.cfg zProject z has a 'pyproject.toml' and its build backend is missing the 'build_editable' hook. Since it does not have a 'setup.py' nor a 'setup.cfg', it cannot be installed in editable mode. Consider using a build backend that supports PEP 660.N) rMrPrr:r<isfilerrrrrGrGrHisolated_editable_sanity_checks   z1InstallRequirement.isolated_editable_sanity_checkcCs|jsJ|jr-|jdusJ|jr#|jr#|r#t|j|jd|_nt |j|jd|_nt |j|j |j |j |jp>d|jd|_|jsJ|n||dS)zEnsure that project metadata is available. Under PEP 517 and PEP 660, call the backend hook to prepare the metadata. Under legacy processing, call setup.py egg-info. N)rprzfrom )rprr`rQdetails)r`rPrsrMrXrrrpr4rgenerate_metadata_legacyrrrQrrNrrassert_source_matches_versionrrGrGrHprepare_metadatas8     z#InstallRequirement.prepare_metadatacCst|ds t||_|jS)N _metadata)hasattrr.get_distrrrGrGrHr8Bs zInstallRequirement.metadatacCrr)rIr4rrGrGrHrIs zInstallRequirement.get_distcCsT|jsJ|jd}|jjr||jjvrtd||dStdt|j||dS)Nrz'Requested %s, but installing version %sz;Source in %s has version %s, which satisfies requirement %s)r`r8rKrrrrr')rurrGrGrHrLs  z0InstallRequirement.assert_source_matches_version parent_dircCs$|jdur|j|||d|_dSdS)aAEnsure that a source_dir is set. This will create a temporary build dir if the name of the requirement isn't known yet. :param parent_dir: The ideal pip parent_dir for the source_dir. Generally src_dir for editables and build_dir for sdists. :return: self.source_dir N)rr)r`r)rurrrrGrGrHensure_has_source_dir^s  z(InstallRequirement.ensure_has_source_dircCs|js td|jdS|jsJ|jsJ|jjdkrdSt|jj}|s0Jd|jjt |jj}|j |j|ddS)Nz>Cannot update repository at %s; repository location is unknownfilezUnsupported VCS URL )re) rNrrr`rMschemer3get_backend_for_schemerer,obtain)ru vcs_backend hidden_urlrGrGrHupdate_editableus    z"InstallRequirement.update_editable auto_confirmverbosecCsR|jsJt|jj}|std|jdStd|t|}||||S)a Uninstall the distribution currently satisfying this requirement. Prompts before removing or modifying files unless ``auto_confirm`` is True. Refuses to delete or modify files outside of ``sys.prefix`` - thus uninstallation within a virtual environment can only modify that virtual environment, even if the virtualenv is linked to global site-packages. z#Skipping %s as it is not installed.NzFound existing installation: %s) rKr+rrrinfor from_distremove)rurrdistuninstalled_pathsetrGrGrH uninstalls     zInstallRequirement.uninstallr< parentdirrootdircCs<dtdtdtfdd}tj||}|||}|jd|S)Nrprefixr5cSsN||tjjsJd|d||t|dd}|tjjd}|S)Nzname z doesn't start with prefix r/) startswithr:r<r;rreplace)rrrGrGrH_clean_zip_names z=InstallRequirement._get_archive_name.._clean_zip_namer)rxr:r<rr)rur<rrrrrGrGrH_get_archive_names z$InstallRequirement._get_archive_namecCs|jsJ|dur dSd}d|j|jd}tj||}tj|rjtdt |d}|dkr5d}n5|d krGt d t |t |n#|d krat |}t d t |t |t||n |d krjtd|sndStj|d tjdd}|Utjtj|j}t|D]<\} } } | D]} |j| | |d} t| d}d|_||dq| D]}|j|| |d}tj| |}|||qqWdn1swYt dt |dS)z}Saves archive to provided build_dir. Used for saving downloaded VCS requirements as part of `pip download`. NTz {}-{}.ziprz8The file {} exists. (i)gnore, (w)ipe, (b)ackup, (a)bort )iwbarFrz Deleting %srzBacking up %s to %sr) allowZip64)rrrirzSaved %s)r`ryrr8r:r<rrr%r'rrrr&shutilmovesysexitzipfileZipFile ZIP_DEFLATEDnormcasercrwalkrZipInfo external_attrwritestrwriter)rurcreate_archive archive_name archive_pathresponse dest_file zip_outputdirdirpathdirnames filenamesdirname dir_arcnamezipdirfilename file_arcnamerGrGrHarchivesv     zInstallRequirement.archiveroothomerwarn_script_location pycompilec Cst|j||||j|d} |dur|ng}|jr2|js2t||||||j|j|j|j|jd d|_ dS|jrh|j s:Jd} |jrEt |j} n |j rQt |j |j|j} t|j|j | t|j||| |jdd|_ dSt||j}t||j}zt|||||||| |j|j|j|j|jt|jd} Wnty} zd|_ | jd} ~ wtyd|_ w| |_ | r|jdkrtd|jd ddd dSdSdS) N)userr(r'rQr)rr(rrrrQrprT)rreq_descriptionr*r) direct_url requested)rRrSr'r(rrr*rrrQreq_namerprr,Fi zg{} was installed using the legacy 'setup.py install' method, because a wheel could not be built for it.z+to fix the wheel build issue reported abovereason replacementgone_inissue)rrrQrMrinstall_editable_legacyrrprrnrhr"rfr#r`rgrrxrKrWlistrSrRinstall_legacyr __cause__ Exceptionr_r!ry) rurRrSr'r(rr)rr*rr-successexcrGrGrHrs          zInstallRequirement.install) FNNNFNNNFrGFFr)T)r5N)FF)NNNNTFT)9r __module__ __qualname____doc__rr r rxrrr rrrrvr~rrpropertyr functools lru_cacherr rrrrrr$rr{rrrrrrrrrrrrrr8rrrrrr rrr&rrrGrGrGrHrJ\s       j     + .   )    F   rJrKcCs>d}|jsd}n |jrd}n|jrd}|rtddddd|S) Nrz3Unnamed requirements are not allowed as constraintsz4Editable requirements are not allowed as constraintszConstraints cannot have extrasaConstraints are only allowed to take the form of a package name and a version specifier. Other forms were originally permitted as an accident of the implementation, but were undocumented. The new implementation of the resolver no longer supports these forms.z+replacing the constraint with a requirementi r0)rrMrVr!)rKproblemrGrGrHcheck_invalid_constraint_typebsrC)br@loggingr:r r rrtypingrrrrrrrr pip._vendorr Zpip._vendor.packaging.markersr Z"pip._vendor.packaging.requirementsr Z pip._vendor.packaging.specifiersr pip._vendor.packaging.utilsrZpip._vendor.packaging.versionrrrZpip._vendor.pep517.wrappersrpip._vendor.pkg_resourcesrpip._internal.build_envrrpip._internal.exceptionsrpip._internal.locationsrpip._internal.models.linkr'pip._internal.operations.build.metadatar0pip._internal.operations.build.metadata_editabler.pip._internal.operations.build.metadata_legacyr0pip._internal.operations.install.editable_legacyrr5'pip._internal.operations.install.legacyrrr7&pip._internal.operations.install.wheelrpip._internal.pyprojectrrpip._internal.req.req_uninstallr pip._internal.utils.deprecationr!&pip._internal.utils.direct_url_helpersr"r#pip._internal.utils.hashesr$pip._internal.utils.miscr%r&r'r(r)r*r+r,r-pip._internal.utils.packagingr.pip._internal.utils.subprocessr/pip._internal.utils.temp_dirr0r1pip._internal.utils.virtualenvr2pip._internal.vcsr3 getLoggerrrrxrIrJrCrGrGrGrHsb(                      ,     PKH]Ou6T,,Spython3.10/site-packages/pip/_internal/req/__pycache__/constructors.cpython-310.pycnu[o ai;@s dZddlZddlZddlZddlmZmZmZmZm Z m Z ddl m Z ddl mZmZddlmZddlmZmZddlmZdd lmZmZdd lmZdd lmZdd lmZdd l m!Z!ddl"m#Z#ddl$m%Z%ddl&m'Z'ddl(m)Z)ddl*m+Z+m,Z,gdZ-e.e/Z0ej12Z3de4de e4ee4ffddZ5dee4dee4fddZ6de4de ee4e4ee4ffddZ7de4de4fdd Z8Gd!d"d"Z9de4de9fd#d$Z:   %  % % %dCde4d&ee e!e4fd'ee;d(e;d)eee4efd*e;d+e;d,e;de!fd-d.Zd/e4d4ee4de9fd5d6Z?   %  %  %dDd/e4d&ee e4e!fd'ee;d(e;d)eee4efd*e;d4ee4d+e;de!fd7d8Z@  %  %dEd9e4d&ee!d(e;d'ee;d+e;de!f d:d;ZA %  %dFdZBd?ed@e!de!fdAdBZCdS)Ga~Backing implementation for InstallRequirement's various constructors The idea here is that these formed a major chunk of InstallRequirement's size so, moving them and support code dedicated to them outside of that class helps creates for better understandability for the rest of the code. These are meant to be used elsewhere within pip to create instances of InstallRequirement. N)AnyDictOptionalSetTupleUnion)Marker)InvalidRequirement Requirement) Specifier)RequirementParseErrorparse_requirements)InstallationError)PyPITestPyPI)Link)Wheel)ParsedRequirement)InstallRequirement)is_archive_file)is_installable_dir)get_requirement) path_to_url)is_urlvcs)install_req_from_editableinstall_req_from_lineparse_editablepathreturncCs<td|}d}|r|d}|d}||fS|}||fS)Nz^(.+)(\[[^\]]+\])$)rematchgroup)rmextraspath_no_extrasr(/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/req/constructors.py _strip_extras+s   r*r&cCs|stStd|jS)N placeholder)setrlowerr&)r&r(r(r)convert_extras7sr. editable_reqcCs|}t|\}}tj|rt|}|dr2t|j}|r,||t d|j fS||t fSt D]}||drI|d|}nq4t|}|j sadt j}t|d|d|j}|smtd|||t fS) aParses an editable requirement into: - a requirement name - an URL - extras - editable options Accepted requirements: svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir .[some_extra] zfile:r+:+z, zq is not a valid editable requirement. It should either be a path to a local project or a VCS URL (beginning with z).zZCould not detect requirement name for '{}', please specify one with #egg=your_package_name)r*osrisdirrr- startswithr egg_fragmentrr&r,ris_vcsjoin all_schemesrformat)r/url url_no_extrasr& package_nameversion_controllinkbackendsr(r(r)r=s@      rreqcCsd}tj|rEd}z(t|}tt||d|7}WdW|S1s+wYW|StyDt j d|ddY|Sw|d|d 7}|S) zReturns helpful msg in case requirements file does not exist, or cannot be parsed. :params req: Requirements file path z The path does exist. zThe argument you provided ({}) appears to be a requirements file. If that is the case, use the '-r' flag to install the packages specified within it.Nz&Cannot parse '%s' as requirements fileT)exc_infoz File 'z' does not exist.) r2rexistsopennextr readr9r loggerdebug)r@msgfpr(r(r)deduce_helpful_msgts(    rKc @s6eZdZdeedeedeedeefddZ dS)RequirementParts requirementr>markersr&cCs||_||_||_||_dSN)rMr>rNr&)selfrMr>rNr&r(r(r)__init__s zRequirementParts.__init__N) __name__ __module__ __qualname__rr rrrstrrQr(r(r(r)rLsrLcCs\t|\}}}|dur!zt|}Wnty td|dwd}t|}t||d|S)NInvalid requirement: '')rr r rrrL)r/namer:extras_overrider@r>r(r(r)parse_req_from_editables  rZF comes_from use_pep517isolatedoptions constraint user_suppliedpermit_editable_wheelsc Cs`t|}t|j||d||j||||r|dgng|r!|dgng|r*|dini|jd S)NTinstall_optionsglobal_optionshashes) r[r`editablerar>r_r\r]rbrc hash_optionsr&)rZrrMr>getr&) r/r[r\r]r^r_r`rapartsr(r(r)rs  rrXcCs>tjj|vrdStjjdurtjj|vrdS|drdSdS)akChecks whether the string "looks like" a path on the filesystem. This does not check whether the target actually exists, only judge from the appearance. Returns true if any of the following conditions is true: * a path separator is found (either os.path.sep or os.path.altsep); * a dot is found (which represents the current directory). TN.F)r2rsepaltsepr4)rXr(r(r)_looks_like_paths  rlcCst|rtj|rt|rt|Std|dt|s dStj|r*t|S| dd}t |dkr>t|ds>dSt d|t|S) aK First, it checks whether a provided path is an installable directory. If it is, returns the path. If false, check if the path is an archive file (such as a .whl). The function checks if the path is a file. If false, if the path has an @, it will treat it as a PEP 440 URL requirement and return the path. z Directory zC is not installable. Neither 'setup.py' nor 'pyproject.toml' found.N@r r!rzARequirement %r looks like a filename, but the file does not exist) rlr2rr3rrrrisfilesplitlenrGwarning)rrX urlreq_partsr(r(r)_get_url_from_paths$    rs line_sourcecslt|rd}nd}||vr#||d\}}|}|sd}nt|}nd}|}d}tjtj|}d}d}t|rBt|}nt |\} }t | |} | durUt| }|r|j dkrrt d|jrrtttjtj|j}|jrt|j} | jd| j}n|j}n|}t|} dtdtffd d d tdtffd d } |dur| |}nd}t|||| S)Nz; ;r filez\.\./z==textrcss|S|ddS)Nz (from )r()rw)rtr(r) with_source4sz(parse_req_from_line..with_source req_as_stringcszt}Wn>tyDtjjvrd}|t7}ndvr.tfddtDs.d}nd}d}|r@|d|7}t|w|j D]}t |}| d r]d |d }t|qH|S) NzIt looks like a path.=c3s|]}|vVqdSrOr().0oprzr(r) @s zAparse_req_from_line.._parse_req_string..z,= is not a valid operator. Did you mean == ?rAzInvalid requirement: z Hint: ]zExtras after version 'z'.) rr r2rrjrKany operatorsr specifierrUendswith)rzr@add_msgrIspecspec_str)ryr~r)_parse_req_string9s.      z.parse_req_from_line.._parse_req_string)rrostriprr2rnormpathabspathrr*rsschemer"searchr:ris_wheelrfilenamerXversionr5r.rUr rL)rXrt marker_sepmarkers_as_stringrNrzrr>extras_as_stringpr:wheelr&rr@r()rtryr)parse_req_from_linesH      rc Csbt||}t|j||j|j|||r|dgng|r |dgng|r)|dini||j|d S)aCreates an InstallRequirement from a name, which might be a requirement, directory containing 'setup.py', filename, or URL. :param line_source: An optional string describing where the line is from, for logging purposes in case of an error. rbrcrd) r>rNr\r]rbrcrfr_r&r`)rrrMr>rNrgr&) rXr[r\r]r^r_rtr`rhr(r(r)r^s r req_stringcCsxzt|}Wntytd|dwtjtjg}|jr3|r3|jr3|jj|vr3td |j |t |||||dS)NrVrWzkPackages installed from PyPI cannot depend on packages which are not also hosted on PyPI. {} depends on {} )r]r\r`) rr rrfile_storage_domainrr:r>netlocr9rXr)rr[r]r\r`r@domains_not_allowedr(r(r)install_req_from_req_strings4    r parsed_reqc CsJ|jrt|j|j||j||d}|St|j|j|||j|j|j|d}|S)N)r[r\r_r]r`)r[r\r]r^r_rtr`) is_editablerrMr[r_rr^rt)rr]r\r`r@r(r(r)#install_req_from_parsed_requirements* rr>ireqc Cs.t|j|j|j||j|j|j|j|j|j d S)N) r@r[rer>rNr\r]rbrcrf) rr@r[rerNr\r]rbrcrf)r>rr(r(r)install_req_from_link_and_ireqsr)NNFNFFF)NNFNFNF)NFNF)FNF)D__doc__loggingr2r"typingrrrrrrZpip._vendor.packaging.markersrZ"pip._vendor.packaging.requirementsr r Z pip._vendor.packaging.specifiersr pip._vendor.pkg_resourcesr r pip._internal.exceptionsrpip._internal.models.indexrrpip._internal.models.linkrpip._internal.models.wheelrZpip._internal.req.req_filerpip._internal.req.req_installrpip._internal.utils.filetypesrpip._internal.utils.miscrpip._internal.utils.packagingrpip._internal.utils.urlsrpip._internal.vcsrr__all__ getLoggerrRrG _operatorskeysrrUr*r.rrKrLrZboolrrlrsrrrrrr(r(r(r)s                $7 "\ $ ( PKH]29python3.10/site-packages/pip/_internal/req/req_tracker.pynu[import contextlib import hashlib import logging import os from types import TracebackType from typing import Dict, Iterator, Optional, Set, Type, Union from pip._internal.models.link import Link from pip._internal.req.req_install import InstallRequirement from pip._internal.utils.temp_dir import TempDirectory logger = logging.getLogger(__name__) @contextlib.contextmanager def update_env_context_manager(**changes: str) -> Iterator[None]: target = os.environ # Save values from the target and change them. non_existent_marker = object() saved_values: Dict[str, Union[object, str]] = {} for name, new_value in changes.items(): try: saved_values[name] = target[name] except KeyError: saved_values[name] = non_existent_marker target[name] = new_value try: yield finally: # Restore original values in the target. for name, original_value in saved_values.items(): if original_value is non_existent_marker: del target[name] else: assert isinstance(original_value, str) # for mypy target[name] = original_value @contextlib.contextmanager def get_requirement_tracker() -> Iterator["RequirementTracker"]: root = os.environ.get("PIP_REQ_TRACKER") with contextlib.ExitStack() as ctx: if root is None: root = ctx.enter_context(TempDirectory(kind="req-tracker")).path ctx.enter_context(update_env_context_manager(PIP_REQ_TRACKER=root)) logger.debug("Initialized build tracking at %s", root) with RequirementTracker(root) as tracker: yield tracker class RequirementTracker: def __init__(self, root: str) -> None: self._root = root self._entries: Set[InstallRequirement] = set() logger.debug("Created build tracker: %s", self._root) def __enter__(self) -> "RequirementTracker": logger.debug("Entered build tracker: %s", self._root) return self def __exit__( self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType], ) -> None: self.cleanup() def _entry_path(self, link: Link) -> str: hashed = hashlib.sha224(link.url_without_fragment.encode()).hexdigest() return os.path.join(self._root, hashed) def add(self, req: InstallRequirement) -> None: """Add an InstallRequirement to build tracking.""" assert req.link # Get the file to write information about this requirement. entry_path = self._entry_path(req.link) # Try reading from the file. If it exists and can be read from, a build # is already in progress, so a LookupError is raised. try: with open(entry_path) as fp: contents = fp.read() except FileNotFoundError: pass else: message = "{} is already being built: {}".format(req.link, contents) raise LookupError(message) # If we're here, req should really not be building already. assert req not in self._entries # Start tracking this requirement. with open(entry_path, "w", encoding="utf-8") as fp: fp.write(str(req)) self._entries.add(req) logger.debug("Added %s to build tracker %r", req, self._root) def remove(self, req: InstallRequirement) -> None: """Remove an InstallRequirement from build tracking.""" assert req.link # Delete the created file and the corresponding entries. os.unlink(self._entry_path(req.link)) self._entries.remove(req) logger.debug("Removed %s from build tracker %r", req, self._root) def cleanup(self) -> None: for req in set(self._entries): self.remove(req) logger.debug("Removed build tracker: %r", self._root) @contextlib.contextmanager def track(self, req: InstallRequirement) -> Iterator[None]: self.add(req) yield self.remove(req) PKH]\\;python3.10/site-packages/pip/_internal/req/req_uninstall.pynu[import csv import functools import os import sys import sysconfig from importlib.util import cache_from_source from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Set, Tuple from pip._vendor import pkg_resources from pip._vendor.pkg_resources import Distribution from pip._internal.exceptions import UninstallationError from pip._internal.locations import get_bin_prefix, get_bin_user from pip._internal.utils.compat import WINDOWS from pip._internal.utils.egg_link import egg_link_path_from_location from pip._internal.utils.logging import getLogger, indent_log from pip._internal.utils.misc import ( ask, dist_in_usersite, dist_is_local, is_local, normalize_path, renames, rmtree, ) from pip._internal.utils.temp_dir import AdjacentTempDirectory, TempDirectory logger = getLogger(__name__) def _script_names(dist: Distribution, script_name: str, is_gui: bool) -> List[str]: """Create the fully qualified name of the files created by {console,gui}_scripts for the given ``dist``. Returns the list of file names """ if dist_in_usersite(dist): bin_dir = get_bin_user() else: bin_dir = get_bin_prefix() exe_name = os.path.join(bin_dir, script_name) paths_to_remove = [exe_name] if WINDOWS: paths_to_remove.append(exe_name + ".exe") paths_to_remove.append(exe_name + ".exe.manifest") if is_gui: paths_to_remove.append(exe_name + "-script.pyw") else: paths_to_remove.append(exe_name + "-script.py") return paths_to_remove def _unique(fn: Callable[..., Iterator[Any]]) -> Callable[..., Iterator[Any]]: @functools.wraps(fn) def unique(*args: Any, **kw: Any) -> Iterator[Any]: seen: Set[Any] = set() for item in fn(*args, **kw): if item not in seen: seen.add(item) yield item return unique @_unique def uninstallation_paths(dist: Distribution) -> Iterator[str]: """ Yield all the uninstallation paths for dist based on RECORD-without-.py[co] Yield paths to all the files in RECORD. For each .py file in RECORD, add the .pyc and .pyo in the same directory. UninstallPathSet.add() takes care of the __pycache__ .py[co]. If RECORD is not found, raises UninstallationError, with possible information from the INSTALLER file. https://packaging.python.org/specifications/recording-installed-packages/ """ try: r = csv.reader(dist.get_metadata_lines("RECORD")) except FileNotFoundError as missing_record_exception: msg = "Cannot uninstall {dist}, RECORD file not found.".format(dist=dist) try: installer = next(dist.get_metadata_lines("INSTALLER")) if not installer or installer == "pip": raise ValueError() except (OSError, StopIteration, ValueError): dep = "{}=={}".format(dist.project_name, dist.version) msg += ( " You might be able to recover from this via: " "'pip install --force-reinstall --no-deps {}'.".format(dep) ) else: msg += " Hint: The package was installed by {}.".format(installer) raise UninstallationError(msg) from missing_record_exception for row in r: path = os.path.join(dist.location, row[0]) yield path if path.endswith(".py"): dn, fn = os.path.split(path) base = fn[:-3] path = os.path.join(dn, base + ".pyc") yield path path = os.path.join(dn, base + ".pyo") yield path def compact(paths: Iterable[str]) -> Set[str]: """Compact a path set to contain the minimal number of paths necessary to contain all paths in the set. If /a/path/ and /a/path/to/a/file.txt are both in the set, leave only the shorter path.""" sep = os.path.sep short_paths: Set[str] = set() for path in sorted(paths, key=len): should_skip = any( path.startswith(shortpath.rstrip("*")) and path[len(shortpath.rstrip("*").rstrip(sep))] == sep for shortpath in short_paths ) if not should_skip: short_paths.add(path) return short_paths def compress_for_rename(paths: Iterable[str]) -> Set[str]: """Returns a set containing the paths that need to be renamed. This set may include directories when the original sequence of paths included every file on disk. """ case_map = {os.path.normcase(p): p for p in paths} remaining = set(case_map) unchecked = sorted({os.path.split(p)[0] for p in case_map.values()}, key=len) wildcards: Set[str] = set() def norm_join(*a: str) -> str: return os.path.normcase(os.path.join(*a)) for root in unchecked: if any(os.path.normcase(root).startswith(w) for w in wildcards): # This directory has already been handled. continue all_files: Set[str] = set() all_subdirs: Set[str] = set() for dirname, subdirs, files in os.walk(root): all_subdirs.update(norm_join(root, dirname, d) for d in subdirs) all_files.update(norm_join(root, dirname, f) for f in files) # If all the files we found are in our remaining set of files to # remove, then remove them from the latter set and add a wildcard # for the directory. if not (all_files - remaining): remaining.difference_update(all_files) wildcards.add(root + os.sep) return set(map(case_map.__getitem__, remaining)) | wildcards def compress_for_output_listing(paths: Iterable[str]) -> Tuple[Set[str], Set[str]]: """Returns a tuple of 2 sets of which paths to display to user The first set contains paths that would be deleted. Files of a package are not added and the top-level directory of the package has a '*' added at the end - to signify that all it's contents are removed. The second set contains files that would have been skipped in the above folders. """ will_remove = set(paths) will_skip = set() # Determine folders and files folders = set() files = set() for path in will_remove: if path.endswith(".pyc"): continue if path.endswith("__init__.py") or ".dist-info" in path: folders.add(os.path.dirname(path)) files.add(path) # probably this one https://github.com/python/mypy/issues/390 _normcased_files = set(map(os.path.normcase, files)) # type: ignore folders = compact(folders) # This walks the tree using os.walk to not miss extra folders # that might get added. for folder in folders: for dirpath, _, dirfiles in os.walk(folder): for fname in dirfiles: if fname.endswith(".pyc"): continue file_ = os.path.join(dirpath, fname) if ( os.path.isfile(file_) and os.path.normcase(file_) not in _normcased_files ): # We are skipping this file. Add it to the set. will_skip.add(file_) will_remove = files | {os.path.join(folder, "*") for folder in folders} return will_remove, will_skip class StashedUninstallPathSet: """A set of file rename operations to stash files while tentatively uninstalling them.""" def __init__(self) -> None: # Mapping from source file root to [Adjacent]TempDirectory # for files under that directory. self._save_dirs: Dict[str, TempDirectory] = {} # (old path, new path) tuples for each move that may need # to be undone. self._moves: List[Tuple[str, str]] = [] def _get_directory_stash(self, path: str) -> str: """Stashes a directory. Directories are stashed adjacent to their original location if possible, or else moved/copied into the user's temp dir.""" try: save_dir: TempDirectory = AdjacentTempDirectory(path) except OSError: save_dir = TempDirectory(kind="uninstall") self._save_dirs[os.path.normcase(path)] = save_dir return save_dir.path def _get_file_stash(self, path: str) -> str: """Stashes a file. If no root has been provided, one will be created for the directory in the user's temp directory.""" path = os.path.normcase(path) head, old_head = os.path.dirname(path), None save_dir = None while head != old_head: try: save_dir = self._save_dirs[head] break except KeyError: pass head, old_head = os.path.dirname(head), head else: # Did not find any suitable root head = os.path.dirname(path) save_dir = TempDirectory(kind="uninstall") self._save_dirs[head] = save_dir relpath = os.path.relpath(path, head) if relpath and relpath != os.path.curdir: return os.path.join(save_dir.path, relpath) return save_dir.path def stash(self, path: str) -> str: """Stashes the directory or file and returns its new location. Handle symlinks as files to avoid modifying the symlink targets. """ path_is_dir = os.path.isdir(path) and not os.path.islink(path) if path_is_dir: new_path = self._get_directory_stash(path) else: new_path = self._get_file_stash(path) self._moves.append((path, new_path)) if path_is_dir and os.path.isdir(new_path): # If we're moving a directory, we need to # remove the destination first or else it will be # moved to inside the existing directory. # We just created new_path ourselves, so it will # be removable. os.rmdir(new_path) renames(path, new_path) return new_path def commit(self) -> None: """Commits the uninstall by removing stashed files.""" for _, save_dir in self._save_dirs.items(): save_dir.cleanup() self._moves = [] self._save_dirs = {} def rollback(self) -> None: """Undoes the uninstall by moving stashed files back.""" for p in self._moves: logger.info("Moving to %s\n from %s", *p) for new_path, path in self._moves: try: logger.debug("Replacing %s from %s", new_path, path) if os.path.isfile(new_path) or os.path.islink(new_path): os.unlink(new_path) elif os.path.isdir(new_path): rmtree(new_path) renames(path, new_path) except OSError as ex: logger.error("Failed to restore %s", new_path) logger.debug("Exception: %s", ex) self.commit() @property def can_rollback(self) -> bool: return bool(self._moves) class UninstallPathSet: """A set of file paths to be removed in the uninstallation of a requirement.""" def __init__(self, dist: Distribution) -> None: self.paths: Set[str] = set() self._refuse: Set[str] = set() self.pth: Dict[str, UninstallPthEntries] = {} self.dist = dist self._moved_paths = StashedUninstallPathSet() def _permitted(self, path: str) -> bool: """ Return True if the given path is one we are permitted to remove/modify, False otherwise. """ return is_local(path) def add(self, path: str) -> None: head, tail = os.path.split(path) # we normalize the head to resolve parent directory symlinks, but not # the tail, since we only want to uninstall symlinks, not their targets path = os.path.join(normalize_path(head), os.path.normcase(tail)) if not os.path.exists(path): return if self._permitted(path): self.paths.add(path) else: self._refuse.add(path) # __pycache__ files can show up after 'installed-files.txt' is created, # due to imports if os.path.splitext(path)[1] == ".py": self.add(cache_from_source(path)) def add_pth(self, pth_file: str, entry: str) -> None: pth_file = normalize_path(pth_file) if self._permitted(pth_file): if pth_file not in self.pth: self.pth[pth_file] = UninstallPthEntries(pth_file) self.pth[pth_file].add(entry) else: self._refuse.add(pth_file) def remove(self, auto_confirm: bool = False, verbose: bool = False) -> None: """Remove paths in ``self.paths`` with confirmation (unless ``auto_confirm`` is True).""" if not self.paths: logger.info( "Can't uninstall '%s'. No files were found to uninstall.", self.dist.project_name, ) return dist_name_version = self.dist.project_name + "-" + self.dist.version logger.info("Uninstalling %s:", dist_name_version) with indent_log(): if auto_confirm or self._allowed_to_proceed(verbose): moved = self._moved_paths for_rename = compress_for_rename(self.paths) for path in sorted(compact(for_rename)): moved.stash(path) logger.verbose("Removing file or directory %s", path) for pth in self.pth.values(): pth.remove() logger.info("Successfully uninstalled %s", dist_name_version) def _allowed_to_proceed(self, verbose: bool) -> bool: """Display which files would be deleted and prompt for confirmation""" def _display(msg: str, paths: Iterable[str]) -> None: if not paths: return logger.info(msg) with indent_log(): for path in sorted(compact(paths)): logger.info(path) if not verbose: will_remove, will_skip = compress_for_output_listing(self.paths) else: # In verbose mode, display all the files that are going to be # deleted. will_remove = set(self.paths) will_skip = set() _display("Would remove:", will_remove) _display("Would not remove (might be manually added):", will_skip) _display("Would not remove (outside of prefix):", self._refuse) if verbose: _display("Will actually move:", compress_for_rename(self.paths)) return ask("Proceed (Y/n)? ", ("y", "n", "")) != "n" def rollback(self) -> None: """Rollback the changes previously made by remove().""" if not self._moved_paths.can_rollback: logger.error( "Can't roll back %s; was not uninstalled", self.dist.project_name, ) return logger.info("Rolling back uninstall of %s", self.dist.project_name) self._moved_paths.rollback() for pth in self.pth.values(): pth.rollback() def commit(self) -> None: """Remove temporary save dir: rollback will no longer be possible.""" self._moved_paths.commit() @classmethod def from_dist(cls, dist: Distribution) -> "UninstallPathSet": dist_path = normalize_path(dist.location) if not dist_is_local(dist): logger.info( "Not uninstalling %s at %s, outside environment %s", dist.key, dist_path, sys.prefix, ) return cls(dist) if dist_path in { p for p in {sysconfig.get_path("stdlib"), sysconfig.get_path("platstdlib")} if p }: logger.info( "Not uninstalling %s at %s, as it is in the standard library.", dist.key, dist_path, ) return cls(dist) paths_to_remove = cls(dist) develop_egg_link = egg_link_path_from_location(dist.project_name) develop_egg_link_egg_info = "{}.egg-info".format( pkg_resources.to_filename(dist.project_name) ) egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info) # Special case for distutils installed package distutils_egg_info = getattr(dist._provider, "path", None) # Uninstall cases order do matter as in the case of 2 installs of the # same package, pip needs to uninstall the currently detected version if ( egg_info_exists and dist.egg_info.endswith(".egg-info") and not dist.egg_info.endswith(develop_egg_link_egg_info) ): # if dist.egg_info.endswith(develop_egg_link_egg_info), we # are in fact in the develop_egg_link case paths_to_remove.add(dist.egg_info) if dist.has_metadata("installed-files.txt"): for installed_file in dist.get_metadata( "installed-files.txt" ).splitlines(): path = os.path.normpath(os.path.join(dist.egg_info, installed_file)) paths_to_remove.add(path) # FIXME: need a test for this elif block # occurs with --single-version-externally-managed/--record outside # of pip elif dist.has_metadata("top_level.txt"): if dist.has_metadata("namespace_packages.txt"): namespaces = dist.get_metadata("namespace_packages.txt") else: namespaces = [] for top_level_pkg in [ p for p in dist.get_metadata("top_level.txt").splitlines() if p and p not in namespaces ]: path = os.path.join(dist.location, top_level_pkg) paths_to_remove.add(path) paths_to_remove.add(path + ".py") paths_to_remove.add(path + ".pyc") paths_to_remove.add(path + ".pyo") elif distutils_egg_info: raise UninstallationError( "Cannot uninstall {!r}. It is a distutils installed project " "and thus we cannot accurately determine which files belong " "to it which would lead to only a partial uninstall.".format( dist.project_name, ) ) elif dist.location.endswith(".egg"): # package installed by easy_install # We cannot match on dist.egg_name because it can slightly vary # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg paths_to_remove.add(dist.location) easy_install_egg = os.path.split(dist.location)[1] easy_install_pth = os.path.join( os.path.dirname(dist.location), "easy-install.pth" ) paths_to_remove.add_pth(easy_install_pth, "./" + easy_install_egg) elif egg_info_exists and dist.egg_info.endswith(".dist-info"): for path in uninstallation_paths(dist): paths_to_remove.add(path) elif develop_egg_link: # develop egg with open(develop_egg_link) as fh: link_pointer = os.path.normcase(fh.readline().strip()) assert ( link_pointer == dist.location ), "Egg-link {} does not match installed location of {} (at {})".format( link_pointer, dist.project_name, dist.location ) paths_to_remove.add(develop_egg_link) easy_install_pth = os.path.join( os.path.dirname(develop_egg_link), "easy-install.pth" ) paths_to_remove.add_pth(easy_install_pth, dist.location) else: logger.debug( "Not sure how to uninstall: %s - Check: %s", dist, dist.location, ) # find distutils scripts= scripts if dist.has_metadata("scripts") and dist.metadata_isdir("scripts"): for script in dist.metadata_listdir("scripts"): if dist_in_usersite(dist): bin_dir = get_bin_user() else: bin_dir = get_bin_prefix() paths_to_remove.add(os.path.join(bin_dir, script)) if WINDOWS: paths_to_remove.add(os.path.join(bin_dir, script) + ".bat") # find console_scripts _scripts_to_remove = [] console_scripts = dist.get_entry_map(group="console_scripts") for name in console_scripts.keys(): _scripts_to_remove.extend(_script_names(dist, name, False)) # find gui_scripts gui_scripts = dist.get_entry_map(group="gui_scripts") for name in gui_scripts.keys(): _scripts_to_remove.extend(_script_names(dist, name, True)) for s in _scripts_to_remove: paths_to_remove.add(s) return paths_to_remove class UninstallPthEntries: def __init__(self, pth_file: str) -> None: self.file = pth_file self.entries: Set[str] = set() self._saved_lines: Optional[List[bytes]] = None def add(self, entry: str) -> None: entry = os.path.normcase(entry) # On Windows, os.path.normcase converts the entry to use # backslashes. This is correct for entries that describe absolute # paths outside of site-packages, but all the others use forward # slashes. # os.path.splitdrive is used instead of os.path.isabs because isabs # treats non-absolute paths with drive letter markings like c:foo\bar # as absolute paths. It also does not recognize UNC paths if they don't # have more than "\\sever\share". Valid examples: "\\server\share\" or # "\\server\share\folder". if WINDOWS and not os.path.splitdrive(entry)[0]: entry = entry.replace("\\", "/") self.entries.add(entry) def remove(self) -> None: logger.verbose("Removing pth entries from %s:", self.file) # If the file doesn't exist, log a warning and return if not os.path.isfile(self.file): logger.warning("Cannot remove entries from nonexistent file %s", self.file) return with open(self.file, "rb") as fh: # windows uses '\r\n' with py3k, but uses '\n' with py2.x lines = fh.readlines() self._saved_lines = lines if any(b"\r\n" in line for line in lines): endline = "\r\n" else: endline = "\n" # handle missing trailing newline if lines and not lines[-1].endswith(endline.encode("utf-8")): lines[-1] = lines[-1] + endline.encode("utf-8") for entry in self.entries: try: logger.verbose("Removing entry: %s", entry) lines.remove((entry + endline).encode("utf-8")) except ValueError: pass with open(self.file, "wb") as fh: fh.writelines(lines) def rollback(self) -> bool: if self._saved_lines is None: logger.error("Cannot roll back changes to %s, none were made", self.file) return False logger.debug("Rolling %s back to previous state", self.file) with open(self.file, "wb") as fh: fh.writelines(self._saved_lines) return True PKH]#Ġ5python3.10/site-packages/pip/_internal/req/req_set.pynu[import logging from collections import OrderedDict from typing import Dict, Iterable, List, Optional, Tuple from pip._vendor.packaging.utils import canonicalize_name from pip._internal.exceptions import InstallationError from pip._internal.models.wheel import Wheel from pip._internal.req.req_install import InstallRequirement from pip._internal.utils import compatibility_tags logger = logging.getLogger(__name__) class RequirementSet: def __init__(self, check_supported_wheels: bool = True) -> None: """Create a RequirementSet.""" self.requirements: Dict[str, InstallRequirement] = OrderedDict() self.check_supported_wheels = check_supported_wheels self.unnamed_requirements: List[InstallRequirement] = [] def __str__(self) -> str: requirements = sorted( (req for req in self.requirements.values() if not req.comes_from), key=lambda req: canonicalize_name(req.name or ""), ) return " ".join(str(req.req) for req in requirements) def __repr__(self) -> str: requirements = sorted( self.requirements.values(), key=lambda req: canonicalize_name(req.name or ""), ) format_string = "<{classname} object; {count} requirement(s): {reqs}>" return format_string.format( classname=self.__class__.__name__, count=len(requirements), reqs=", ".join(str(req.req) for req in requirements), ) def add_unnamed_requirement(self, install_req: InstallRequirement) -> None: assert not install_req.name self.unnamed_requirements.append(install_req) def add_named_requirement(self, install_req: InstallRequirement) -> None: assert install_req.name project_name = canonicalize_name(install_req.name) self.requirements[project_name] = install_req def add_requirement( self, install_req: InstallRequirement, parent_req_name: Optional[str] = None, extras_requested: Optional[Iterable[str]] = None, ) -> Tuple[List[InstallRequirement], Optional[InstallRequirement]]: """Add install_req as a requirement to install. :param parent_req_name: The name of the requirement that needed this added. The name is used because when multiple unnamed requirements resolve to the same name, we could otherwise end up with dependency links that point outside the Requirements set. parent_req must already be added. Note that None implies that this is a user supplied requirement, vs an inferred one. :param extras_requested: an iterable of extras used to evaluate the environment markers. :return: Additional requirements to scan. That is either [] if the requirement is not applicable, or [install_req] if the requirement is applicable and has just been added. """ # If the markers do not match, ignore this requirement. if not install_req.match_markers(extras_requested): logger.info( "Ignoring %s: markers '%s' don't match your environment", install_req.name, install_req.markers, ) return [], None # If the wheel is not supported, raise an error. # Should check this after filtering out based on environment markers to # allow specifying different wheels based on the environment/OS, in a # single requirements file. if install_req.link and install_req.link.is_wheel: wheel = Wheel(install_req.link.filename) tags = compatibility_tags.get_supported() if self.check_supported_wheels and not wheel.supported(tags): raise InstallationError( "{} is not a supported wheel on this platform.".format( wheel.filename ) ) # This next bit is really a sanity check. assert ( not install_req.user_supplied or parent_req_name is None ), "a user supplied req shouldn't have a parent" # Unnamed requirements are scanned again and the requirement won't be # added as a dependency until after scanning. if not install_req.name: self.add_unnamed_requirement(install_req) return [install_req], None try: existing_req: Optional[InstallRequirement] = self.get_requirement( install_req.name ) except KeyError: existing_req = None has_conflicting_requirement = ( parent_req_name is None and existing_req and not existing_req.constraint and existing_req.extras == install_req.extras and existing_req.req and install_req.req and existing_req.req.specifier != install_req.req.specifier ) if has_conflicting_requirement: raise InstallationError( "Double requirement given: {} (already in {}, name={!r})".format( install_req, existing_req, install_req.name ) ) # When no existing requirement exists, add the requirement as a # dependency and it will be scanned again after. if not existing_req: self.add_named_requirement(install_req) # We'd want to rescan this requirement later return [install_req], install_req # Assume there's no need to scan, and that we've already # encountered this for scanning. if install_req.constraint or not existing_req.constraint: return [], existing_req does_not_satisfy_constraint = install_req.link and not ( existing_req.link and install_req.link.path == existing_req.link.path ) if does_not_satisfy_constraint: raise InstallationError( "Could not satisfy constraints for '{}': " "installation from path or url cannot be " "constrained to a version".format(install_req.name) ) # If we're now installing a constraint, mark the existing # object for real installation. existing_req.constraint = False # If we're now installing a user supplied requirement, # mark the existing object as such. if install_req.user_supplied: existing_req.user_supplied = True existing_req.extras = tuple( sorted(set(existing_req.extras) | set(install_req.extras)) ) logger.debug( "Setting %s extras to: %s", existing_req, existing_req.extras, ) # Return the existing requirement for addition to the parent and # scanning again. return [existing_req], existing_req def has_requirement(self, name: str) -> bool: project_name = canonicalize_name(name) return ( project_name in self.requirements and not self.requirements[project_name].constraint ) def get_requirement(self, name: str) -> InstallRequirement: project_name = canonicalize_name(name) if project_name in self.requirements: return self.requirements[project_name] raise KeyError(f"No project with the name {name!r}") @property def all_requirements(self) -> List[InstallRequirement]: return self.unnamed_requirements + list(self.requirements.values()) PKH]' D D6python3.10/site-packages/pip/_internal/req/req_file.pynu[""" Requirements file parsing """ import optparse import os import re import shlex import urllib.parse from optparse import Values from typing import ( TYPE_CHECKING, Any, Callable, Dict, Iterable, Iterator, List, Optional, Tuple, ) from pip._internal.cli import cmdoptions from pip._internal.exceptions import InstallationError, RequirementsFileParseError from pip._internal.models.search_scope import SearchScope from pip._internal.network.session import PipSession from pip._internal.network.utils import raise_for_status from pip._internal.utils.encoding import auto_decode from pip._internal.utils.urls import get_url_scheme if TYPE_CHECKING: # NoReturn introduced in 3.6.2; imported only for type checking to maintain # pip compatibility with older patch versions of Python 3.6 from typing import NoReturn from pip._internal.index.package_finder import PackageFinder __all__ = ["parse_requirements"] ReqFileLines = Iterable[Tuple[int, str]] LineParser = Callable[[str], Tuple[str, Values]] SCHEME_RE = re.compile(r"^(http|https|file):", re.I) COMMENT_RE = re.compile(r"(^|\s+)#.*$") # Matches environment variable-style values in '${MY_VARIABLE_1}' with the # variable name consisting of only uppercase letters, digits or the '_' # (underscore). This follows the POSIX standard defined in IEEE Std 1003.1, # 2013 Edition. ENV_VAR_RE = re.compile(r"(?P\$\{(?P[A-Z0-9_]+)\})") SUPPORTED_OPTIONS: List[Callable[..., optparse.Option]] = [ cmdoptions.index_url, cmdoptions.extra_index_url, cmdoptions.no_index, cmdoptions.constraints, cmdoptions.requirements, cmdoptions.editable, cmdoptions.find_links, cmdoptions.no_binary, cmdoptions.only_binary, cmdoptions.prefer_binary, cmdoptions.require_hashes, cmdoptions.pre, cmdoptions.trusted_host, cmdoptions.use_new_feature, ] # options to be passed to requirements SUPPORTED_OPTIONS_REQ: List[Callable[..., optparse.Option]] = [ cmdoptions.install_options, cmdoptions.global_options, cmdoptions.hash, ] # the 'dest' string values SUPPORTED_OPTIONS_REQ_DEST = [str(o().dest) for o in SUPPORTED_OPTIONS_REQ] class ParsedRequirement: def __init__( self, requirement: str, is_editable: bool, comes_from: str, constraint: bool, options: Optional[Dict[str, Any]] = None, line_source: Optional[str] = None, ) -> None: self.requirement = requirement self.is_editable = is_editable self.comes_from = comes_from self.options = options self.constraint = constraint self.line_source = line_source class ParsedLine: def __init__( self, filename: str, lineno: int, args: str, opts: Values, constraint: bool, ) -> None: self.filename = filename self.lineno = lineno self.opts = opts self.constraint = constraint if args: self.is_requirement = True self.is_editable = False self.requirement = args elif opts.editables: self.is_requirement = True self.is_editable = True # We don't support multiple -e on one line self.requirement = opts.editables[0] else: self.is_requirement = False def parse_requirements( filename: str, session: PipSession, finder: Optional["PackageFinder"] = None, options: Optional[optparse.Values] = None, constraint: bool = False, ) -> Iterator[ParsedRequirement]: """Parse a requirements file and yield ParsedRequirement instances. :param filename: Path or url of requirements file. :param session: PipSession instance. :param finder: Instance of pip.index.PackageFinder. :param options: cli options. :param constraint: If true, parsing a constraint file rather than requirements file. """ line_parser = get_line_parser(finder) parser = RequirementsFileParser(session, line_parser) for parsed_line in parser.parse(filename, constraint): parsed_req = handle_line( parsed_line, options=options, finder=finder, session=session ) if parsed_req is not None: yield parsed_req def preprocess(content: str) -> ReqFileLines: """Split, filter, and join lines, and return a line iterator :param content: the content of the requirements file """ lines_enum: ReqFileLines = enumerate(content.splitlines(), start=1) lines_enum = join_lines(lines_enum) lines_enum = ignore_comments(lines_enum) lines_enum = expand_env_variables(lines_enum) return lines_enum def handle_requirement_line( line: ParsedLine, options: Optional[optparse.Values] = None, ) -> ParsedRequirement: # preserve for the nested code path line_comes_from = "{} {} (line {})".format( "-c" if line.constraint else "-r", line.filename, line.lineno, ) assert line.is_requirement if line.is_editable: # For editable requirements, we don't support per-requirement # options, so just return the parsed requirement. return ParsedRequirement( requirement=line.requirement, is_editable=line.is_editable, comes_from=line_comes_from, constraint=line.constraint, ) else: if options: # Disable wheels if the user has specified build options cmdoptions.check_install_build_global(options, line.opts) # get the options that apply to requirements req_options = {} for dest in SUPPORTED_OPTIONS_REQ_DEST: if dest in line.opts.__dict__ and line.opts.__dict__[dest]: req_options[dest] = line.opts.__dict__[dest] line_source = f"line {line.lineno} of {line.filename}" return ParsedRequirement( requirement=line.requirement, is_editable=line.is_editable, comes_from=line_comes_from, constraint=line.constraint, options=req_options, line_source=line_source, ) def handle_option_line( opts: Values, filename: str, lineno: int, finder: Optional["PackageFinder"] = None, options: Optional[optparse.Values] = None, session: Optional[PipSession] = None, ) -> None: if options: # percolate options upward if opts.require_hashes: options.require_hashes = opts.require_hashes if opts.features_enabled: options.features_enabled.extend( f for f in opts.features_enabled if f not in options.features_enabled ) # set finder options if finder: find_links = finder.find_links index_urls = finder.index_urls if opts.index_url: index_urls = [opts.index_url] if opts.no_index is True: index_urls = [] if opts.extra_index_urls: index_urls.extend(opts.extra_index_urls) if opts.find_links: # FIXME: it would be nice to keep track of the source # of the find_links: support a find-links local path # relative to a requirements file. value = opts.find_links[0] req_dir = os.path.dirname(os.path.abspath(filename)) relative_to_reqs_file = os.path.join(req_dir, value) if os.path.exists(relative_to_reqs_file): value = relative_to_reqs_file find_links.append(value) if session: # We need to update the auth urls in session session.update_index_urls(index_urls) search_scope = SearchScope( find_links=find_links, index_urls=index_urls, ) finder.search_scope = search_scope if opts.pre: finder.set_allow_all_prereleases() if opts.prefer_binary: finder.set_prefer_binary() if session: for host in opts.trusted_hosts or []: source = f"line {lineno} of {filename}" session.add_trusted_host(host, source=source) def handle_line( line: ParsedLine, options: Optional[optparse.Values] = None, finder: Optional["PackageFinder"] = None, session: Optional[PipSession] = None, ) -> Optional[ParsedRequirement]: """Handle a single parsed requirements line; This can result in creating/yielding requirements, or updating the finder. :param line: The parsed line to be processed. :param options: CLI options. :param finder: The finder - updated by non-requirement lines. :param session: The session - updated by non-requirement lines. Returns a ParsedRequirement object if the line is a requirement line, otherwise returns None. For lines that contain requirements, the only options that have an effect are from SUPPORTED_OPTIONS_REQ, and they are scoped to the requirement. Other options from SUPPORTED_OPTIONS may be present, but are ignored. For lines that do not contain requirements, the only options that have an effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may be present, but are ignored. These lines may contain multiple options (although our docs imply only one is supported), and all our parsed and affect the finder. """ if line.is_requirement: parsed_req = handle_requirement_line(line, options) return parsed_req else: handle_option_line( line.opts, line.filename, line.lineno, finder, options, session, ) return None class RequirementsFileParser: def __init__( self, session: PipSession, line_parser: LineParser, ) -> None: self._session = session self._line_parser = line_parser def parse(self, filename: str, constraint: bool) -> Iterator[ParsedLine]: """Parse a given file, yielding parsed lines.""" yield from self._parse_and_recurse(filename, constraint) def _parse_and_recurse( self, filename: str, constraint: bool ) -> Iterator[ParsedLine]: for line in self._parse_file(filename, constraint): if not line.is_requirement and ( line.opts.requirements or line.opts.constraints ): # parse a nested requirements file if line.opts.requirements: req_path = line.opts.requirements[0] nested_constraint = False else: req_path = line.opts.constraints[0] nested_constraint = True # original file is over http if SCHEME_RE.search(filename): # do a url join so relative paths work req_path = urllib.parse.urljoin(filename, req_path) # original file and nested file are paths elif not SCHEME_RE.search(req_path): # do a join so relative paths work req_path = os.path.join( os.path.dirname(filename), req_path, ) yield from self._parse_and_recurse(req_path, nested_constraint) else: yield line def _parse_file(self, filename: str, constraint: bool) -> Iterator[ParsedLine]: _, content = get_file_content(filename, self._session) lines_enum = preprocess(content) for line_number, line in lines_enum: try: args_str, opts = self._line_parser(line) except OptionParsingError as e: # add offending line msg = f"Invalid requirement: {line}\n{e.msg}" raise RequirementsFileParseError(msg) yield ParsedLine( filename, line_number, args_str, opts, constraint, ) def get_line_parser(finder: Optional["PackageFinder"]) -> LineParser: def parse_line(line: str) -> Tuple[str, Values]: # Build new parser for each line since it accumulates appendable # options. parser = build_parser() defaults = parser.get_default_values() defaults.index_url = None if finder: defaults.format_control = finder.format_control args_str, options_str = break_args_options(line) opts, _ = parser.parse_args(shlex.split(options_str), defaults) return args_str, opts return parse_line def break_args_options(line: str) -> Tuple[str, str]: """Break up the line into an args and options string. We only want to shlex (and then optparse) the options, not the args. args can contain markers which are corrupted by shlex. """ tokens = line.split(" ") args = [] options = tokens[:] for token in tokens: if token.startswith("-") or token.startswith("--"): break else: args.append(token) options.pop(0) return " ".join(args), " ".join(options) class OptionParsingError(Exception): def __init__(self, msg: str) -> None: self.msg = msg def build_parser() -> optparse.OptionParser: """ Return a parser for parsing requirement lines """ parser = optparse.OptionParser(add_help_option=False) option_factories = SUPPORTED_OPTIONS + SUPPORTED_OPTIONS_REQ for option_factory in option_factories: option = option_factory() parser.add_option(option) # By default optparse sys.exits on parsing errors. We want to wrap # that in our own exception. def parser_exit(self: Any, msg: str) -> "NoReturn": raise OptionParsingError(msg) # NOTE: mypy disallows assigning to a method # https://github.com/python/mypy/issues/2427 parser.exit = parser_exit # type: ignore return parser def join_lines(lines_enum: ReqFileLines) -> ReqFileLines: """Joins a line ending in '\' with the previous line (except when following comments). The joined line takes on the index of the first line. """ primary_line_number = None new_line: List[str] = [] for line_number, line in lines_enum: if not line.endswith("\\") or COMMENT_RE.match(line): if COMMENT_RE.match(line): # this ensures comments are always matched later line = " " + line if new_line: new_line.append(line) assert primary_line_number is not None yield primary_line_number, "".join(new_line) new_line = [] else: yield line_number, line else: if not new_line: primary_line_number = line_number new_line.append(line.strip("\\")) # last line contains \ if new_line: assert primary_line_number is not None yield primary_line_number, "".join(new_line) # TODO: handle space after '\'. def ignore_comments(lines_enum: ReqFileLines) -> ReqFileLines: """ Strips comments and filter empty lines. """ for line_number, line in lines_enum: line = COMMENT_RE.sub("", line) line = line.strip() if line: yield line_number, line def expand_env_variables(lines_enum: ReqFileLines) -> ReqFileLines: """Replace all environment variables that can be retrieved via `os.getenv`. The only allowed format for environment variables defined in the requirement file is `${MY_VARIABLE_1}` to ensure two things: 1. Strings that contain a `$` aren't accidentally (partially) expanded. 2. Ensure consistency across platforms for requirement files. These points are the result of a discussion on the `github pull request #3514 `_. Valid characters in variable names follow the `POSIX standard `_ and are limited to uppercase letter, digits and the `_` (underscore). """ for line_number, line in lines_enum: for env_var, var_name in ENV_VAR_RE.findall(line): value = os.getenv(var_name) if not value: continue line = line.replace(env_var, value) yield line_number, line def get_file_content(url: str, session: PipSession) -> Tuple[str, str]: """Gets the content of a file; it may be a filename, file: URL, or http: URL. Returns (location, content). Content is unicode. Respects # -*- coding: declarations on the retrieved files. :param url: File path or url. :param session: PipSession instance. """ scheme = get_url_scheme(url) # Pip has special support for file:// URLs (LocalFSAdapter). if scheme in ["http", "https", "file"]: resp = session.get(url) raise_for_status(resp) return resp.url, resp.text # Assume this is a bare path. try: with open(url, "rb") as f: content = auto_decode(f.read()) except OSError as exc: raise InstallationError(f"Could not open requirements file: {exc}") return url, content PKH]t 6python3.10/site-packages/pip/_internal/req/__init__.pynu[import collections import logging from typing import Iterator, List, Optional, Sequence, Tuple from pip._internal.utils.logging import indent_log from .req_file import parse_requirements from .req_install import InstallRequirement from .req_set import RequirementSet __all__ = [ "RequirementSet", "InstallRequirement", "parse_requirements", "install_given_reqs", ] logger = logging.getLogger(__name__) class InstallationResult: def __init__(self, name: str) -> None: self.name = name def __repr__(self) -> str: return f"InstallationResult(name={self.name!r})" def _validate_requirements( requirements: List[InstallRequirement], ) -> Iterator[Tuple[str, InstallRequirement]]: for req in requirements: assert req.name, f"invalid to-be-installed requirement: {req}" yield req.name, req def install_given_reqs( requirements: List[InstallRequirement], install_options: List[str], global_options: Sequence[str], root: Optional[str], home: Optional[str], prefix: Optional[str], warn_script_location: bool, use_user_site: bool, pycompile: bool, ) -> List[InstallationResult]: """ Install everything in the given list. (to be called after having downloaded and unpacked the packages) """ to_install = collections.OrderedDict(_validate_requirements(requirements)) if to_install: logger.info( "Installing collected packages: %s", ", ".join(to_install.keys()), ) installed = [] with indent_log(): for req_name, requirement in to_install.items(): if requirement.should_reinstall: logger.info("Attempting uninstall: %s", req_name) with indent_log(): uninstalled_pathset = requirement.uninstall(auto_confirm=True) else: uninstalled_pathset = None try: requirement.install( install_options, global_options, root=root, home=home, prefix=prefix, warn_script_location=warn_script_location, use_user_site=use_user_site, pycompile=pycompile, ) except Exception: # if install did not succeed, rollback previous uninstall if uninstalled_pathset and not requirement.install_succeeded: uninstalled_pathset.rollback() raise else: if uninstalled_pathset and requirement.install_succeeded: uninstalled_pathset.commit() installed.append(InstallationResult(req_name)) return installed PKH]SJJ9python3.10/site-packages/pip/_internal/req/req_install.pynu[# The following comment should be removed at some point in the future. # mypy: strict-optional=False import functools import logging import os import shutil import sys import uuid import zipfile from typing import Any, Collection, Dict, Iterable, List, Optional, Sequence, Union from pip._vendor import pkg_resources from pip._vendor.packaging.markers import Marker from pip._vendor.packaging.requirements import Requirement from pip._vendor.packaging.specifiers import SpecifierSet from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.packaging.version import Version from pip._vendor.packaging.version import parse as parse_version from pip._vendor.pep517.wrappers import Pep517HookCaller from pip._vendor.pkg_resources import Distribution from pip._internal.build_env import BuildEnvironment, NoOpBuildEnvironment from pip._internal.exceptions import InstallationError from pip._internal.locations import get_scheme from pip._internal.models.link import Link from pip._internal.operations.build.metadata import generate_metadata from pip._internal.operations.build.metadata_editable import generate_editable_metadata from pip._internal.operations.build.metadata_legacy import ( generate_metadata as generate_metadata_legacy, ) from pip._internal.operations.install.editable_legacy import ( install_editable as install_editable_legacy, ) from pip._internal.operations.install.legacy import LegacyInstallFailure from pip._internal.operations.install.legacy import install as install_legacy from pip._internal.operations.install.wheel import install_wheel from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path from pip._internal.req.req_uninstall import UninstallPathSet from pip._internal.utils.deprecation import deprecated from pip._internal.utils.direct_url_helpers import ( direct_url_for_editable, direct_url_from_link, ) from pip._internal.utils.hashes import Hashes from pip._internal.utils.misc import ( ask_path_exists, backup_dir, display_path, dist_in_install_path, dist_in_site_packages, dist_in_usersite, get_distribution, hide_url, redact_auth_from_url, ) from pip._internal.utils.packaging import get_metadata from pip._internal.utils.subprocess import runner_with_spinner_message from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds from pip._internal.utils.virtualenv import running_under_virtualenv from pip._internal.vcs import vcs logger = logging.getLogger(__name__) def _get_dist(metadata_directory: str) -> Distribution: """Return a pkg_resources.Distribution for the provided metadata directory. """ dist_dir = metadata_directory.rstrip(os.sep) # Build a PathMetadata object, from path to metadata. :wink: base_dir, dist_dir_name = os.path.split(dist_dir) metadata = pkg_resources.PathMetadata(base_dir, dist_dir) # Determine the correct Distribution object type. if dist_dir.endswith(".egg-info"): dist_cls = pkg_resources.Distribution dist_name = os.path.splitext(dist_dir_name)[0] else: assert dist_dir.endswith(".dist-info") dist_cls = pkg_resources.DistInfoDistribution dist_name = os.path.splitext(dist_dir_name)[0].split("-")[0] return dist_cls( base_dir, project_name=dist_name, metadata=metadata, ) class InstallRequirement: """ Represents something that may be installed later on, may have information about where to fetch the relevant requirement and also contains logic for installing the said requirement. """ def __init__( self, req: Optional[Requirement], comes_from: Optional[Union[str, "InstallRequirement"]], editable: bool = False, link: Optional[Link] = None, markers: Optional[Marker] = None, use_pep517: Optional[bool] = None, isolated: bool = False, install_options: Optional[List[str]] = None, global_options: Optional[List[str]] = None, hash_options: Optional[Dict[str, List[str]]] = None, constraint: bool = False, extras: Collection[str] = (), user_supplied: bool = False, permit_editable_wheels: bool = False, ) -> None: assert req is None or isinstance(req, Requirement), req self.req = req self.comes_from = comes_from self.constraint = constraint self.editable = editable self.permit_editable_wheels = permit_editable_wheels self.legacy_install_reason: Optional[int] = None # source_dir is the local directory where the linked requirement is # located, or unpacked. In case unpacking is needed, creating and # populating source_dir is done by the RequirementPreparer. Note this # is not necessarily the directory where pyproject.toml or setup.py is # located - that one is obtained via unpacked_source_directory. self.source_dir: Optional[str] = None if self.editable: assert link if link.is_file: self.source_dir = os.path.normpath(os.path.abspath(link.file_path)) if link is None and req and req.url: # PEP 508 URL requirement link = Link(req.url) self.link = self.original_link = link self.original_link_is_in_wheel_cache = False # Path to any downloaded or already-existing package. self.local_file_path: Optional[str] = None if self.link and self.link.is_file: self.local_file_path = self.link.file_path if extras: self.extras = extras elif req: self.extras = {pkg_resources.safe_extra(extra) for extra in req.extras} else: self.extras = set() if markers is None and req: markers = req.marker self.markers = markers # This holds the pkg_resources.Distribution object if this requirement # is already available: self.satisfied_by: Optional[Distribution] = None # Whether the installation process should try to uninstall an existing # distribution before installing this requirement. self.should_reinstall = False # Temporary build location self._temp_build_dir: Optional[TempDirectory] = None # Set to True after successful installation self.install_succeeded: Optional[bool] = None # Supplied options self.install_options = install_options if install_options else [] self.global_options = global_options if global_options else [] self.hash_options = hash_options if hash_options else {} # Set to True after successful preparation of this requirement self.prepared = False # User supplied requirement are explicitly requested for installation # by the user via CLI arguments or requirements files, as opposed to, # e.g. dependencies, extras or constraints. self.user_supplied = user_supplied self.isolated = isolated self.build_env: BuildEnvironment = NoOpBuildEnvironment() # For PEP 517, the directory where we request the project metadata # gets stored. We need this to pass to build_wheel, so the backend # can ensure that the wheel matches the metadata (see the PEP for # details). self.metadata_directory: Optional[str] = None # The static build requirements (from pyproject.toml) self.pyproject_requires: Optional[List[str]] = None # Build requirements that we will check are available self.requirements_to_check: List[str] = [] # The PEP 517 backend we should use to build the project self.pep517_backend: Optional[Pep517HookCaller] = None # Are we using PEP 517 for this requirement? # After pyproject.toml has been loaded, the only valid values are True # and False. Before loading, None is valid (meaning "use the default"). # Setting an explicit value before loading pyproject.toml is supported, # but after loading this flag should be treated as read only. self.use_pep517 = use_pep517 # This requirement needs more preparation before it can be built self.needs_more_preparation = False def __str__(self) -> str: if self.req: s = str(self.req) if self.link: s += " from {}".format(redact_auth_from_url(self.link.url)) elif self.link: s = redact_auth_from_url(self.link.url) else: s = "" if self.satisfied_by is not None: s += " in {}".format(display_path(self.satisfied_by.location)) if self.comes_from: if isinstance(self.comes_from, str): comes_from: Optional[str] = self.comes_from else: comes_from = self.comes_from.from_path() if comes_from: s += f" (from {comes_from})" return s def __repr__(self) -> str: return "<{} object: {} editable={!r}>".format( self.__class__.__name__, str(self), self.editable ) def format_debug(self) -> str: """An un-tested helper for getting state, for debugging.""" attributes = vars(self) names = sorted(attributes) state = ("{}={!r}".format(attr, attributes[attr]) for attr in sorted(names)) return "<{name} object: {{{state}}}>".format( name=self.__class__.__name__, state=", ".join(state), ) # Things that are valid for all kinds of requirements? @property def name(self) -> Optional[str]: if self.req is None: return None return pkg_resources.safe_name(self.req.name) @functools.lru_cache() # use cached_property in python 3.8+ def supports_pyproject_editable(self) -> bool: if not self.use_pep517: return False assert self.pep517_backend with self.build_env: runner = runner_with_spinner_message( "Checking if build backend supports build_editable" ) with self.pep517_backend.subprocess_runner(runner): return "build_editable" in self.pep517_backend._supported_features() @property def specifier(self) -> SpecifierSet: return self.req.specifier @property def is_pinned(self) -> bool: """Return whether I am pinned to an exact version. For example, some-package==1.2 is pinned; some-package>1.2 is not. """ specifiers = self.specifier return len(specifiers) == 1 and next(iter(specifiers)).operator in {"==", "==="} def match_markers(self, extras_requested: Optional[Iterable[str]] = None) -> bool: if not extras_requested: # Provide an extra to safely evaluate the markers # without matching any extra extras_requested = ("",) if self.markers is not None: return any( self.markers.evaluate({"extra": extra}) for extra in extras_requested ) else: return True @property def has_hash_options(self) -> bool: """Return whether any known-good hashes are specified as options. These activate --require-hashes mode; hashes specified as part of a URL do not. """ return bool(self.hash_options) def hashes(self, trust_internet: bool = True) -> Hashes: """Return a hash-comparer that considers my option- and URL-based hashes to be known-good. Hashes in URLs--ones embedded in the requirements file, not ones downloaded from an index server--are almost peers with ones from flags. They satisfy --require-hashes (whether it was implicitly or explicitly activated) but do not activate it. md5 and sha224 are not allowed in flags, which should nudge people toward good algos. We always OR all hashes together, even ones from URLs. :param trust_internet: Whether to trust URL-based (#md5=...) hashes downloaded from the internet, as by populate_link() """ good_hashes = self.hash_options.copy() link = self.link if trust_internet else self.original_link if link and link.hash: good_hashes.setdefault(link.hash_name, []).append(link.hash) return Hashes(good_hashes) def from_path(self) -> Optional[str]: """Format a nice indicator to show where this "comes from" """ if self.req is None: return None s = str(self.req) if self.comes_from: if isinstance(self.comes_from, str): comes_from = self.comes_from else: comes_from = self.comes_from.from_path() if comes_from: s += "->" + comes_from return s def ensure_build_location( self, build_dir: str, autodelete: bool, parallel_builds: bool ) -> str: assert build_dir is not None if self._temp_build_dir is not None: assert self._temp_build_dir.path return self._temp_build_dir.path if self.req is None: # Some systems have /tmp as a symlink which confuses custom # builds (such as numpy). Thus, we ensure that the real path # is returned. self._temp_build_dir = TempDirectory( kind=tempdir_kinds.REQ_BUILD, globally_managed=True ) return self._temp_build_dir.path # This is the only remaining place where we manually determine the path # for the temporary directory. It is only needed for editables where # it is the value of the --src option. # When parallel builds are enabled, add a UUID to the build directory # name so multiple builds do not interfere with each other. dir_name: str = canonicalize_name(self.name) if parallel_builds: dir_name = f"{dir_name}_{uuid.uuid4().hex}" # FIXME: Is there a better place to create the build_dir? (hg and bzr # need this) if not os.path.exists(build_dir): logger.debug("Creating directory %s", build_dir) os.makedirs(build_dir) actual_build_dir = os.path.join(build_dir, dir_name) # `None` indicates that we respect the globally-configured deletion # settings, which is what we actually want when auto-deleting. delete_arg = None if autodelete else False return TempDirectory( path=actual_build_dir, delete=delete_arg, kind=tempdir_kinds.REQ_BUILD, globally_managed=True, ).path def _set_requirement(self) -> None: """Set requirement after generating metadata.""" assert self.req is None assert self.metadata is not None assert self.source_dir is not None # Construct a Requirement object from the generated metadata if isinstance(parse_version(self.metadata["Version"]), Version): op = "==" else: op = "===" self.req = Requirement( "".join( [ self.metadata["Name"], op, self.metadata["Version"], ] ) ) def warn_on_mismatching_name(self) -> None: metadata_name = canonicalize_name(self.metadata["Name"]) if canonicalize_name(self.req.name) == metadata_name: # Everything is fine. return # If we're here, there's a mismatch. Log a warning about it. logger.warning( "Generating metadata for package %s " "produced metadata for project name %s. Fix your " "#egg=%s fragments.", self.name, metadata_name, self.name, ) self.req = Requirement(metadata_name) def check_if_exists(self, use_user_site: bool) -> None: """Find an installed distribution that satisfies or conflicts with this requirement, and set self.satisfied_by or self.should_reinstall appropriately. """ if self.req is None: return existing_dist = get_distribution(self.req.name) if not existing_dist: return # pkg_resouces may contain a different copy of packaging.version from # pip in if the downstream distributor does a poor job debundling pip. # We avoid existing_dist.parsed_version and let SpecifierSet.contains # parses the version instead. existing_version = existing_dist.version version_compatible = ( existing_version is not None and self.req.specifier.contains(existing_version, prereleases=True) ) if not version_compatible: self.satisfied_by = None if use_user_site: if dist_in_usersite(existing_dist): self.should_reinstall = True elif running_under_virtualenv() and dist_in_site_packages( existing_dist ): raise InstallationError( "Will not install to the user site because it will " "lack sys.path precedence to {} in {}".format( existing_dist.project_name, existing_dist.location ) ) elif dist_in_install_path(existing_dist): self.should_reinstall = True else: if self.editable: self.should_reinstall = True # when installing editables, nothing pre-existing should ever # satisfy self.satisfied_by = None else: self.satisfied_by = existing_dist # Things valid for wheels @property def is_wheel(self) -> bool: if not self.link: return False return self.link.is_wheel # Things valid for sdists @property def unpacked_source_directory(self) -> str: return os.path.join( self.source_dir, self.link and self.link.subdirectory_fragment or "" ) @property def setup_py_path(self) -> str: assert self.source_dir, f"No source dir for {self}" setup_py = os.path.join(self.unpacked_source_directory, "setup.py") return setup_py @property def setup_cfg_path(self) -> str: assert self.source_dir, f"No source dir for {self}" setup_cfg = os.path.join(self.unpacked_source_directory, "setup.cfg") return setup_cfg @property def pyproject_toml_path(self) -> str: assert self.source_dir, f"No source dir for {self}" return make_pyproject_path(self.unpacked_source_directory) def load_pyproject_toml(self) -> None: """Load the pyproject.toml file. After calling this routine, all of the attributes related to PEP 517 processing for this requirement have been set. In particular, the use_pep517 attribute can be used to determine whether we should follow the PEP 517 or legacy (setup.py) code path. """ pyproject_toml_data = load_pyproject_toml( self.use_pep517, self.pyproject_toml_path, self.setup_py_path, str(self) ) if pyproject_toml_data is None: self.use_pep517 = False return self.use_pep517 = True requires, backend, check, backend_path = pyproject_toml_data self.requirements_to_check = check self.pyproject_requires = requires self.pep517_backend = Pep517HookCaller( self.unpacked_source_directory, backend, backend_path=backend_path, ) def isolated_editable_sanity_check(self) -> None: """Check that an editable requirement if valid for use with PEP 517/518. This verifies that an editable that has a pyproject.toml either supports PEP 660 or as a setup.py or a setup.cfg """ if ( self.editable and self.use_pep517 and not self.supports_pyproject_editable() and not os.path.isfile(self.setup_py_path) and not os.path.isfile(self.setup_cfg_path) ): raise InstallationError( f"Project {self} has a 'pyproject.toml' and its build " f"backend is missing the 'build_editable' hook. Since it does not " f"have a 'setup.py' nor a 'setup.cfg', " f"it cannot be installed in editable mode. " f"Consider using a build backend that supports PEP 660." ) def prepare_metadata(self) -> None: """Ensure that project metadata is available. Under PEP 517 and PEP 660, call the backend hook to prepare the metadata. Under legacy processing, call setup.py egg-info. """ assert self.source_dir if self.use_pep517: assert self.pep517_backend is not None if ( self.editable and self.permit_editable_wheels and self.supports_pyproject_editable() ): self.metadata_directory = generate_editable_metadata( build_env=self.build_env, backend=self.pep517_backend, ) else: self.metadata_directory = generate_metadata( build_env=self.build_env, backend=self.pep517_backend, ) else: self.metadata_directory = generate_metadata_legacy( build_env=self.build_env, setup_py_path=self.setup_py_path, source_dir=self.unpacked_source_directory, isolated=self.isolated, details=self.name or f"from {self.link}", ) # Act on the newly generated metadata, based on the name and version. if not self.name: self._set_requirement() else: self.warn_on_mismatching_name() self.assert_source_matches_version() @property def metadata(self) -> Any: if not hasattr(self, "_metadata"): self._metadata = get_metadata(self.get_dist()) return self._metadata def get_dist(self) -> Distribution: return _get_dist(self.metadata_directory) def assert_source_matches_version(self) -> None: assert self.source_dir version = self.metadata["version"] if self.req.specifier and version not in self.req.specifier: logger.warning( "Requested %s, but installing version %s", self, version, ) else: logger.debug( "Source in %s has version %s, which satisfies requirement %s", display_path(self.source_dir), version, self, ) # For both source distributions and editables def ensure_has_source_dir( self, parent_dir: str, autodelete: bool = False, parallel_builds: bool = False, ) -> None: """Ensure that a source_dir is set. This will create a temporary build dir if the name of the requirement isn't known yet. :param parent_dir: The ideal pip parent_dir for the source_dir. Generally src_dir for editables and build_dir for sdists. :return: self.source_dir """ if self.source_dir is None: self.source_dir = self.ensure_build_location( parent_dir, autodelete=autodelete, parallel_builds=parallel_builds, ) # For editable installations def update_editable(self) -> None: if not self.link: logger.debug( "Cannot update repository at %s; repository location is unknown", self.source_dir, ) return assert self.editable assert self.source_dir if self.link.scheme == "file": # Static paths don't get updated return vcs_backend = vcs.get_backend_for_scheme(self.link.scheme) # Editable requirements are validated in Requirement constructors. # So here, if it's neither a path nor a valid VCS URL, it's a bug. assert vcs_backend, f"Unsupported VCS URL {self.link.url}" hidden_url = hide_url(self.link.url) vcs_backend.obtain(self.source_dir, url=hidden_url) # Top-level Actions def uninstall( self, auto_confirm: bool = False, verbose: bool = False ) -> Optional[UninstallPathSet]: """ Uninstall the distribution currently satisfying this requirement. Prompts before removing or modifying files unless ``auto_confirm`` is True. Refuses to delete or modify files outside of ``sys.prefix`` - thus uninstallation within a virtual environment can only modify that virtual environment, even if the virtualenv is linked to global site-packages. """ assert self.req dist = get_distribution(self.req.name) if not dist: logger.warning("Skipping %s as it is not installed.", self.name) return None logger.info("Found existing installation: %s", dist) uninstalled_pathset = UninstallPathSet.from_dist(dist) uninstalled_pathset.remove(auto_confirm, verbose) return uninstalled_pathset def _get_archive_name(self, path: str, parentdir: str, rootdir: str) -> str: def _clean_zip_name(name: str, prefix: str) -> str: assert name.startswith( prefix + os.path.sep ), f"name {name!r} doesn't start with prefix {prefix!r}" name = name[len(prefix) + 1 :] name = name.replace(os.path.sep, "/") return name path = os.path.join(parentdir, path) name = _clean_zip_name(path, rootdir) return self.name + "/" + name def archive(self, build_dir: Optional[str]) -> None: """Saves archive to provided build_dir. Used for saving downloaded VCS requirements as part of `pip download`. """ assert self.source_dir if build_dir is None: return create_archive = True archive_name = "{}-{}.zip".format(self.name, self.metadata["version"]) archive_path = os.path.join(build_dir, archive_name) if os.path.exists(archive_path): response = ask_path_exists( "The file {} exists. (i)gnore, (w)ipe, " "(b)ackup, (a)bort ".format(display_path(archive_path)), ("i", "w", "b", "a"), ) if response == "i": create_archive = False elif response == "w": logger.warning("Deleting %s", display_path(archive_path)) os.remove(archive_path) elif response == "b": dest_file = backup_dir(archive_path) logger.warning( "Backing up %s to %s", display_path(archive_path), display_path(dest_file), ) shutil.move(archive_path, dest_file) elif response == "a": sys.exit(-1) if not create_archive: return zip_output = zipfile.ZipFile( archive_path, "w", zipfile.ZIP_DEFLATED, allowZip64=True, ) with zip_output: dir = os.path.normcase(os.path.abspath(self.unpacked_source_directory)) for dirpath, dirnames, filenames in os.walk(dir): for dirname in dirnames: dir_arcname = self._get_archive_name( dirname, parentdir=dirpath, rootdir=dir, ) zipdir = zipfile.ZipInfo(dir_arcname + "/") zipdir.external_attr = 0x1ED << 16 # 0o755 zip_output.writestr(zipdir, "") for filename in filenames: file_arcname = self._get_archive_name( filename, parentdir=dirpath, rootdir=dir, ) filename = os.path.join(dirpath, filename) zip_output.write(filename, file_arcname) logger.info("Saved %s", display_path(archive_path)) def install( self, install_options: List[str], global_options: Optional[Sequence[str]] = None, root: Optional[str] = None, home: Optional[str] = None, prefix: Optional[str] = None, warn_script_location: bool = True, use_user_site: bool = False, pycompile: bool = True, ) -> None: scheme = get_scheme( self.name, user=use_user_site, home=home, root=root, isolated=self.isolated, prefix=prefix, ) global_options = global_options if global_options is not None else [] if self.editable and not self.is_wheel: install_editable_legacy( install_options, global_options, prefix=prefix, home=home, use_user_site=use_user_site, name=self.name, setup_py_path=self.setup_py_path, isolated=self.isolated, build_env=self.build_env, unpacked_source_directory=self.unpacked_source_directory, ) self.install_succeeded = True return if self.is_wheel: assert self.local_file_path direct_url = None if self.editable: direct_url = direct_url_for_editable(self.unpacked_source_directory) elif self.original_link: direct_url = direct_url_from_link( self.original_link, self.source_dir, self.original_link_is_in_wheel_cache, ) install_wheel( self.name, self.local_file_path, scheme=scheme, req_description=str(self.req), pycompile=pycompile, warn_script_location=warn_script_location, direct_url=direct_url, requested=self.user_supplied, ) self.install_succeeded = True return # TODO: Why don't we do this for editable installs? # Extend the list of global and install options passed on to # the setup.py call with the ones from the requirements file. # Options specified in requirements file override those # specified on the command line, since the last option given # to setup.py is the one that is used. global_options = list(global_options) + self.global_options install_options = list(install_options) + self.install_options try: success = install_legacy( install_options=install_options, global_options=global_options, root=root, home=home, prefix=prefix, use_user_site=use_user_site, pycompile=pycompile, scheme=scheme, setup_py_path=self.setup_py_path, isolated=self.isolated, req_name=self.name, build_env=self.build_env, unpacked_source_directory=self.unpacked_source_directory, req_description=str(self.req), ) except LegacyInstallFailure as exc: self.install_succeeded = False raise exc.__cause__ except Exception: self.install_succeeded = True raise self.install_succeeded = success if success and self.legacy_install_reason == 8368: deprecated( reason=( "{} was installed using the legacy 'setup.py install' " "method, because a wheel could not be built for it.".format( self.name ) ), replacement="to fix the wheel build issue reported above", gone_in=None, issue=8368, ) def check_invalid_constraint_type(req: InstallRequirement) -> str: # Check for unsupported forms problem = "" if not req.name: problem = "Unnamed requirements are not allowed as constraints" elif req.editable: problem = "Editable requirements are not allowed as constraints" elif req.extras: problem = "Constraints cannot have extras" if problem: deprecated( reason=( "Constraints are only allowed to take the form of a package " "name and a version specifier. Other forms were originally " "permitted as an accident of the implementation, but were " "undocumented. The new implementation of the resolver no " "longer supports these forms." ), replacement="replacing the constraint with a requirement", # No plan yet for when the new resolver becomes default gone_in=None, issue=8210, ) return problem PKH]ecu˵;;:python3.10/site-packages/pip/_internal/req/constructors.pynu["""Backing implementation for InstallRequirement's various constructors The idea here is that these formed a major chunk of InstallRequirement's size so, moving them and support code dedicated to them outside of that class helps creates for better understandability for the rest of the code. These are meant to be used elsewhere within pip to create instances of InstallRequirement. """ import logging import os import re from typing import Any, Dict, Optional, Set, Tuple, Union from pip._vendor.packaging.markers import Marker from pip._vendor.packaging.requirements import InvalidRequirement, Requirement from pip._vendor.packaging.specifiers import Specifier from pip._vendor.pkg_resources import RequirementParseError, parse_requirements from pip._internal.exceptions import InstallationError from pip._internal.models.index import PyPI, TestPyPI from pip._internal.models.link import Link from pip._internal.models.wheel import Wheel from pip._internal.req.req_file import ParsedRequirement from pip._internal.req.req_install import InstallRequirement from pip._internal.utils.filetypes import is_archive_file from pip._internal.utils.misc import is_installable_dir from pip._internal.utils.packaging import get_requirement from pip._internal.utils.urls import path_to_url from pip._internal.vcs import is_url, vcs __all__ = [ "install_req_from_editable", "install_req_from_line", "parse_editable", ] logger = logging.getLogger(__name__) operators = Specifier._operators.keys() def _strip_extras(path: str) -> Tuple[str, Optional[str]]: m = re.match(r"^(.+)(\[[^\]]+\])$", path) extras = None if m: path_no_extras = m.group(1) extras = m.group(2) else: path_no_extras = path return path_no_extras, extras def convert_extras(extras: Optional[str]) -> Set[str]: if not extras: return set() return get_requirement("placeholder" + extras.lower()).extras def parse_editable(editable_req: str) -> Tuple[Optional[str], str, Set[str]]: """Parses an editable requirement into: - a requirement name - an URL - extras - editable options Accepted requirements: svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir .[some_extra] """ url = editable_req # If a file path is specified with extras, strip off the extras. url_no_extras, extras = _strip_extras(url) if os.path.isdir(url_no_extras): # Treating it as code that has already been checked out url_no_extras = path_to_url(url_no_extras) if url_no_extras.lower().startswith("file:"): package_name = Link(url_no_extras).egg_fragment if extras: return ( package_name, url_no_extras, get_requirement("placeholder" + extras.lower()).extras, ) else: return package_name, url_no_extras, set() for version_control in vcs: if url.lower().startswith(f"{version_control}:"): url = f"{version_control}+{url}" break link = Link(url) if not link.is_vcs: backends = ", ".join(vcs.all_schemes) raise InstallationError( f"{editable_req} is not a valid editable requirement. " f"It should either be a path to a local project or a VCS URL " f"(beginning with {backends})." ) package_name = link.egg_fragment if not package_name: raise InstallationError( "Could not detect requirement name for '{}', please specify one " "with #egg=your_package_name".format(editable_req) ) return package_name, url, set() def deduce_helpful_msg(req: str) -> str: """Returns helpful msg in case requirements file does not exist, or cannot be parsed. :params req: Requirements file path """ msg = "" if os.path.exists(req): msg = " The path does exist. " # Try to parse and check if it is a requirements file. try: with open(req) as fp: # parse first line only next(parse_requirements(fp.read())) msg += ( "The argument you provided " "({}) appears to be a" " requirements file. If that is the" " case, use the '-r' flag to install" " the packages specified within it." ).format(req) except RequirementParseError: logger.debug("Cannot parse '%s' as requirements file", req, exc_info=True) else: msg += f" File '{req}' does not exist." return msg class RequirementParts: def __init__( self, requirement: Optional[Requirement], link: Optional[Link], markers: Optional[Marker], extras: Set[str], ): self.requirement = requirement self.link = link self.markers = markers self.extras = extras def parse_req_from_editable(editable_req: str) -> RequirementParts: name, url, extras_override = parse_editable(editable_req) if name is not None: try: req: Optional[Requirement] = Requirement(name) except InvalidRequirement: raise InstallationError(f"Invalid requirement: '{name}'") else: req = None link = Link(url) return RequirementParts(req, link, None, extras_override) # ---- The actual constructors follow ---- def install_req_from_editable( editable_req: str, comes_from: Optional[Union[InstallRequirement, str]] = None, use_pep517: Optional[bool] = None, isolated: bool = False, options: Optional[Dict[str, Any]] = None, constraint: bool = False, user_supplied: bool = False, permit_editable_wheels: bool = False, ) -> InstallRequirement: parts = parse_req_from_editable(editable_req) return InstallRequirement( parts.requirement, comes_from=comes_from, user_supplied=user_supplied, editable=True, permit_editable_wheels=permit_editable_wheels, link=parts.link, constraint=constraint, use_pep517=use_pep517, isolated=isolated, install_options=options.get("install_options", []) if options else [], global_options=options.get("global_options", []) if options else [], hash_options=options.get("hashes", {}) if options else {}, extras=parts.extras, ) def _looks_like_path(name: str) -> bool: """Checks whether the string "looks like" a path on the filesystem. This does not check whether the target actually exists, only judge from the appearance. Returns true if any of the following conditions is true: * a path separator is found (either os.path.sep or os.path.altsep); * a dot is found (which represents the current directory). """ if os.path.sep in name: return True if os.path.altsep is not None and os.path.altsep in name: return True if name.startswith("."): return True return False def _get_url_from_path(path: str, name: str) -> Optional[str]: """ First, it checks whether a provided path is an installable directory. If it is, returns the path. If false, check if the path is an archive file (such as a .whl). The function checks if the path is a file. If false, if the path has an @, it will treat it as a PEP 440 URL requirement and return the path. """ if _looks_like_path(name) and os.path.isdir(path): if is_installable_dir(path): return path_to_url(path) # TODO: The is_installable_dir test here might not be necessary # now that it is done in load_pyproject_toml too. raise InstallationError( f"Directory {name!r} is not installable. Neither 'setup.py' " "nor 'pyproject.toml' found." ) if not is_archive_file(path): return None if os.path.isfile(path): return path_to_url(path) urlreq_parts = name.split("@", 1) if len(urlreq_parts) >= 2 and not _looks_like_path(urlreq_parts[0]): # If the path contains '@' and the part before it does not look # like a path, try to treat it as a PEP 440 URL req instead. return None logger.warning( "Requirement %r looks like a filename, but the file does not exist", name, ) return path_to_url(path) def parse_req_from_line(name: str, line_source: Optional[str]) -> RequirementParts: if is_url(name): marker_sep = "; " else: marker_sep = ";" if marker_sep in name: name, markers_as_string = name.split(marker_sep, 1) markers_as_string = markers_as_string.strip() if not markers_as_string: markers = None else: markers = Marker(markers_as_string) else: markers = None name = name.strip() req_as_string = None path = os.path.normpath(os.path.abspath(name)) link = None extras_as_string = None if is_url(name): link = Link(name) else: p, extras_as_string = _strip_extras(path) url = _get_url_from_path(p, name) if url is not None: link = Link(url) # it's a local file, dir, or url if link: # Handle relative file URLs if link.scheme == "file" and re.search(r"\.\./", link.url): link = Link(path_to_url(os.path.normpath(os.path.abspath(link.path)))) # wheel file if link.is_wheel: wheel = Wheel(link.filename) # can raise InvalidWheelFilename req_as_string = f"{wheel.name}=={wheel.version}" else: # set the req to the egg fragment. when it's not there, this # will become an 'unnamed' requirement req_as_string = link.egg_fragment # a requirement specifier else: req_as_string = name extras = convert_extras(extras_as_string) def with_source(text: str) -> str: if not line_source: return text return f"{text} (from {line_source})" def _parse_req_string(req_as_string: str) -> Requirement: try: req = get_requirement(req_as_string) except InvalidRequirement: if os.path.sep in req_as_string: add_msg = "It looks like a path." add_msg += deduce_helpful_msg(req_as_string) elif "=" in req_as_string and not any( op in req_as_string for op in operators ): add_msg = "= is not a valid operator. Did you mean == ?" else: add_msg = "" msg = with_source(f"Invalid requirement: {req_as_string!r}") if add_msg: msg += f"\nHint: {add_msg}" raise InstallationError(msg) else: # Deprecate extras after specifiers: "name>=1.0[extras]" # This currently works by accident because _strip_extras() parses # any extras in the end of the string and those are saved in # RequirementParts for spec in req.specifier: spec_str = str(spec) if spec_str.endswith("]"): msg = f"Extras after version '{spec_str}'." raise InstallationError(msg) return req if req_as_string is not None: req: Optional[Requirement] = _parse_req_string(req_as_string) else: req = None return RequirementParts(req, link, markers, extras) def install_req_from_line( name: str, comes_from: Optional[Union[str, InstallRequirement]] = None, use_pep517: Optional[bool] = None, isolated: bool = False, options: Optional[Dict[str, Any]] = None, constraint: bool = False, line_source: Optional[str] = None, user_supplied: bool = False, ) -> InstallRequirement: """Creates an InstallRequirement from a name, which might be a requirement, directory containing 'setup.py', filename, or URL. :param line_source: An optional string describing where the line is from, for logging purposes in case of an error. """ parts = parse_req_from_line(name, line_source) return InstallRequirement( parts.requirement, comes_from, link=parts.link, markers=parts.markers, use_pep517=use_pep517, isolated=isolated, install_options=options.get("install_options", []) if options else [], global_options=options.get("global_options", []) if options else [], hash_options=options.get("hashes", {}) if options else {}, constraint=constraint, extras=parts.extras, user_supplied=user_supplied, ) def install_req_from_req_string( req_string: str, comes_from: Optional[InstallRequirement] = None, isolated: bool = False, use_pep517: Optional[bool] = None, user_supplied: bool = False, ) -> InstallRequirement: try: req = get_requirement(req_string) except InvalidRequirement: raise InstallationError(f"Invalid requirement: '{req_string}'") domains_not_allowed = [ PyPI.file_storage_domain, TestPyPI.file_storage_domain, ] if ( req.url and comes_from and comes_from.link and comes_from.link.netloc in domains_not_allowed ): # Explicitly disallow pypi packages that depend on external urls raise InstallationError( "Packages installed from PyPI cannot depend on packages " "which are not also hosted on PyPI.\n" "{} depends on {} ".format(comes_from.name, req) ) return InstallRequirement( req, comes_from, isolated=isolated, use_pep517=use_pep517, user_supplied=user_supplied, ) def install_req_from_parsed_requirement( parsed_req: ParsedRequirement, isolated: bool = False, use_pep517: Optional[bool] = None, user_supplied: bool = False, ) -> InstallRequirement: if parsed_req.is_editable: req = install_req_from_editable( parsed_req.requirement, comes_from=parsed_req.comes_from, use_pep517=use_pep517, constraint=parsed_req.constraint, isolated=isolated, user_supplied=user_supplied, ) else: req = install_req_from_line( parsed_req.requirement, comes_from=parsed_req.comes_from, use_pep517=use_pep517, isolated=isolated, options=parsed_req.options, constraint=parsed_req.constraint, line_source=parsed_req.line_source, user_supplied=user_supplied, ) return req def install_req_from_link_and_ireq( link: Link, ireq: InstallRequirement ) -> InstallRequirement: return InstallRequirement( req=ireq.req, comes_from=ireq.comes_from, editable=ireq.editable, link=link, markers=ireq.markers, use_pep517=ireq.use_pep517, isolated=ireq.isolated, install_options=ireq.install_options, global_options=ireq.global_options, hash_options=ireq.hash_options, ) PKH]_//7python3.10/site-packages/pip/_internal/wheel_builder.pynu["""Orchestrator for building wheels from InstallRequirements. """ import logging import os.path import re import shutil from typing import Any, Callable, Iterable, List, Optional, Tuple from pip._vendor.packaging.utils import canonicalize_name, canonicalize_version from pip._vendor.packaging.version import InvalidVersion, Version from pip._internal.cache import WheelCache from pip._internal.exceptions import InvalidWheelFilename, UnsupportedWheel from pip._internal.metadata import FilesystemWheel, get_wheel_distribution from pip._internal.models.link import Link from pip._internal.models.wheel import Wheel from pip._internal.operations.build.wheel import build_wheel_pep517 from pip._internal.operations.build.wheel_editable import build_wheel_editable from pip._internal.operations.build.wheel_legacy import build_wheel_legacy from pip._internal.req.req_install import InstallRequirement from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import ensure_dir, hash_file, is_wheel_installed from pip._internal.utils.setuptools_build import make_setuptools_clean_args from pip._internal.utils.subprocess import call_subprocess from pip._internal.utils.temp_dir import TempDirectory from pip._internal.utils.urls import path_to_url from pip._internal.vcs import vcs logger = logging.getLogger(__name__) _egg_info_re = re.compile(r"([a-z0-9_.]+)-([a-z0-9_.!+-]+)", re.IGNORECASE) BinaryAllowedPredicate = Callable[[InstallRequirement], bool] BuildResult = Tuple[List[InstallRequirement], List[InstallRequirement]] def _contains_egg_info(s: str) -> bool: """Determine whether the string looks like an egg_info. :param s: The string to parse. E.g. foo-2.1 """ return bool(_egg_info_re.search(s)) def _should_build( req: InstallRequirement, need_wheel: bool, check_binary_allowed: BinaryAllowedPredicate, ) -> bool: """Return whether an InstallRequirement should be built into a wheel.""" if req.constraint: # never build requirements that are merely constraints return False if req.is_wheel: if need_wheel: logger.info( "Skipping %s, due to already being wheel.", req.name, ) return False if need_wheel: # i.e. pip wheel, not pip install return True # From this point, this concerns the pip install command only # (need_wheel=False). if not req.source_dir: return False if req.editable: # we only build PEP 660 editable requirements return req.supports_pyproject_editable() if req.use_pep517: return True if not check_binary_allowed(req): logger.info( "Skipping wheel build for %s, due to binaries being disabled for it.", req.name, ) return False if not is_wheel_installed(): # we don't build legacy requirements if wheel is not installed logger.info( "Using legacy 'setup.py install' for %s, " "since package 'wheel' is not installed.", req.name, ) return False return True def should_build_for_wheel_command( req: InstallRequirement, ) -> bool: return _should_build(req, need_wheel=True, check_binary_allowed=_always_true) def should_build_for_install_command( req: InstallRequirement, check_binary_allowed: BinaryAllowedPredicate, ) -> bool: return _should_build( req, need_wheel=False, check_binary_allowed=check_binary_allowed ) def _should_cache( req: InstallRequirement, ) -> Optional[bool]: """ Return whether a built InstallRequirement can be stored in the persistent wheel cache, assuming the wheel cache is available, and _should_build() has determined a wheel needs to be built. """ if req.editable or not req.source_dir: # never cache editable requirements return False if req.link and req.link.is_vcs: # VCS checkout. Do not cache # unless it points to an immutable commit hash. assert not req.editable assert req.source_dir vcs_backend = vcs.get_backend_for_scheme(req.link.scheme) assert vcs_backend if vcs_backend.is_immutable_rev_checkout(req.link.url, req.source_dir): return True return False assert req.link base, ext = req.link.splitext() if _contains_egg_info(base): return True # Otherwise, do not cache. return False def _get_cache_dir( req: InstallRequirement, wheel_cache: WheelCache, ) -> str: """Return the persistent or temporary cache directory where the built wheel need to be stored. """ cache_available = bool(wheel_cache.cache_dir) assert req.link if cache_available and _should_cache(req): cache_dir = wheel_cache.get_path_for_link(req.link) else: cache_dir = wheel_cache.get_ephem_path_for_link(req.link) return cache_dir def _always_true(_: Any) -> bool: return True def _verify_one(req: InstallRequirement, wheel_path: str) -> None: canonical_name = canonicalize_name(req.name or "") w = Wheel(os.path.basename(wheel_path)) if canonicalize_name(w.name) != canonical_name: raise InvalidWheelFilename( "Wheel has unexpected file name: expected {!r}, " "got {!r}".format(canonical_name, w.name), ) dist = get_wheel_distribution(FilesystemWheel(wheel_path), canonical_name) dist_verstr = str(dist.version) if canonicalize_version(dist_verstr) != canonicalize_version(w.version): raise InvalidWheelFilename( "Wheel has unexpected file name: expected {!r}, " "got {!r}".format(dist_verstr, w.version), ) metadata_version_value = dist.metadata_version if metadata_version_value is None: raise UnsupportedWheel("Missing Metadata-Version") try: metadata_version = Version(metadata_version_value) except InvalidVersion: msg = f"Invalid Metadata-Version: {metadata_version_value}" raise UnsupportedWheel(msg) if metadata_version >= Version("1.2") and not isinstance(dist.version, Version): raise UnsupportedWheel( "Metadata 1.2 mandates PEP 440 version, " "but {!r} is not".format(dist_verstr) ) def _build_one( req: InstallRequirement, output_dir: str, verify: bool, build_options: List[str], global_options: List[str], editable: bool, ) -> Optional[str]: """Build one wheel. :return: The filename of the built wheel, or None if the build failed. """ artifact = "editable" if editable else "wheel" try: ensure_dir(output_dir) except OSError as e: logger.warning( "Building %s for %s failed: %s", artifact, req.name, e, ) return None # Install build deps into temporary directory (PEP 518) with req.build_env: wheel_path = _build_one_inside_env( req, output_dir, build_options, global_options, editable ) if wheel_path and verify: try: _verify_one(req, wheel_path) except (InvalidWheelFilename, UnsupportedWheel) as e: logger.warning("Built %s for %s is invalid: %s", artifact, req.name, e) return None return wheel_path def _build_one_inside_env( req: InstallRequirement, output_dir: str, build_options: List[str], global_options: List[str], editable: bool, ) -> Optional[str]: with TempDirectory(kind="wheel") as temp_dir: assert req.name if req.use_pep517: assert req.metadata_directory assert req.pep517_backend if global_options: logger.warning( "Ignoring --global-option when building %s using PEP 517", req.name ) if build_options: logger.warning( "Ignoring --build-option when building %s using PEP 517", req.name ) if editable: wheel_path = build_wheel_editable( name=req.name, backend=req.pep517_backend, metadata_directory=req.metadata_directory, tempd=temp_dir.path, ) else: wheel_path = build_wheel_pep517( name=req.name, backend=req.pep517_backend, metadata_directory=req.metadata_directory, tempd=temp_dir.path, ) else: wheel_path = build_wheel_legacy( name=req.name, setup_py_path=req.setup_py_path, source_dir=req.unpacked_source_directory, global_options=global_options, build_options=build_options, tempd=temp_dir.path, ) if wheel_path is not None: wheel_name = os.path.basename(wheel_path) dest_path = os.path.join(output_dir, wheel_name) try: wheel_hash, length = hash_file(wheel_path) shutil.move(wheel_path, dest_path) logger.info( "Created wheel for %s: filename=%s size=%d sha256=%s", req.name, wheel_name, length, wheel_hash.hexdigest(), ) logger.info("Stored in directory: %s", output_dir) return dest_path except Exception as e: logger.warning( "Building wheel for %s failed: %s", req.name, e, ) # Ignore return, we can't do anything else useful. if not req.use_pep517: _clean_one_legacy(req, global_options) return None def _clean_one_legacy(req: InstallRequirement, global_options: List[str]) -> bool: clean_args = make_setuptools_clean_args( req.setup_py_path, global_options=global_options, ) logger.info("Running setup.py clean for %s", req.name) try: call_subprocess(clean_args, cwd=req.source_dir) return True except Exception: logger.error("Failed cleaning build dir for %s", req.name) return False def build( requirements: Iterable[InstallRequirement], wheel_cache: WheelCache, verify: bool, build_options: List[str], global_options: List[str], ) -> BuildResult: """Build wheels. :return: The list of InstallRequirement that succeeded to build and the list of InstallRequirement that failed to build. """ if not requirements: return [], [] # Build the wheels. logger.info( "Building wheels for collected packages: %s", ", ".join(req.name for req in requirements), # type: ignore ) with indent_log(): build_successes, build_failures = [], [] for req in requirements: assert req.name cache_dir = _get_cache_dir(req, wheel_cache) wheel_file = _build_one( req, cache_dir, verify, build_options, global_options, req.editable and req.permit_editable_wheels, ) if wheel_file: # Update the link for this. req.link = Link(path_to_url(wheel_file)) req.local_file_path = req.link.file_path assert req.link.is_wheel build_successes.append(req) else: build_failures.append(req) # notify success/failure if build_successes: logger.info( "Successfully built %s", " ".join([req.name for req in build_successes]), # type: ignore ) if build_failures: logger.info( "Failed to build %s", " ".join([req.name for req in build_failures]), # type: ignore ) # Return a list of requirements that failed to build return build_successes, build_failures PKH]yfl114python3.10/site-packages/pip/_internal/exceptions.pynu["""Exceptions used throughout package""" import configparser from itertools import chain, groupby, repeat from typing import TYPE_CHECKING, Dict, List, Optional, Union from pip._vendor.pkg_resources import Distribution from pip._vendor.requests.models import Request, Response if TYPE_CHECKING: from hashlib import _Hash from pip._internal.metadata import BaseDistribution from pip._internal.req.req_install import InstallRequirement class PipError(Exception): """Base pip exception""" class ConfigurationError(PipError): """General exception in configuration""" class InstallationError(PipError): """General exception during installation""" class UninstallationError(PipError): """General exception during uninstallation""" class NoneMetadataError(PipError): """ Raised when accessing "METADATA" or "PKG-INFO" metadata for a pip._vendor.pkg_resources.Distribution object and `dist.has_metadata('METADATA')` returns True but `dist.get_metadata('METADATA')` returns None (and similarly for "PKG-INFO"). """ def __init__( self, dist: Union[Distribution, "BaseDistribution"], metadata_name: str, ) -> None: """ :param dist: A Distribution object. :param metadata_name: The name of the metadata being accessed (can be "METADATA" or "PKG-INFO"). """ self.dist = dist self.metadata_name = metadata_name def __str__(self) -> str: # Use `dist` in the error message because its stringification # includes more information, like the version and location. return "None {} metadata found for distribution: {}".format( self.metadata_name, self.dist, ) class UserInstallationInvalid(InstallationError): """A --user install is requested on an environment without user site.""" def __str__(self) -> str: return "User base directory is not specified" class InvalidSchemeCombination(InstallationError): def __str__(self) -> str: before = ", ".join(str(a) for a in self.args[:-1]) return f"Cannot set {before} and {self.args[-1]} together" class DistributionNotFound(InstallationError): """Raised when a distribution cannot be found to satisfy a requirement""" class RequirementsFileParseError(InstallationError): """Raised when a general error occurs parsing a requirements file line.""" class BestVersionAlreadyInstalled(PipError): """Raised when the most up-to-date version of a package is already installed.""" class BadCommand(PipError): """Raised when virtualenv or a command is not found""" class CommandError(PipError): """Raised when there is an error in command-line arguments""" class PreviousBuildDirError(PipError): """Raised when there's a previous conflicting build directory""" class NetworkConnectionError(PipError): """HTTP connection error""" def __init__( self, error_msg: str, response: Response = None, request: Request = None ) -> None: """ Initialize NetworkConnectionError with `request` and `response` objects. """ self.response = response self.request = request self.error_msg = error_msg if ( self.response is not None and not self.request and hasattr(response, "request") ): self.request = self.response.request super().__init__(error_msg, response, request) def __str__(self) -> str: return str(self.error_msg) class InvalidWheelFilename(InstallationError): """Invalid wheel filename.""" class UnsupportedWheel(InstallationError): """Unsupported wheel.""" class MetadataInconsistent(InstallationError): """Built metadata contains inconsistent information. This is raised when the metadata contains values (e.g. name and version) that do not match the information previously obtained from sdist filename or user-supplied ``#egg=`` value. """ def __init__( self, ireq: "InstallRequirement", field: str, f_val: str, m_val: str ) -> None: self.ireq = ireq self.field = field self.f_val = f_val self.m_val = m_val def __str__(self) -> str: template = ( "Requested {} has inconsistent {}: " "filename has {!r}, but metadata has {!r}" ) return template.format(self.ireq, self.field, self.f_val, self.m_val) class InstallationSubprocessError(InstallationError): """A subprocess call failed during installation.""" def __init__(self, returncode: int, description: str) -> None: self.returncode = returncode self.description = description def __str__(self) -> str: return ( "Command errored out with exit status {}: {} " "Check the logs for full command output." ).format(self.returncode, self.description) class HashErrors(InstallationError): """Multiple HashError instances rolled into one for reporting""" def __init__(self) -> None: self.errors: List["HashError"] = [] def append(self, error: "HashError") -> None: self.errors.append(error) def __str__(self) -> str: lines = [] self.errors.sort(key=lambda e: e.order) for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__): lines.append(cls.head) lines.extend(e.body() for e in errors_of_cls) if lines: return "\n".join(lines) return "" def __bool__(self) -> bool: return bool(self.errors) class HashError(InstallationError): """ A failure to verify a package against known-good hashes :cvar order: An int sorting hash exception classes by difficulty of recovery (lower being harder), so the user doesn't bother fretting about unpinned packages when he has deeper issues, like VCS dependencies, to deal with. Also keeps error reports in a deterministic order. :cvar head: A section heading for display above potentially many exceptions of this kind :ivar req: The InstallRequirement that triggered this error. This is pasted on after the exception is instantiated, because it's not typically available earlier. """ req: Optional["InstallRequirement"] = None head = "" order: int = -1 def body(self) -> str: """Return a summary of me for display under the heading. This default implementation simply prints a description of the triggering requirement. :param req: The InstallRequirement that provoked this error, with its link already populated by the resolver's _populate_link(). """ return f" {self._requirement_name()}" def __str__(self) -> str: return f"{self.head}\n{self.body()}" def _requirement_name(self) -> str: """Return a description of the requirement that triggered me. This default implementation returns long description of the req, with line numbers """ return str(self.req) if self.req else "unknown package" class VcsHashUnsupported(HashError): """A hash was provided for a version-control-system-based requirement, but we don't have a method for hashing those.""" order = 0 head = ( "Can't verify hashes for these requirements because we don't " "have a way to hash version control repositories:" ) class DirectoryUrlHashUnsupported(HashError): """A hash was provided for a version-control-system-based requirement, but we don't have a method for hashing those.""" order = 1 head = ( "Can't verify hashes for these file:// requirements because they " "point to directories:" ) class HashMissing(HashError): """A hash was needed for a requirement but is absent.""" order = 2 head = ( "Hashes are required in --require-hashes mode, but they are " "missing from some requirements. Here is a list of those " "requirements along with the hashes their downloaded archives " "actually had. Add lines like these to your requirements files to " "prevent tampering. (If you did not enable --require-hashes " "manually, note that it turns on automatically when any package " "has a hash.)" ) def __init__(self, gotten_hash: str) -> None: """ :param gotten_hash: The hash of the (possibly malicious) archive we just downloaded """ self.gotten_hash = gotten_hash def body(self) -> str: # Dodge circular import. from pip._internal.utils.hashes import FAVORITE_HASH package = None if self.req: # In the case of URL-based requirements, display the original URL # seen in the requirements file rather than the package name, # so the output can be directly copied into the requirements file. package = ( self.req.original_link if self.req.original_link # In case someone feeds something downright stupid # to InstallRequirement's constructor. else getattr(self.req, "req", None) ) return " {} --hash={}:{}".format( package or "unknown package", FAVORITE_HASH, self.gotten_hash ) class HashUnpinned(HashError): """A requirement had a hash specified but was not pinned to a specific version.""" order = 3 head = ( "In --require-hashes mode, all requirements must have their " "versions pinned with ==. These do not:" ) class HashMismatch(HashError): """ Distribution file hash values don't match. :ivar package_name: The name of the package that triggered the hash mismatch. Feel free to write to this after the exception is raise to improve its error message. """ order = 4 head = ( "THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS " "FILE. If you have updated the package versions, please update " "the hashes. Otherwise, examine the package contents carefully; " "someone may have tampered with them." ) def __init__(self, allowed: Dict[str, List[str]], gots: Dict[str, "_Hash"]) -> None: """ :param allowed: A dict of algorithm names pointing to lists of allowed hex digests :param gots: A dict of algorithm names pointing to hashes we actually got from the files under suspicion """ self.allowed = allowed self.gots = gots def body(self) -> str: return " {}:\n{}".format(self._requirement_name(), self._hash_comparison()) def _hash_comparison(self) -> str: """ Return a comparison of actual and expected hash values. Example:: Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde or 123451234512345123451234512345123451234512345 Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef """ def hash_then_or(hash_name: str) -> "chain[str]": # For now, all the decent hashes have 6-char names, so we can get # away with hard-coding space literals. return chain([hash_name], repeat(" or")) lines: List[str] = [] for hash_name, expecteds in self.allowed.items(): prefix = hash_then_or(hash_name) lines.extend( (" Expected {} {}".format(next(prefix), e)) for e in expecteds ) lines.append( " Got {}\n".format(self.gots[hash_name].hexdigest()) ) return "\n".join(lines) class UnsupportedPythonVersion(InstallationError): """Unsupported python version according to Requires-Python package metadata.""" class ConfigurationFileCouldNotBeLoaded(ConfigurationError): """When there are errors while loading a configuration file""" def __init__( self, reason: str = "could not be loaded", fname: Optional[str] = None, error: Optional[configparser.Error] = None, ) -> None: super().__init__(error) self.reason = reason self.fname = fname self.error = error def __str__(self) -> str: if self.fname is not None: message_part = f" in {self.fname}." else: assert self.error is not None message_part = f".\n{self.error}\n" return f"Configuration file {self.reason}{message_part}" PKH] $Wpython3.10/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-310.pycnu[o ai@stddlZddlZddlZddlZddlZddlZddlmZm Z ddl m Z m Z ddl mZddlmZmZeeZeeZeeddZdefd d Zdefd d Zdefd dZdefddZgdZ e!ddurse "d     d$dededej#edej#ededej#ede fddZ$defddZ%defddZ&defd d!Z'dedej(eeffd"d#Z)dS)%N)InvalidSchemeCombinationUserInstallationInvalid) SCHEME_KEYSScheme)running_under_virtualenv)get_major_minor_versionis_osx_frameworkget_preferred_schemereturncCsdtvo t o tS)aCheck for Apple's ``osx_framework_library`` scheme. Python distributed by Apple's Command Line Tools has this special scheme that's used when: * This is a framework build. * We are installing into the system prefix. This does not account for ``pip install --prefix`` (also means we're not installing to the system prefix), which should use ``posix_prefix``, but logic here means ``_infer_prefix()`` outputs ``osx_framework_library``. But since ``prefix`` is not available for ``sysconfig.get_default_scheme()``, which is the stdlib replacement for ``_infer_prefix()``, presumably Apple wouldn't be able to magically switch between ``osx_framework_library`` and ``posix_prefix``. ``_infer_prefix()`` returning ``osx_framework_library`` means its behavior is consistent whether we use the stdlib implementation or our own, and we deal with this special case in ``get_scheme()`` instead. osx_framework_library)_AVAILABLE_SCHEMESrr rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/locations/_sysconfig.py _should_use_osx_framework_prefixs rcCsvtrtdStr dStjjdtj}|tvr|Stjjtvr%tjjStjd}|tvr1|Stjtvr9tjSdS)a!Try to find a prefix scheme for the current platform. This tries: * A special ``osx_framework_library`` for Python distributed by Apple's Command Line Tools, when not running in a virtual environment. * Implementation + OS, used by PyPy on Windows (``pypy_nt``). * Implementation without OS, used by PyPy on POSIX (``pypy``). * OS + "prefix", used by CPython on POSIX (``posix_prefix``). * Just the OS name, used by CPython on Windows (``nt``). If none of the above works, fall back to ``posix_prefix``. prefixr __prefix posix_prefix)_PREFERRED_SCHEME_APIrsysimplementationnameosr )implementation_suffixedsuffixedrrr _infer_prefix8s   rcCsHtrtdStrtsd}ntjd}|tvr|Sdtvr"tdS)z3Try to find a user scheme for the current platform.userosx_framework_user_user posix_user)rr rrrr rrrrr _infer_userWs  r"cCs(trtdStjd}|tvr|SdS)z,Try to find a home for the current platform.home_home posix_home)rrrr r!rrr _infer_homefs  r&)installed_basebaseinstalled_platbaseplatbaser exec_prefixuserbaseF dist_namerr#rootisolatedrcs^|r r tddrrtdddurt}n |r t}nt}dur-|dkr-d}dur;fddtD}ndurIfd dtD}ni}tj||d }trx|r_|d t j } n|d t j } d t } t j | dd| |d<n|s|d}t|d|dt j |d||d|dd} |durtD]} tj|t| | } t| | | q| S)a\ Get the "scheme" corresponding to the input parameters. :param dist_name: the name of the package to retrieve the scheme for, used in the headers scheme path :param user: indicates to use the "user" scheme :param home: indicates to use the "home" scheme :param root: root under which other directories are re-based :param isolated: ignored, but kept for distutils compatibility (where this controls whether the user-site pydistutils.cfg is honored) :param prefix: indicates to use the "prefix" scheme and provides the base directory for the same z--userz--prefixz--homeNr rci|]}|qSrr.0k)r#rr zget_scheme..cr0rrr1)rrrr4r5)schemevarsr,r(pythonincludesiteUNKNOWNplatlibpurelibscriptsdata)r<r=headersr>r?)rr&r"r _HOME_KEYS sysconfig get_pathsrgetrrrrpathjoinrr distutilsutil change_rootgetattrsetattr)r-rr#r.r/r scheme_name variablespathsr( python_xyr6keyvaluer)r#rr get_scheme}sJ   rRcCs4tjdddkrtjdddkrdStdS)Ndarwinz/System/Library/z/usr/local/binr>)rplatformrrBrCrrrrget_bin_prefixs$ rWcC tdS)Nr=rBrCrrrr get_purelib rZcCrX)Nr<rYrrrr get_platlibr[r\cCs"tj||dd}|d|dfS)N)r(r*)r7r=r<rY)rrNrrrget_prefixed_libssr])FNNFN)*distutils.utilrGloggingrrrBtypingpip._internal.exceptionsrrpip._internal.models.schemerrpip._internal.utils.virtualenvrr(rr getLogger__name__loggersetget_scheme_namesr rJrboolrstrrr"r&rAget_config_varappendOptionalrRrWrZr\Tupler]rrrrsX      M PKH]\!)!)Upython3.10/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-310.pycnu[o ail8@sUddlZddlZddlZddlZddlZddlZddlmZmZm Z m Z m Z m Z ddl mZmZddlmZddlmZddlmZddlmZmZdd lmZmZmZmZmZmZgd Z e!e"Z#ej$%d rnej&Z'nej(Z'e)ed d Z*e+e,d<ej-dkZ.de/fddZ0dee+e+fde/fddZ1ej2ddde/fddZ3ej2ddde/fddZ4ej2ddde/fddZ5ej2ddde/fddZ6de e+de e+fd d!Z7ej2ddd"ej8d#ej8d$e+ddfd%d&Z9d"ej8d#ej8d$e+de/fd'd(Z:ej2ddd)dddd*d+e/d,e e+d-e e+d.e e+ddf d/d0Z; )   ) dFd1e+d+e/d,e e+d-e e+d2e/d.e e+defd3d4Zd9e+de/fd:d;Z?de+fdd?ZAd@e+dAe+de e+fdBdCZBd.e+de e+fdDdEZCdS)GN)AnyDictIteratorListOptionalTuple) SCHEME_KEYSScheme)WINDOWS) deprecated)running_under_virtualenv) _distutils _sysconfig)USER_CACHE_DIRget_major_minor_versionget_src_prefixis_osx_framework site_packages user_site) rget_bin_prefix get_bin_userr get_platlibget_prefixed_libs get_purelib get_schemerrrZ"_PIP_LOCATIONS_NO_WARN_ON_MISMATCH platlibdirlib _PLATLIBDIR) returncCs8ddlm}z |dd}W|dkStyYdSw)zsThe resolution to bpo-44860 will change this incorrect platlib. See . rINSTALL_SCHEMES unix_userplatlibFz $usersite)distutils.command.installr#KeyError)r#unix_user_platlibr)/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/locations/__init__.py_looks_like_bpo_448603s  r+schemecCs\|d}d|vrttdr|ddtjd}d|vrdS|dd}|dd |d kS) Nr%z /$platlibdir/r/z/lib64/Fz/lib/z $platbase/z$base/purelib)hasattrsysreplacer)r,r% unpatchedr)r)r*+_looks_like_red_hat_patched_platlib_purelibAs r3)maxsizecs"ddlmtfdddDS)zRed Hat patches platlib in unix_prefix and unix_home, but not purelib. This is the only way I can see to tell a Red Hat-patched Python. rr"c3s$|] }|vo t|VqdSN)r3.0kr"r)r* Ss   z*_looks_like_red_hat_lib..) unix_prefix unix_home)r&r#allr)r)r"r*_looks_like_red_hat_libKs  r=cCsddlm}d|vo d|vS)z#Debian adds two additional schemes.rr" deb_system unix_local)r&r#r"r)r)r*_looks_like_debian_schemeZs r@cCs^ddlm}ddlm}||}||jtjt jdko.|j tjt j dkS)a\Red Hat patches ``sys.prefix`` and ``sys.exec_prefix``. Red Hat's ``00251-change-user-install-location.patch`` changes the install command's ``prefix`` and ``exec_prefix`` to append ``"/local"``. This is (fortunately?) done quite unconditionally, so we create a default command object without any configuration to detect this. r)install) Distributionz/local) r&rAdistutils.distrBfinalize_options exec_prefixospathnormpathr0prefix)rArBcmdr)r)r*_looks_like_red_hat_schemebs  rKcs.tjdddtddfdddDDS)aMSYS2 patches distutils and sysconfig to use a UNIX-like scheme. However, MSYS2 incorrectly patches sysconfig ``nt`` scheme. The fix is likely going to be included in their 3.10 release, so we ignore the warning. See msys2/MINGW-packages#9319. MSYS2 MINGW's patch uses lowercase ``"lib"`` instead of the usual uppercase, and is missing the final ``"site-packages"``. ntF)expandcss,|]}d|vod|vo|d VqdS)Librz site-packagesN)endswith)r7pr)r)r*r9s  z1_looks_like_msys2_mingw_scheme..c3s|]}|VqdSr5r))r7keypathsr)r*r9sr%r.) sysconfig get_pathsr<r)r)rRr*_looks_like_msys2_mingw_schemevs rWpartsccsjtd}ttdd}|r|r||s|EdHdS|D]}||r/|ddt|}|VqdS)N LDVERSIONabiflagsr)rUget_config_vargetattrr0rOlen)rX ldversionrZpartr)r)r* _fix_abiflagss    r`oldnewrQcCs d}d}tt|||||dS)Nz(https://github.com/pypa/pip/issues/10151zSValue for %s does not match. Please report this to <%s> distutils: %s sysconfig: %s)loggerlog_MISMATCH_LEVEL)rarbrQ issue_urlmessager)r)r*_warn_mismatchedsrhcCs||krdSt|||ddS)NFrQT)rh)rarbrQr)r)r*_warn_if_mismatchsrjFuserhomerootrIrlrmrnrIcCs&gd}ttd|||||dS)N)zAdditional context:z user = %rz home = %rz root = %rz prefix = %r )rcrdrejoin)rlrmrnrIrXr)r)r* _log_contextsrq dist_nameisolatedc stj||||||d}tr|Stj||||||dg}tD]}tt|} tt||} | | kr5qtj j dkoT|duoT|dvoT| j | j koT| j doT| j d} | rXq|ont on|dkon| j j | j kon| j j d} | rrq|dkrztrzq|o|dkot otjdkotdkot} | rq|p|p|pt o| jd d d kot| jd ko| jd d kot| jd kp| jd dkotpt}|rqtjdkot o|dvott| j| jk}|rqto|dvot}|rqtjddot o|dv}|rq|| | d|fq|sStj||||||ddtfddtDr2t ddddS|D] \} } }t!| | |dq4t"||||dS)N)rlrmrnrsrIpypyrTpythonheadersr%)r rr r)usrlocalrxry)r)rvr%r.T) check_home)rvinclude platincludezscheme.)ignore_config_filesc3s"|] }|t|kVqdSr5)r\r6 default_oldrar)r*r9Os zget_scheme..zConfiguring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621)reason replacementgone_inrirk)#rr_USE_SYSCONFIGrrpathlibPathr\r0implementationnameparent startswithrr=r version_inforr+r rXr]rKr@tupler`rWrUis_python_buildappenddistutils_schemeanyr rhrq)rrrlrmrnrsrIrbwarning_contextsr8old_vnew_vskip_pypy_special_case$skip_osx_framework_user_special_caseskip_bpo_44860skip_linux_system_special_caseskip_sysconfig_abiflag_bugskip_msys2_mingw_bugskip_cpython_buildrQr)rr*rs              rcCs<t}tr|St}tt|t|ddrt|S)N bin_prefixri)rrrrrjrrrqrbrar)r)r*rdsrcCstjdddjS)NT)rl)rrscriptsr)r)r)r*rosrvaluecCstsdS|dkr dSdS)aCheck if the value is Debian's APT-controlled dist-packages. Debian's ``distutils.sysconfig.get_python_lib()`` implementation returns the default package path controlled by APT, but does not patch ``sysconfig`` to do the same. This is similar to the bug worked around in ``get_scheme()``, but here the default is ``deb_system`` instead of ``unix_local``. Ultimately we can't do anything about this Debian bug, and this detection allows us to skip the warning when needed. Fz/usr/lib/python3/dist-packagesT)r@)rr)r)r*$_looks_like_deb_system_dist_packagesss  rcCHt}tr|St}t|r|Stt|t|ddr"t|S)z,Return the default pure-Python lib location.r.ri) rrrrrrjrrrqrr)r)r*rrcCr)z0Return the default platform-shared lib location.r%ri) rrrrrrjrrrqrr)r)r*rrrv1v2cCs||kr|gS||gS)zDeduplicate values from a list.r))rrr)r)r* _deduplicatedsrcCszt|\}}trt||St|\}}tt|t|ddtt|t|ddg}t|r8t |dt||S)z*Return the lib locations under ``prefix``.zprefixed-purelibrizprefixed-platlib)rI) rrrrrrjrrrrq)rInew_purenew_platold_pureold_platwarnedr)r)r*rs$   r)FNNFN)D functoolsloggingrFrr0rUtypingrrrrrrpip._internal.models.schemerr pip._internal.utils.compatr pip._internal.utils.deprecationr pip._internal.utils.virtualenvr rrrbaserrrrrr__all__ getLogger__name__rcenvirongetDEBUGreWARNINGr\rstr__annotations__rrboolr+r3 lru_cacher=r@rKrWr`rrhrjrqrrrrrrrrr)r)r)r*s                  ( PKH],,Qpython3.10/site-packages/pip/_internal/locations/__pycache__/base.cpython-310.pycnu[o ai+@sUddlZddlZddlZddlZddlZddlZddlmZddlm Z e dZ e dZ ejeed<defdd Zdefd d Zz eZejeed <Wn ey]ejZYnwejdd defddZdS)N)appdirs)running_under_virtualenvpippurelib site_packagesreturncCs djtjS)ze Return the major-minor version of the current Python as a string, e.g. "3.7" or "3.10". z{}.{})formatsys version_infor r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/locations/base.pyget_major_minor_versions r cCsXtr tjtjd}nz tjtd}Wnty%tdYnwtj |S)Nsrcz=The folder you are executing pip from can no longer be found.) rospathjoinr prefixgetcwdOSErrorexitabspath) src_prefixr r r get_src_prefixs  r user_site)maxsizecCsttdS)NPYTHONFRAMEWORK)bool sysconfigget_config_varr r r r is_osx_framework2sr) functoolsrsiter rtypingpip._internal.utilsrpip._internal.utils.virtualenvruser_cache_dirUSER_CACHE_DIRget_pathrOptionalstr__annotations__r rgetusersitepackagesrAttributeError USER_SITE lru_cacherrr r r r s&       PKH]oZZWpython3.10/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-310.pycnu[o ai@spdZddlZddlZddlZddlmZddlmZddlm Z ddl m Z ddl mZmZmZmZmZmZddlmZdd lmZdd lmZd d lmZeeZ   d#d ddede dedede dede deeeffddZ!   d#dede deedeede deedefddZ"defddZ#defddZ$defdd Z%dedeeeffd!d"Z&dS)$z7Locations where we look for configs, install stuff, etcN)Command) SCHEME_KEYS)installget_python_lib)DictListOptionalTupleUnioncast)Scheme)WINDOWS)running_under_virtualenv)get_major_minor_versionF)ignore_config_files dist_nameuserhomerootisolatedprefixrreturnc Csddlm}d|i}|rdg|d<||} |s9z| Wnty8| } tdddd | DYnwd } | jd d d } | d usHJt t | } |r[|r[Jd|d||ri|riJd|d||pm| j | _ |ss|rvd| _ |pz| j | _ |p| j | _ |p| j| _| i} tD] }t| d|| |<qd| d vr| t| j| jdtr|r|}n |r| j}n| j }tj|dddt|| d<|d urtjtj| dd}tj||dd | d<| S)z+ Return a distutils install scheme r) Distributionnamez --no-user-cfg script_argsz6Ignore distutils configs in %s due to encoding errors.z, css|] }tj|VqdS)N)ospathbasename).0pr"/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/locations/_distutils.py 4sz#distutils_scheme..NrT)createzuser=z prefix=zhome=install_ install_lib)purelibplatlibincludesitepythonheadersr)distutils.distrparse_config_filesUnicodeDecodeErrorfind_config_filesloggerwarningjoinget_command_objr distutils_install_commandrrrrfinalize_optionsrgetattrget_option_dictupdatedictr(rinstall_userbaserrr splitdriveabspath)rrrrrrrr dist_argsdpathsobjischemekey path_no_driver"r"r#distutils_schemesd           rHcCs8t||||||}t|d|d|d|d|ddS)a; Get the "scheme" corresponding to the input parameters. The distutils documentation provides the context for the available schemes: https://docs.python.org/3/install/index.html#alternate-installation :param dist_name: the name of the package to retrieve the scheme for, used in the headers scheme path :param user: indicates to use the "user" scheme :param home: indicates to use the "home" scheme and provides the base directory for the same :param root: root under which other directories are re-based :param isolated: equivalent to --no-user-cfg, i.e. do not consider ~/.pydistutils.cfg (posix) or ~/pydistutils.cfg (non-posix) for scheme paths :param prefix: indicates to use the "prefix" scheme and provides the base directory for the same r*r)r.scriptsdata)r*r)r.rIrJ)rHr )rrrrrrrEr"r"r# get_schemeisrKcCsrtjtj}trtj|d}tj|stj|d}|Stjdddkr2|dddkr2dStj|dS)NScriptsbindarwinz/System/Library/z/usr/local/bin) rrnormpathsysrrr5existsplatform)rbin_pyr"r"r#get_bin_prefixs "rVcC tddS)NF plat_specificrr"r"r"r# get_purelib rZcCrW)NTrXrr"r"r"r# get_platlibr[r\cCstd|dtd|dfS)NF)rYrTr)rr"r"r#get_prefixed_libss  r])FNNFN)'__doc__loggingrrR distutils.cmdrDistutilsCommanddistutils.command.installrrr7distutils.sysconfigrtypingrrr r r r pip._internal.models.schemer pip._internal.utils.compatrpip._internal.utils.virtualenvrbaser getLogger__name__r3strboolrHrKrVrZr\r]r"r"r"r#s|           S #PKH]8 z>python3.10/site-packages/pip/_internal/locations/_sysconfig.pynu[import distutils.util # FIXME: For change_root. import logging import os import sys import sysconfig import typing from pip._internal.exceptions import InvalidSchemeCombination, UserInstallationInvalid from pip._internal.models.scheme import SCHEME_KEYS, Scheme from pip._internal.utils.virtualenv import running_under_virtualenv from .base import get_major_minor_version, is_osx_framework logger = logging.getLogger(__name__) # Notes on _infer_* functions. # Unfortunately ``get_default_scheme()`` didn't exist before 3.10, so there's no # way to ask things like "what is the '_prefix' scheme on this platform". These # functions try to answer that with some heuristics while accounting for ad-hoc # platforms not covered by CPython's default sysconfig implementation. If the # ad-hoc implementation does not fully implement sysconfig, we'll fall back to # a POSIX scheme. _AVAILABLE_SCHEMES = set(sysconfig.get_scheme_names()) _PREFERRED_SCHEME_API = getattr(sysconfig, "get_preferred_scheme", None) def _should_use_osx_framework_prefix() -> bool: """Check for Apple's ``osx_framework_library`` scheme. Python distributed by Apple's Command Line Tools has this special scheme that's used when: * This is a framework build. * We are installing into the system prefix. This does not account for ``pip install --prefix`` (also means we're not installing to the system prefix), which should use ``posix_prefix``, but logic here means ``_infer_prefix()`` outputs ``osx_framework_library``. But since ``prefix`` is not available for ``sysconfig.get_default_scheme()``, which is the stdlib replacement for ``_infer_prefix()``, presumably Apple wouldn't be able to magically switch between ``osx_framework_library`` and ``posix_prefix``. ``_infer_prefix()`` returning ``osx_framework_library`` means its behavior is consistent whether we use the stdlib implementation or our own, and we deal with this special case in ``get_scheme()`` instead. """ return ( "osx_framework_library" in _AVAILABLE_SCHEMES and not running_under_virtualenv() and is_osx_framework() ) def _infer_prefix() -> str: """Try to find a prefix scheme for the current platform. This tries: * A special ``osx_framework_library`` for Python distributed by Apple's Command Line Tools, when not running in a virtual environment. * Implementation + OS, used by PyPy on Windows (``pypy_nt``). * Implementation without OS, used by PyPy on POSIX (``pypy``). * OS + "prefix", used by CPython on POSIX (``posix_prefix``). * Just the OS name, used by CPython on Windows (``nt``). If none of the above works, fall back to ``posix_prefix``. """ if _PREFERRED_SCHEME_API: return _PREFERRED_SCHEME_API("prefix") if _should_use_osx_framework_prefix(): return "osx_framework_library" implementation_suffixed = f"{sys.implementation.name}_{os.name}" if implementation_suffixed in _AVAILABLE_SCHEMES: return implementation_suffixed if sys.implementation.name in _AVAILABLE_SCHEMES: return sys.implementation.name suffixed = f"{os.name}_prefix" if suffixed in _AVAILABLE_SCHEMES: return suffixed if os.name in _AVAILABLE_SCHEMES: # On Windows, prefx is just called "nt". return os.name return "posix_prefix" def _infer_user() -> str: """Try to find a user scheme for the current platform.""" if _PREFERRED_SCHEME_API: return _PREFERRED_SCHEME_API("user") if is_osx_framework() and not running_under_virtualenv(): suffixed = "osx_framework_user" else: suffixed = f"{os.name}_user" if suffixed in _AVAILABLE_SCHEMES: return suffixed if "posix_user" not in _AVAILABLE_SCHEMES: # User scheme unavailable. raise UserInstallationInvalid() return "posix_user" def _infer_home() -> str: """Try to find a home for the current platform.""" if _PREFERRED_SCHEME_API: return _PREFERRED_SCHEME_API("home") suffixed = f"{os.name}_home" if suffixed in _AVAILABLE_SCHEMES: return suffixed return "posix_home" # Update these keys if the user sets a custom home. _HOME_KEYS = [ "installed_base", "base", "installed_platbase", "platbase", "prefix", "exec_prefix", ] if sysconfig.get_config_var("userbase") is not None: _HOME_KEYS.append("userbase") def get_scheme( dist_name: str, user: bool = False, home: typing.Optional[str] = None, root: typing.Optional[str] = None, isolated: bool = False, prefix: typing.Optional[str] = None, ) -> Scheme: """ Get the "scheme" corresponding to the input parameters. :param dist_name: the name of the package to retrieve the scheme for, used in the headers scheme path :param user: indicates to use the "user" scheme :param home: indicates to use the "home" scheme :param root: root under which other directories are re-based :param isolated: ignored, but kept for distutils compatibility (where this controls whether the user-site pydistutils.cfg is honored) :param prefix: indicates to use the "prefix" scheme and provides the base directory for the same """ if user and prefix: raise InvalidSchemeCombination("--user", "--prefix") if home and prefix: raise InvalidSchemeCombination("--home", "--prefix") if home is not None: scheme_name = _infer_home() elif user: scheme_name = _infer_user() else: scheme_name = _infer_prefix() # Special case: When installing into a custom prefix, use posix_prefix # instead of osx_framework_library. See _should_use_osx_framework_prefix() # docstring for details. if prefix is not None and scheme_name == "osx_framework_library": scheme_name = "posix_prefix" if home is not None: variables = {k: home for k in _HOME_KEYS} elif prefix is not None: variables = {k: prefix for k in _HOME_KEYS} else: variables = {} paths = sysconfig.get_paths(scheme=scheme_name, vars=variables) # Logic here is very arbitrary, we're doing it for compatibility, don't ask. # 1. Pip historically uses a special header path in virtual environments. # 2. If the distribution name is not known, distutils uses 'UNKNOWN'. We # only do the same when not running in a virtual environment because # pip's historical header path logic (see point 1) did not do this. if running_under_virtualenv(): if user: base = variables.get("userbase", sys.prefix) else: base = variables.get("base", sys.prefix) python_xy = f"python{get_major_minor_version()}" paths["include"] = os.path.join(base, "include", "site", python_xy) elif not dist_name: dist_name = "UNKNOWN" scheme = Scheme( platlib=paths["platlib"], purelib=paths["purelib"], headers=os.path.join(paths["include"], dist_name), scripts=paths["scripts"], data=paths["data"], ) if root is not None: for key in SCHEME_KEYS: value = distutils.util.change_root(root, getattr(scheme, key)) setattr(scheme, key, value) return scheme def get_bin_prefix() -> str: # Forcing to use /usr/local/bin for standard macOS framework installs. if sys.platform[:6] == "darwin" and sys.prefix[:16] == "/System/Library/": return "/usr/local/bin" return sysconfig.get_paths()["scripts"] def get_purelib() -> str: return sysconfig.get_paths()["purelib"] def get_platlib() -> str: return sysconfig.get_paths()["platlib"] def get_prefixed_libs(prefix: str) -> typing.Tuple[str, str]: paths = sysconfig.get_paths(vars={"base": prefix, "platbase": prefix}) return (paths["purelib"], paths["platlib"]) PKH]Y++8python3.10/site-packages/pip/_internal/locations/base.pynu[import functools import os import site import sys import sysconfig import typing from pip._internal.utils import appdirs from pip._internal.utils.virtualenv import running_under_virtualenv # Application Directories USER_CACHE_DIR = appdirs.user_cache_dir("pip") # FIXME doesn't account for venv linked to global site-packages site_packages: typing.Optional[str] = sysconfig.get_path("purelib") def get_major_minor_version() -> str: """ Return the major-minor version of the current Python as a string, e.g. "3.7" or "3.10". """ return "{}.{}".format(*sys.version_info) def get_src_prefix() -> str: if running_under_virtualenv(): src_prefix = os.path.join(sys.prefix, "src") else: # FIXME: keep src in cwd for now (it is not a temporary folder) try: src_prefix = os.path.join(os.getcwd(), "src") except OSError: # In case the current working directory has been renamed or deleted sys.exit("The folder you are executing pip from can no longer be found.") # under macOS + virtualenv sys.prefix is not properly resolved # it is something like /path/to/python/bin/.. return os.path.abspath(src_prefix) try: # Use getusersitepackages if this is present, as it ensures that the # value is initialised properly. user_site: typing.Optional[str] = site.getusersitepackages() except AttributeError: user_site = site.USER_SITE @functools.lru_cache(maxsize=None) def is_osx_framework() -> bool: return bool(sysconfig.get_config_var("PYTHONFRAMEWORK")) PKH]őkl8l8<python3.10/site-packages/pip/_internal/locations/__init__.pynu[import functools import logging import os import pathlib import sys import sysconfig from typing import Any, Dict, Iterator, List, Optional, Tuple from pip._internal.models.scheme import SCHEME_KEYS, Scheme from pip._internal.utils.compat import WINDOWS from pip._internal.utils.deprecation import deprecated from pip._internal.utils.virtualenv import running_under_virtualenv from . import _distutils, _sysconfig from .base import ( USER_CACHE_DIR, get_major_minor_version, get_src_prefix, is_osx_framework, site_packages, user_site, ) __all__ = [ "USER_CACHE_DIR", "get_bin_prefix", "get_bin_user", "get_major_minor_version", "get_platlib", "get_prefixed_libs", "get_purelib", "get_scheme", "get_src_prefix", "site_packages", "user_site", ] logger = logging.getLogger(__name__) if os.environ.get("_PIP_LOCATIONS_NO_WARN_ON_MISMATCH"): _MISMATCH_LEVEL = logging.DEBUG else: _MISMATCH_LEVEL = logging.WARNING _PLATLIBDIR: str = getattr(sys, "platlibdir", "lib") _USE_SYSCONFIG = sys.version_info >= (3, 10) def _looks_like_bpo_44860() -> bool: """The resolution to bpo-44860 will change this incorrect platlib. See . """ from distutils.command.install import INSTALL_SCHEMES # type: ignore try: unix_user_platlib = INSTALL_SCHEMES["unix_user"]["platlib"] except KeyError: return False return unix_user_platlib == "$usersite" def _looks_like_red_hat_patched_platlib_purelib(scheme: Dict[str, str]) -> bool: platlib = scheme["platlib"] if "/$platlibdir/" in platlib and hasattr(sys, "platlibdir"): platlib = platlib.replace("/$platlibdir/", f"/{sys.platlibdir}/") if "/lib64/" not in platlib: return False unpatched = platlib.replace("/lib64/", "/lib/") return unpatched.replace("$platbase/", "$base/") == scheme["purelib"] @functools.lru_cache(maxsize=None) def _looks_like_red_hat_lib() -> bool: """Red Hat patches platlib in unix_prefix and unix_home, but not purelib. This is the only way I can see to tell a Red Hat-patched Python. """ from distutils.command.install import INSTALL_SCHEMES # type: ignore return all( k in INSTALL_SCHEMES and _looks_like_red_hat_patched_platlib_purelib(INSTALL_SCHEMES[k]) for k in ("unix_prefix", "unix_home") ) @functools.lru_cache(maxsize=None) def _looks_like_debian_scheme() -> bool: """Debian adds two additional schemes.""" from distutils.command.install import INSTALL_SCHEMES # type: ignore return "deb_system" in INSTALL_SCHEMES and "unix_local" in INSTALL_SCHEMES @functools.lru_cache(maxsize=None) def _looks_like_red_hat_scheme() -> bool: """Red Hat patches ``sys.prefix`` and ``sys.exec_prefix``. Red Hat's ``00251-change-user-install-location.patch`` changes the install command's ``prefix`` and ``exec_prefix`` to append ``"/local"``. This is (fortunately?) done quite unconditionally, so we create a default command object without any configuration to detect this. """ from distutils.command.install import install from distutils.dist import Distribution cmd: Any = install(Distribution()) cmd.finalize_options() return ( cmd.exec_prefix == f"{os.path.normpath(sys.exec_prefix)}/local" and cmd.prefix == f"{os.path.normpath(sys.prefix)}/local" ) @functools.lru_cache(maxsize=None) def _looks_like_msys2_mingw_scheme() -> bool: """MSYS2 patches distutils and sysconfig to use a UNIX-like scheme. However, MSYS2 incorrectly patches sysconfig ``nt`` scheme. The fix is likely going to be included in their 3.10 release, so we ignore the warning. See msys2/MINGW-packages#9319. MSYS2 MINGW's patch uses lowercase ``"lib"`` instead of the usual uppercase, and is missing the final ``"site-packages"``. """ paths = sysconfig.get_paths("nt", expand=False) return all( "Lib" not in p and "lib" in p and not p.endswith("site-packages") for p in (paths[key] for key in ("platlib", "purelib")) ) def _fix_abiflags(parts: Tuple[str]) -> Iterator[str]: ldversion = sysconfig.get_config_var("LDVERSION") abiflags: str = getattr(sys, "abiflags", None) # LDVERSION does not end with sys.abiflags. Just return the path unchanged. if not ldversion or not abiflags or not ldversion.endswith(abiflags): yield from parts return # Strip sys.abiflags from LDVERSION-based path components. for part in parts: if part.endswith(ldversion): part = part[: (0 - len(abiflags))] yield part @functools.lru_cache(maxsize=None) def _warn_mismatched(old: pathlib.Path, new: pathlib.Path, *, key: str) -> None: issue_url = "https://github.com/pypa/pip/issues/10151" message = ( "Value for %s does not match. Please report this to <%s>" "\ndistutils: %s" "\nsysconfig: %s" ) logger.log(_MISMATCH_LEVEL, message, key, issue_url, old, new) def _warn_if_mismatch(old: pathlib.Path, new: pathlib.Path, *, key: str) -> bool: if old == new: return False _warn_mismatched(old, new, key=key) return True @functools.lru_cache(maxsize=None) def _log_context( *, user: bool = False, home: Optional[str] = None, root: Optional[str] = None, prefix: Optional[str] = None, ) -> None: parts = [ "Additional context:", "user = %r", "home = %r", "root = %r", "prefix = %r", ] logger.log(_MISMATCH_LEVEL, "\n".join(parts), user, home, root, prefix) def get_scheme( dist_name: str, user: bool = False, home: Optional[str] = None, root: Optional[str] = None, isolated: bool = False, prefix: Optional[str] = None, ) -> Scheme: new = _sysconfig.get_scheme( dist_name, user=user, home=home, root=root, isolated=isolated, prefix=prefix, ) if _USE_SYSCONFIG: return new old = _distutils.get_scheme( dist_name, user=user, home=home, root=root, isolated=isolated, prefix=prefix, ) warning_contexts = [] for k in SCHEME_KEYS: old_v = pathlib.Path(getattr(old, k)) new_v = pathlib.Path(getattr(new, k)) if old_v == new_v: continue # distutils incorrectly put PyPy packages under ``site-packages/python`` # in the ``posix_home`` scheme, but PyPy devs said they expect the # directory name to be ``pypy`` instead. So we treat this as a bug fix # and not warn about it. See bpo-43307 and python/cpython#24628. skip_pypy_special_case = ( sys.implementation.name == "pypy" and home is not None and k in ("platlib", "purelib") and old_v.parent == new_v.parent and old_v.name.startswith("python") and new_v.name.startswith("pypy") ) if skip_pypy_special_case: continue # sysconfig's ``osx_framework_user`` does not include ``pythonX.Y`` in # the ``include`` value, but distutils's ``headers`` does. We'll let # CPython decide whether this is a bug or feature. See bpo-43948. skip_osx_framework_user_special_case = ( user and is_osx_framework() and k == "headers" and old_v.parent.parent == new_v.parent and old_v.parent.name.startswith("python") ) if skip_osx_framework_user_special_case: continue # On Red Hat and derived Linux distributions, distutils is patched to # use "lib64" instead of "lib" for platlib. if k == "platlib" and _looks_like_red_hat_lib(): continue # On Python 3.9+, sysconfig's posix_user scheme sets platlib against # sys.platlibdir, but distutils's unix_user incorrectly coninutes # using the same $usersite for both platlib and purelib. This creates a # mismatch when sys.platlibdir is not "lib". skip_bpo_44860 = ( user and k == "platlib" and not WINDOWS and sys.version_info >= (3, 9) and _PLATLIBDIR != "lib" and _looks_like_bpo_44860() ) if skip_bpo_44860: continue # Both Debian and Red Hat patch Python to place the system site under # /usr/local instead of /usr. Debian also places lib in dist-packages # instead of site-packages, but the /usr/local check should cover it. skip_linux_system_special_case = ( not (user or home or prefix or running_under_virtualenv()) and old_v.parts[1:3] == ("usr", "local") and len(new_v.parts) > 1 and new_v.parts[1] == "usr" and (len(new_v.parts) < 3 or new_v.parts[2] != "local") and (_looks_like_red_hat_scheme() or _looks_like_debian_scheme()) ) if skip_linux_system_special_case: continue # On Python 3.7 and earlier, sysconfig does not include sys.abiflags in # the "pythonX.Y" part of the path, but distutils does. skip_sysconfig_abiflag_bug = ( sys.version_info < (3, 8) and not WINDOWS and k in ("headers", "platlib", "purelib") and tuple(_fix_abiflags(old_v.parts)) == new_v.parts ) if skip_sysconfig_abiflag_bug: continue # MSYS2 MINGW's sysconfig patch does not include the "site-packages" # part of the path. This is incorrect and will be fixed in MSYS. skip_msys2_mingw_bug = ( WINDOWS and k in ("platlib", "purelib") and _looks_like_msys2_mingw_scheme() ) if skip_msys2_mingw_bug: continue # CPython's POSIX install script invokes pip (via ensurepip) against the # interpreter located in the source tree, not the install site. This # triggers special logic in sysconfig that's not present in distutils. # https://github.com/python/cpython/blob/8c21941ddaf/Lib/sysconfig.py#L178-L194 skip_cpython_build = ( sysconfig.is_python_build(check_home=True) and not WINDOWS and k in ("headers", "include", "platinclude") ) if skip_cpython_build: continue warning_contexts.append((old_v, new_v, f"scheme.{k}")) if not warning_contexts: return old # Check if this path mismatch is caused by distutils config files. Those # files will no longer work once we switch to sysconfig, so this raises a # deprecation message for them. default_old = _distutils.distutils_scheme( dist_name, user, home, root, isolated, prefix, ignore_config_files=True, ) if any(default_old[k] != getattr(old, k) for k in SCHEME_KEYS): deprecated( reason=( "Configuring installation scheme with distutils config files " "is deprecated and will no longer work in the near future. If you " "are using a Homebrew or Linuxbrew Python, please see discussion " "at https://github.com/Homebrew/homebrew-core/issues/76621" ), replacement=None, gone_in=None, ) return old # Post warnings about this mismatch so user can report them back. for old_v, new_v, key in warning_contexts: _warn_mismatched(old_v, new_v, key=key) _log_context(user=user, home=home, root=root, prefix=prefix) return old def get_bin_prefix() -> str: new = _sysconfig.get_bin_prefix() if _USE_SYSCONFIG: return new old = _distutils.get_bin_prefix() if _warn_if_mismatch(pathlib.Path(old), pathlib.Path(new), key="bin_prefix"): _log_context() return old def get_bin_user() -> str: return _sysconfig.get_scheme("", user=True).scripts def _looks_like_deb_system_dist_packages(value: str) -> bool: """Check if the value is Debian's APT-controlled dist-packages. Debian's ``distutils.sysconfig.get_python_lib()`` implementation returns the default package path controlled by APT, but does not patch ``sysconfig`` to do the same. This is similar to the bug worked around in ``get_scheme()``, but here the default is ``deb_system`` instead of ``unix_local``. Ultimately we can't do anything about this Debian bug, and this detection allows us to skip the warning when needed. """ if not _looks_like_debian_scheme(): return False if value == "/usr/lib/python3/dist-packages": return True return False def get_purelib() -> str: """Return the default pure-Python lib location.""" new = _sysconfig.get_purelib() if _USE_SYSCONFIG: return new old = _distutils.get_purelib() if _looks_like_deb_system_dist_packages(old): return old if _warn_if_mismatch(pathlib.Path(old), pathlib.Path(new), key="purelib"): _log_context() return old def get_platlib() -> str: """Return the default platform-shared lib location.""" new = _sysconfig.get_platlib() if _USE_SYSCONFIG: return new old = _distutils.get_platlib() if _looks_like_deb_system_dist_packages(old): return old if _warn_if_mismatch(pathlib.Path(old), pathlib.Path(new), key="platlib"): _log_context() return old def _deduplicated(v1: str, v2: str) -> List[str]: """Deduplicate values from a list.""" if v1 == v2: return [v1] return [v1, v2] def get_prefixed_libs(prefix: str) -> List[str]: """Return the lib locations under ``prefix``.""" new_pure, new_plat = _sysconfig.get_prefixed_libs(prefix) if _USE_SYSCONFIG: return _deduplicated(new_pure, new_plat) old_pure, old_plat = _distutils.get_prefixed_libs(prefix) warned = [ _warn_if_mismatch( pathlib.Path(old_pure), pathlib.Path(new_pure), key="prefixed-purelib", ), _warn_if_mismatch( pathlib.Path(old_plat), pathlib.Path(new_plat), key="prefixed-platlib", ), ] if any(warned): _log_context(prefix=prefix) return _deduplicated(old_pure, old_plat) PKH]ڝ>python3.10/site-packages/pip/_internal/locations/_distutils.pynu["""Locations where we look for configs, install stuff, etc""" # The following comment should be removed at some point in the future. # mypy: strict-optional=False import logging import os import sys from distutils.cmd import Command as DistutilsCommand from distutils.command.install import SCHEME_KEYS from distutils.command.install import install as distutils_install_command from distutils.sysconfig import get_python_lib from typing import Dict, List, Optional, Tuple, Union, cast from pip._internal.models.scheme import Scheme from pip._internal.utils.compat import WINDOWS from pip._internal.utils.virtualenv import running_under_virtualenv from .base import get_major_minor_version logger = logging.getLogger(__name__) def distutils_scheme( dist_name: str, user: bool = False, home: str = None, root: str = None, isolated: bool = False, prefix: str = None, *, ignore_config_files: bool = False, ) -> Dict[str, str]: """ Return a distutils install scheme """ from distutils.dist import Distribution dist_args: Dict[str, Union[str, List[str]]] = {"name": dist_name} if isolated: dist_args["script_args"] = ["--no-user-cfg"] d = Distribution(dist_args) if not ignore_config_files: try: d.parse_config_files() except UnicodeDecodeError: # Typeshed does not include find_config_files() for some reason. paths = d.find_config_files() # type: ignore logger.warning( "Ignore distutils configs in %s due to encoding errors.", ", ".join(os.path.basename(p) for p in paths), ) obj: Optional[DistutilsCommand] = None obj = d.get_command_obj("install", create=True) assert obj is not None i = cast(distutils_install_command, obj) # NOTE: setting user or home has the side-effect of creating the home dir # or user base for installations during finalize_options() # ideally, we'd prefer a scheme class that has no side-effects. assert not (user and prefix), f"user={user} prefix={prefix}" assert not (home and prefix), f"home={home} prefix={prefix}" i.user = user or i.user if user or home: i.prefix = "" i.prefix = prefix or i.prefix i.home = home or i.home i.root = root or i.root i.finalize_options() scheme = {} for key in SCHEME_KEYS: scheme[key] = getattr(i, "install_" + key) # install_lib specified in setup.cfg should install *everything* # into there (i.e. it takes precedence over both purelib and # platlib). Note, i.install_lib is *always* set after # finalize_options(); we only want to override here if the user # has explicitly requested it hence going back to the config if "install_lib" in d.get_option_dict("install"): scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib)) if running_under_virtualenv(): if home: prefix = home elif user: prefix = i.install_userbase # type: ignore else: prefix = i.prefix scheme["headers"] = os.path.join( prefix, "include", "site", f"python{get_major_minor_version()}", dist_name, ) if root is not None: path_no_drive = os.path.splitdrive(os.path.abspath(scheme["headers"]))[1] scheme["headers"] = os.path.join(root, path_no_drive[1:]) return scheme def get_scheme( dist_name: str, user: bool = False, home: Optional[str] = None, root: Optional[str] = None, isolated: bool = False, prefix: Optional[str] = None, ) -> Scheme: """ Get the "scheme" corresponding to the input parameters. The distutils documentation provides the context for the available schemes: https://docs.python.org/3/install/index.html#alternate-installation :param dist_name: the name of the package to retrieve the scheme for, used in the headers scheme path :param user: indicates to use the "user" scheme :param home: indicates to use the "home" scheme and provides the base directory for the same :param root: root under which other directories are re-based :param isolated: equivalent to --no-user-cfg, i.e. do not consider ~/.pydistutils.cfg (posix) or ~/pydistutils.cfg (non-posix) for scheme paths :param prefix: indicates to use the "prefix" scheme and provides the base directory for the same """ scheme = distutils_scheme(dist_name, user, home, root, isolated, prefix) return Scheme( platlib=scheme["platlib"], purelib=scheme["purelib"], headers=scheme["headers"], scripts=scheme["scripts"], data=scheme["data"], ) def get_bin_prefix() -> str: # XXX: In old virtualenv versions, sys.prefix can contain '..' components, # so we need to call normpath to eliminate them. prefix = os.path.normpath(sys.prefix) if WINDOWS: bin_py = os.path.join(prefix, "Scripts") # buildout uses 'bin' on Windows too? if not os.path.exists(bin_py): bin_py = os.path.join(prefix, "bin") return bin_py # Forcing to use /usr/local/bin for standard macOS framework installs # Also log to ~/Library/Logs/ for use with the Console.app log viewer if sys.platform[:6] == "darwin" and prefix[:16] == "/System/Library/": return "/usr/local/bin" return os.path.join(prefix, "bin") def get_purelib() -> str: return get_python_lib(plat_specific=False) def get_platlib() -> str: return get_python_lib(plat_specific=True) def get_prefixed_libs(prefix: str) -> Tuple[str, str]: return ( get_python_lib(plat_specific=False, prefix=prefix), get_python_lib(plat_specific=True, prefix=prefix), ) PKH]'TT.python3.10/site-packages/pip/_internal/main.pynu[from typing import List, Optional def main(args: Optional[List[str]] = None) -> int: """This is preserved for old console scripts that may still be referencing it. For additional details, see https://github.com/pypa/pip/issues/7498. """ from pip._internal.utils.entrypoints import _wrapper return _wrapper(args) PKH]J=python3.10/site-packages/pip/_internal/distributions/sdist.pynu[import logging from typing import Iterable, Set, Tuple from pip._internal.build_env import BuildEnvironment from pip._internal.distributions.base import AbstractDistribution from pip._internal.exceptions import InstallationError from pip._internal.index.package_finder import PackageFinder from pip._internal.metadata import BaseDistribution from pip._internal.utils.subprocess import runner_with_spinner_message logger = logging.getLogger(__name__) class SourceDistribution(AbstractDistribution): """Represents a source distribution. The preparation step for these needs metadata for the packages to be generated, either using PEP 517 or using the legacy `setup.py egg_info`. """ def get_metadata_distribution(self) -> BaseDistribution: from pip._internal.metadata.pkg_resources import Distribution as _Dist return _Dist(self.req.get_dist()) def prepare_distribution_metadata( self, finder: PackageFinder, build_isolation: bool ) -> None: # Load pyproject.toml, to determine whether PEP 517 is to be used self.req.load_pyproject_toml() # Set up the build isolation, if this requirement should be isolated should_isolate = self.req.use_pep517 and build_isolation if should_isolate: # Setup an isolated environment and install the build backend static # requirements in it. self._prepare_build_backend(finder) # Check that if the requirement is editable, it either supports PEP 660 or # has a setup.py or a setup.cfg. This cannot be done earlier because we need # to setup the build backend to verify it supports build_editable, nor can # it be done later, because we want to avoid installing build requirements # needlessly. Doing it here also works around setuptools generating # UNKNOWN.egg-info when running get_requires_for_build_wheel on a directory # without setup.py nor setup.cfg. self.req.isolated_editable_sanity_check() # Install the dynamic build requirements. self._install_build_reqs(finder) self.req.prepare_metadata() def _prepare_build_backend(self, finder: PackageFinder) -> None: # Isolate in a BuildEnvironment and install the build-time # requirements. pyproject_requires = self.req.pyproject_requires assert pyproject_requires is not None self.req.build_env = BuildEnvironment() self.req.build_env.install_requirements( finder, pyproject_requires, "overlay", "Installing build dependencies" ) conflicting, missing = self.req.build_env.check_requirements( self.req.requirements_to_check ) if conflicting: self._raise_conflicts("PEP 517/518 supported requirements", conflicting) if missing: logger.warning( "Missing build requirements in pyproject.toml for %s.", self.req, ) logger.warning( "The project does not specify a build backend, and " "pip cannot fall back to setuptools without %s.", " and ".join(map(repr, sorted(missing))), ) def _get_build_requires_wheel(self) -> Iterable[str]: with self.req.build_env: runner = runner_with_spinner_message("Getting requirements to build wheel") backend = self.req.pep517_backend assert backend is not None with backend.subprocess_runner(runner): return backend.get_requires_for_build_wheel() def _get_build_requires_editable(self) -> Iterable[str]: with self.req.build_env: runner = runner_with_spinner_message( "Getting requirements to build editable" ) backend = self.req.pep517_backend assert backend is not None with backend.subprocess_runner(runner): return backend.get_requires_for_build_editable() def _install_build_reqs(self, finder: PackageFinder) -> None: # Install any extra build dependencies that the backend requests. # This must be done in a second pass, as the pyproject.toml # dependencies must be installed before we can call the backend. if ( self.req.editable and self.req.permit_editable_wheels and self.req.supports_pyproject_editable() ): build_reqs = self._get_build_requires_editable() else: build_reqs = self._get_build_requires_wheel() conflicting, missing = self.req.build_env.check_requirements(build_reqs) if conflicting: self._raise_conflicts("the backend dependencies", conflicting) self.req.build_env.install_requirements( finder, missing, "normal", "Installing backend dependencies" ) def _raise_conflicts( self, conflicting_with: str, conflicting_reqs: Set[Tuple[str, str]] ) -> None: format_string = ( "Some build dependencies for {requirement} " "conflict with {conflicting_with}: {description}." ) error_message = format_string.format( requirement=self.req, conflicting_with=conflicting_with, description=", ".join( f"{installed} is incompatible with {wanted}" for installed, wanted in sorted(conflicting_reqs) ), ) raise InstallationError(error_message) PKH]q') VVZpython3.10/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-310.pycnu[o ai@s8ddlmZddlmZddlmZGdddeZdS))AbstractDistribution) PackageFinder)BaseDistributionc@s4eZdZdZdefddZdededdfdd ZdS) InstalledDistributionzRepresents an installed package. This does not need any preparation as the required information has already been computed. returncCs,ddlm}|jjdusJd||jjS)Nr) Distributionznot actually installed)$pip._internal.metadata.pkg_resourcesrreq satisfied_by)self_Distr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/distributions/installed.pyget_metadata_distribution s  z/InstalledDistribution.get_metadata_distributionfinderbuild_isolationNcCsdS)Nr )r rrr r rprepare_distribution_metadatasz3InstalledDistribution.prepare_distribution_metadata) __name__ __module__ __qualname____doc__rrrboolrr r r rrsrN) pip._internal.distributions.baser"pip._internal.index.package_finderrpip._internal.metadatarrr r r rs  PKH]@>KKYpython3.10/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-310.pycnu[o aiZ@sFddlmZddlmZddlmZddlmZdedefddZd S) )AbstractDistribution)SourceDistribution)WheelDistribution)InstallRequirement install_reqreturncCs$|jrt|S|jrt|St|S)z7Returns a Distribution for the given InstallRequirement)editableris_wheelr)rr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/distributions/__init__.py)make_distribution_for_install_requirements r N) pip._internal.distributions.baser!pip._internal.distributions.sdistr!pip._internal.distributions.wheelrpip._internal.req.req_installrr r r r r s   PKH].ҔllUpython3.10/site-packages/pip/_internal/distributions/__pycache__/base.cpython-310.pycnu[o ai@sDddlZddlmZddlmZddlmZGdddejdZdS)N) PackageFinder)BaseDistribution)InstallRequirementcsZeZdZdZdeddffdd ZejdefddZ ejd e d e ddfd d Z Z S) AbstractDistributiona A base class for handling installable artifacts. The requirements for anything installable are as follows: - we must be able to determine the requirement name (or we can't correctly handle the non-upgrade case). - for packages with setup requirements, we must also be able to determine their requirements without installing additional packages (for the same reason as run-time dependencies) - we must be able to create a Distribution object exposing the above metadata. reqreturnNcst||_dSN)super__init__r)selfr __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/distributions/base.pyr s  zAbstractDistribution.__init__cCtrNotImplementedError)r rrrget_metadata_distributionsz.AbstractDistribution.get_metadata_distributionfinderbuild_isolationcCrrr)r rrrrrprepare_distribution_metadata sz2AbstractDistribution.prepare_distribution_metadata)__name__ __module__ __qualname____doc__rr abcabstractmethodrrrboolr __classcell__rrr rrsr) metaclass) r"pip._internal.index.package_finderrZpip._internal.metadata.baserpip._internal.reqrABCMetarrrrrs    PKH].XVpython3.10/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-310.pycnu[o ai@sddlZddlmZmZmZddlmZddlmZddl m Z ddl m Z ddl mZddlmZeeZGd d d eZdS) N)IterableSetTuple)BuildEnvironment)AbstractDistribution)InstallationError) PackageFinder)BaseDistribution)runner_with_spinner_messagec@seZdZdZdefddZdededdfdd Zdeddfd d Z de e fd d Z de e fddZ deddfddZde deee e fddfddZdS)SourceDistributionzRepresents a source distribution. The preparation step for these needs metadata for the packages to be generated, either using PEP 517 or using the legacy `setup.py egg_info`. returncCsddlm}||jS)Nr) Distribution)$pip._internal.metadata.pkg_resourcesr reqget_dist)self_Distr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/distributions/sdist.pyget_metadata_distributions z,SourceDistribution.get_metadata_distributionfinderbuild_isolationNcCsF|j|jjo |}|r|||j|||jdS)N)rload_pyproject_toml use_pep517_prepare_build_backendisolated_editable_sanity_check_install_build_reqsprepare_metadata)rrrshould_isolaterrrprepare_distribution_metadatas     z0SourceDistribution.prepare_distribution_metadatac Cs|jj}|dus Jt|j_|jj||dd|jj|jj\}}|r,|d||rEt d|jt dd t t t |dSdS)NoverlayzInstalling build dependenciesz"PEP 517/518 supported requirementsz4Missing build requirements in pyproject.toml for %s.z`The project does not specify a build backend, and pip cannot fall back to setuptools without %s.z and )rpyproject_requiresr build_envinstall_requirementscheck_requirementsrequirements_to_check_raise_conflictsloggerwarningjoinmapreprsorted)rrr! conflictingmissingrrrr3s*   z)SourceDistribution._prepare_build_backendc C|jj7td}|jj}|dusJ|||WdWdS1s.wYWddS1s>wYdS)Nz#Getting requirements to build wheel)rr"r pep517_backendsubprocess_runnerget_requires_for_build_wheelrrunnerbackendrrr_get_build_requires_wheelMs   "z,SourceDistribution._get_build_requires_wheelc Cr/)Nz&Getting requirements to build editable)rr"r r0r1get_requires_for_build_editabler3rrr_get_build_requires_editableUs   "z/SourceDistribution._get_build_requires_editablecCsf|jjr|jjr|jr|}n|}|jj|\}}|r'|d||jj ||dddS)Nzthe backend dependenciesnormalzInstalling backend dependencies) reditablepermit_editable_wheelssupports_pyproject_editabler8r6r"r$r&r#)rr build_reqsr-r.rrrr_s  z&SourceDistribution._install_build_reqsconflicting_withconflicting_reqscCs2d}|j|j|dddt|Dd}t|)NzZSome build dependencies for {requirement} conflict with {conflicting_with}: {description}.z, css"|] \}}|d|VqdS)z is incompatible with Nr).0 installedwantedrrr |s  z6SourceDistribution._raise_conflicts..) requirementr> description)formatrr)r,r)rr>r? format_string error_messagerrrr&rs z#SourceDistribution._raise_conflicts)__name__ __module__ __qualname____doc__r rrboolrrrstrr6r8rrrr&rrrrr s*  r )loggingtypingrrrpip._internal.build_envr pip._internal.distributions.baserpip._internal.exceptionsr"pip._internal.index.package_finderrpip._internal.metadatar pip._internal.utils.subprocessr getLoggerrIr'r rrrrs       PKH]^llVpython3.10/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-310.pycnu[o ai[@sLddlmZddlmZddlmZddlmZmZm Z GdddeZ dS))canonicalize_name)AbstractDistribution) PackageFinder)BaseDistributionFilesystemWheelget_wheel_distributionc@s4eZdZdZdefddZdededdfdd ZdS) WheelDistributionzqRepresents a wheel distribution. This does not need any preparation as wheels can be directly unpacked. returncCs>|jjsJd|jjsJdt|jj}t|t|jjS)zLoads the metadata from the wheel file into memory and returns a Distribution that uses it, not relying on the wheel file or requirement. z*Set as part of preparation during downloadzWheels are never unnamed)reqlocal_file_pathnamerrr)selfwheelr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/distributions/wheel.pyget_metadata_distributions z+WheelDistribution.get_metadata_distributionfinderbuild_isolationNcCsdS)Nr)r rrrrrprepare_distribution_metadatasz/WheelDistribution.prepare_distribution_metadata) __name__ __module__ __qualname____doc__rrrboolrrrrrr s rN) pip._vendor.packaging.utilsr pip._internal.distributions.baser"pip._internal.index.package_finderrpip._internal.metadatarrrrrrrrs  PKH]Ph[[=python3.10/site-packages/pip/_internal/distributions/wheel.pynu[from pip._vendor.packaging.utils import canonicalize_name from pip._internal.distributions.base import AbstractDistribution from pip._internal.index.package_finder import PackageFinder from pip._internal.metadata import ( BaseDistribution, FilesystemWheel, get_wheel_distribution, ) class WheelDistribution(AbstractDistribution): """Represents a wheel distribution. This does not need any preparation as wheels can be directly unpacked. """ def get_metadata_distribution(self) -> BaseDistribution: """Loads the metadata from the wheel file into memory and returns a Distribution that uses it, not relying on the wheel file or requirement. """ assert self.req.local_file_path, "Set as part of preparation during download" assert self.req.name, "Wheels are never unnamed" wheel = FilesystemWheel(self.req.local_file_path) return get_wheel_distribution(wheel, canonicalize_name(self.req.name)) def prepare_distribution_metadata( self, finder: PackageFinder, build_isolation: bool ) -> None: pass PKH]h <python3.10/site-packages/pip/_internal/distributions/base.pynu[import abc from pip._internal.index.package_finder import PackageFinder from pip._internal.metadata.base import BaseDistribution from pip._internal.req import InstallRequirement class AbstractDistribution(metaclass=abc.ABCMeta): """A base class for handling installable artifacts. The requirements for anything installable are as follows: - we must be able to determine the requirement name (or we can't correctly handle the non-upgrade case). - for packages with setup requirements, we must also be able to determine their requirements without installing additional packages (for the same reason as run-time dependencies) - we must be able to create a Distribution object exposing the above metadata. """ def __init__(self, req: InstallRequirement) -> None: super().__init__() self.req = req @abc.abstractmethod def get_metadata_distribution(self) -> BaseDistribution: raise NotImplementedError() @abc.abstractmethod def prepare_distribution_metadata( self, finder: PackageFinder, build_isolation: bool ) -> None: raise NotImplementedError() PKH]rApython3.10/site-packages/pip/_internal/distributions/installed.pynu[from pip._internal.distributions.base import AbstractDistribution from pip._internal.index.package_finder import PackageFinder from pip._internal.metadata import BaseDistribution class InstalledDistribution(AbstractDistribution): """Represents an installed package. This does not need any preparation as the required information has already been computed. """ def get_metadata_distribution(self) -> BaseDistribution: from pip._internal.metadata.pkg_resources import Distribution as _Dist assert self.req.satisfied_by is not None, "not actually installed" return _Dist(self.req.satisfied_by) def prepare_distribution_metadata( self, finder: PackageFinder, build_isolation: bool ) -> None: pass PKH]u .ZZ@python3.10/site-packages/pip/_internal/distributions/__init__.pynu[from pip._internal.distributions.base import AbstractDistribution from pip._internal.distributions.sdist import SourceDistribution from pip._internal.distributions.wheel import WheelDistribution from pip._internal.req.req_install import InstallRequirement def make_distribution_for_install_requirement( install_req: InstallRequirement, ) -> AbstractDistribution: """Returns a Distribution for the given InstallRequirement""" # Editable requirements will always be source distributions. They use the # legacy logic until we create a modern standard for them. if install_req.editable: return SourceDistribution(install_req) # If it's a wheel, it's a WheelDistribution if install_req.is_wheel: return WheelDistribution(install_req) # Otherwise, a SourceDistribution return SourceDistribution(install_req) PKH];Ւ//3python3.10/site-packages/pip/_internal/pyproject.pynu[import os from collections import namedtuple from typing import Any, List, Optional from pip._vendor import tomli from pip._vendor.packaging.requirements import InvalidRequirement, Requirement from pip._internal.exceptions import InstallationError def _is_list_of_str(obj: Any) -> bool: return isinstance(obj, list) and all(isinstance(item, str) for item in obj) def make_pyproject_path(unpacked_source_directory: str) -> str: return os.path.join(unpacked_source_directory, "pyproject.toml") BuildSystemDetails = namedtuple( "BuildSystemDetails", ["requires", "backend", "check", "backend_path"] ) def load_pyproject_toml( use_pep517: Optional[bool], pyproject_toml: str, setup_py: str, req_name: str ) -> Optional[BuildSystemDetails]: """Load the pyproject.toml file. Parameters: use_pep517 - Has the user requested PEP 517 processing? None means the user hasn't explicitly specified. pyproject_toml - Location of the project's pyproject.toml file setup_py - Location of the project's setup.py file req_name - The name of the requirement we're processing (for error reporting) Returns: None if we should use the legacy code path, otherwise a tuple ( requirements from pyproject.toml, name of PEP 517 backend, requirements we should check are installed after setting up the build environment directory paths to import the backend from (backend-path), relative to the project root. ) """ has_pyproject = os.path.isfile(pyproject_toml) has_setup = os.path.isfile(setup_py) if not has_pyproject and not has_setup: raise InstallationError( f"{req_name} does not appear to be a Python project: " f"neither 'setup.py' nor 'pyproject.toml' found." ) if has_pyproject: with open(pyproject_toml, encoding="utf-8") as f: pp_toml = tomli.load(f) build_system = pp_toml.get("build-system") else: build_system = None # The following cases must use PEP 517 # We check for use_pep517 being non-None and falsey because that means # the user explicitly requested --no-use-pep517. The value 0 as # opposed to False can occur when the value is provided via an # environment variable or config file option (due to the quirk of # strtobool() returning an integer in pip's configuration code). if has_pyproject and not has_setup: if use_pep517 is not None and not use_pep517: raise InstallationError( "Disabling PEP 517 processing is invalid: " "project does not have a setup.py" ) use_pep517 = True elif build_system and "build-backend" in build_system: if use_pep517 is not None and not use_pep517: raise InstallationError( "Disabling PEP 517 processing is invalid: " "project specifies a build backend of {} " "in pyproject.toml".format(build_system["build-backend"]) ) use_pep517 = True # If we haven't worked out whether to use PEP 517 yet, # and the user hasn't explicitly stated a preference, # we do so if the project has a pyproject.toml file. elif use_pep517 is None: use_pep517 = has_pyproject # At this point, we know whether we're going to use PEP 517. assert use_pep517 is not None # If we're using the legacy code path, there is nothing further # for us to do here. if not use_pep517: return None if build_system is None: # Either the user has a pyproject.toml with no build-system # section, or the user has no pyproject.toml, but has opted in # explicitly via --use-pep517. # In the absence of any explicit backend specification, we # assume the setuptools backend that most closely emulates the # traditional direct setup.py execution, and require wheel and # a version of setuptools that supports that backend. build_system = { "requires": ["setuptools>=40.8.0", "wheel"], "build-backend": "setuptools.build_meta:__legacy__", } # If we're using PEP 517, we have build system information (either # from pyproject.toml, or defaulted by the code above). # Note that at this point, we do not know if the user has actually # specified a backend, though. assert build_system is not None # Ensure that the build-system section in pyproject.toml conforms # to PEP 518. error_template = ( "{package} has a pyproject.toml file that does not comply " "with PEP 518: {reason}" ) # Specifying the build-system table but not the requires key is invalid if "requires" not in build_system: raise InstallationError( error_template.format( package=req_name, reason=( "it has a 'build-system' table but not " "'build-system.requires' which is mandatory in the table" ), ) ) # Error out if requires is not a list of strings requires = build_system["requires"] if not _is_list_of_str(requires): raise InstallationError( error_template.format( package=req_name, reason="'build-system.requires' is not a list of strings.", ) ) # Each requirement must be valid as per PEP 508 for requirement in requires: try: Requirement(requirement) except InvalidRequirement: raise InstallationError( error_template.format( package=req_name, reason=( "'build-system.requires' contains an invalid " "requirement: {!r}".format(requirement) ), ) ) backend = build_system.get("build-backend") backend_path = build_system.get("backend-path", []) check: List[str] = [] if backend is None: # If the user didn't specify a backend, we assume they want to use # the setuptools backend. But we can't be sure they have included # a version of setuptools which supplies the backend, or wheel # (which is needed by the backend) in their requirements. So we # make a note to check that those requirements are present once # we have set up the environment. # This is quite a lot of work to check for a very specific case. But # the problem is, that case is potentially quite common - projects that # adopted PEP 518 early for the ability to specify requirements to # execute setup.py, but never considered needing to mention the build # tools themselves. The original PEP 518 code had a similar check (but # implemented in a different way). backend = "setuptools.build_meta:__legacy__" check = ["setuptools>=40.8.0", "wheel"] return BuildSystemDetails(requires, backend, check, backend_path) PKH]3S5^^Tpython3.10/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-310.pycnu[o ai*&@sBddlZddlZddlZddlmZmZmZmZmZm Z m Z m Z ddl m Z ddlmZddlmZmZddlmZmZddlmZmZddlmZdd lmZeeZGd d d e Z   dde ee!de"de"de ee!de"de"dee!dee!fddZ#dede!fddZ$dede fddZ%GdddZ&dS) N) ContainerDictIterableIteratorList NamedTupleOptionalSet)canonicalize_name)Version) BadCommandInstallationError)BaseDistributionget_environment)install_req_from_editableinstall_req_from_line) COMMENT_RE)%direct_url_as_pep440_direct_referencec@s"eZdZUeed<eeed<dS) _EditableInfo requirementcommentsN)__name__ __module__ __qualname__str__annotations__rrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/freeze.pyrs rFrr local_only user_onlypathsisolatedexclude_editableskipreturnc cs^i}t|j|d|d}|D]} t| } |r| jrq| || j<q|rt} tt } |D]} t | }|D]}| rJ| dsJ| dr[| }|| vrZ| ||Vq8| dse| dr| drs|dd }n |tdd d}t||d }n ttd | |d }|jstd | | td q8t|j}||vr| |jstd | td | |jq8| |j| q8t|| V||=| |j| q8Wdn1swYq/| D]\}}t|dkrtd|dtt|qdVt|dddD]}|j|vr+t| VqdS)Nr)rr#r#) z-rz --requirementz-fz --find-linksz-iz --index-urlz--prez--trusted-hostz--process-dependency-linksz--extra-index-urlz --use-featurez-ez --editable=)r!zWSkipping line in requirement file [%s] because it's not clear what it would install: %sz9 (add #egg=PackageName to the URL to avoid this warning)zBRequirement file [%s] contains %s, but package %r is not installedz+Requirement %s included multiple times [%s]z, z7## The following requirements were added by pip freeze:cSs |jSN)namelower)xrrrs zfreeze..)key) riter_installed_distributionsFrozenRequirement from_disteditablecanonical_nameset collections defaultdictlistopenstrip startswithrstripaddlenlstriprrrsubr+loggerinfor warningappendritemsjoinsortedvalues)rrrr r!r"r#Z installationsdistsdistreqZemitted_optionsZ req_filesZ req_file_pathreq_filelineZline_reqZline_req_canonical_namer+filesZ installationrrrfreezes           K rOrJcCs0t|jtr|jd|jS|jd|jS)Nz==z===) isinstanceversionr raw_name)rJrrr_format_as_name_versions rSc Cs|j}|sJtjtj|}ddlm}m}m}| |}|dur:t |}t d||t |d|dgdSt|j}z |||j} Wnq|yct |}t |d|d |dgdYS|y} zt |}t |d|d |d d | jd gdWYd} ~ Sd} ~ wtyt d||jt |gdYSty} z t d| WYd} ~ n d} ~ wwt | gdSt d|t |dgdS)za Compute and return values (req, comments) for use in FrozenRequirement.from_dist(). r)RemoteNotFoundErrorRemoteNotValidErrorvcsNz1No VCS found for editable requirement "%s" in: %rz,# Editable install with no version control ())rrz # Editable z install with no remote (z install (z4) with either a deleted local remote or invalid URI:z# ''zPcannot determine version of editable source in %s (%s command not found in path)z6Error when trying to get requirement for VCS system %sz-Could not determine repository location of %sz-## !! Could not determine repository location)editable_project_locationospathnormcaseabspathpip._internal.vcsrTrUrVget_backend_for_dirrSrAdebugrtyperget_src_requirementrRurlr rCr+r ) rJrYlocationrTrUrV vcs_backendZdisplayZvcs_namerKexexcrrr_get_editable_infosf         rhc @sVeZdZ ddedededeeddf dd Zed eddfd d Z defd dZ dS)r1rr+rKr3rr$NcCs&||_t||_||_||_||_dSr*)r+r r4rKr3r)selfr+rKr3rrrr__init__s   zFrozenRequirement.__init__rJcCsN|j}|r t|\}}ng}|j}|rt||j}nt|}||j|||dS)N)r)r3rh direct_urlrrRrS)clsrJr3rKrrkrrrr2szFrozenRequirement.from_distcCs4|j}|jr d|}dt|jt|gdS)Nz-e  )rKr3rFr8rr)rirKrrr__str__s zFrozenRequirement.__str__)r) rrrrboolrrj classmethodrr2rnrrrrr1s   r1)NFFNFFr)'r6loggingrZtypingrrrrrrrr pip._vendor.packaging.utilsr Zpip._vendor.packaging.versionr pip._internal.exceptionsr r pip._internal.metadatarrpip._internal.req.constructorsrrZpip._internal.req.req_filer&pip._internal.utils.direct_url_helpersr getLoggerrrArrrorOrSrhr1rrrrsP(        yBPKH]#Vpython3.10/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-310.pycnu[o ai@sdS)Nrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/__init__.pysPKH];'99Upython3.10/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-310.pycnu[o ai]@sdZddlZddlZddlZddlZddlmZmZmZm Z ddl m Z ddl m Z ddlmZddlmZmZmZmZmZmZmZddlmZdd lmZdd lmZdd lmZdd l m!Z!m"Z"dd l#m$Z$m%Z%ddl&m'Z'ddl(m)Z)ddl*m+Z+ddl,m-Z-ddl.m/Z/m0Z0ddl1m2Z2ddl3m4Z4m5Z5m6Z6m7Z7ddl8m9Z9ddl:m;Z;ddle?Z@de)de+dedeAdef ddZBded eCddfd!d"ZDGd#d$d$ZE  d:ded%e"d&e eCd'e e/deEf d(d)ZFd*eCd+eCddfd,d-ZGd.eCd/eCddfd0d1ZH d:ded&e eCd'e e/deEfd2d3ZI  d:ded eCd%e"d&e eCd'e e/de eEf d4d5ZJded&eCd'e e/de eCfd6d7ZKGd8d9d9ZLdS);z)Prepares a distribution for installation N)DictIterableListOptional)canonicalize_name))make_distribution_for_install_requirement)InstalledDistribution)DirectoryUrlHashUnsupported HashMismatch HashUnpinnedInstallationErrorNetworkConnectionErrorPreviousBuildDirErrorVcsHashUnsupported) PackageFinder)BaseDistribution)Link)Wheel)BatchDownloader Downloader)HTTPRangeRequestUnsupporteddist_from_wheel_url) PipSession)InstallRequirement)RequirementTracker) copy2_fixed)Hashes MissingHashes) indent_log) display_pathhide_urlis_installable_dirrmtree) TempDirectory) unpack_file)vcsreq req_trackerfinderbuild_isolationreturncCsLt|}|||||Wd|S1swY|S)z(Prepare a distribution for installation.N)rtrackprepare_distribution_metadataget_metadata_distribution)r&r'r(r) abstract_distr//builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/prepare.py_get_prepared_distribution1s  r1linklocationcCs0t|j}|dus J|j|t|jddS)N)url)r%get_backend_for_schemeschemeunpackr r4)r2r3 vcs_backendr/r/r0unpack_vcs_link>s  r9c@s&eZdZdedeeddfddZdS)Filepath content_typer*NcCs,||_|durt|d|_dS||_dS)Nr)r; mimetypes guess_typer<)selfr;r<r/r/r0__init__Es z File.__init__)__name__ __module__ __qualname__strrr@r/r/r/r0r:Dsr:download download_dirhashescCsVtddd}d}|rt|||}|r|}d}n|||j\}}|r&||t||S)Nr7Tkindglobally_managed)r#_check_download_dirr;check_against_pathr:)r2rErFrGtemp_diralready_downloaded_path from_pathr<r/r/r0 get_http_urlMs    rPsrcdestc CsNzt||WdStjy&}ztdt|||WYd}~dSd}~ww)zCopying special files is not supported, but as a convenience to users we skip errors copying them. This supports tools that may create e.g. socket files in the project source directory. z>Ignoring special file error '%s' encountered copying %s to %s.N)rshutilSpecialFileErrorloggerwarningrD)rQrRer/r/r0_copy2_ignoring_special_filesesrXsourcetargetcsbtj|}tj|tj|dtdttdttffdd }tj||dt ddS)Ndnamesr*cs6g}|kr |ddg7}tj|kr|g7}|S)Nz.toxz.nox)osr;abspath)r[r\skippedrYtarget_basenametarget_dirnamer/r0ignore~s   z!_copy_source_tree..ignoreT)rcsymlinks copy_function) r]r;r^basenamedirnamerDrrScopytreerX)rYrZtarget_abspathrcr/r`r0_copy_source_treeys   & rjcCs<d}|r t|||}|r|}n|j}|r||t|dS)z'Get file and optionally check its hash.N)rK file_pathrLr:)r2rFrGrNrOr/r/r0 get_file_urls   rlcCs|jr t||dS|r tj|rt|t|j|dS|j r+t |||d}nt ||||d}|j s>t |j||j|S)a_Unpack link into location, downloading if required. :param hashes: A Hashes object, one of whose embedded hashes must match, or HashMismatch will be raised. If the Hashes is empty, no matches are required, and unhashable types of requirements (like VCS ones, which would ordinarily raise HashUnsupported) are allowed. N)rG)is_vcsr9is_existing_dirr]r;isdirr"rjrkis_filerlrPis_wheelr$r<)r2r3rErFrGfiler/r/r0 unpack_urls&    rscCsptj||j}tj|sdStd||r6z||W|Sty5t d|t |YdSw|S)zCheck download_dir for previously downloaded file with correct hash If a correct file is found return its path else None NzFile was already downloaded %sz;Previously-downloaded file %s has bad hash. Re-downloading.) r]r;joinfilenameexistsrUinforLr rVunlink)r2rFrG download_pathr/r/r0rKs"     rKcsPeZdZdZdedeedededededed e d ed ed ed eddffdd Z de ddfddZ de deddfddZ de defddZdedeefddZ d/dee deddfdd Z d/de dedefd!d"Z d/d#ee deddfd$d%Zde dedefd&d'Zde ddfd(d)Zde defd*d+Zde d,edefd-d.ZZS)0RequirementPreparerzPrepares a Requirement build_dirrFsrc_dirr)r'session progress_barr(require_hashes use_user_site lazy_wheel in_tree_buildr*Nc stt||_||_||_||_t|||_t|||_ ||_ ||_ ||_ | |_ | |_| |_| |_i|_d|_dS)N)r)superr@r|r{r'_sessionr _downloadr_batch_downloadr(rFr)rruse_lazy_wheelr _downloaded_previous_requirement_header) r?r{rFr|r)r'r}r~r(rrrr __class__r/r0r@s    zRequirementPreparer.__init__r&cCs|jjr|jsd}tt|jj}n d}t|jp|}||f|jkr-||f|_t |||jrNt t d|jj WddS1sGwYdSdS)z3Provide context for the requirement being prepared.z Processing %sz Collecting %szUsing cached %sN) r2rporiginal_link_is_in_wheel_cacherDrrkr&rrUrwrru)r?r&message informationr/r/r0_log_preparing_link3s  "z'RequirementPreparer._log_preparing_linkparallel_buildscCsj|jjrdS|jdus J|jr|jr|jj|_dS|j|jd|dt|jr3t d ||jdS)z1Ensure source_dir of a linked InstallRequirement.NT) autodeleterzpip can't proceed with requirements '{}' due to apre-existing build directory ({}). This is likely due to a previous installation that failed . pip is being responsible and not assuming it can delete this. Please delete it and try again.) r2rq source_dirrnrrkensure_has_source_dirr{r!rformat)r?r&rr/r/r0_ensure_link_req_src_dirDs"   z,RequirementPreparer._ensure_link_req_src_dircCsX|js |jddS|jjrt|jrt|jdur#|js#t |jddp+t S)NT)trust_internetF) rrGr2rmrrnr original_link is_pinnedr r)r?r&r/r/r0_get_linked_req_hashesis  z*RequirementPreparer._get_linked_req_hashesr2cCs|jsdS|jrtddS|js|jstd|dSt|j}t|j }t d||j |j ddd}zt|||jWStyPtd|YdSw) z-Fetch metadata using lazy wheel, if possible.Nz3Lazy wheel is not used as hash checking is requiredz>Lazy wheel is not used as %r does not points to a remote wheelz+Obtaining dependency information from %s %s#rz"%s does not support range requests)rrrUdebugrprqrrurnamerwversionr4splitrrr)r?r2wheelrr4r/r/r0 _fetch_metadata_using_lazy_wheels2      z4RequirementPreparer._fetch_metadata_using_lazy_wheelFpartially_downloaded_reqsc Cstdddj}i}|D] }|jsJ|||j<q |||}|D]\}\}} td||||}||_q"|D]}|||q9dS)z>Download any requirements which were only fetched by metadata.r7TrHzDownloading link %s to %sN) r#r;r2rkeysrUrlocal_file_path_prepare_linked_requirement) r?rrrMlinks_to_fully_downloadr&batch_downloadr2filepath_r/r/r0_complete_partial_requirementss   z2RequirementPreparer._complete_partial_requirementscCs|jsJ|j}||tFd}|jdur(|jr(||}t|j|j|}|dur4||j|jj<n| |}|durId|_ |WdS| ||WdS1sYwYdS)z3Prepare a requirement to be obtained from req.link.NT) r2rrrFrqrrKrr4rneeds_more_preparationr)r?r&rr2rkrG wheel_distr/r/r0prepare_linked_requirements"     $z.RequirementPreparer.prepare_linked_requirementreqscCsdd|D}|D]&}|jdur/|jjr/||}t|j|j|}|dur/||j|jj<d|_q g}|D]}|jr?||q4| ||q4|j ||ddS)z,Prepare linked requirements more, if needed.cSsg|]}|jr|qSr/)r).0r&r/r/r0 szHRequirementPreparer.prepare_linked_requirements_more..NF)r) rFr2rqrrKrr4rappendrr)r?rrr&rGrkrr/r/r0 prepare_linked_requirements_mores$   z4RequirementPreparer.prepare_linked_requirements_morec Cs|jsJ|j}|||||}|r|jrd}n<|j|jvrFz t||j|j |j |}Wn(t yE}z t d |||d}~ww|j|j}|rS||t|dd}|r_|j|_t||j|j|j}|S)NzDCould not install requirement {} because of HTTP error {} for URL {})r<)r2rrrnrr4rrsrrrFr r rrLr:r;rr1r'r(r)) r?r&rr2rG local_fileexcrkdistr/r/r0rs>        z/RequirementPreparer._prepare_linked_requirementcCs|jdusJ|jdusJ|j}|js|r#|jr#||jdS|r/td|dS|jdur6dSt j |j|j }t j |sXt|j|t|}td|dSdS)NzENot copying link to destination directory since it is a directory: %szSaved %s)rFr2rmrneditablearchiverUrrr]r;rtrurvrScopyrrw)r?r&r2download_locationryr/r/r0save_linked_requirement*s(   z+RequirementPreparer.save_linked_requirementcCs|jsJdtd|t-|jrtd|||j| t ||j |j |j }||jWd|S1s@wY|S)z Prepare an editable requirement.z-cannot prepare a non-editable req as editablez Obtaining %szoThe editable requirement {} cannot be installed when requiring hashes, because there is no single file to hash.N)rrUrwrrr rrr|update_editabler1r'r(r)check_if_existsr)r?r&rr/r/r0prepare_editable_requirementDs*   z0RequirementPreparer.prepare_editable_requirement skip_reasoncCs|jsJd|dusJd|jtd|||jjt|jr)tdt| WdS1s9wYdS)z)Prepare an already-installed requirement.z(req should have been satisfied but isn'tNzAdid not get skip reason skipped but req.satisfied_by is set to {}zRequirement %s: %s (%s)zSince it is already installed, we are trusting this package without checking its hash. To ensure a completely repeatable environment, install into an empty virtualenv.) satisfied_byrrUrwrrrrrr-)r?r&rr/r/r0prepare_installed_requirementbs   $z1RequirementPreparer.prepare_installed_requirement)F)rArBrC__doc__rDrboolrrrr@rrrrrrrrrrrrrrrr __classcell__r/r/rr0rzs     2 %  " !   ( rz)NN)Mrloggingr=r]rStypingrrrrpip._vendor.packaging.utilsrpip._internal.distributionsr%pip._internal.distributions.installedrpip._internal.exceptionsr r r r r rr"pip._internal.index.package_finderrpip._internal.metadatarpip._internal.models.linkrpip._internal.models.wheelrpip._internal.network.downloadrr pip._internal.network.lazy_wheelrrpip._internal.network.sessionrpip._internal.req.req_installrpip._internal.req.req_trackerrpip._internal.utils.filesystemrpip._internal.utils.hashesrrpip._internal.utils.loggingrpip._internal.utils.miscrr r!r"pip._internal.utils.temp_dirr#pip._internal.utils.unpackingr$pip._internal.vcsr% getLoggerrArUrr1rDr9r:rPrXrjrlrsrKrzr/r/r/r0s   $                  6 PKH]S,Spython3.10/site-packages/pip/_internal/operations/__pycache__/check.cpython-310.pycnu[o ai@sdZddlZddlmZmZmZmZmZmZm Z ddl m Z ddl m Z mZddlmZddlmZddlmZdd lmZeeZGd d d eZee efZe e e fZe e ee fZee eefZee eefZe eefZ e ee fZ!d e ee"ffd dZ# ddedeee$ge"fd e fddZ%deed e!fddZ&deeded ee fddZ'dee ded ee fddZ(dS)z'Validation of dependencies of packages N)CallableDictList NamedTupleOptionalSetTuple) Requirement)NormalizedNamecanonicalize_name))make_distribution_for_install_requirement)get_default_environment)DistributionVersion)InstallRequirementc@s"eZdZUeed<eeed<dS)PackageDetailsversion dependenciesN)__name__ __module__ __qualname__r__annotations__rr rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/check.pyrs rreturnc Csi}d}t}|jdddD]2}|j}zt|}t|j|||<Wqttfy@}zt d||d}WYd}~qd}~ww||fS)z3Converts a list of distributions into a PackageSet.Fr) local_onlyskipz%Error parsing requirements for %s: %sTN) r iter_installed_distributionscanonical_namelistiter_dependenciesrrOSError ValueErrorloggerwarning) package_setproblemsenvdistnamererrr!create_package_set_from_installed"s r*r$ should_ignorec Csi}i}|D]_\}}t}t}|r||rq|jD]6}t|j} | |vr=d} |jdur3|j} | r<|| |fq|| j} |j j | ddsR|| | |fq|r]t |t d||<|rgt |t d||<q||fS)zCheck if a package set is consistent If should_ignore is passed, it should be a callable that takes a package name and returns a boolean. TN) prereleases)key) itemssetrr r(markerevaluateaddr specifiercontainssortedstr) r$r+missing conflicting package_namepackage_detail missing_depsconflicting_depsreqr(missedrrrrcheck_package_set3s4       r? to_installcs6t\}}t||}t|||t|fdddfS)zeFor checking if the dependency graph would be consistent after installing given requirements cs|vSNr)r( whitelistrrosz)check_install_conflicts..)r+)r*_simulate_installation_of_create_whitelistr?)r@r$_would_be_installedrrBrcheck_install_conflicts`s    rIcCsLt}|D]}t|}|}|j}t|jt|||<||q|S)z=Computes the version of packages after installing to_install.) r/r get_metadata_distributionrrrrrr2)r@r$ installedinst_req abstract_distr'r(rrrrEts rErHcCsLt|}|D]}||vr q||jD]}t|j|vr"||nqq|SrA)r/rr r(r2)rHr$packages_affectedr9r=rrrrFs rFrA))__doc__loggingtypingrrrrrrrZ"pip._vendor.packaging.requirementsr pip._vendor.packaging.utilsr r pip._internal.distributionsr pip._internal.metadatar Zpip._internal.metadata.baserpip._internal.req.req_installr getLoggerrr"r PackageSetMissing Conflicting MissingDictConflictingDict CheckResultConflictDetailsboolr*r6r?rIrErFrrrrsT$           - PKH]k<3bpython3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-310.pycnu[o ai} @shddlZddlZddlmZddlmZmZddlmZe e Z de dede de d ee f d d Z dS) N)Optional) HookMissingPep517HookCaller)runner_with_spinner_messagenamebackendmetadata_directorytempdreturnc Cs|dusJzPtd|td|d}||3z |j||d}Wn!tyE}ztd||WYd}~WdWdSd}~wwWdn1sPwYWntyftd|YdSwtj ||S)zBuild one InstallRequirement using the PEP 660 build process. Returns path to wheel if successfully built. Otherwise, returns None. NzDestination directory: %szBuilding editable for z (pyproject.toml))rzLCannot build editable %s because the build backend does not have the %s hookzFailed building editable for %s) loggerdebugrsubprocess_runnerbuild_editablererror Exceptionospathjoin)rrrr runner wheel_nameer/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/build/wheel_editable.pybuild_wheel_editable s<        r)loggingrtypingrZpip._vendor.pep517.wrappersrrpip._internal.utils.subprocessr getLogger__name__r strrrrrrs"   PKH]Gcpython3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-310.pycnu[o ai @sdZddlZddlZddlmZddlmZddlmZddl m Z ddl m Z ddl mZeeZd ed efd d Zd ededededed ef ddZdS)z;Metadata generation logic for legacy source distributions. N)BuildEnvironment) open_spinner)InstallationError)make_setuptools_egg_info_args)call_subprocess) TempDirectory directoryreturncCsRddt|D}|std|t|dkr td|tj||dS)z.Find an .egg-info subdirectory in `directory`.cSsg|] }|dr|qS)z .egg-info)endswith).0fr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/build/metadata_legacy.py sz"_find_egg_info..z No .egg-info directory found in z-More than one .egg-info directory found in {}r)oslistdirrlenformatpathjoin)r filenamesr r r_find_egg_infos r build_env setup_py_path source_dirisolateddetailsc Cstd||tdddj}t|||d}|1td}t||d|dWd n1s/wYWd t|SWd t|S1sKwYt|S) znGenerate metadata using setup.py-based defacto mechanisms. Returns the generated metadata directory. z2Running setup.py (path:%s) egg_info for package %sz pip-egg-infoT)kindglobally_managed) egg_info_dirno_user_configzPreparing metadata (setup.py)zpython setup.py egg_info)cwd command_descspinnerN)loggerdebugrrrrrr)rrrrrr argsr$r r rgenerate_metadata s6       r()__doc__loggingrpip._internal.build_envrpip._internal.cli.spinnersrpip._internal.exceptionsr$pip._internal.utils.setuptools_buildrpip._internal.utils.subprocessrpip._internal.utils.temp_dirr getLogger__name__r%strrboolr(r r r rs0       PKH]ں~\python3.10/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-310.pycnu[o ai@sdS)Nrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/build/__init__.pysPKH]q_p2 `python3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-310.pycnu[o ai @sddlZddlZddlmZmZddlmZddlm Z ddl m Z m Z m Z eeZdeededefd d Zd eed ed edeededeef ddZd edededeedeededeefddZdS)N)ListOptional) open_spinner) make_setuptools_bdist_wheel_args) LOG_DIVIDERcall_subprocessformat_command_args command_argscommand_outputreturncCsft|}d|d}|s|d7}|Sttjkr|d7}|S|ds(|d7}|d|t7}|S)z'Format command information for logging.zCommand arguments:  zCommand output: Nonez'Command output: [use --verbose to show]zCommand output: )rloggergetEffectiveLevelloggingDEBUGendswithr)r r command_desctextr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/build/wheel_legacy.pyformat_command_results  rnamestemp_dirnamecCstt|}|sd|}|t||7}t|dSt|dkr1d||}|t||7}t|tj||dS)z>Return the path to the wheel in the temporary build directory.z1Legacy build of wheel for {!r} created no files. NzZLegacy build of wheel for {!r} created more than one file. Filenames (choosing first): {} r) sortedformatrr warninglenospathjoin)rrrr r msgrrrget_legacy_build_wheel_path$s     r# setup_py_path source_dirglobal_options build_optionstempdc Cst||||d}d|d}t|C}td|z t|||d} Wnty=|dtd|YWddSwt |} t | |||| d } | WdS1sXwYdS) zBuild one unpacked package using the "legacy" build process. Returns path to wheel if successfully built. Otherwise, returns None. )r&r'destination_dirzBuilding wheel for z (setup.py)zDestination directory: %s)cwdspinnererrorzFailed building wheel for %sN)rrrr r ) rrr debugr Exceptionfinishr,rlistdirr#) rr$r%r&r'r( wheel_args spin_messager+outputr wheel_pathrrrbuild_wheel_legacy?s>        $r5)ros.pathrtypingrrpip._internal.cli.spinnersr$pip._internal.utils.setuptools_buildrpip._internal.utils.subprocessrrr getLogger__name__r strrr#r5rrrrsT     PKH]IYpython3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-310.pycnu[o ai' @sdddlZddlZddlmZddlmZddlmZee Z de dede de d ee f d d Z dS) N)Optional)Pep517HookCaller)runner_with_spinner_messagenamebackendmetadata_directorytempdreturncCs|dusJz,td|td|d}|||j||d}Wdn1s,wYWntyBtd|YdSwtj ||S)zBuild one InstallRequirement using the PEP 517 build process. Returns path to wheel if successfully built. Otherwise, returns None. NzDestination directory: %szBuilding wheel for z (pyproject.toml))rzFailed building wheel for %s) loggerdebugrsubprocess_runner build_wheel Exceptionerrorospathjoin)rrrrrunner wheel_namer/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/build/wheel.pybuild_wheel_pep517 s$      r) loggingrtypingrZpip._vendor.pep517.wrappersrpip._internal.utils.subprocessr getLogger__name__r strrrrrrs"    PKH]|`\python3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-310.pycnu[o ai_@sVdZddlZddlmZddlmZddlmZddlm Z deded e fd d Z dS) z4Metadata generation logic for source distributions. N)Pep517HookCaller)BuildEnvironment)runner_with_spinner_message) TempDirectory build_envbackendreturnc Cstddd}|j}|&td}|| ||}Wdn1s%wYWdn1s4wYtj||S)zlGenerate metadata using mechanisms described in PEP 517. Returns the generated metadata directory. zmodern-metadataT)kindglobally_managedz#Preparing metadata (pyproject.toml)N)rpathrsubprocess_runner prepare_metadata_for_build_wheelosjoin)rrmetadata_tmpdir metadata_dirrunner distinfo_dirr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/build/metadata.pygenerate_metadata s   r) __doc__rZpip._vendor.pep517.wrappersrpip._internal.build_envrpip._internal.utils.subprocessrpip._internal.utils.temp_dirrstrrrrrrs    PKH]~-epython3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-310.pycnu[o ai@sVdZddlZddlmZddlmZddlmZddlm Z deded e fd d Z dS) z4Metadata generation logic for source distributions. N)Pep517HookCaller)BuildEnvironment)runner_with_spinner_message) TempDirectory build_envbackendreturnc Cstddd}|j}|&td}|| ||}Wdn1s%wYWdn1s4wYtj||S)zlGenerate metadata using mechanisms described in PEP 660. Returns the generated metadata directory. zmodern-metadataT)kindglobally_managedz,Preparing editable metadata (pyproject.toml)N)rpathrsubprocess_runner#prepare_metadata_for_build_editableosjoin)rrmetadata_tmpdir metadata_dirrunner distinfo_dirr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/build/metadata_editable.pygenerate_editable_metadata s    r) __doc__rZpip._vendor.pep517.wrappersrpip._internal.build_envrpip._internal.utils.subprocessrpip._internal.utils.temp_dirrstrrrrrrs    PKH]jLpython3.10/site-packages/pip/_internal/operations/build/metadata_editable.pynu["""Metadata generation logic for source distributions. """ import os from pip._vendor.pep517.wrappers import Pep517HookCaller from pip._internal.build_env import BuildEnvironment from pip._internal.utils.subprocess import runner_with_spinner_message from pip._internal.utils.temp_dir import TempDirectory def generate_editable_metadata( build_env: BuildEnvironment, backend: Pep517HookCaller ) -> str: """Generate metadata using mechanisms described in PEP 660. Returns the generated metadata directory. """ metadata_tmpdir = TempDirectory(kind="modern-metadata", globally_managed=True) metadata_dir = metadata_tmpdir.path with build_env: # Note that Pep517HookCaller implements a fallback for # prepare_metadata_for_build_wheel/editable, so we don't have to # consider the possibility that this hook doesn't exist. runner = runner_with_spinner_message( "Preparing editable metadata (pyproject.toml)" ) with backend.subprocess_runner(runner): distinfo_dir = backend.prepare_metadata_for_build_editable(metadata_dir) return os.path.join(metadata_dir, distinfo_dir) PKH]ȇe Gpython3.10/site-packages/pip/_internal/operations/build/wheel_legacy.pynu[import logging import os.path from typing import List, Optional from pip._internal.cli.spinners import open_spinner from pip._internal.utils.setuptools_build import make_setuptools_bdist_wheel_args from pip._internal.utils.subprocess import ( LOG_DIVIDER, call_subprocess, format_command_args, ) logger = logging.getLogger(__name__) def format_command_result( command_args: List[str], command_output: str, ) -> str: """Format command information for logging.""" command_desc = format_command_args(command_args) text = f"Command arguments: {command_desc}\n" if not command_output: text += "Command output: None" elif logger.getEffectiveLevel() > logging.DEBUG: text += "Command output: [use --verbose to show]" else: if not command_output.endswith("\n"): command_output += "\n" text += f"Command output:\n{command_output}{LOG_DIVIDER}" return text def get_legacy_build_wheel_path( names: List[str], temp_dir: str, name: str, command_args: List[str], command_output: str, ) -> Optional[str]: """Return the path to the wheel in the temporary build directory.""" # Sort for determinism. names = sorted(names) if not names: msg = ("Legacy build of wheel for {!r} created no files.\n").format(name) msg += format_command_result(command_args, command_output) logger.warning(msg) return None if len(names) > 1: msg = ( "Legacy build of wheel for {!r} created more than one file.\n" "Filenames (choosing first): {}\n" ).format(name, names) msg += format_command_result(command_args, command_output) logger.warning(msg) return os.path.join(temp_dir, names[0]) def build_wheel_legacy( name: str, setup_py_path: str, source_dir: str, global_options: List[str], build_options: List[str], tempd: str, ) -> Optional[str]: """Build one unpacked package using the "legacy" build process. Returns path to wheel if successfully built. Otherwise, returns None. """ wheel_args = make_setuptools_bdist_wheel_args( setup_py_path, global_options=global_options, build_options=build_options, destination_dir=tempd, ) spin_message = f"Building wheel for {name} (setup.py)" with open_spinner(spin_message) as spinner: logger.debug("Destination directory: %s", tempd) try: output = call_subprocess( wheel_args, cwd=source_dir, spinner=spinner, ) except Exception: spinner.finish("error") logger.error("Failed building wheel for %s", name) return None names = os.listdir(tempd) wheel_path = get_legacy_build_wheel_path( names=names, temp_dir=tempd, name=name, command_args=wheel_args, command_output=output, ) return wheel_path PKH]}}Ipython3.10/site-packages/pip/_internal/operations/build/wheel_editable.pynu[import logging import os from typing import Optional from pip._vendor.pep517.wrappers import HookMissing, Pep517HookCaller from pip._internal.utils.subprocess import runner_with_spinner_message logger = logging.getLogger(__name__) def build_wheel_editable( name: str, backend: Pep517HookCaller, metadata_directory: str, tempd: str, ) -> Optional[str]: """Build one InstallRequirement using the PEP 660 build process. Returns path to wheel if successfully built. Otherwise, returns None. """ assert metadata_directory is not None try: logger.debug("Destination directory: %s", tempd) runner = runner_with_spinner_message( f"Building editable for {name} (pyproject.toml)" ) with backend.subprocess_runner(runner): try: wheel_name = backend.build_editable( tempd, metadata_directory=metadata_directory, ) except HookMissing as e: logger.error( "Cannot build editable %s because the build " "backend does not have the %s hook", name, e, ) return None except Exception: logger.error("Failed building editable for %s", name) return None return os.path.join(tempd, wheel_name) PKH]<F''@python3.10/site-packages/pip/_internal/operations/build/wheel.pynu[import logging import os from typing import Optional from pip._vendor.pep517.wrappers import Pep517HookCaller from pip._internal.utils.subprocess import runner_with_spinner_message logger = logging.getLogger(__name__) def build_wheel_pep517( name: str, backend: Pep517HookCaller, metadata_directory: str, tempd: str, ) -> Optional[str]: """Build one InstallRequirement using the PEP 517 build process. Returns path to wheel if successfully built. Otherwise, returns None. """ assert metadata_directory is not None try: logger.debug("Destination directory: %s", tempd) runner = runner_with_spinner_message( f"Building wheel for {name} (pyproject.toml)" ) with backend.subprocess_runner(runner): wheel_name = backend.build_wheel( tempd, metadata_directory=metadata_directory, ) except Exception: logger.error("Failed building wheel for %s", name) return None return os.path.join(tempd, wheel_name) PKH] Jpython3.10/site-packages/pip/_internal/operations/build/metadata_legacy.pynu["""Metadata generation logic for legacy source distributions. """ import logging import os from pip._internal.build_env import BuildEnvironment from pip._internal.cli.spinners import open_spinner from pip._internal.exceptions import InstallationError from pip._internal.utils.setuptools_build import make_setuptools_egg_info_args from pip._internal.utils.subprocess import call_subprocess from pip._internal.utils.temp_dir import TempDirectory logger = logging.getLogger(__name__) def _find_egg_info(directory: str) -> str: """Find an .egg-info subdirectory in `directory`.""" filenames = [f for f in os.listdir(directory) if f.endswith(".egg-info")] if not filenames: raise InstallationError(f"No .egg-info directory found in {directory}") if len(filenames) > 1: raise InstallationError( "More than one .egg-info directory found in {}".format(directory) ) return os.path.join(directory, filenames[0]) def generate_metadata( build_env: BuildEnvironment, setup_py_path: str, source_dir: str, isolated: bool, details: str, ) -> str: """Generate metadata using setup.py-based defacto mechanisms. Returns the generated metadata directory. """ logger.debug( "Running setup.py (path:%s) egg_info for package %s", setup_py_path, details, ) egg_info_dir = TempDirectory(kind="pip-egg-info", globally_managed=True).path args = make_setuptools_egg_info_args( setup_py_path, egg_info_dir=egg_info_dir, no_user_config=isolated, ) with build_env: with open_spinner("Preparing metadata (setup.py)") as spinner: call_subprocess( args, cwd=source_dir, command_desc="python setup.py egg_info", spinner=spinner, ) # Return the .egg-info directory. return _find_egg_info(egg_info_dir) PKH]Y0__Cpython3.10/site-packages/pip/_internal/operations/build/metadata.pynu["""Metadata generation logic for source distributions. """ import os from pip._vendor.pep517.wrappers import Pep517HookCaller from pip._internal.build_env import BuildEnvironment from pip._internal.utils.subprocess import runner_with_spinner_message from pip._internal.utils.temp_dir import TempDirectory def generate_metadata(build_env: BuildEnvironment, backend: Pep517HookCaller) -> str: """Generate metadata using mechanisms described in PEP 517. Returns the generated metadata directory. """ metadata_tmpdir = TempDirectory(kind="modern-metadata", globally_managed=True) metadata_dir = metadata_tmpdir.path with build_env: # Note that Pep517HookCaller implements a fallback for # prepare_metadata_for_build_wheel, so we don't have to # consider the possibility that this hook doesn't exist. runner = runner_with_spinner_message("Preparing metadata (pyproject.toml)") with backend.subprocess_runner(runner): distinfo_dir = backend.prepare_metadata_for_build_wheel(metadata_dir) return os.path.join(metadata_dir, distinfo_dir) PKH]Cpython3.10/site-packages/pip/_internal/operations/build/__init__.pynu[PKH]:e]]<python3.10/site-packages/pip/_internal/operations/prepare.pynu["""Prepares a distribution for installation """ # The following comment should be removed at some point in the future. # mypy: strict-optional=False import logging import mimetypes import os import shutil from typing import Dict, Iterable, List, Optional from pip._vendor.packaging.utils import canonicalize_name from pip._internal.distributions import make_distribution_for_install_requirement from pip._internal.distributions.installed import InstalledDistribution from pip._internal.exceptions import ( DirectoryUrlHashUnsupported, HashMismatch, HashUnpinned, InstallationError, NetworkConnectionError, PreviousBuildDirError, VcsHashUnsupported, ) from pip._internal.index.package_finder import PackageFinder from pip._internal.metadata import BaseDistribution from pip._internal.models.link import Link from pip._internal.models.wheel import Wheel from pip._internal.network.download import BatchDownloader, Downloader from pip._internal.network.lazy_wheel import ( HTTPRangeRequestUnsupported, dist_from_wheel_url, ) from pip._internal.network.session import PipSession from pip._internal.req.req_install import InstallRequirement from pip._internal.req.req_tracker import RequirementTracker from pip._internal.utils.filesystem import copy2_fixed from pip._internal.utils.hashes import Hashes, MissingHashes from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import display_path, hide_url, is_installable_dir, rmtree from pip._internal.utils.temp_dir import TempDirectory from pip._internal.utils.unpacking import unpack_file from pip._internal.vcs import vcs logger = logging.getLogger(__name__) def _get_prepared_distribution( req: InstallRequirement, req_tracker: RequirementTracker, finder: PackageFinder, build_isolation: bool, ) -> BaseDistribution: """Prepare a distribution for installation.""" abstract_dist = make_distribution_for_install_requirement(req) with req_tracker.track(req): abstract_dist.prepare_distribution_metadata(finder, build_isolation) return abstract_dist.get_metadata_distribution() def unpack_vcs_link(link: Link, location: str) -> None: vcs_backend = vcs.get_backend_for_scheme(link.scheme) assert vcs_backend is not None vcs_backend.unpack(location, url=hide_url(link.url)) class File: def __init__(self, path: str, content_type: Optional[str]) -> None: self.path = path if content_type is None: self.content_type = mimetypes.guess_type(path)[0] else: self.content_type = content_type def get_http_url( link: Link, download: Downloader, download_dir: Optional[str] = None, hashes: Optional[Hashes] = None, ) -> File: temp_dir = TempDirectory(kind="unpack", globally_managed=True) # If a download dir is specified, is the file already downloaded there? already_downloaded_path = None if download_dir: already_downloaded_path = _check_download_dir(link, download_dir, hashes) if already_downloaded_path: from_path = already_downloaded_path content_type = None else: # let's download to a tmp dir from_path, content_type = download(link, temp_dir.path) if hashes: hashes.check_against_path(from_path) return File(from_path, content_type) def _copy2_ignoring_special_files(src: str, dest: str) -> None: """Copying special files is not supported, but as a convenience to users we skip errors copying them. This supports tools that may create e.g. socket files in the project source directory. """ try: copy2_fixed(src, dest) except shutil.SpecialFileError as e: # SpecialFileError may be raised due to either the source or # destination. If the destination was the cause then we would actually # care, but since the destination directory is deleted prior to # copy we ignore all of them assuming it is caused by the source. logger.warning( "Ignoring special file error '%s' encountered copying %s to %s.", str(e), src, dest, ) def _copy_source_tree(source: str, target: str) -> None: target_abspath = os.path.abspath(target) target_basename = os.path.basename(target_abspath) target_dirname = os.path.dirname(target_abspath) def ignore(d: str, names: List[str]) -> List[str]: skipped: List[str] = [] if d == source: # Pulling in those directories can potentially be very slow, # exclude the following directories if they appear in the top # level dir (and only it). # See discussion at https://github.com/pypa/pip/pull/6770 skipped += [".tox", ".nox"] if os.path.abspath(d) == target_dirname: # Prevent an infinite recursion if the target is in source. # This can happen when TMPDIR is set to ${PWD}/... # and we copy PWD to TMPDIR. skipped += [target_basename] return skipped shutil.copytree( source, target, ignore=ignore, symlinks=True, copy_function=_copy2_ignoring_special_files, ) def get_file_url( link: Link, download_dir: Optional[str] = None, hashes: Optional[Hashes] = None ) -> File: """Get file and optionally check its hash.""" # If a download dir is specified, is the file already there and valid? already_downloaded_path = None if download_dir: already_downloaded_path = _check_download_dir(link, download_dir, hashes) if already_downloaded_path: from_path = already_downloaded_path else: from_path = link.file_path # If --require-hashes is off, `hashes` is either empty, the # link's embedded hash, or MissingHashes; it is required to # match. If --require-hashes is on, we are satisfied by any # hash in `hashes` matching: a URL-based or an option-based # one; no internet-sourced hash will be in `hashes`. if hashes: hashes.check_against_path(from_path) return File(from_path, None) def unpack_url( link: Link, location: str, download: Downloader, download_dir: Optional[str] = None, hashes: Optional[Hashes] = None, ) -> Optional[File]: """Unpack link into location, downloading if required. :param hashes: A Hashes object, one of whose embedded hashes must match, or HashMismatch will be raised. If the Hashes is empty, no matches are required, and unhashable types of requirements (like VCS ones, which would ordinarily raise HashUnsupported) are allowed. """ # non-editable vcs urls if link.is_vcs: unpack_vcs_link(link, location) return None # Once out-of-tree-builds are no longer supported, could potentially # replace the below condition with `assert not link.is_existing_dir` # - unpack_url does not need to be called for in-tree-builds. # # As further cleanup, _copy_source_tree and accompanying tests can # be removed. # # TODO when use-deprecated=out-of-tree-build is removed if link.is_existing_dir(): if os.path.isdir(location): rmtree(location) _copy_source_tree(link.file_path, location) return None # file urls if link.is_file: file = get_file_url(link, download_dir, hashes=hashes) # http urls else: file = get_http_url( link, download, download_dir, hashes=hashes, ) # unpack the archive to the build dir location. even when only downloading # archives, they have to be unpacked to parse dependencies, except wheels if not link.is_wheel: unpack_file(file.path, location, file.content_type) return file def _check_download_dir( link: Link, download_dir: str, hashes: Optional[Hashes] ) -> Optional[str]: """Check download_dir for previously downloaded file with correct hash If a correct file is found return its path else None """ download_path = os.path.join(download_dir, link.filename) if not os.path.exists(download_path): return None # If already downloaded, does its hash match? logger.info("File was already downloaded %s", download_path) if hashes: try: hashes.check_against_path(download_path) except HashMismatch: logger.warning( "Previously-downloaded file %s has bad hash. Re-downloading.", download_path, ) os.unlink(download_path) return None return download_path class RequirementPreparer: """Prepares a Requirement""" def __init__( self, build_dir: str, download_dir: Optional[str], src_dir: str, build_isolation: bool, req_tracker: RequirementTracker, session: PipSession, progress_bar: str, finder: PackageFinder, require_hashes: bool, use_user_site: bool, lazy_wheel: bool, in_tree_build: bool, ) -> None: super().__init__() self.src_dir = src_dir self.build_dir = build_dir self.req_tracker = req_tracker self._session = session self._download = Downloader(session, progress_bar) self._batch_download = BatchDownloader(session, progress_bar) self.finder = finder # Where still-packed archives should be written to. If None, they are # not saved, and are deleted immediately after unpacking. self.download_dir = download_dir # Is build isolation allowed? self.build_isolation = build_isolation # Should hash-checking be required? self.require_hashes = require_hashes # Should install in user site-packages? self.use_user_site = use_user_site # Should wheels be downloaded lazily? self.use_lazy_wheel = lazy_wheel # Should in-tree builds be used for local paths? self.in_tree_build = in_tree_build # Memoized downloaded files, as mapping of url: path. self._downloaded: Dict[str, str] = {} # Previous "header" printed for a link-based InstallRequirement self._previous_requirement_header = ("", "") def _log_preparing_link(self, req: InstallRequirement) -> None: """Provide context for the requirement being prepared.""" if req.link.is_file and not req.original_link_is_in_wheel_cache: message = "Processing %s" information = str(display_path(req.link.file_path)) else: message = "Collecting %s" information = str(req.req or req) if (message, information) != self._previous_requirement_header: self._previous_requirement_header = (message, information) logger.info(message, information) if req.original_link_is_in_wheel_cache: with indent_log(): logger.info("Using cached %s", req.link.filename) def _ensure_link_req_src_dir( self, req: InstallRequirement, parallel_builds: bool ) -> None: """Ensure source_dir of a linked InstallRequirement.""" # Since source_dir is only set for editable requirements. if req.link.is_wheel: # We don't need to unpack wheels, so no need for a source # directory. return assert req.source_dir is None if req.link.is_existing_dir() and self.in_tree_build: # build local directories in-tree req.source_dir = req.link.file_path return # We always delete unpacked sdists after pip runs. req.ensure_has_source_dir( self.build_dir, autodelete=True, parallel_builds=parallel_builds, ) # If a checkout exists, it's unwise to keep going. version # inconsistencies are logged later, but do not fail the # installation. # FIXME: this won't upgrade when there's an existing # package unpacked in `req.source_dir` # TODO: this check is now probably dead code if is_installable_dir(req.source_dir): raise PreviousBuildDirError( "pip can't proceed with requirements '{}' due to a" "pre-existing build directory ({}). This is likely " "due to a previous installation that failed . pip is " "being responsible and not assuming it can delete this. " "Please delete it and try again.".format(req, req.source_dir) ) def _get_linked_req_hashes(self, req: InstallRequirement) -> Hashes: # By the time this is called, the requirement's link should have # been checked so we can tell what kind of requirements req is # and raise some more informative errors than otherwise. # (For example, we can raise VcsHashUnsupported for a VCS URL # rather than HashMissing.) if not self.require_hashes: return req.hashes(trust_internet=True) # We could check these first 2 conditions inside unpack_url # and save repetition of conditions, but then we would # report less-useful error messages for unhashable # requirements, complaining that there's no hash provided. if req.link.is_vcs: raise VcsHashUnsupported() if req.link.is_existing_dir(): raise DirectoryUrlHashUnsupported() # Unpinned packages are asking for trouble when a new version # is uploaded. This isn't a security check, but it saves users # a surprising hash mismatch in the future. # file:/// URLs aren't pinnable, so don't complain about them # not being pinned. if req.original_link is None and not req.is_pinned: raise HashUnpinned() # If known-good hashes are missing for this requirement, # shim it with a facade object that will provoke hash # computation and then raise a HashMissing exception # showing the user what the hash should be. return req.hashes(trust_internet=False) or MissingHashes() def _fetch_metadata_using_lazy_wheel( self, link: Link, ) -> Optional[BaseDistribution]: """Fetch metadata using lazy wheel, if possible.""" if not self.use_lazy_wheel: return None if self.require_hashes: logger.debug("Lazy wheel is not used as hash checking is required") return None if link.is_file or not link.is_wheel: logger.debug( "Lazy wheel is not used as %r does not points to a remote wheel", link, ) return None wheel = Wheel(link.filename) name = canonicalize_name(wheel.name) logger.info( "Obtaining dependency information from %s %s", name, wheel.version, ) url = link.url.split("#", 1)[0] try: return dist_from_wheel_url(name, url, self._session) except HTTPRangeRequestUnsupported: logger.debug("%s does not support range requests", url) return None def _complete_partial_requirements( self, partially_downloaded_reqs: Iterable[InstallRequirement], parallel_builds: bool = False, ) -> None: """Download any requirements which were only fetched by metadata.""" # Download to a temporary directory. These will be copied over as # needed for downstream 'download', 'wheel', and 'install' commands. temp_dir = TempDirectory(kind="unpack", globally_managed=True).path # Map each link to the requirement that owns it. This allows us to set # `req.local_file_path` on the appropriate requirement after passing # all the links at once into BatchDownloader. links_to_fully_download: Dict[Link, InstallRequirement] = {} for req in partially_downloaded_reqs: assert req.link links_to_fully_download[req.link] = req batch_download = self._batch_download( links_to_fully_download.keys(), temp_dir, ) for link, (filepath, _) in batch_download: logger.debug("Downloading link %s to %s", link, filepath) req = links_to_fully_download[link] req.local_file_path = filepath # This step is necessary to ensure all lazy wheels are processed # successfully by the 'download', 'wheel', and 'install' commands. for req in partially_downloaded_reqs: self._prepare_linked_requirement(req, parallel_builds) def prepare_linked_requirement( self, req: InstallRequirement, parallel_builds: bool = False ) -> BaseDistribution: """Prepare a requirement to be obtained from req.link.""" assert req.link link = req.link self._log_preparing_link(req) with indent_log(): # Check if the relevant file is already available # in the download directory file_path = None if self.download_dir is not None and link.is_wheel: hashes = self._get_linked_req_hashes(req) file_path = _check_download_dir(req.link, self.download_dir, hashes) if file_path is not None: # The file is already available, so mark it as downloaded self._downloaded[req.link.url] = file_path else: # The file is not available, attempt to fetch only metadata wheel_dist = self._fetch_metadata_using_lazy_wheel(link) if wheel_dist is not None: req.needs_more_preparation = True return wheel_dist # None of the optimizations worked, fully prepare the requirement return self._prepare_linked_requirement(req, parallel_builds) def prepare_linked_requirements_more( self, reqs: Iterable[InstallRequirement], parallel_builds: bool = False ) -> None: """Prepare linked requirements more, if needed.""" reqs = [req for req in reqs if req.needs_more_preparation] for req in reqs: # Determine if any of these requirements were already downloaded. if self.download_dir is not None and req.link.is_wheel: hashes = self._get_linked_req_hashes(req) file_path = _check_download_dir(req.link, self.download_dir, hashes) if file_path is not None: self._downloaded[req.link.url] = file_path req.needs_more_preparation = False # Prepare requirements we found were already downloaded for some # reason. The other downloads will be completed separately. partially_downloaded_reqs: List[InstallRequirement] = [] for req in reqs: if req.needs_more_preparation: partially_downloaded_reqs.append(req) else: self._prepare_linked_requirement(req, parallel_builds) # TODO: separate this part out from RequirementPreparer when the v1 # resolver can be removed! self._complete_partial_requirements( partially_downloaded_reqs, parallel_builds=parallel_builds, ) def _prepare_linked_requirement( self, req: InstallRequirement, parallel_builds: bool ) -> BaseDistribution: assert req.link link = req.link self._ensure_link_req_src_dir(req, parallel_builds) hashes = self._get_linked_req_hashes(req) if link.is_existing_dir() and self.in_tree_build: local_file = None elif link.url not in self._downloaded: try: local_file = unpack_url( link, req.source_dir, self._download, self.download_dir, hashes ) except NetworkConnectionError as exc: raise InstallationError( "Could not install requirement {} because of HTTP " "error {} for URL {}".format(req, exc, link) ) else: file_path = self._downloaded[link.url] if hashes: hashes.check_against_path(file_path) local_file = File(file_path, content_type=None) # For use in later processing, # preserve the file path on the requirement. if local_file: req.local_file_path = local_file.path dist = _get_prepared_distribution( req, self.req_tracker, self.finder, self.build_isolation, ) return dist def save_linked_requirement(self, req: InstallRequirement) -> None: assert self.download_dir is not None assert req.link is not None link = req.link if link.is_vcs or (link.is_existing_dir() and req.editable): # Make a .zip of the source_dir we already created. req.archive(self.download_dir) return if link.is_existing_dir(): logger.debug( "Not copying link to destination directory " "since it is a directory: %s", link, ) return if req.local_file_path is None: # No distribution was downloaded for this requirement. return download_location = os.path.join(self.download_dir, link.filename) if not os.path.exists(download_location): shutil.copy(req.local_file_path, download_location) download_path = display_path(download_location) logger.info("Saved %s", download_path) def prepare_editable_requirement( self, req: InstallRequirement, ) -> BaseDistribution: """Prepare an editable requirement.""" assert req.editable, "cannot prepare a non-editable req as editable" logger.info("Obtaining %s", req) with indent_log(): if self.require_hashes: raise InstallationError( "The editable requirement {} cannot be installed when " "requiring hashes, because there is no single file to " "hash.".format(req) ) req.ensure_has_source_dir(self.src_dir) req.update_editable() dist = _get_prepared_distribution( req, self.req_tracker, self.finder, self.build_isolation, ) req.check_if_exists(self.use_user_site) return dist def prepare_installed_requirement( self, req: InstallRequirement, skip_reason: str, ) -> BaseDistribution: """Prepare an already-installed requirement.""" assert req.satisfied_by, "req should have been satisfied but isn't" assert skip_reason is not None, ( "did not get skip reason skipped but req.satisfied_by " "is set to {}".format(req.satisfied_by) ) logger.info( "Requirement %s: %s (%s)", skip_reason, req, req.satisfied_by.version ) with indent_log(): if self.require_hashes: logger.debug( "Since it is already installed, we are trusting this " "package without checking its hash. To ensure a " "completely repeatable environment, install into an " "empty virtualenv." ) return InstalledDistribution(req).get_metadata_distribution() PKH]ͯ:python3.10/site-packages/pip/_internal/operations/check.pynu["""Validation of dependencies of packages """ import logging from typing import Callable, Dict, List, NamedTuple, Optional, Set, Tuple from pip._vendor.packaging.requirements import Requirement from pip._vendor.packaging.utils import NormalizedName, canonicalize_name from pip._internal.distributions import make_distribution_for_install_requirement from pip._internal.metadata import get_default_environment from pip._internal.metadata.base import DistributionVersion from pip._internal.req.req_install import InstallRequirement logger = logging.getLogger(__name__) class PackageDetails(NamedTuple): version: DistributionVersion dependencies: List[Requirement] # Shorthands PackageSet = Dict[NormalizedName, PackageDetails] Missing = Tuple[NormalizedName, Requirement] Conflicting = Tuple[NormalizedName, DistributionVersion, Requirement] MissingDict = Dict[NormalizedName, List[Missing]] ConflictingDict = Dict[NormalizedName, List[Conflicting]] CheckResult = Tuple[MissingDict, ConflictingDict] ConflictDetails = Tuple[PackageSet, CheckResult] def create_package_set_from_installed() -> Tuple[PackageSet, bool]: """Converts a list of distributions into a PackageSet.""" package_set = {} problems = False env = get_default_environment() for dist in env.iter_installed_distributions(local_only=False, skip=()): name = dist.canonical_name try: dependencies = list(dist.iter_dependencies()) package_set[name] = PackageDetails(dist.version, dependencies) except (OSError, ValueError) as e: # Don't crash on unreadable or broken metadata. logger.warning("Error parsing requirements for %s: %s", name, e) problems = True return package_set, problems def check_package_set( package_set: PackageSet, should_ignore: Optional[Callable[[str], bool]] = None ) -> CheckResult: """Check if a package set is consistent If should_ignore is passed, it should be a callable that takes a package name and returns a boolean. """ missing = {} conflicting = {} for package_name, package_detail in package_set.items(): # Info about dependencies of package_name missing_deps: Set[Missing] = set() conflicting_deps: Set[Conflicting] = set() if should_ignore and should_ignore(package_name): continue for req in package_detail.dependencies: name = canonicalize_name(req.name) # Check if it's missing if name not in package_set: missed = True if req.marker is not None: missed = req.marker.evaluate() if missed: missing_deps.add((name, req)) continue # Check if there's a conflict version = package_set[name].version if not req.specifier.contains(version, prereleases=True): conflicting_deps.add((name, version, req)) if missing_deps: missing[package_name] = sorted(missing_deps, key=str) if conflicting_deps: conflicting[package_name] = sorted(conflicting_deps, key=str) return missing, conflicting def check_install_conflicts(to_install: List[InstallRequirement]) -> ConflictDetails: """For checking if the dependency graph would be consistent after \ installing given requirements """ # Start from the current state package_set, _ = create_package_set_from_installed() # Install packages would_be_installed = _simulate_installation_of(to_install, package_set) # Only warn about directly-dependent packages; create a whitelist of them whitelist = _create_whitelist(would_be_installed, package_set) return ( package_set, check_package_set( package_set, should_ignore=lambda name: name not in whitelist ), ) def _simulate_installation_of( to_install: List[InstallRequirement], package_set: PackageSet ) -> Set[NormalizedName]: """Computes the version of packages after installing to_install.""" # Keep track of packages that were installed installed = set() # Modify it as installing requirement_set would (assuming no errors) for inst_req in to_install: abstract_dist = make_distribution_for_install_requirement(inst_req) dist = abstract_dist.get_metadata_distribution() name = dist.canonical_name package_set[name] = PackageDetails(dist.version, list(dist.iter_dependencies())) installed.add(name) return installed def _create_whitelist( would_be_installed: Set[NormalizedName], package_set: PackageSet ) -> Set[NormalizedName]: packages_affected = set(would_be_installed) for package_name in package_set: if package_name in packages_affected: continue for req in package_set[package_name].dependencies: if canonicalize_name(req.name) in packages_affected: packages_affected.add(package_name) break return packages_affected PKH]ľ *&*&;python3.10/site-packages/pip/_internal/operations/freeze.pynu[import collections import logging import os from typing import Container, Dict, Iterable, Iterator, List, NamedTuple, Optional, Set from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.packaging.version import Version from pip._internal.exceptions import BadCommand, InstallationError from pip._internal.metadata import BaseDistribution, get_environment from pip._internal.req.constructors import ( install_req_from_editable, install_req_from_line, ) from pip._internal.req.req_file import COMMENT_RE from pip._internal.utils.direct_url_helpers import direct_url_as_pep440_direct_reference logger = logging.getLogger(__name__) class _EditableInfo(NamedTuple): requirement: str comments: List[str] def freeze( requirement: Optional[List[str]] = None, local_only: bool = False, user_only: bool = False, paths: Optional[List[str]] = None, isolated: bool = False, exclude_editable: bool = False, skip: Container[str] = (), ) -> Iterator[str]: installations: Dict[str, FrozenRequirement] = {} dists = get_environment(paths).iter_installed_distributions( local_only=local_only, skip=(), user_only=user_only, ) for dist in dists: req = FrozenRequirement.from_dist(dist) if exclude_editable and req.editable: continue installations[req.canonical_name] = req if requirement: # the options that don't get turned into an InstallRequirement # should only be emitted once, even if the same option is in multiple # requirements files, so we need to keep track of what has been emitted # so that we don't emit it again if it's seen again emitted_options: Set[str] = set() # keep track of which files a requirement is in so that we can # give an accurate warning if a requirement appears multiple times. req_files: Dict[str, List[str]] = collections.defaultdict(list) for req_file_path in requirement: with open(req_file_path) as req_file: for line in req_file: if ( not line.strip() or line.strip().startswith("#") or line.startswith( ( "-r", "--requirement", "-f", "--find-links", "-i", "--index-url", "--pre", "--trusted-host", "--process-dependency-links", "--extra-index-url", "--use-feature", ) ) ): line = line.rstrip() if line not in emitted_options: emitted_options.add(line) yield line continue if line.startswith("-e") or line.startswith("--editable"): if line.startswith("-e"): line = line[2:].strip() else: line = line[len("--editable") :].strip().lstrip("=") line_req = install_req_from_editable( line, isolated=isolated, ) else: line_req = install_req_from_line( COMMENT_RE.sub("", line).strip(), isolated=isolated, ) if not line_req.name: logger.info( "Skipping line in requirement file [%s] because " "it's not clear what it would install: %s", req_file_path, line.strip(), ) logger.info( " (add #egg=PackageName to the URL to avoid" " this warning)" ) else: line_req_canonical_name = canonicalize_name(line_req.name) if line_req_canonical_name not in installations: # either it's not installed, or it is installed # but has been processed already if not req_files[line_req.name]: logger.warning( "Requirement file [%s] contains %s, but " "package %r is not installed", req_file_path, COMMENT_RE.sub("", line).strip(), line_req.name, ) else: req_files[line_req.name].append(req_file_path) else: yield str(installations[line_req_canonical_name]).rstrip() del installations[line_req_canonical_name] req_files[line_req.name].append(req_file_path) # Warn about requirements that were included multiple times (in a # single requirements file or in different requirements files). for name, files in req_files.items(): if len(files) > 1: logger.warning( "Requirement %s included multiple times [%s]", name, ", ".join(sorted(set(files))), ) yield ("## The following requirements were added by pip freeze:") for installation in sorted(installations.values(), key=lambda x: x.name.lower()): if installation.canonical_name not in skip: yield str(installation).rstrip() def _format_as_name_version(dist: BaseDistribution) -> str: if isinstance(dist.version, Version): return f"{dist.raw_name}=={dist.version}" return f"{dist.raw_name}==={dist.version}" def _get_editable_info(dist: BaseDistribution) -> _EditableInfo: """ Compute and return values (req, comments) for use in FrozenRequirement.from_dist(). """ editable_project_location = dist.editable_project_location assert editable_project_location location = os.path.normcase(os.path.abspath(editable_project_location)) from pip._internal.vcs import RemoteNotFoundError, RemoteNotValidError, vcs vcs_backend = vcs.get_backend_for_dir(location) if vcs_backend is None: display = _format_as_name_version(dist) logger.debug( 'No VCS found for editable requirement "%s" in: %r', display, location, ) return _EditableInfo( requirement=location, comments=[f"# Editable install with no version control ({display})"], ) vcs_name = type(vcs_backend).__name__ try: req = vcs_backend.get_src_requirement(location, dist.raw_name) except RemoteNotFoundError: display = _format_as_name_version(dist) return _EditableInfo( requirement=location, comments=[f"# Editable {vcs_name} install with no remote ({display})"], ) except RemoteNotValidError as ex: display = _format_as_name_version(dist) return _EditableInfo( requirement=location, comments=[ f"# Editable {vcs_name} install ({display}) with either a deleted " f"local remote or invalid URI:", f"# '{ex.url}'", ], ) except BadCommand: logger.warning( "cannot determine version of editable source in %s " "(%s command not found in path)", location, vcs_backend.name, ) return _EditableInfo(requirement=location, comments=[]) except InstallationError as exc: logger.warning("Error when trying to get requirement for VCS system %s", exc) else: return _EditableInfo(requirement=req, comments=[]) logger.warning("Could not determine repository location of %s", location) return _EditableInfo( requirement=location, comments=["## !! Could not determine repository location"], ) class FrozenRequirement: def __init__( self, name: str, req: str, editable: bool, comments: Iterable[str] = (), ) -> None: self.name = name self.canonical_name = canonicalize_name(name) self.req = req self.editable = editable self.comments = comments @classmethod def from_dist(cls, dist: BaseDistribution) -> "FrozenRequirement": editable = dist.editable if editable: req, comments = _get_editable_info(dist) else: comments = [] direct_url = dist.direct_url if direct_url: # if PEP 610 metadata is present, use it req = direct_url_as_pep440_direct_reference(direct_url, dist.raw_name) else: # name==version requirement req = _format_as_name_version(dist) return cls(dist.raw_name, req, editable, comments=comments) def __str__(self) -> str: req = self.req if self.editable: req = f"-e {req}" return "\n".join(list(self.comments) + [str(req)]) + "\n" PKH]>\python3.10/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-310.pycnu[o ai>@s.dZddlZddlZddlmZddlmZmZmZddl m Z ddl m Z ddl mZddlmZdd lmZdd lmZdd lmZdd lmZeeZGd ddeZdeedeededdfddZdeedeedeedeedeede de dedede dede d edede fd!d"Z!dS)#z6Legacy installation process, i.e. `setup.py install`. N) change_root)ListOptionalSequence)BuildEnvironment)InstallationError)Scheme) indent_log) ensure_dir)make_setuptools_install_args)runner_with_spinner_message) TempDirectoryc@s eZdZdS)LegacyInstallFailureN)__name__ __module__ __qualname__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/install/legacy.pyrsr record_linesrootreq_descriptionreturnc sdtdtffdd }|D]}tj|}|dr ||}n q d|}t|g}|D]}|} tj| r@| tjj 7} | tj || |q.| t |tj|d} t| d} | d |d WddS1swwYdS) Npathrcs"dus tj|s |St|S)N)osrisabsr)rrrr prepend_roots zBwrite_installed_files_from_setuptools_record..prepend_rootz .egg-infoz{} did not indicate that it installed an .egg-info directory. Only setup.py projects generating .egg-info directories are supported.zinstalled-files.txtw )strrrdirnameendswithformatrstripisdirsepappendrelpathsortr joinopenwrite) rrrrline directory egg_info_dirmessage new_linesfilenameinst_files_pathfrrr,write_installed_files_from_setuptools_records.     "r4install_optionsglobal_optionshomeprefix use_user_site pycompilescheme setup_py_pathisolatedreq_name build_envunpacked_source_directorycCsT|j}tdd}z`tj|jd}t|||||||||| |d }td| }t | ||| dWdn1s?wYWdn1sNwYtj|sht d|WWddSWnt yx}zt |d}~wwt |}|}Wdn1swYWdn1swYt||| d S) Nrecord)kindzinstall-record.txt) r6r5record_filenamerr8 header_dirr7r9no_user_configr:zRunning setup.py install for )cmdcwdzRecord file %s not foundFT)headersr rrr)r r r existsloggerdebug Exceptionrr*read splitlinesr4)r5r6rr7r8r9r:r;r<r=r>r?r@rrDtemp_dirrC install_argsrunnerer3rrrrinstall>sX     +rS)"__doc__loggingrdistutils.utilrtypingrrrpip._internal.build_envrpip._internal.exceptionsrpip._internal.models.schemerpip._internal.utils.loggingr pip._internal.utils.miscr $pip._internal.utils.setuptools_buildr pip._internal.utils.subprocessr pip._internal.utils.temp_dirr getLoggerrrJrLrrr4boolrSrrrrsn           %     PKH]3# 00^python3.10/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-310.pycnu[o ai3@sdZdS)z,For modules related to installing packages. N)__doc__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/install/__init__.pysPKH]we  epython3.10/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-310.pycnu[o ai@sdZddlZddlmZmZmZddlmZddlm Z ddl m Z ddl m Z eeZdeed eed eed eed ed edededededdfddZdS)z?Legacy editable installation process, i.e. `setup.py develop`. N)ListOptionalSequence)BuildEnvironment) indent_log)make_setuptools_develop_args)call_subprocessinstall_optionsglobal_optionsprefixhome use_user_sitename setup_py_pathisolated build_envunpacked_source_directoryreturnc Cstd|t|||||||d} t)|t| | dWdn1s(wYWddSWddS1s@wYdS)z[Install a package in editable mode. Most arguments are pass-through to setuptools. zRunning setup.py develop for %s)r r no_user_configr r r )cwdN)loggerinforrr) r r r r r rrrrrargsr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/operations/install/editable_legacy.pyinstall_editables(  "r)__doc__loggingtypingrrrpip._internal.build_envrpip._internal.utils.loggingr$pip._internal.utils.setuptools_buildrpip._internal.utils.subprocessr getLogger__name__rstrboolrrrrrs>        PKH]nRR[python3.10/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-310.pycnu[o aik@sdZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl mZddlmZddlmZmZmZddlmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%ddl&m'Z'm(Z(ddl)m*Z*dd l+m,Z,dd l-m.Z.dd l/m0Z0dd l1m2Z2dd l3m4Z4m5Z5m6Z6ddl7m8Z8m9Z9ddl:m;Z;mZ>m?Z?ddl@mAZAmBZBmCZCmDZDddlEmFZFmGZGmHZHmIZIddlJmKZKerddlmLZLGdddeLZMeNeOZPedeQZRe#eReQe$eSeQffZTd[deQdeSde#eQeQffddZUdeQdeeQeffdd ZVdeQdeWfd!d"ZXd#edeWfd$d%ZYd&e4de#eeQeQfeeQeQfffd'd(ZZd)e!eQde eQfd*d+Z[d,eeTdee#eQeQeQffd-d.Z\d/eRdeQfd0d1Z]d\deQd2e eQdeRfd3d4Z^d5eeeQd6eeReRfd7e"eRd8eeQd9eQdeeTf d:d;Z_dZ`Gd?d@d@ZaGdAdBdBZbGdCdDdDe0ZcdEeQddfdFdGZdGdHdIdIe*Ze J J  Kd]dLeQdMe'dNeQdOesz5message_about_scripts_not_on_PATH..PATHrQcs&i|]\}}tj|vr||qSr8)rYrFry)r| parent_dirrx not_warn_dirsr8r; s z5message_about_scripts_not_on_PATH..z script {} isrzscripts {} are, z and z.The {} installed in '{}' which is not on PATH.zeConsider adding {} to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.zthis directoryzthese directoriescss |] }|r|ddkVqdS)r~Nr8r{r8r8r; s   z4message_about_scripts_not_on_PATH..ziNOTE: The current PATH contains path(s) starting with `~`, which may not be expanded by all applications. ) collections defaultdictsetrYrFdirnamebasenameaddenvironrlsplitpathsepappendryr^r_itemssortedlenformatjoinany) rxgrouped_by_dirdestfiler script_namewarn_for msg_lines dir_scriptssorted_scripts start_text last_line_fmtwarn_for_tildetilde_warning_msgr8rr;!message_about_scripts_not_on_PATHsT        routrowscCstdd|DS)aNormalize the given rows of a RECORD file. Items in each row are converted into str. Rows are then sorted to make the value more predictable for tests. Each row is a 3-tuple (path, hash, size) and corresponds to a record of a RECORD file (see PEP 376 and PEP 427 for details). For the rows passed to this function, the size can be an integer as an int or string, or the empty string. css$|] \}}}||t|fVqdSr7)rC)r| record_pathhash_sizer8r8r;rs z&_normalized_outrows..)r)rr8r8r;_normalized_outrowssrrcCs|Sr7r8)rr8r8r;_record_to_fs_pathr=r relative_tocCsX|durtj|dtj|dkrtj||}|tjjd}td|S)Nr/r2)rYrF splitdrivermrelpathr&rzr)rFrr8r8r;_fs_to_record_paths r old_csv_rows installedr5 generatedlib_dircCsg}|D]H}t|dkrtd|td|d}|||}||vr,tt|\} } nt|dkr6|dnd} t|dkrB|dnd} ||| | fq|D]} t| |} t| \} } || | | fqO| D] } || ddfqi|S)z_ :param installed: A map from archive RECORD path to installation RECORD path. z,RECORD line has more than three elements: %sr2rrrQ) rloggerwarningrpoprOrrrvalues)rrr5rrinstalled_rowsrowold_record_pathnew_record_pathrJrNfrFinstalled_record_pathr8r8r;get_csv_rows_for_installeds$       rconsolecCs|}g}|dd}|rJdtjvr|d|tjdddkr/|dtjd||dt d |d d |D}|D]}||=qD|d d}|rwdtjvr^|d ||dt |dd |D}|D]}||=qq| t dj| |S)zk Given the mapping from entrypoint name to callable, return the relevant console script specs. pipNENSUREPIP_OPTIONSzpip = rQ altinstallz pip{} = {}rz = cSg|] }td|r|qS)zpip(\d(\.\d)?)?$rematchr|kr8r8r;r~Jsz,get_console_script_specs.. easy_installzeasy_install = zeasy_install-{} = {}cSr)zeasy_install(-\d\.\d)?$rrr8r8r;r~Xs  {} = {}) copyrrYrrrlrr^ version_inforextendrr)rscripts_to_generate pip_scriptpip_epreasy_install_scripteasy_install_epr8r8r;get_console_script_specss< #   rc@s>eZdZdedededdfddZdefdd Zd d d Z dS) ZipBackedFiler3r4zip_filer6NcCs||_||_||_d|_dSNF)r3r4 _zip_filer5)r:r3r4rr8r8r;__init__es zZipBackedFile.__init__cCs|j|jSr7)rgetinfor3r9r8r8r;_getinfomszZipBackedFile._getinfoc Cstj|j}t|tj|jrt|j|}|j |$}t |jd}t ||Wdn1s:wYWdn1sIwYt |rYt |jdSdS)NrX)rYrFrr4r(existsunlinkrrr[shutil copyfileobjr.r-)r:rzipinfordestr8r8r;r<ps zZipBackedFile.saver>) r?r@rAr2rCrrrrr<r8r8r8r;rds rc@s eZdZd ddZd ddZdS) ScriptFilefiler1r6NcCs$||_|jj|_|jj|_d|_dSr)_filer3r4r5)r:rr8r8r;rs   zScriptFile.__init__cCs|jt|j|_dSr7)rr<rir4r5r9r8r8r;r<s zScriptFile.save)rr1r6Nr>)r?r@rArr<r8r8r8r;rs rcs&eZdZdeddffdd ZZS)MissingCallableSuffixrvr6Ncstd|dS)NzInvalid script entry point: {} - A callable suffix is required. Cf https://packaging.python.org/specifications/entry-points/#use-for-scripts for more information.)superrr)r:rv __class__r8r;rszMissingCallableSuffix.__init__)r?r@rArCr __classcell__r8r8rr;rsr specificationcCs.t|}|dur|jdurtt|dSdSr7)rsuffixrrC)rentryr8r8r;_raise_for_invalid_entrypoints rcs8eZdZddedeeefdeeffdd ZZS)PipScriptMakerNroptionsr6cst|t||Sr7)rrmake)r:rrrr8r;rszPipScriptMaker.maker7) r?r@rArCr r rrrr8r8rr;rs0rTFru wheel_zip wheel_pathscheme pycompilewarn_script_location direct_url requestedc8 s(t||\}} t| r|jn|jitg} d8dtdtdtddffdd } d tdtfd d } d td tddffdd dtdtdt tgdfffdd } dtdt dt tgdfffdd }d tdtfdd}t t t| }t| |}t||\}}| |}t||}d tdtfdd}t||\}}|||}t||}t||}ttt|}t|\dddtffdd }t||}t||}tt|}t||}|D]}|| |j|j|jqdttffdd }d tdtfd!d"} |rktQ}!t<td#|D]+}"t j!|"d$d$d%}#|#rB| |"}$t"j#$|$s2Jt d&|$%t"j#j&d'}%| |%|$qWdn 1sOwYWdn 1s_wYt'(|!)t*d|j+}&d$|&_,d(h|&_-d$|&_.t/}'t0t1d)j23}(|&4|'})| 5|)| 5|&4|(d*d$i|rt6|)}*|*durt'7|*d+t8@t9j:d td,t;dtt<ffd-d. }+t"j#=|},t"j#=|,d/}-|+|- }.|.>d0Wdn 1swY| ?|-|dur$t"j#=|,t@}/|+|/}0|0>|ABd1Wdn 1swY| ?|/|rIt"j#=|,d2}1tC|1d3Wdn 1s?wY| ?|1|Dd4}2t0tEF|2G}3tH|3| d5}4t"j#=|,d4}5|+|5fitId6}6tEJt d7|6}7|7KtL|4WddS1swYdS)9aInstall a wheel. :param name: Name of the project to install :param wheel_zip: open ZipFile for wheel being installed :param scheme: Distutils scheme dictating the install directories :param req_description: String used in place of the requirement, for logging :param pycompile: Whether to byte-compile installed Python files :param warn_script_location: Whether to check that scripts are installed into a directory on PATH :raises UnsupportedWheel: * when the directory holds an unpacked wheel with incompatible Wheel-Version * when the .dist-info dir does not match the wheel Fsrcfilermodifiedr6Ncs,t|}||<|rt|dSdS)z6Map archive RECORD paths to installation RECORD paths.N)rr)rrrnewpath)r5rrr8r;record_installeds z(_install_wheel..record_installedrFcSs |dS)Nr)endswithrFr8r8r; is_dir_paths z#_install_wheel..is_dir_path dest_dir_path target_pathcs$t||sd}t|||dS)NzRThe wheel {!r} has a file {!r} trying to install outside the target directory {!r})r,rr)rrmessage)rr8r;assert_no_path_traversals  z0_install_wheel..assert_no_path_traversalrrr1csdtddffdd }|S)Nrr6r1cs0tj|}tj|}|t||Sr7)rYrFnormpathrr)r normed_pathr4)rrrr8r;make_root_scheme_files   zM_install_wheel..root_scheme_file_maker..make_root_scheme_file)r2)rrr)r)rrr;root_scheme_file_makersz._install_wheel..root_scheme_file_makerrcs2fddtDdtddffdd }|S)Ncsi|]}|t|qSr8)getattr)r|key)rr8r;rszB_install_wheel..data_scheme_file_maker..rr6r1c stj|}z |tjjd\}}}Wnty$d|}t|wz|}WntyEd t }d|||}t|wtj ||}||t ||S)NrzbUnexpected file in {}: {!r}. .data directory contents should be named like: '/'.rzUnknown scheme key used in {}: {} (for file {!r}). .data directory contents should be in subdirectories named with a valid scheme key ({})) rYrFrrrz ValueErrorrrKeyErrorrrr) rr_ scheme_key dest_subpathr scheme_pathvalid_scheme_keysr4)r scheme_pathsrrr8r;make_data_scheme_files*       zM_install_wheel..data_scheme_file_maker..make_data_scheme_file)r#r2)rrr)rr)rrrr;data_scheme_file_makersz._install_wheel..data_scheme_file_makercSs|ddddS)Nrrr.data)rrrr8r8r;is_data_scheme_pathsz+_install_wheel..is_data_scheme_pathcSs2|dd}t|dko|ddo|ddkS)Nrrrrrrx)rrr)rFpartsr8r8r;is_script_scheme_path"s &z-_install_wheel..is_script_scheme_pathrcsz|j}tj|}|dr|dd}n|dr%|dd}n|dr3|dd}n|}|vp<|vS)Nz.exez -script.pyiz.pya)r4rYrFrrmr)rrFru matchname)rguir8r;is_entrypoint_wrapper5s z-_install_wheel..is_entrypoint_wrapperc3sJttD]}tj|}tj|sq |dsq |Vq dS)Nz.py)rrrrYrFrrZr)installed_pathfull_installed_path)rrr8r;pyc_source_file_pathsPs  z-_install_wheel..pyc_source_file_pathscSs tj|S)z8Return the path the pyc file would have been written to.) importlibutilcache_from_sourcerr8r8r;pyc_output_path]s z'_install_wheel..pyc_output_pathignoreT)forcequietr2rrQrrikwargsc;sVt|fi| }|VWdn1swYt|jt|j|dSr7)r%rYchmodrur&)rFr'r)generated_file_moder8r;_generate_files z&_install_wheel.._generate_file INSTALLERspip rR REQUESTEDrXRECORD)rr5rrwzIO[str])F)Mr/rnpurelibplatlibrr2rCrDrr r$rrnamelistrr*maprr rrrwrr<r3r4r5rr'warningscatch_warningsfilterwarnings compileall compile_filerYrFrr&rzrdebuggetvaluerrxclobbervariantsset_moderlistrrr make_multiplerrrr+ contextlibcontextmanagerr r rrdrr!to_jsonr`r[ read_textcsvreader splitlinesrrUwriter writerowsr)8rurrrrrrrinfo_dirrjrrrrrrpaths file_pathsroot_scheme_pathsdata_scheme_pathsrfilesrother_scheme_pathsscript_scheme_pathsrother_scheme_files distributionrscript_scheme_filesrrr#stdoutrFsuccesspyc_pathpyc_record_pathmakerrgui_scripts_to_generategenerated_console_scriptsmsgr* dest_info_dirinstaller_pathinstaller_filedirect_url_pathdirect_url_filerequested_path record_text record_rowsrowsr record_filerFr8)rr5rr)rrrrr;_install_wheels     !                                $rereq_descriptionc csDzdVWdSty!}zd||jd}t||d}~ww)NzFor req: {}. {}r)rrargs)rferr8r8r;req_error_contexts  ric Cst|dd1}t|t||||||||dWdn1s"wYWddSWddS1s:wYdS)NT) allowZip64)rurrrrrrr)rrire) rurrrfrrrrzr8r8r; install_wheels  "rl)rEr7)TTNF)j__doc__rr6r?rCr loggingos.pathrYrrr^r3base64r email.messager itertoolsrrrtypingrrr r r r r rrrrrrrrrzipfilerrpip._vendor.distlib.scriptsrZpip._vendor.distlib.utilrpip._vendor.packaging.utilsrpip._internal.exceptionsrpip._internal.locationsrpip._internal.metadatarrr pip._internal.models.direct_urlr!r"pip._internal.models.schemer#r$pip._internal.utils.filesystemr%r&pip._internal.utils.miscr'r(r)r*pip._internal.utils.unpackingr+r,r-r.pip._internal.utils.wheelr/r0r1 getLoggerr?rrCr2intInstalledCSVRowrOrUrDrirnrwrrrrrrrrrrrrer@rirlr8r8r8r;s  H         * H     Q(      PKH] >>Cpython3.10/site-packages/pip/_internal/operations/install/legacy.pynu["""Legacy installation process, i.e. `setup.py install`. """ import logging import os from distutils.util import change_root from typing import List, Optional, Sequence from pip._internal.build_env import BuildEnvironment from pip._internal.exceptions import InstallationError from pip._internal.models.scheme import Scheme from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import ensure_dir from pip._internal.utils.setuptools_build import make_setuptools_install_args from pip._internal.utils.subprocess import runner_with_spinner_message from pip._internal.utils.temp_dir import TempDirectory logger = logging.getLogger(__name__) class LegacyInstallFailure(Exception): pass def write_installed_files_from_setuptools_record( record_lines: List[str], root: Optional[str], req_description: str, ) -> None: def prepend_root(path: str) -> str: if root is None or not os.path.isabs(path): return path else: return change_root(root, path) for line in record_lines: directory = os.path.dirname(line) if directory.endswith(".egg-info"): egg_info_dir = prepend_root(directory) break else: message = ( "{} did not indicate that it installed an " ".egg-info directory. Only setup.py projects " "generating .egg-info directories are supported." ).format(req_description) raise InstallationError(message) new_lines = [] for line in record_lines: filename = line.strip() if os.path.isdir(filename): filename += os.path.sep new_lines.append(os.path.relpath(prepend_root(filename), egg_info_dir)) new_lines.sort() ensure_dir(egg_info_dir) inst_files_path = os.path.join(egg_info_dir, "installed-files.txt") with open(inst_files_path, "w") as f: f.write("\n".join(new_lines) + "\n") def install( install_options: List[str], global_options: Sequence[str], root: Optional[str], home: Optional[str], prefix: Optional[str], use_user_site: bool, pycompile: bool, scheme: Scheme, setup_py_path: str, isolated: bool, req_name: str, build_env: BuildEnvironment, unpacked_source_directory: str, req_description: str, ) -> bool: header_dir = scheme.headers with TempDirectory(kind="record") as temp_dir: try: record_filename = os.path.join(temp_dir.path, "install-record.txt") install_args = make_setuptools_install_args( setup_py_path, global_options=global_options, install_options=install_options, record_filename=record_filename, root=root, prefix=prefix, header_dir=header_dir, home=home, use_user_site=use_user_site, no_user_config=isolated, pycompile=pycompile, ) runner = runner_with_spinner_message( f"Running setup.py install for {req_name}" ) with indent_log(), build_env: runner( cmd=install_args, cwd=unpacked_source_directory, ) if not os.path.exists(record_filename): logger.debug("Record file %s not found", record_filename) # Signal to the caller that we didn't install the new package return False except Exception as e: # Signal to the caller that we didn't install the new package raise LegacyInstallFailure from e # At this point, we have successfully installed the requirement. # We intentionally do not use any encoding to read the file because # setuptools writes the file using distutils.file_util.write_file, # which does not specify an encoding. with open(record_filename) as f: record_lines = f.read().splitlines() write_installed_files_from_setuptools_record(record_lines, root, req_description) return True PKH]ZLpython3.10/site-packages/pip/_internal/operations/install/editable_legacy.pynu["""Legacy editable installation process, i.e. `setup.py develop`. """ import logging from typing import List, Optional, Sequence from pip._internal.build_env import BuildEnvironment from pip._internal.utils.logging import indent_log from pip._internal.utils.setuptools_build import make_setuptools_develop_args from pip._internal.utils.subprocess import call_subprocess logger = logging.getLogger(__name__) def install_editable( install_options: List[str], global_options: Sequence[str], prefix: Optional[str], home: Optional[str], use_user_site: bool, name: str, setup_py_path: str, isolated: bool, build_env: BuildEnvironment, unpacked_source_directory: str, ) -> None: """Install a package in editable mode. Most arguments are pass-through to setuptools. """ logger.info("Running setup.py develop for %s", name) args = make_setuptools_develop_args( setup_py_path, global_options=global_options, install_options=install_options, no_user_config=isolated, prefix=prefix, home=home, use_user_site=use_user_site, ) with indent_log(): with build_env: call_subprocess( args, cwd=unpacked_source_directory, ) PKH]X*kkBpython3.10/site-packages/pip/_internal/operations/install/wheel.pynu["""Support for installing and building the "wheel" binary package format. """ import collections import compileall import contextlib import csv import importlib import logging import os.path import re import shutil import sys import warnings from base64 import urlsafe_b64encode from email.message import Message from itertools import chain, filterfalse, starmap from typing import ( IO, TYPE_CHECKING, Any, BinaryIO, Callable, Dict, Iterable, Iterator, List, NewType, Optional, Sequence, Set, Tuple, Union, cast, ) from zipfile import ZipFile, ZipInfo from pip._vendor.distlib.scripts import ScriptMaker from pip._vendor.distlib.util import get_export_entry from pip._vendor.packaging.utils import canonicalize_name from pip._internal.exceptions import InstallationError from pip._internal.locations import get_major_minor_version from pip._internal.metadata import ( BaseDistribution, FilesystemWheel, get_wheel_distribution, ) from pip._internal.models.direct_url import DIRECT_URL_METADATA_NAME, DirectUrl from pip._internal.models.scheme import SCHEME_KEYS, Scheme from pip._internal.utils.filesystem import adjacent_tmp_file, replace from pip._internal.utils.misc import captured_stdout, ensure_dir, hash_file, partition from pip._internal.utils.unpacking import ( current_umask, is_within_directory, set_extracted_file_to_default_mode_plus_executable, zip_item_is_executable, ) from pip._internal.utils.wheel import parse_wheel if TYPE_CHECKING: from typing import Protocol class File(Protocol): src_record_path: "RecordPath" dest_path: str changed: bool def save(self) -> None: pass logger = logging.getLogger(__name__) RecordPath = NewType("RecordPath", str) InstalledCSVRow = Tuple[RecordPath, str, Union[int, str]] def rehash(path: str, blocksize: int = 1 << 20) -> Tuple[str, str]: """Return (encoded_digest, length) for path using hashlib.sha256()""" h, length = hash_file(path, blocksize) digest = "sha256=" + urlsafe_b64encode(h.digest()).decode("latin1").rstrip("=") return (digest, str(length)) def csv_io_kwargs(mode: str) -> Dict[str, Any]: """Return keyword arguments to properly open a CSV file in the given mode. """ return {"mode": mode, "newline": "", "encoding": "utf-8"} def fix_script(path: str) -> bool: """Replace #!python with #!/path/to/python Return True if file was changed. """ # XXX RECORD hashes will need to be updated assert os.path.isfile(path) with open(path, "rb") as script: firstline = script.readline() if not firstline.startswith(b"#!python"): return False exename = sys.executable.encode(sys.getfilesystemencoding()) firstline = b"#!" + exename + os.linesep.encode("ascii") rest = script.read() with open(path, "wb") as script: script.write(firstline) script.write(rest) return True def wheel_root_is_purelib(metadata: Message) -> bool: return metadata.get("Root-Is-Purelib", "").lower() == "true" def get_entrypoints(dist: BaseDistribution) -> Tuple[Dict[str, str], Dict[str, str]]: console_scripts = {} gui_scripts = {} for entry_point in dist.iter_entry_points(): if entry_point.group == "console_scripts": console_scripts[entry_point.name] = entry_point.value elif entry_point.group == "gui_scripts": gui_scripts[entry_point.name] = entry_point.value return console_scripts, gui_scripts def message_about_scripts_not_on_PATH(scripts: Sequence[str]) -> Optional[str]: """Determine if any scripts are not on PATH and format a warning. Returns a warning message if one or more scripts are not on PATH, otherwise None. """ if not scripts: return None # Group scripts by the path they were installed in grouped_by_dir: Dict[str, Set[str]] = collections.defaultdict(set) for destfile in scripts: parent_dir = os.path.dirname(destfile) script_name = os.path.basename(destfile) grouped_by_dir[parent_dir].add(script_name) # We don't want to warn for directories that are on PATH. not_warn_dirs = [ os.path.normcase(i).rstrip(os.sep) for i in os.environ.get("PATH", "").split(os.pathsep) ] # If an executable sits with sys.executable, we don't warn for it. # This covers the case of venv invocations without activating the venv. not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) warn_for: Dict[str, Set[str]] = { parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() if os.path.normcase(parent_dir) not in not_warn_dirs } if not warn_for: return None # Format a message msg_lines = [] for parent_dir, dir_scripts in warn_for.items(): sorted_scripts: List[str] = sorted(dir_scripts) if len(sorted_scripts) == 1: start_text = "script {} is".format(sorted_scripts[0]) else: start_text = "scripts {} are".format( ", ".join(sorted_scripts[:-1]) + " and " + sorted_scripts[-1] ) msg_lines.append( "The {} installed in '{}' which is not on PATH.".format( start_text, parent_dir ) ) last_line_fmt = ( "Consider adding {} to PATH or, if you prefer " "to suppress this warning, use --no-warn-script-location." ) if len(msg_lines) == 1: msg_lines.append(last_line_fmt.format("this directory")) else: msg_lines.append(last_line_fmt.format("these directories")) # Add a note if any directory starts with ~ warn_for_tilde = any( i[0] == "~" for i in os.environ.get("PATH", "").split(os.pathsep) if i ) if warn_for_tilde: tilde_warning_msg = ( "NOTE: The current PATH contains path(s) starting with `~`, " "which may not be expanded by all applications." ) msg_lines.append(tilde_warning_msg) # Returns the formatted multiline message return "\n".join(msg_lines) def _normalized_outrows( outrows: Iterable[InstalledCSVRow], ) -> List[Tuple[str, str, str]]: """Normalize the given rows of a RECORD file. Items in each row are converted into str. Rows are then sorted to make the value more predictable for tests. Each row is a 3-tuple (path, hash, size) and corresponds to a record of a RECORD file (see PEP 376 and PEP 427 for details). For the rows passed to this function, the size can be an integer as an int or string, or the empty string. """ # Normally, there should only be one row per path, in which case the # second and third elements don't come into play when sorting. # However, in cases in the wild where a path might happen to occur twice, # we don't want the sort operation to trigger an error (but still want # determinism). Since the third element can be an int or string, we # coerce each element to a string to avoid a TypeError in this case. # For additional background, see-- # https://github.com/pypa/pip/issues/5868 return sorted( (record_path, hash_, str(size)) for record_path, hash_, size in outrows ) def _record_to_fs_path(record_path: RecordPath) -> str: return record_path def _fs_to_record_path(path: str, relative_to: Optional[str] = None) -> RecordPath: if relative_to is not None: # On Windows, do not handle relative paths if they belong to different # logical disks if ( os.path.splitdrive(path)[0].lower() == os.path.splitdrive(relative_to)[0].lower() ): path = os.path.relpath(path, relative_to) path = path.replace(os.path.sep, "/") return cast("RecordPath", path) def get_csv_rows_for_installed( old_csv_rows: List[List[str]], installed: Dict[RecordPath, RecordPath], changed: Set[RecordPath], generated: List[str], lib_dir: str, ) -> List[InstalledCSVRow]: """ :param installed: A map from archive RECORD path to installation RECORD path. """ installed_rows: List[InstalledCSVRow] = [] for row in old_csv_rows: if len(row) > 3: logger.warning("RECORD line has more than three elements: %s", row) old_record_path = cast("RecordPath", row[0]) new_record_path = installed.pop(old_record_path, old_record_path) if new_record_path in changed: digest, length = rehash(_record_to_fs_path(new_record_path)) else: digest = row[1] if len(row) > 1 else "" length = row[2] if len(row) > 2 else "" installed_rows.append((new_record_path, digest, length)) for f in generated: path = _fs_to_record_path(f, lib_dir) digest, length = rehash(f) installed_rows.append((path, digest, length)) for installed_record_path in installed.values(): installed_rows.append((installed_record_path, "", "")) return installed_rows def get_console_script_specs(console: Dict[str, str]) -> List[str]: """ Given the mapping from entrypoint name to callable, return the relevant console script specs. """ # Don't mutate caller's version console = console.copy() scripts_to_generate = [] # Special case pip and setuptools to generate versioned wrappers # # The issue is that some projects (specifically, pip and setuptools) use # code in setup.py to create "versioned" entry points - pip2.7 on Python # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into # the wheel metadata at build time, and so if the wheel is installed with # a *different* version of Python the entry points will be wrong. The # correct fix for this is to enhance the metadata to be able to describe # such versioned entry points, but that won't happen till Metadata 2.0 is # available. # In the meantime, projects using versioned entry points will either have # incorrect versioned entry points, or they will not be able to distribute # "universal" wheels (i.e., they will need a wheel per Python version). # # Because setuptools and pip are bundled with _ensurepip and virtualenv, # we need to use universal wheels. So, as a stopgap until Metadata 2.0, we # override the versioned entry points in the wheel and generate the # correct ones. This code is purely a short-term measure until Metadata 2.0 # is available. # # To add the level of hack in this section of code, in order to support # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment # variable which will control which version scripts get installed. # # ENSUREPIP_OPTIONS=altinstall # - Only pipX.Y and easy_install-X.Y will be generated and installed # ENSUREPIP_OPTIONS=install # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note # that this option is technically if ENSUREPIP_OPTIONS is set and is # not altinstall # DEFAULT # - The default behavior is to install pip, pipX, pipX.Y, easy_install # and easy_install-X.Y. pip_script = console.pop("pip", None) if pip_script: if "ENSUREPIP_OPTIONS" not in os.environ: scripts_to_generate.append("pip = " + pip_script) if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": scripts_to_generate.append( "pip{} = {}".format(sys.version_info[0], pip_script) ) scripts_to_generate.append(f"pip{get_major_minor_version()} = {pip_script}") # Delete any other versioned pip entry points pip_ep = [k for k in console if re.match(r"pip(\d(\.\d)?)?$", k)] for k in pip_ep: del console[k] easy_install_script = console.pop("easy_install", None) if easy_install_script: if "ENSUREPIP_OPTIONS" not in os.environ: scripts_to_generate.append("easy_install = " + easy_install_script) scripts_to_generate.append( "easy_install-{} = {}".format( get_major_minor_version(), easy_install_script ) ) # Delete any other versioned easy_install entry points easy_install_ep = [ k for k in console if re.match(r"easy_install(-\d\.\d)?$", k) ] for k in easy_install_ep: del console[k] # Generate the console entry points specified in the wheel scripts_to_generate.extend(starmap("{} = {}".format, console.items())) return scripts_to_generate class ZipBackedFile: def __init__( self, src_record_path: RecordPath, dest_path: str, zip_file: ZipFile ) -> None: self.src_record_path = src_record_path self.dest_path = dest_path self._zip_file = zip_file self.changed = False def _getinfo(self) -> ZipInfo: return self._zip_file.getinfo(self.src_record_path) def save(self) -> None: # directory creation is lazy and after file filtering # to ensure we don't install empty dirs; empty dirs can't be # uninstalled. parent_dir = os.path.dirname(self.dest_path) ensure_dir(parent_dir) # When we open the output file below, any existing file is truncated # before we start writing the new contents. This is fine in most # cases, but can cause a segfault if pip has loaded a shared # object (e.g. from pyopenssl through its vendored urllib3) # Since the shared object is mmap'd an attempt to call a # symbol in it will then cause a segfault. Unlinking the file # allows writing of new contents while allowing the process to # continue to use the old copy. if os.path.exists(self.dest_path): os.unlink(self.dest_path) zipinfo = self._getinfo() with self._zip_file.open(zipinfo) as f: with open(self.dest_path, "wb") as dest: shutil.copyfileobj(f, dest) if zip_item_is_executable(zipinfo): set_extracted_file_to_default_mode_plus_executable(self.dest_path) class ScriptFile: def __init__(self, file: "File") -> None: self._file = file self.src_record_path = self._file.src_record_path self.dest_path = self._file.dest_path self.changed = False def save(self) -> None: self._file.save() self.changed = fix_script(self.dest_path) class MissingCallableSuffix(InstallationError): def __init__(self, entry_point: str) -> None: super().__init__( "Invalid script entry point: {} - A callable " "suffix is required. Cf https://packaging.python.org/" "specifications/entry-points/#use-for-scripts for more " "information.".format(entry_point) ) def _raise_for_invalid_entrypoint(specification: str) -> None: entry = get_export_entry(specification) if entry is not None and entry.suffix is None: raise MissingCallableSuffix(str(entry)) class PipScriptMaker(ScriptMaker): def make(self, specification: str, options: Dict[str, Any] = None) -> List[str]: _raise_for_invalid_entrypoint(specification) return super().make(specification, options) def _install_wheel( name: str, wheel_zip: ZipFile, wheel_path: str, scheme: Scheme, pycompile: bool = True, warn_script_location: bool = True, direct_url: Optional[DirectUrl] = None, requested: bool = False, ) -> None: """Install a wheel. :param name: Name of the project to install :param wheel_zip: open ZipFile for wheel being installed :param scheme: Distutils scheme dictating the install directories :param req_description: String used in place of the requirement, for logging :param pycompile: Whether to byte-compile installed Python files :param warn_script_location: Whether to check that scripts are installed into a directory on PATH :raises UnsupportedWheel: * when the directory holds an unpacked wheel with incompatible Wheel-Version * when the .dist-info dir does not match the wheel """ info_dir, metadata = parse_wheel(wheel_zip, name) if wheel_root_is_purelib(metadata): lib_dir = scheme.purelib else: lib_dir = scheme.platlib # Record details of the files moved # installed = files copied from the wheel to the destination # changed = files changed while installing (scripts #! line typically) # generated = files newly generated during the install (script wrappers) installed: Dict[RecordPath, RecordPath] = {} changed: Set[RecordPath] = set() generated: List[str] = [] def record_installed( srcfile: RecordPath, destfile: str, modified: bool = False ) -> None: """Map archive RECORD paths to installation RECORD paths.""" newpath = _fs_to_record_path(destfile, lib_dir) installed[srcfile] = newpath if modified: changed.add(_fs_to_record_path(destfile)) def is_dir_path(path: RecordPath) -> bool: return path.endswith("/") def assert_no_path_traversal(dest_dir_path: str, target_path: str) -> None: if not is_within_directory(dest_dir_path, target_path): message = ( "The wheel {!r} has a file {!r} trying to install" " outside the target directory {!r}" ) raise InstallationError( message.format(wheel_path, target_path, dest_dir_path) ) def root_scheme_file_maker( zip_file: ZipFile, dest: str ) -> Callable[[RecordPath], "File"]: def make_root_scheme_file(record_path: RecordPath) -> "File": normed_path = os.path.normpath(record_path) dest_path = os.path.join(dest, normed_path) assert_no_path_traversal(dest, dest_path) return ZipBackedFile(record_path, dest_path, zip_file) return make_root_scheme_file def data_scheme_file_maker( zip_file: ZipFile, scheme: Scheme ) -> Callable[[RecordPath], "File"]: scheme_paths = {key: getattr(scheme, key) for key in SCHEME_KEYS} def make_data_scheme_file(record_path: RecordPath) -> "File": normed_path = os.path.normpath(record_path) try: _, scheme_key, dest_subpath = normed_path.split(os.path.sep, 2) except ValueError: message = ( "Unexpected file in {}: {!r}. .data directory contents" " should be named like: '/'." ).format(wheel_path, record_path) raise InstallationError(message) try: scheme_path = scheme_paths[scheme_key] except KeyError: valid_scheme_keys = ", ".join(sorted(scheme_paths)) message = ( "Unknown scheme key used in {}: {} (for file {!r}). .data" " directory contents should be in subdirectories named" " with a valid scheme key ({})" ).format(wheel_path, scheme_key, record_path, valid_scheme_keys) raise InstallationError(message) dest_path = os.path.join(scheme_path, dest_subpath) assert_no_path_traversal(scheme_path, dest_path) return ZipBackedFile(record_path, dest_path, zip_file) return make_data_scheme_file def is_data_scheme_path(path: RecordPath) -> bool: return path.split("/", 1)[0].endswith(".data") paths = cast(List[RecordPath], wheel_zip.namelist()) file_paths = filterfalse(is_dir_path, paths) root_scheme_paths, data_scheme_paths = partition(is_data_scheme_path, file_paths) make_root_scheme_file = root_scheme_file_maker(wheel_zip, lib_dir) files: Iterator[File] = map(make_root_scheme_file, root_scheme_paths) def is_script_scheme_path(path: RecordPath) -> bool: parts = path.split("/", 2) return len(parts) > 2 and parts[0].endswith(".data") and parts[1] == "scripts" other_scheme_paths, script_scheme_paths = partition( is_script_scheme_path, data_scheme_paths ) make_data_scheme_file = data_scheme_file_maker(wheel_zip, scheme) other_scheme_files = map(make_data_scheme_file, other_scheme_paths) files = chain(files, other_scheme_files) # Get the defined entry points distribution = get_wheel_distribution( FilesystemWheel(wheel_path), canonicalize_name(name), ) console, gui = get_entrypoints(distribution) def is_entrypoint_wrapper(file: "File") -> bool: # EP, EP.exe and EP-script.py are scripts generated for # entry point EP by setuptools path = file.dest_path name = os.path.basename(path) if name.lower().endswith(".exe"): matchname = name[:-4] elif name.lower().endswith("-script.py"): matchname = name[:-10] elif name.lower().endswith(".pya"): matchname = name[:-4] else: matchname = name # Ignore setuptools-generated scripts return matchname in console or matchname in gui script_scheme_files: Iterator[File] = map( make_data_scheme_file, script_scheme_paths ) script_scheme_files = filterfalse(is_entrypoint_wrapper, script_scheme_files) script_scheme_files = map(ScriptFile, script_scheme_files) files = chain(files, script_scheme_files) for file in files: file.save() record_installed(file.src_record_path, file.dest_path, file.changed) def pyc_source_file_paths() -> Iterator[str]: # We de-duplicate installation paths, since there can be overlap (e.g. # file in .data maps to same location as file in wheel root). # Sorting installation paths makes it easier to reproduce and debug # issues related to permissions on existing files. for installed_path in sorted(set(installed.values())): full_installed_path = os.path.join(lib_dir, installed_path) if not os.path.isfile(full_installed_path): continue if not full_installed_path.endswith(".py"): continue yield full_installed_path def pyc_output_path(path: str) -> str: """Return the path the pyc file would have been written to.""" return importlib.util.cache_from_source(path) # Compile all of the pyc files for the installed files if pycompile: with captured_stdout() as stdout: with warnings.catch_warnings(): warnings.filterwarnings("ignore") for path in pyc_source_file_paths(): success = compileall.compile_file(path, force=True, quiet=True) if success: pyc_path = pyc_output_path(path) assert os.path.exists(pyc_path) pyc_record_path = cast( "RecordPath", pyc_path.replace(os.path.sep, "/") ) record_installed(pyc_record_path, pyc_path) logger.debug(stdout.getvalue()) maker = PipScriptMaker(None, scheme.scripts) # Ensure old scripts are overwritten. # See https://github.com/pypa/pip/issues/1800 maker.clobber = True # Ensure we don't generate any variants for scripts because this is almost # never what somebody wants. # See https://bitbucket.org/pypa/distlib/issue/35/ maker.variants = {""} # This is required because otherwise distlib creates scripts that are not # executable. # See https://bitbucket.org/pypa/distlib/issue/32/ maker.set_mode = True # Generate the console and GUI entry points specified in the wheel scripts_to_generate = get_console_script_specs(console) gui_scripts_to_generate = list(starmap("{} = {}".format, gui.items())) generated_console_scripts = maker.make_multiple(scripts_to_generate) generated.extend(generated_console_scripts) generated.extend(maker.make_multiple(gui_scripts_to_generate, {"gui": True})) if warn_script_location: msg = message_about_scripts_not_on_PATH(generated_console_scripts) if msg is not None: logger.warning(msg) generated_file_mode = 0o666 & ~current_umask() @contextlib.contextmanager def _generate_file(path: str, **kwargs: Any) -> Iterator[BinaryIO]: with adjacent_tmp_file(path, **kwargs) as f: yield f os.chmod(f.name, generated_file_mode) replace(f.name, path) dest_info_dir = os.path.join(lib_dir, info_dir) # Record pip as the installer installer_path = os.path.join(dest_info_dir, "INSTALLER") with _generate_file(installer_path) as installer_file: installer_file.write(b"pip\n") generated.append(installer_path) # Record the PEP 610 direct URL reference if direct_url is not None: direct_url_path = os.path.join(dest_info_dir, DIRECT_URL_METADATA_NAME) with _generate_file(direct_url_path) as direct_url_file: direct_url_file.write(direct_url.to_json().encode("utf-8")) generated.append(direct_url_path) # Record the REQUESTED file if requested: requested_path = os.path.join(dest_info_dir, "REQUESTED") with open(requested_path, "wb"): pass generated.append(requested_path) record_text = distribution.read_text("RECORD") record_rows = list(csv.reader(record_text.splitlines())) rows = get_csv_rows_for_installed( record_rows, installed=installed, changed=changed, generated=generated, lib_dir=lib_dir, ) # Record details of all files installed record_path = os.path.join(dest_info_dir, "RECORD") with _generate_file(record_path, **csv_io_kwargs("w")) as record_file: # Explicitly cast to typing.IO[str] as a workaround for the mypy error: # "writer" has incompatible type "BinaryIO"; expected "_Writer" writer = csv.writer(cast("IO[str]", record_file)) writer.writerows(_normalized_outrows(rows)) @contextlib.contextmanager def req_error_context(req_description: str) -> Iterator[None]: try: yield except InstallationError as e: message = "For req: {}. {}".format(req_description, e.args[0]) raise InstallationError(message) from e def install_wheel( name: str, wheel_path: str, scheme: Scheme, req_description: str, pycompile: bool = True, warn_script_location: bool = True, direct_url: Optional[DirectUrl] = None, requested: bool = False, ) -> None: with ZipFile(wheel_path, allowZip64=True) as z: with req_error_context(req_description): _install_wheel( name=name, wheel_zip=z, wheel_path=wheel_path, scheme=scheme, pycompile=pycompile, warn_script_location=warn_script_location, direct_url=direct_url, requested=requested, ) PKH]{33Epython3.10/site-packages/pip/_internal/operations/install/__init__.pynu["""For modules related to installing packages. """ PKH]=python3.10/site-packages/pip/_internal/operations/__init__.pynu[PKH]NqOpython3.10/site-packages/pip/_internal/network/__pycache__/auth.cpython-310.pycnu[o ai/ @s.dZddlZddlmZmZmZmZmZddl m Z m Z ddl m Z mZddlmZddlmZddlmZmZmZmZmZdd lmZeeZeeeefZzddlaWn&e y`daYne!y{Z"ze#d ee"daWYdZ"["ndZ"["wwd eed eed eefddZ$Gddde Z%dS)zNetwork Authentication Helpers Contains interface (MultiDomainBasicAuth) and associated glue code for providing credentials in the context of network requests. N)AnyDictListOptionalTuple)AuthBase HTTPBasicAuth)RequestResponse)get_netrc_auth) getLogger)ask ask_input ask_passwordremove_auth_from_urlsplit_auth_netloc_from_url)AuthInfo*Keyring is skipped due to an exception: %surlusernamereturnc Cs|rtsdSzCztj}Wn tyYnwtd||||}|dur,|j|jfWSWdS|rDtd|t||}|rG||fWSWdSWdStyf}zt dt |daWYd}~dSd}~ww)z3Return the tuple auth for a given url from keyring.Nz'Getting credentials from keyring for %sz$Getting password from keyring for %sr) keyringget_credentialAttributeErrorloggerdebugrpassword get_password Exceptionwarningstr)rrrcredrexcr#/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/network/auth.pyget_keyring_auth(s>         r%c @seZdZ d#dedeeeddfddZdedeefd d Z  d$d ed edede fddZ d ede eeeeeffddZ de de fddZdede eeeeeffddZdefddZdededefddZdededdfdd Zdededdfd!d"ZdS)%MultiDomainBasicAuthTN prompting index_urlsrcCs||_||_i|_d|_dS)N)r'r( passwords_credentials_to_save)selfr'r(r#r#r$__init__Js zMultiDomainBasicAuth.__init__rcCsB|r|jsdS|jD]}t|dd}||r|Sq dS)aReturn the original index URL matching the requested URL. Cached or dynamically generated credentials may work against the original index URL rather than just the netloc. The provided url should have had its username and password removed already. If the original index url had credentials then they will be included in the return value. Returns None if no matching index was found, or if --no-index was specified by the user. N/)r(rrstrip startswith)r+ruprefixr#r#r$_get_index_urlWs   z#MultiDomainBasicAuth._get_index_urlF original_url allow_netrc allow_keyringcCst|\}}}|\}}|dur|durtd||S||} | r3t| } | r3| \} } } td| | rO| ddurO| \}}|durO|durOtd|| S|r_t|} | r_td|| S|rut| |pjt||}|rutd||S||fS)z2Find and return credentials for the specified URL.NzFound credentials in url for %szFound index url %srz%Found credentials in index url for %sz!Found credentials in netrc for %sz#Found credentials in keyring for %s)rrrr2r r%)r+r3r4r5rnetlocurl_user_passwordrr index_url index_info_index_url_user_password netrc_authkr_authr#r#r$_get_new_credentialsms>         z)MultiDomainBasicAuth._get_new_credentialsc Cst|\}}}||\}}|dus|dur/||jvr/|j|\}}|dus*||kr/||}}|dus7|durF|p:d}|p>d}||f|j|<|durN|dus]|durV|dus]Jd||||fS)a_Return the credentials to use for the provided URL. If allowed, netrc and keyring may be used to obtain the correct credentials. Returns (url_without_credentials, username, password). Note that even if the original URL contains credentials, this function may return a different username and password. Nz%Could not load credentials from url: )rr>r)) r+r3rr6r:rrunpwr#r#r$_get_url_and_credentialss   z-MultiDomainBasicAuth._get_url_and_credentialsreqcCsH||j\}}}||_|dur|durt|||}|d|j|S)Nresponse)rBrr register_hook handle_401)r+rCrrrr#r#r$__call__s zMultiDomainBasicAuth.__call__r6cCsbtd|d}|s dSt||}|r(|ddur(|ddur(|d|ddfStd}||dfS) Nz User for z: )NNFrFz Password: T)rr%r)r+r6rauthrr#r#r$_prompt_for_passwords  z)MultiDomainBasicAuth._prompt_for_passwordcCstsdStdddgdkS)NFz#Save credentials to keyring [y/N]: yn)rr )r+r#r#r$ _should_save_password_to_keyringsz5MultiDomainBasicAuth._should_save_password_to_keyringrespkwargsc Ks|jdkr|S|js |Stj|j}|j|jddd\}}d}|s-|s-||j\}}}d|_ |durM|durM||f|j |j<|rM| rM|j||f|_ |j |j t|pYd|p\d|j}|d|j|j rr|d|j|jj|fi|}|j||S)NFT)r4r5r?rD) status_coder'urllibparseurlparserr>rJr6r*r)rMcontentraw release_connrrequestrE warn_on_401save_credentials connectionsendhistoryappend) r+rNrOparsedrrsaverCnew_respr#r#r$rFs6     zMultiDomainBasicAuth.handle_401cKs"|jdkrtd|jjdSdS)z6Response callback to warn about incorrect credentials.rPz)401 Error, Credentials not correct for %sN)rQrrrXr)r+rNrOr#r#r$rY.s z MultiDomainBasicAuth.warn_on_401cKsttdusJdts dS|j}d|_|r6|jdkr8z tdtj|WdSty5tdYdSwdSdS)z1Response callback to save credentials on success.Nz'should never reach here without keyringizSaving credentials to keyringzFailed to save credentials)rr*rQrinfo set_passwordr exception)r+rNrOcredsr#r#r$rZ6s  z%MultiDomainBasicAuth.save_credentials)TN)TF)__name__ __module__ __qualname__boolrrr r,r2rr>rrBr rGrJrMr rrFrYrZr#r#r#r$r&IsH    8 0  6r&)&__doc__ urllib.parserRtypingrrrrrZpip._vendor.requests.authrrpip._vendor.requests.modelsr r Zpip._vendor.requests.utilsr pip._internal.utils.loggingr pip._internal.utils.miscr rrrr pip._internal.vcs.versioncontrolrrfrr Credentialsr ImportErrorrr"rr%r&r#r#r#r$s2     "!PKH]Z*@**Rpython3.10/site-packages/pip/_internal/network/__pycache__/session.cpython-310.pycnu[o aiYA@sUdZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl ZddlZddlmZmZmZmZmZmZmZmZmZddlmZmZddlmZddlm Z m!Z!ddl"m#Z#m$Z$ddl%m&Z&dd l'm(Z(dd l)m*Z*dd l+m,Z,dd l-m.Z.dd l/m0Z0ddl1m2Z2ddl3m4Z4ddl5m6Z6ddl7m8Z8ddl9m:Z:m;Z;ddle?Z@eeAeAeeeBeAffZCejDde*dgdZEeeCeFd<dZGdeHfddZIdeAfddZJGddde ZKGd d!d!e!ZLGd"d#d#eZMGd$d%d%ejNZOdS)&zhPipSession and supporting code, containing all pip-specific network request configuration and behavior. N) AnyDictIteratorListMappingOptionalSequenceTupleUnion)requestsurllib3)CacheControlAdapter) BaseAdapter HTTPAdapter)PreparedRequestResponse)CaseInsensitiveDict)ConnectionPool)InsecureRequestWarning) __version__)get_default_environment)Link)MultiDomainBasicAuth) SafeFileCache)has_tls)libc_ver)build_url_from_netloc parse_netloc) url_to_pathignore)category))https*r")r" localhostr")r"z 127.0.0.0/8r")r"z::1/128r")filer"N)sshr"r"SECURE_ORIGINS) BUILD_BUILDIDBUILD_IDCI PIP_IS_CIreturncCstddtDS)z? Return whether it looks like pip is running under CI. css|]}|tjvVqdSN)osenviron).0namer1/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/network/session.py Xsz looks_like_ci..)anyCI_ENVIRONMENT_VARIABLESr1r1r1r2 looks_like_ciQsr6c Csdtdtdtid}|dddkr t|dd<nF|dddkrEtj}|jd kr6|d d }d d d|D|dd<n!|dddkrVt|dd<n|dddkrft|dd<tjdrddl m }| | | f}ttddtgd|}ttddtddgt}|r||d<|r||d<tjdrtdrdtdd|d<trt|did<trt|did<trt|d<trdd l}|j|d <td!}|d urt|j |d"<td#d ur2z tj d#d$gtj!d%d&}Wn t"y Ynw|d'r2|#d(d)$|d*<t%r8d+nd |d,<t&j'(d-} | d urK| |d.<d/j)|t*j+|d0d+d1d2S)3z6 Return a string representing the user agent. pip)r0versionr0) installerpythonimplementationr;CPythonr8PyPyfinalN.cSsg|]}t|qSr1)str)r/xr1r1r2 nszuser_agent..Jython IronPythonlinuxr)distrocS|dSNr1rBr1r1r2}zuser_agent..)r0r8idcSrHrIr1rKr1r1r2rLrMliblibcrGdarwinmacOSsystemreleasecpuopenssl_version setuptoolssetuptools_versionrustcz --versiong?)stderrtimeoutsrustc  rJ rustc_versionTciPIP_USER_AGENT_USER_DATA user_dataz9{data[installer][name]}/{data[installer][version]} {json}),:) separators sort_keys)datajson),rplatformpython_versionpython_implementationsyspypy_version_info releaseleveljoin startswith pip._vendorrGr0r8codenamedictfilterziprmac_verrS setdefaultrTmachiner_sslOPENSSL_VERSIONrget_distributionrAshutilwhich subprocess check_outputSTDOUT Exceptionsplitdecoder6r-r.getformatrfdumps) rerkrGlinux_distribution distro_infosrPsslsetuptools_dist rustc_outputr`r1r1r2 user_agent[s               rc@seZdZ     ddededeeeeeeffdeee fdeee ee e ffd ee e e fd e fd d Z dd dZ dS)LocalFSAdapterFNTrequeststreamr[verifycertproxiesr+c Cst|j}t}d|_|j|_zt|} Wn+tyA} zd|_t| j|_ t |j d|  d|_ WYd} ~ |Sd} ~ wwtjj| jdd} t|dpSd} t| | j| d |_t|d |_ |j j|_|S) Niz: utf8T)usegmtrz text/plain)z Content-TypezContent-Lengthz Last-Modifiedrb)rurlr status_coder-statOSErrortype__name__reasonioBytesIOencoderawemailutils formatdatest_mtime mimetypes guess_typerst_sizeheadersopenclose) selfrrr[rrrpathnamerespstatsexcmodified content_typer1r1r2sends0  (  zLocalFSAdapter.sendcCsdSr,r1)rr1r1r2rszLocalFSAdapter.close)FNTNN)r+N)r __module__ __qualname__rboolrr floatr rArrrrr1r1r1r2rs,  'rc NeZdZdededeeefdeeeeeeffddf fdd Z Z S) InsecureHTTPAdapterconnrrrr+Nctj||d|ddSNF)rrrrsuper cert_verifyrrrrr __class__r1r2rzInsecureHTTPAdapter.cert_verify rrrrrAr rrr r __classcell__r1r1rr2r rc r) InsecureCacheControlAdapterrrrrr+Ncrrrrrr1r2rrz'InsecureCacheControlAdapter.cert_verifyrr1r1rr2rrrcseZdZUdZeeed<ddddddededeed e ed ee ed ed dffd dZ de ed dfddZ d!dedeede d dfddZd eefddZded e fddZdededed ed ef fdd ZZS)" PipSessionNr[rr1)retriescache trusted_hosts index_urlsargsrrrrkwargsr+c stj|i|g|_t|jd<t|d|_tj|gddd}t |d}|r;t t ||d}t t ||d|_ nt|d}||_ |d||d ||d t|D] } |j| d d qXd S)zj :param trusted_hosts: Domains not to emit warnings for when not using HTTPS. z User-Agent)r)iiiig?)totalstatus_forcelistbackoff_factor) max_retries)rrzhttps://zhttp://zfile://T)suppress_loggingN)r__init__pip_trusted_originsrrrauthr Retryrr rr_trusted_host_adapterrmountradd_trusted_host) rrrrrrrinsecure_adaptersecure_adapterhostrr1r2rs6       zPipSession.__init__new_index_urlscCs ||j_dS)zn :param new_index_urls: New index urls to update the authentication handler with. N)rr)rrr1r1r2update_index_urlsSs zPipSession.update_index_urlsFrsourcercCs|sd|}|dur|d|d7}t|t|}||jvr'|j||t|ddd|j|t|d|j|ds]|t|ddd |j|t|d |jdSdS) z :param host: It is okay to provide a host that has previously been added. :param source: An optional source string, for logging where the host string came from. zadding trusted host: Nz (from )http)scheme/rJrb)loggerinforrappendrrr)rrrrmsg host_portr1r1r2rZs&    zPipSession.add_trusted_hostccs8tEdH|jD]\}}d||durdn|fVq dS)Nr")r&r)rrportr1r1r2iter_secure_originsys  zPipSession.iter_secure_originslocationc Cstjt|}|j|j|j}}}|ddd}|D]J}|\}}} ||kr/|dkr/qz t |} t |} Wnt yT|rR| | krR|dkrRYqYnw| | vrZq|| krg| dkrg| durgqdStd||dS)N+rJr"TzThe repository located at %s is not a trusted or secure host and is being ignored. If this repository is available via HTTPS we recommend you use HTTPS instead, otherwise you may silence this warning and allow it anyway with '--trusted-host %s'.F)urllibparseurlparserArhostnamerrsplitr ipaddress ip_address ip_network ValueErrorlowerrwarning) rrparsedorigin_protocol origin_host origin_port secure_originsecure_protocol secure_host secure_portaddrnetworkr1r1r2is_secure_origin~sD       zPipSession.is_secure_originmethodrcs*|d|jtj||g|Ri|S)Nr[)rur[rr)rrrrrrr1r2rszPipSession.request)NF)rrrr[rint__annotations__rrArrrrrrr SecureOriginrrrrrrr1r1rr2rsF  M *Cr)P__doc__ email.utilsrrrrfloggingrr-rgrzr|rj urllib.parserwarningstypingrrrrrrrr r ror r pip._vendor.cachecontrolr Zpip._vendor.requests.adaptersrrpip._vendor.requests.modelsrrZpip._vendor.requests.structuresrZ"pip._vendor.urllib3.connectionpoolrZpip._vendor.urllib3.exceptionsrr7rpip._internal.metadatarpip._internal.models.linkrpip._internal.network.authrpip._internal.network.cacherpip._internal.utils.compatrpip._internal.utils.glibcrpip._internal.utils.miscrrpip._internal.utils.urlsr getLoggerrrrArrfilterwarningsr&rr5rr6rrrrSessionrr1r1r1r2sT,               e,  PKH]~USSpython3.10/site-packages/pip/_internal/network/__pycache__/download.cpython-310.pycnu[o ai @sjdZddlZddlZddlZddlZddlmZmZmZddl m Z m Z ddl m Z ddlmZddlmZddlmZdd lmZdd lmZdd lmZmZmZdd lmZmZmZe e!Z"d e dee#fddZ$d e dede%dee&fddZ'de%de%fddZ(de%de%de%fddZ)d e dede%fddZ*dedede fdd Z+Gd!d"d"Z,Gd#d$d$Z-dS)%z)Download files with progress indicators. N)IterableOptionalTuple)CONTENT_CHUNK_SIZEResponse)DownloadProgressProvider)NetworkConnectionError)PyPI)Link) is_from_cache) PipSession)HEADERSraise_for_statusresponse_chunks) format_sizeredact_auth_from_urlsplitextrespreturnc Cs,zt|jdWStttfyYdSw)Nzcontent-length)intheaders ValueErrorKeyError TypeError)rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/network/download.py_get_http_response_sizes rlink progress_barcCst|}|jtjkr|j}n|j}t|}|rd|t|}t |r*t d|nt d|t t jkr:d}nt |rAd}n|sFd}n |dkrMd}nd}t|t}|sX|St||d|S)Nz{} ({})zUsing cached %szDownloading %sFTi@)max)rnetlocr file_storage_domainshow_urlurl_without_fragmentrformatrr loggerinfogetEffectiveLevelloggingINFOrrr)rrr total_lengthurl logged_url show_progresschunksrrr_prepare_downloads.   r/filenamecCs tj|S)zJ Sanitize the "filename" value from a Content-Disposition header. )ospathbasename)r0rrrsanitize_content_filenameGs r4content_dispositiondefault_filenamecCs,t|\}}|d}|rt|}|p|S)z Parse the "filename" value from a Content-Disposition header, and return the default filename if the result is empty. r0)cgi parse_headergetr4)r5r6_typeparamsr0rrrparse_content_dispositionNs  r<cCs|j}|jd}|rt||}t|d}|s(t|jdd}|r(||7}|s?|j|jkr?tj |jd}|r?||7}|S)zoGet an ideal filename from the given HTTP response, falling back to the link filename if not provided. zcontent-dispositionz content-type) r0rr9r<r mimetypesguess_extensionr+r1r2)rrr0r5extrrr_get_http_response_filename\s   rBsessioncCs.|jddd}|j|tdd}t||S)N#r=rT)rstream)r+splitr9r r)rCr target_urlrrrr_http_get_downloadqsrHc@s@eZdZdededdfddZdededeeeffd d ZdS) DownloaderrCrrNcC||_||_dSN_session _progress_barselfrCrrrr__init__y zDownloader.__init__rlocationc Cszt|j|}Wnty%}z|jdusJtd|jj|d}~wwt||}tj ||}t |||j }t |d}|D]} || qAWdn1sSwY|jdd} || fS)z.Download the file given by link into location.NHTTP error %s while getting %swb Content-Typer>rHrMrresponser%critical status_coderBr1r2joinr/rNopenwriterr9) rPrrSrer0filepathr. content_filechunk content_typerrr__call__s(    zDownloader.__call__) __name__ __module__ __qualname__r strrQr rrcrrrrrIxs "rIc @sPeZdZdededdfddZdeededeeeeeefffd d Z dS) BatchDownloaderrCrrNcCrJrKrLrOrrrrQrRzBatchDownloader.__init__linksrSc cs|D]h}zt|j|}Wnty*}z|jdusJtd|jj|d}~wwt||}tj ||}t |||j }t |d} |D]} | | qFWdn1sXwY|jdd} ||| ffVqdS)z0Download the files given by links into location.NrTrUrVr>rW) rPrirSrrr^r0r_r.r`rarbrrrrcs2   zBatchDownloader.__call__) rdrerfr rgrQrr rrcrrrrrhs rh).__doc__r7r(r?r1typingrrrpip._vendor.requests.modelsrrpip._internal.cli.progress_barsrpip._internal.exceptionsrpip._internal.models.indexr pip._internal.models.linkr pip._internal.network.cacher pip._internal.network.sessionr pip._internal.network.utilsr rrpip._internal.utils.miscrrr getLoggerrdr%rrrgbytesr/r4r<rBrHrIrhrrrrs@        )PKH]099Qpython3.10/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-310.pycnu[o ai@sdZddlZddlZddlZddlmZmZddl m Z ddl m Z ddl mZer2ddlmZmZeeZGdd d ejjZdS) z#xmlrpclib.Transport implementation N) TYPE_CHECKINGTuple)NetworkConnectionError) PipSession)raise_for_status) _HostType _Marshallablec s\eZdZdZ ddedededdffdd Z dd d d ed edede df ddZ Z S)PipXmlrpcTransportzRProvide a `xmlrpclib.Transport` implementation via a `PipSession` object. F index_urlsession use_datetimereturnNcs*t|tj|}|j|_||_dS)N)super__init__urllibparseurlparsescheme_scheme_session)selfr r r Z index_parts __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/network/xmlrpc.pyrs   zPipXmlrpcTransport.__init__hostrhandler request_bodyverbose)r.c Cst|tsJ|j||dddf}tj|}zddi}|jj|||dd}t|||_ | |j WSt yM} z| j s?Jtd| j j|d} ~ ww)Nz Content-Typeztext/xmlT)dataheadersstreamzHTTP error %s while getting %s) isinstancestrrrr urlunparserpostrrparse_responserawrresponseloggercritical status_code) rrrrrpartsurlr r(excrrrrequest s0  zPipXmlrpcTransport.request)F) __name__ __module__ __qualname____doc__r#rboolrbytesrr/ __classcell__rrrrr s0 r )r3logging urllib.parser xmlrpc.clientZxmlrpctypingrrpip._internal.exceptionsrpip._internal.network.sessionrpip._internal.network.utilsrrr getLoggerr0r)client Transportr rrrrs    PKH]Z$$Spython3.10/site-packages/pip/_internal/network/__pycache__/__init__.cpython-310.pycnu[o ai2@sdZdS)z+Contains purely network-related utilities. N)__doc__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/network/__init__.pysPKH] { Upython3.10/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-310.pycnu[o ai@sdZddgZddlmZmZddlmZddlmZddl m Z m Z m Z m Z mZmZddlmZmZdd lmZdd lmZmZdd lmZmZmZdd lmZdd lmZm Z m!Z!Gddde"Z#de$de$dedefddZ%GdddZ&dS)zLazy ZIP over HTTPHTTPRangeRequestUnsupporteddist_from_wheel_url) bisect_left bisect_right)contextmanager)NamedTemporaryFile)AnyDictIteratorListOptionalTuple) BadZipfileZipFile)canonicalize_name)CONTENT_CHUNK_SIZEResponse)BaseDistribution MemoryWheelget_wheel_distribution) PipSession)HEADERSraise_for_statusresponse_chunksc@s eZdZdS)rN)__name__ __module__ __qualname__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/network/lazy_wheel.pyrsnameurlsessionreturncCsHt||}t|j|}t|t|WdS1swYdS)aReturn a distribution object from the given wheel URL. This uses HTTP range requests to only fetch the potion of the wheel containing metadata, just enough for the object to be constructed. If such requests are not supported, HTTPRangeRequestUnsupported is raised. N)LazyZipOverHTTPrrrr)rr r!zfwheelrrrrs   $c @seZdZdZefdedededdfddZe defd d Z e defd d Z de fd dZ d8ddZe de fddZd9dedefddZde fddZd:dededefddZdefddZd;deedefd d!Zde fd"d#Zd)zWhether the file is closed.)r2closedr<rrrrCSr?zLazyZipOverHTTP.closedsizecCs`t||j}||j}}|dkr|nt|||}td||}|||d|j|S)zRead up to size bytes from the object and return them. As a convenience, if size is unspecified or -1, all bytes until EOF are returned. Fewer than size bytes may be returned if EOF is reached. r)maxr/tellr1min _downloadr2read)r8rE download_sizestartlengthstoprrrrKXs  zLazyZipOverHTTP.readcCr:)z3Return whether the file is readable, which is True.Trr<rrrreadablefrAzLazyZipOverHTTP.readableroffsetwhencecCs|j||S)a-Change stream position and return the new absolute position. Seek to offset relative position indicated by whence: * 0: Start of stream (the default). pos should be >= 0; * 1: Current position - pos may be negative; * 2: End of stream - pos usually negative. )r2seek)r8rQrRrrrrSjszLazyZipOverHTTP.seekcCs |jS)zReturn the current position.)r2rHr<rrrrHts zLazyZipOverHTTP.tellcCs |j|S)zResize the stream to the given size in bytes. If size is unspecified resize to the current position. The current stream position isn't changed. Return the new file size. )r2r3)r8rErrrr3xs zLazyZipOverHTTP.truncatecCr:)z Return False.Frr<rrrwritablerAzLazyZipOverHTTP.writablecCs|j|SN)r2 __enter__r<rrrrVs zLazyZipOverHTTP.__enter__exccGs |jj|SrU)r2__exit__)r8rWrrrrXs zLazyZipOverHTTP.__exit__c cs.|}z dVW||dS||w)zyReturn a context manager keeping the position. At the end of the block, seek back to original position. N)rHrS)r8posrrr_stays zLazyZipOverHTTP._stayc Cs|jd}ttd||jD]6}||||"zt|Wn ty*Yn w WddSWdn1s?wYqdS)z1Check and download until the file is a valid ZIP.rFrN)r1reversedranger/rJrZrr)r8endrMrrrr7s     zLazyZipOverHTTP._check_ziprMr] base_headerscCs8|}d|d||d<d|d<|jj|j|ddS)z:Return HTTP response to a range request from start to end.zbytes=-Rangezno-cachez Cache-ControlT)r'stream)copyr-r6r.)r8rMr]r^r'rrr_stream_responsesz LazyZipOverHTTP._stream_responseleftrightc cs|j|||j||}}t|g|dd}}t|g|dd}t||D]\}} ||kr<||dfV| d}q-||krJ||fV|g|g|j||<|j||<dS)a/Return an iterator of intervals to be fetched. Args: start (int): Start of needed interval end (int): End of needed interval left (int): Index of first overlapping downloaded data right (int): Index after last overlapping downloaded data NrFrD)r4r5rIrGzip) r8rMr]rdrelslicersliceijkrrr_merges   &zLazyZipOverHTTP._mergecCs|@t|j|}t|j|}|||||D]"\}}|||}|||t ||j D]}|j |q2qWddS1sGwYdS)z-Download bytes from start to end inclusively.N) rZrr5rr4rlrcrrSrr/r2write)r8rMr]rdreresponsechunkrrrrJs     "zLazyZipOverHTTP._download)r"N)rD)rrU)r"r#)&rrr__doc__rstrrr0r9propertyr=rboolr@rBrCr)rKrPrSrHr r3rTrVrrXrr rZr7rr rrcr rlrJrrrrr#(sj          r#N)'rp__all__bisectrr contextlibrtempfilertypingrr r r r r zipfilerrpip._vendor.packaging.utilsrpip._vendor.requests.modelsrrpip._internal.metadatarrrpip._internal.network.sessionrpip._internal.network.utilsrrr Exceptionrrqrr#rrrrs     PKH] [{ { Ppython3.10/site-packages/pip/_internal/network/__pycache__/cache.cpython-310.pycnu[o ai4@sdZddlZddlmZddlmZmZddlmZddl m Z ddl m Z ddl mZmZdd lmZd e d efd d Zed edfddZGdddeZdS)zHTTP cache implementation. N)contextmanager)IteratorOptional) BaseCache) FileCache)Response)adjacent_tmp_filereplace) ensure_dirresponsereturncCs t|ddS)N from_cacheF)getattr)r r/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/network/cache.py is_from_caches rccs$zdVWdStyYdSw)zvIf we can't access the cache then we can just skip caching and process requests as if caching wasn't enabled. N)OSErrorrrrrsuppressed_cache_errorss   rcszeZdZdZdeddffdd Zdedefdd Zd edeefd d Z d ed eddfddZ d eddfddZ Z S) SafeFileCachezw A file based cache which is safe to use even when the target directory may not be accessible or writable. directoryr Ncs$|dusJdt||_dS)Nz!Cache directory must not be None.)super__init__r)selfr __class__rrr%s  zSafeFileCache.__init__namecCs6t|}t|dd|g}tjj|jg|RS)N)rencodelistospathjoinr)rrhashedpartsrrr_get_cache_path*s zSafeFileCache._get_cache_pathkeyc Csv||}t)t|d}|WdWdS1s$wYWddS1s4wYdS)Nrb)r$ropenread)rr%r frrrget2s  "zSafeFileCache.getvaluec Cs||}t0ttj|t| }||Wdn1s%wYt|j |WddS1s;wYdSN) r$rr rr dirnamerwriter r)rr%r+r r)rrrset8s   "zSafeFileCache.setcCs@||}tt|WddS1swYdSr,)r$rrremove)rr%r rrrdeleteBs  "zSafeFileCache.delete) __name__ __module__ __qualname____doc__strrr$rbytesr*r/r1 __classcell__rrrrrs r)r5r contextlibrtypingrrZpip._vendor.cachecontrol.cacherpip._vendor.cachecontrol.cachesrpip._vendor.requests.modelsrpip._internal.utils.filesystemrr pip._internal.utils.miscr boolrrrrrrrs      PKH]\Ppython3.10/site-packages/pip/_internal/network/__pycache__/utils.cpython-310.pycnu[o ai@szUddlmZmZddlmZmZddlmZddiZee e fe d<dedd fd d Z efd ed e dee fddZd S))DictIterator)CONTENT_CHUNK_SIZEResponse)NetworkConnectionErrorzAccept-EncodingidentityHEADERSrespreturnNcCsd}t|jtr z|jd}Wnty|jd}Ynw|j}d|jkr.dkr=nn |jd|d|j}nd|jkrHdkrVnn |jd |d|j}|r^t||d dS) Nzutf-8z iso-8859-1iiz Client Error: z for url: iXz Server Error: )response) isinstancereasonbytesdecodeUnicodeDecodeError status_codeurlr)r http_error_msgrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/network/utils.pyraise_for_statuss"   rr chunk_sizeccsTz|jj|ddD]}|Vq WdSty) |j|}|s%YdS|Vqw)z3Given a requests Response, provide the data chunks.F)decode_contentTN)rawstreamAttributeErrorread)r rchunkrrrresponse_chunks9s    r)typingrrpip._vendor.requests.modelsrrpip._internal.exceptionsrrstr__annotations__rintrrrrrrs PKH]G\A447python3.10/site-packages/pip/_internal/network/cache.pynu["""HTTP cache implementation. """ import os from contextlib import contextmanager from typing import Iterator, Optional from pip._vendor.cachecontrol.cache import BaseCache from pip._vendor.cachecontrol.caches import FileCache from pip._vendor.requests.models import Response from pip._internal.utils.filesystem import adjacent_tmp_file, replace from pip._internal.utils.misc import ensure_dir def is_from_cache(response: Response) -> bool: return getattr(response, "from_cache", False) @contextmanager def suppressed_cache_errors() -> Iterator[None]: """If we can't access the cache then we can just skip caching and process requests as if caching wasn't enabled. """ try: yield except OSError: pass class SafeFileCache(BaseCache): """ A file based cache which is safe to use even when the target directory may not be accessible or writable. """ def __init__(self, directory: str) -> None: assert directory is not None, "Cache directory must not be None." super().__init__() self.directory = directory def _get_cache_path(self, name: str) -> str: # From cachecontrol.caches.file_cache.FileCache._fn, brought into our # class for backwards-compatibility and to avoid using a non-public # method. hashed = FileCache.encode(name) parts = list(hashed[:5]) + [hashed] return os.path.join(self.directory, *parts) def get(self, key: str) -> Optional[bytes]: path = self._get_cache_path(key) with suppressed_cache_errors(): with open(path, "rb") as f: return f.read() def set(self, key: str, value: bytes) -> None: path = self._get_cache_path(key) with suppressed_cache_errors(): ensure_dir(os.path.dirname(path)) with adjacent_tmp_file(path) as f: f.write(value) replace(f.name, path) def delete(self, key: str) -> None: path = self._get_cache_path(key) with suppressed_cache_errors(): os.remove(path) PKH]aYAYA9python3.10/site-packages/pip/_internal/network/session.pynu["""PipSession and supporting code, containing all pip-specific network request configuration and behavior. """ import email.utils import io import ipaddress import json import logging import mimetypes import os import platform import shutil import subprocess import sys import urllib.parse import warnings from typing import Any, Dict, Iterator, List, Mapping, Optional, Sequence, Tuple, Union from pip._vendor import requests, urllib3 from pip._vendor.cachecontrol import CacheControlAdapter from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter from pip._vendor.requests.models import PreparedRequest, Response from pip._vendor.requests.structures import CaseInsensitiveDict from pip._vendor.urllib3.connectionpool import ConnectionPool from pip._vendor.urllib3.exceptions import InsecureRequestWarning from pip import __version__ from pip._internal.metadata import get_default_environment from pip._internal.models.link import Link from pip._internal.network.auth import MultiDomainBasicAuth from pip._internal.network.cache import SafeFileCache # Import ssl from compat so the initial import occurs in only one place. from pip._internal.utils.compat import has_tls from pip._internal.utils.glibc import libc_ver from pip._internal.utils.misc import build_url_from_netloc, parse_netloc from pip._internal.utils.urls import url_to_path logger = logging.getLogger(__name__) SecureOrigin = Tuple[str, str, Optional[Union[int, str]]] # Ignore warning raised when using --trusted-host. warnings.filterwarnings("ignore", category=InsecureRequestWarning) SECURE_ORIGINS: List[SecureOrigin] = [ # protocol, hostname, port # Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC) ("https", "*", "*"), ("*", "localhost", "*"), ("*", "127.0.0.0/8", "*"), ("*", "::1/128", "*"), ("file", "*", None), # ssh is always secure. ("ssh", "*", "*"), ] # These are environment variables present when running under various # CI systems. For each variable, some CI systems that use the variable # are indicated. The collection was chosen so that for each of a number # of popular systems, at least one of the environment variables is used. # This list is used to provide some indication of and lower bound for # CI traffic to PyPI. Thus, it is okay if the list is not comprehensive. # For more background, see: https://github.com/pypa/pip/issues/5499 CI_ENVIRONMENT_VARIABLES = ( # Azure Pipelines "BUILD_BUILDID", # Jenkins "BUILD_ID", # AppVeyor, CircleCI, Codeship, Gitlab CI, Shippable, Travis CI "CI", # Explicit environment variable. "PIP_IS_CI", ) def looks_like_ci() -> bool: """ Return whether it looks like pip is running under CI. """ # We don't use the method of checking for a tty (e.g. using isatty()) # because some CI systems mimic a tty (e.g. Travis CI). Thus that # method doesn't provide definitive information in either direction. return any(name in os.environ for name in CI_ENVIRONMENT_VARIABLES) def user_agent() -> str: """ Return a string representing the user agent. """ data: Dict[str, Any] = { "installer": {"name": "pip", "version": __version__}, "python": platform.python_version(), "implementation": { "name": platform.python_implementation(), }, } if data["implementation"]["name"] == "CPython": data["implementation"]["version"] = platform.python_version() elif data["implementation"]["name"] == "PyPy": pypy_version_info = sys.pypy_version_info # type: ignore if pypy_version_info.releaselevel == "final": pypy_version_info = pypy_version_info[:3] data["implementation"]["version"] = ".".join( [str(x) for x in pypy_version_info] ) elif data["implementation"]["name"] == "Jython": # Complete Guess data["implementation"]["version"] = platform.python_version() elif data["implementation"]["name"] == "IronPython": # Complete Guess data["implementation"]["version"] = platform.python_version() if sys.platform.startswith("linux"): from pip._vendor import distro linux_distribution = distro.name(), distro.version(), distro.codename() distro_infos: Dict[str, Any] = dict( filter( lambda x: x[1], zip(["name", "version", "id"], linux_distribution), ) ) libc = dict( filter( lambda x: x[1], zip(["lib", "version"], libc_ver()), ) ) if libc: distro_infos["libc"] = libc if distro_infos: data["distro"] = distro_infos if sys.platform.startswith("darwin") and platform.mac_ver()[0]: data["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]} if platform.system(): data.setdefault("system", {})["name"] = platform.system() if platform.release(): data.setdefault("system", {})["release"] = platform.release() if platform.machine(): data["cpu"] = platform.machine() if has_tls(): import _ssl as ssl data["openssl_version"] = ssl.OPENSSL_VERSION setuptools_dist = get_default_environment().get_distribution("setuptools") if setuptools_dist is not None: data["setuptools_version"] = str(setuptools_dist.version) if shutil.which("rustc") is not None: # If for any reason `rustc --version` fails, silently ignore it try: rustc_output = subprocess.check_output( ["rustc", "--version"], stderr=subprocess.STDOUT, timeout=0.5 ) except Exception: pass else: if rustc_output.startswith(b"rustc "): # The format of `rustc --version` is: # `b'rustc 1.52.1 (9bc8c42bb 2021-05-09)\n'` # We extract just the middle (1.52.1) part data["rustc_version"] = rustc_output.split(b" ")[1].decode() # Use None rather than False so as not to give the impression that # pip knows it is not being run under CI. Rather, it is a null or # inconclusive result. Also, we include some value rather than no # value to make it easier to know that the check has been run. data["ci"] = True if looks_like_ci() else None user_data = os.environ.get("PIP_USER_AGENT_USER_DATA") if user_data is not None: data["user_data"] = user_data return "{data[installer][name]}/{data[installer][version]} {json}".format( data=data, json=json.dumps(data, separators=(",", ":"), sort_keys=True), ) class LocalFSAdapter(BaseAdapter): def send( self, request: PreparedRequest, stream: bool = False, timeout: Optional[Union[float, Tuple[float, float]]] = None, verify: Union[bool, str] = True, cert: Optional[Union[str, Tuple[str, str]]] = None, proxies: Optional[Mapping[str, str]] = None, ) -> Response: pathname = url_to_path(request.url) resp = Response() resp.status_code = 200 resp.url = request.url try: stats = os.stat(pathname) except OSError as exc: # format the exception raised as a io.BytesIO object, # to return a better error message: resp.status_code = 404 resp.reason = type(exc).__name__ resp.raw = io.BytesIO(f"{resp.reason}: {exc}".encode("utf8")) else: modified = email.utils.formatdate(stats.st_mtime, usegmt=True) content_type = mimetypes.guess_type(pathname)[0] or "text/plain" resp.headers = CaseInsensitiveDict( { "Content-Type": content_type, "Content-Length": stats.st_size, "Last-Modified": modified, } ) resp.raw = open(pathname, "rb") resp.close = resp.raw.close return resp def close(self) -> None: pass class InsecureHTTPAdapter(HTTPAdapter): def cert_verify( self, conn: ConnectionPool, url: str, verify: Union[bool, str], cert: Optional[Union[str, Tuple[str, str]]], ) -> None: super().cert_verify(conn=conn, url=url, verify=False, cert=cert) class InsecureCacheControlAdapter(CacheControlAdapter): def cert_verify( self, conn: ConnectionPool, url: str, verify: Union[bool, str], cert: Optional[Union[str, Tuple[str, str]]], ) -> None: super().cert_verify(conn=conn, url=url, verify=False, cert=cert) class PipSession(requests.Session): timeout: Optional[int] = None def __init__( self, *args: Any, retries: int = 0, cache: Optional[str] = None, trusted_hosts: Sequence[str] = (), index_urls: Optional[List[str]] = None, **kwargs: Any, ) -> None: """ :param trusted_hosts: Domains not to emit warnings for when not using HTTPS. """ super().__init__(*args, **kwargs) # Namespace the attribute with "pip_" just in case to prevent # possible conflicts with the base class. self.pip_trusted_origins: List[Tuple[str, Optional[int]]] = [] # Attach our User Agent to the request self.headers["User-Agent"] = user_agent() # Attach our Authentication handler to the session self.auth = MultiDomainBasicAuth(index_urls=index_urls) # Create our urllib3.Retry instance which will allow us to customize # how we handle retries. retries = urllib3.Retry( # Set the total number of retries that a particular request can # have. total=retries, # A 503 error from PyPI typically means that the Fastly -> Origin # connection got interrupted in some way. A 503 error in general # is typically considered a transient error so we'll go ahead and # retry it. # A 500 may indicate transient error in Amazon S3 # A 520 or 527 - may indicate transient error in CloudFlare status_forcelist=[500, 503, 520, 527], # Add a small amount of back off between failed requests in # order to prevent hammering the service. backoff_factor=0.25, ) # type: ignore # Our Insecure HTTPAdapter disables HTTPS validation. It does not # support caching so we'll use it for all http:// URLs. # If caching is disabled, we will also use it for # https:// hosts that we've marked as ignoring # TLS errors for (trusted-hosts). insecure_adapter = InsecureHTTPAdapter(max_retries=retries) # We want to _only_ cache responses on securely fetched origins or when # the host is specified as trusted. We do this because # we can't validate the response of an insecurely/untrusted fetched # origin, and we don't want someone to be able to poison the cache and # require manual eviction from the cache to fix it. if cache: secure_adapter = CacheControlAdapter( cache=SafeFileCache(cache), max_retries=retries, ) self._trusted_host_adapter = InsecureCacheControlAdapter( cache=SafeFileCache(cache), max_retries=retries, ) else: secure_adapter = HTTPAdapter(max_retries=retries) self._trusted_host_adapter = insecure_adapter self.mount("https://", secure_adapter) self.mount("http://", insecure_adapter) # Enable file:// urls self.mount("file://", LocalFSAdapter()) for host in trusted_hosts: self.add_trusted_host(host, suppress_logging=True) def update_index_urls(self, new_index_urls: List[str]) -> None: """ :param new_index_urls: New index urls to update the authentication handler with. """ self.auth.index_urls = new_index_urls def add_trusted_host( self, host: str, source: Optional[str] = None, suppress_logging: bool = False ) -> None: """ :param host: It is okay to provide a host that has previously been added. :param source: An optional source string, for logging where the host string came from. """ if not suppress_logging: msg = f"adding trusted host: {host!r}" if source is not None: msg += f" (from {source})" logger.info(msg) host_port = parse_netloc(host) if host_port not in self.pip_trusted_origins: self.pip_trusted_origins.append(host_port) self.mount( build_url_from_netloc(host, scheme="http") + "/", self._trusted_host_adapter ) self.mount(build_url_from_netloc(host) + "/", self._trusted_host_adapter) if not host_port[1]: self.mount( build_url_from_netloc(host, scheme="http") + ":", self._trusted_host_adapter, ) # Mount wildcard ports for the same host. self.mount(build_url_from_netloc(host) + ":", self._trusted_host_adapter) def iter_secure_origins(self) -> Iterator[SecureOrigin]: yield from SECURE_ORIGINS for host, port in self.pip_trusted_origins: yield ("*", host, "*" if port is None else port) def is_secure_origin(self, location: Link) -> bool: # Determine if this url used a secure transport mechanism parsed = urllib.parse.urlparse(str(location)) origin_protocol, origin_host, origin_port = ( parsed.scheme, parsed.hostname, parsed.port, ) # The protocol to use to see if the protocol matches. # Don't count the repository type as part of the protocol: in # cases such as "git+ssh", only use "ssh". (I.e., Only verify against # the last scheme.) origin_protocol = origin_protocol.rsplit("+", 1)[-1] # Determine if our origin is a secure origin by looking through our # hardcoded list of secure origins, as well as any additional ones # configured on this PackageFinder instance. for secure_origin in self.iter_secure_origins(): secure_protocol, secure_host, secure_port = secure_origin if origin_protocol != secure_protocol and secure_protocol != "*": continue try: addr = ipaddress.ip_address(origin_host) network = ipaddress.ip_network(secure_host) except ValueError: # We don't have both a valid address or a valid network, so # we'll check this origin against hostnames. if ( origin_host and origin_host.lower() != secure_host.lower() and secure_host != "*" ): continue else: # We have a valid address and network, so see if the address # is contained within the network. if addr not in network: continue # Check to see if the port matches. if ( origin_port != secure_port and secure_port != "*" and secure_port is not None ): continue # If we've gotten here, then this origin matches the current # secure origin and we should return True return True # If we've gotten to this point, then the origin isn't secure and we # will not accept it as a valid location to search. We will however # log a warning that we are ignoring it. logger.warning( "The repository located at %s is not a trusted or secure host and " "is being ignored. If this repository is available via HTTPS we " "recommend you use HTTPS instead, otherwise you may silence " "this warning and allow it anyway with '--trusted-host %s'.", origin_host, origin_host, ) return False def request(self, method: str, url: str, *args: Any, **kwargs: Any) -> Response: # Allow setting a default timeout on a session kwargs.setdefault("timeout", self.timeout) # Dispatch the actual request return super().request(method, url, *args, **kwargs) PKH]-{_8python3.10/site-packages/pip/_internal/network/xmlrpc.pynu["""xmlrpclib.Transport implementation """ import logging import urllib.parse import xmlrpc.client from typing import TYPE_CHECKING, Tuple from pip._internal.exceptions import NetworkConnectionError from pip._internal.network.session import PipSession from pip._internal.network.utils import raise_for_status if TYPE_CHECKING: from xmlrpc.client import _HostType, _Marshallable logger = logging.getLogger(__name__) class PipXmlrpcTransport(xmlrpc.client.Transport): """Provide a `xmlrpclib.Transport` implementation via a `PipSession` object. """ def __init__( self, index_url: str, session: PipSession, use_datetime: bool = False ) -> None: super().__init__(use_datetime) index_parts = urllib.parse.urlparse(index_url) self._scheme = index_parts.scheme self._session = session def request( self, host: "_HostType", handler: str, request_body: bytes, verbose: bool = False, ) -> Tuple["_Marshallable", ...]: assert isinstance(host, str) parts = (self._scheme, host, handler, None, None, None) url = urllib.parse.urlunparse(parts) try: headers = {"Content-Type": "text/xml"} response = self._session.post( url, data=request_body, headers=headers, stream=True, ) raise_for_status(response) self.verbose = verbose return self.parse_response(response.raw) except NetworkConnectionError as exc: assert exc.response logger.critical( "HTTP error %s while getting %s", exc.response.status_code, url, ) raise PKH]=.R//6python3.10/site-packages/pip/_internal/network/auth.pynu["""Network Authentication Helpers Contains interface (MultiDomainBasicAuth) and associated glue code for providing credentials in the context of network requests. """ import urllib.parse from typing import Any, Dict, List, Optional, Tuple from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth from pip._vendor.requests.models import Request, Response from pip._vendor.requests.utils import get_netrc_auth from pip._internal.utils.logging import getLogger from pip._internal.utils.misc import ( ask, ask_input, ask_password, remove_auth_from_url, split_auth_netloc_from_url, ) from pip._internal.vcs.versioncontrol import AuthInfo logger = getLogger(__name__) Credentials = Tuple[str, str, str] try: import keyring except ImportError: keyring = None # type: ignore[assignment] except Exception as exc: logger.warning( "Keyring is skipped due to an exception: %s", str(exc), ) keyring = None # type: ignore[assignment] def get_keyring_auth(url: Optional[str], username: Optional[str]) -> Optional[AuthInfo]: """Return the tuple auth for a given url from keyring.""" global keyring if not url or not keyring: return None try: try: get_credential = keyring.get_credential except AttributeError: pass else: logger.debug("Getting credentials from keyring for %s", url) cred = get_credential(url, username) if cred is not None: return cred.username, cred.password return None if username: logger.debug("Getting password from keyring for %s", url) password = keyring.get_password(url, username) if password: return username, password except Exception as exc: logger.warning( "Keyring is skipped due to an exception: %s", str(exc), ) keyring = None # type: ignore[assignment] return None class MultiDomainBasicAuth(AuthBase): def __init__( self, prompting: bool = True, index_urls: Optional[List[str]] = None ) -> None: self.prompting = prompting self.index_urls = index_urls self.passwords: Dict[str, AuthInfo] = {} # When the user is prompted to enter credentials and keyring is # available, we will offer to save them. If the user accepts, # this value is set to the credentials they entered. After the # request authenticates, the caller should call # ``save_credentials`` to save these. self._credentials_to_save: Optional[Credentials] = None def _get_index_url(self, url: str) -> Optional[str]: """Return the original index URL matching the requested URL. Cached or dynamically generated credentials may work against the original index URL rather than just the netloc. The provided url should have had its username and password removed already. If the original index url had credentials then they will be included in the return value. Returns None if no matching index was found, or if --no-index was specified by the user. """ if not url or not self.index_urls: return None for u in self.index_urls: prefix = remove_auth_from_url(u).rstrip("/") + "/" if url.startswith(prefix): return u return None def _get_new_credentials( self, original_url: str, allow_netrc: bool = True, allow_keyring: bool = False, ) -> AuthInfo: """Find and return credentials for the specified URL.""" # Split the credentials and netloc from the url. url, netloc, url_user_password = split_auth_netloc_from_url( original_url, ) # Start with the credentials embedded in the url username, password = url_user_password if username is not None and password is not None: logger.debug("Found credentials in url for %s", netloc) return url_user_password # Find a matching index url for this request index_url = self._get_index_url(url) if index_url: # Split the credentials from the url. index_info = split_auth_netloc_from_url(index_url) if index_info: index_url, _, index_url_user_password = index_info logger.debug("Found index url %s", index_url) # If an index URL was found, try its embedded credentials if index_url and index_url_user_password[0] is not None: username, password = index_url_user_password if username is not None and password is not None: logger.debug("Found credentials in index url for %s", netloc) return index_url_user_password # Get creds from netrc if we still don't have them if allow_netrc: netrc_auth = get_netrc_auth(original_url) if netrc_auth: logger.debug("Found credentials in netrc for %s", netloc) return netrc_auth # If we don't have a password and keyring is available, use it. if allow_keyring: # The index url is more specific than the netloc, so try it first # fmt: off kr_auth = ( get_keyring_auth(index_url, username) or get_keyring_auth(netloc, username) ) # fmt: on if kr_auth: logger.debug("Found credentials in keyring for %s", netloc) return kr_auth return username, password def _get_url_and_credentials( self, original_url: str ) -> Tuple[str, Optional[str], Optional[str]]: """Return the credentials to use for the provided URL. If allowed, netrc and keyring may be used to obtain the correct credentials. Returns (url_without_credentials, username, password). Note that even if the original URL contains credentials, this function may return a different username and password. """ url, netloc, _ = split_auth_netloc_from_url(original_url) # Try to get credentials from original url username, password = self._get_new_credentials(original_url) # If credentials not found, use any stored credentials for this netloc. # Do this if either the username or the password is missing. # This accounts for the situation in which the user has specified # the username in the index url, but the password comes from keyring. if (username is None or password is None) and netloc in self.passwords: un, pw = self.passwords[netloc] # It is possible that the cached credentials are for a different username, # in which case the cache should be ignored. if username is None or username == un: username, password = un, pw if username is not None or password is not None: # Convert the username and password if they're None, so that # this netloc will show up as "cached" in the conditional above. # Further, HTTPBasicAuth doesn't accept None, so it makes sense to # cache the value that is going to be used. username = username or "" password = password or "" # Store any acquired credentials. self.passwords[netloc] = (username, password) assert ( # Credentials were found (username is not None and password is not None) # Credentials were not found or (username is None and password is None) ), f"Could not load credentials from url: {original_url}" return url, username, password def __call__(self, req: Request) -> Request: # Get credentials for this request url, username, password = self._get_url_and_credentials(req.url) # Set the url of the request to the url without any credentials req.url = url if username is not None and password is not None: # Send the basic auth with this request req = HTTPBasicAuth(username, password)(req) # Attach a hook to handle 401 responses req.register_hook("response", self.handle_401) return req # Factored out to allow for easy patching in tests def _prompt_for_password( self, netloc: str ) -> Tuple[Optional[str], Optional[str], bool]: username = ask_input(f"User for {netloc}: ") if not username: return None, None, False auth = get_keyring_auth(netloc, username) if auth and auth[0] is not None and auth[1] is not None: return auth[0], auth[1], False password = ask_password("Password: ") return username, password, True # Factored out to allow for easy patching in tests def _should_save_password_to_keyring(self) -> bool: if not keyring: return False return ask("Save credentials to keyring [y/N]: ", ["y", "n"]) == "y" def handle_401(self, resp: Response, **kwargs: Any) -> Response: # We only care about 401 responses, anything else we want to just # pass through the actual response if resp.status_code != 401: return resp # We are not able to prompt the user so simply return the response if not self.prompting: return resp parsed = urllib.parse.urlparse(resp.url) # Query the keyring for credentials: username, password = self._get_new_credentials( resp.url, allow_netrc=False, allow_keyring=True, ) # Prompt the user for a new username and password save = False if not username and not password: username, password, save = self._prompt_for_password(parsed.netloc) # Store the new username and password to use for future requests self._credentials_to_save = None if username is not None and password is not None: self.passwords[parsed.netloc] = (username, password) # Prompt to save the password to keyring if save and self._should_save_password_to_keyring(): self._credentials_to_save = (parsed.netloc, username, password) # Consume content and release the original connection to allow our new # request to reuse the same one. resp.content resp.raw.release_conn() # Add our new username and password to the request req = HTTPBasicAuth(username or "", password or "")(resp.request) req.register_hook("response", self.warn_on_401) # On successful request, save the credentials that were used to # keyring. (Note that if the user responded "no" above, this member # is not set and nothing will be saved.) if self._credentials_to_save: req.register_hook("response", self.save_credentials) # Send our new request new_resp = resp.connection.send(req, **kwargs) new_resp.history.append(resp) return new_resp def warn_on_401(self, resp: Response, **kwargs: Any) -> None: """Response callback to warn about incorrect credentials.""" if resp.status_code == 401: logger.warning( "401 Error, Credentials not correct for %s", resp.request.url, ) def save_credentials(self, resp: Response, **kwargs: Any) -> None: """Response callback to save credentials on success.""" assert keyring is not None, "should never reach here without keyring" if not keyring: return creds = self._credentials_to_save self._credentials_to_save = None if creds and resp.status_code < 400: try: logger.info("Saving credentials to keyring") keyring.set_password(*creds) except Exception: logger.exception("Failed to save credentials") PKH]/P:python3.10/site-packages/pip/_internal/network/download.pynu["""Download files with progress indicators. """ import cgi import logging import mimetypes import os from typing import Iterable, Optional, Tuple from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response from pip._internal.cli.progress_bars import DownloadProgressProvider from pip._internal.exceptions import NetworkConnectionError from pip._internal.models.index import PyPI from pip._internal.models.link import Link from pip._internal.network.cache import is_from_cache from pip._internal.network.session import PipSession from pip._internal.network.utils import HEADERS, raise_for_status, response_chunks from pip._internal.utils.misc import format_size, redact_auth_from_url, splitext logger = logging.getLogger(__name__) def _get_http_response_size(resp: Response) -> Optional[int]: try: return int(resp.headers["content-length"]) except (ValueError, KeyError, TypeError): return None def _prepare_download( resp: Response, link: Link, progress_bar: str, ) -> Iterable[bytes]: total_length = _get_http_response_size(resp) if link.netloc == PyPI.file_storage_domain: url = link.show_url else: url = link.url_without_fragment logged_url = redact_auth_from_url(url) if total_length: logged_url = "{} ({})".format(logged_url, format_size(total_length)) if is_from_cache(resp): logger.info("Using cached %s", logged_url) else: logger.info("Downloading %s", logged_url) if logger.getEffectiveLevel() > logging.INFO: show_progress = False elif is_from_cache(resp): show_progress = False elif not total_length: show_progress = True elif total_length > (40 * 1000): show_progress = True else: show_progress = False chunks = response_chunks(resp, CONTENT_CHUNK_SIZE) if not show_progress: return chunks return DownloadProgressProvider(progress_bar, max=total_length)(chunks) def sanitize_content_filename(filename: str) -> str: """ Sanitize the "filename" value from a Content-Disposition header. """ return os.path.basename(filename) def parse_content_disposition(content_disposition: str, default_filename: str) -> str: """ Parse the "filename" value from a Content-Disposition header, and return the default filename if the result is empty. """ _type, params = cgi.parse_header(content_disposition) filename = params.get("filename") if filename: # We need to sanitize the filename to prevent directory traversal # in case the filename contains ".." path parts. filename = sanitize_content_filename(filename) return filename or default_filename def _get_http_response_filename(resp: Response, link: Link) -> str: """Get an ideal filename from the given HTTP response, falling back to the link filename if not provided. """ filename = link.filename # fallback # Have a look at the Content-Disposition header for a better guess content_disposition = resp.headers.get("content-disposition") if content_disposition: filename = parse_content_disposition(content_disposition, filename) ext: Optional[str] = splitext(filename)[1] if not ext: ext = mimetypes.guess_extension(resp.headers.get("content-type", "")) if ext: filename += ext if not ext and link.url != resp.url: ext = os.path.splitext(resp.url)[1] if ext: filename += ext return filename def _http_get_download(session: PipSession, link: Link) -> Response: target_url = link.url.split("#", 1)[0] resp = session.get(target_url, headers=HEADERS, stream=True) raise_for_status(resp) return resp class Downloader: def __init__( self, session: PipSession, progress_bar: str, ) -> None: self._session = session self._progress_bar = progress_bar def __call__(self, link: Link, location: str) -> Tuple[str, str]: """Download the file given by link into location.""" try: resp = _http_get_download(self._session, link) except NetworkConnectionError as e: assert e.response is not None logger.critical( "HTTP error %s while getting %s", e.response.status_code, link ) raise filename = _get_http_response_filename(resp, link) filepath = os.path.join(location, filename) chunks = _prepare_download(resp, link, self._progress_bar) with open(filepath, "wb") as content_file: for chunk in chunks: content_file.write(chunk) content_type = resp.headers.get("Content-Type", "") return filepath, content_type class BatchDownloader: def __init__( self, session: PipSession, progress_bar: str, ) -> None: self._session = session self._progress_bar = progress_bar def __call__( self, links: Iterable[Link], location: str ) -> Iterable[Tuple[Link, Tuple[str, str]]]: """Download the files given by links into location.""" for link in links: try: resp = _http_get_download(self._session, link) except NetworkConnectionError as e: assert e.response is not None logger.critical( "HTTP error %s while getting %s", e.response.status_code, link, ) raise filename = _get_http_response_filename(resp, link) filepath = os.path.join(location, filename) chunks = _prepare_download(resp, link, self._progress_bar) with open(filepath, "wb") as content_file: for chunk in chunks: content_file.write(chunk) content_type = resp.headers.get("Content-Type", "") yield link, (filepath, content_type) PKH]ӏV17python3.10/site-packages/pip/_internal/network/utils.pynu[from typing import Dict, Iterator from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response from pip._internal.exceptions import NetworkConnectionError # The following comments and HTTP headers were originally added by # Donald Stufft in git commit 22c562429a61bb77172039e480873fb239dd8c03. # # We use Accept-Encoding: identity here because requests defaults to # accepting compressed responses. This breaks in a variety of ways # depending on how the server is configured. # - Some servers will notice that the file isn't a compressible file # and will leave the file alone and with an empty Content-Encoding # - Some servers will notice that the file is already compressed and # will leave the file alone, adding a Content-Encoding: gzip header # - Some servers won't notice anything at all and will take a file # that's already been compressed and compress it again, and set # the Content-Encoding: gzip header # By setting this to request only the identity encoding we're hoping # to eliminate the third case. Hopefully there does not exist a server # which when given a file will notice it is already compressed and that # you're not asking for a compressed file and will then decompress it # before sending because if that's the case I don't think it'll ever be # possible to make this work. HEADERS: Dict[str, str] = {"Accept-Encoding": "identity"} def raise_for_status(resp: Response) -> None: http_error_msg = "" if isinstance(resp.reason, bytes): # We attempt to decode utf-8 first because some servers # choose to localize their reason strings. If the string # isn't utf-8, we fall back to iso-8859-1 for all other # encodings. try: reason = resp.reason.decode("utf-8") except UnicodeDecodeError: reason = resp.reason.decode("iso-8859-1") else: reason = resp.reason if 400 <= resp.status_code < 500: http_error_msg = ( f"{resp.status_code} Client Error: {reason} for url: {resp.url}" ) elif 500 <= resp.status_code < 600: http_error_msg = ( f"{resp.status_code} Server Error: {reason} for url: {resp.url}" ) if http_error_msg: raise NetworkConnectionError(http_error_msg, response=resp) def response_chunks( response: Response, chunk_size: int = CONTENT_CHUNK_SIZE ) -> Iterator[bytes]: """Given a requests Response, provide the data chunks.""" try: # Special case for urllib3. for chunk in response.raw.stream( chunk_size, # We use decode_content=False here because we don't # want urllib3 to mess with the raw bytes we get # from the server. If we decompress inside of # urllib3 then we cannot verify the checksum # because the checksum will be of the compressed # file. This breakage will only occur if the # server adds a Content-Encoding header, which # depends on how the server was configured: # - Some servers will notice that the file isn't a # compressible file and will leave the file alone # and with an empty Content-Encoding # - Some servers will notice that the file is # already compressed and will leave the file # alone and will add a Content-Encoding: gzip # header # - Some servers won't notice anything at all and # will take a file that's already been compressed # and compress it again and set the # Content-Encoding: gzip header # # By setting this not to decode automatically we # hope to eliminate problems with the second case. decode_content=False, ): yield chunk except AttributeError: # Standard file-like object. while True: chunk = response.raw.read(chunk_size) if not chunk: break yield chunk PKH]J22:python3.10/site-packages/pip/_internal/network/__init__.pynu["""Contains purely network-related utilities. """ PKH]w<python3.10/site-packages/pip/_internal/network/lazy_wheel.pynu["""Lazy ZIP over HTTP""" __all__ = ["HTTPRangeRequestUnsupported", "dist_from_wheel_url"] from bisect import bisect_left, bisect_right from contextlib import contextmanager from tempfile import NamedTemporaryFile from typing import Any, Dict, Iterator, List, Optional, Tuple from zipfile import BadZipfile, ZipFile from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response from pip._internal.metadata import BaseDistribution, MemoryWheel, get_wheel_distribution from pip._internal.network.session import PipSession from pip._internal.network.utils import HEADERS, raise_for_status, response_chunks class HTTPRangeRequestUnsupported(Exception): pass def dist_from_wheel_url(name: str, url: str, session: PipSession) -> BaseDistribution: """Return a distribution object from the given wheel URL. This uses HTTP range requests to only fetch the potion of the wheel containing metadata, just enough for the object to be constructed. If such requests are not supported, HTTPRangeRequestUnsupported is raised. """ with LazyZipOverHTTP(url, session) as zf: # For read-only ZIP files, ZipFile only needs methods read, # seek, seekable and tell, not the whole IO protocol. wheel = MemoryWheel(zf.name, zf) # type: ignore # After context manager exit, wheel.name # is an invalid file by intention. return get_wheel_distribution(wheel, canonicalize_name(name)) class LazyZipOverHTTP: """File-like object mapped to a ZIP file over HTTP. This uses HTTP range requests to lazily fetch the file's content, which is supposed to be fed to ZipFile. If such requests are not supported by the server, raise HTTPRangeRequestUnsupported during initialization. """ def __init__( self, url: str, session: PipSession, chunk_size: int = CONTENT_CHUNK_SIZE ) -> None: head = session.head(url, headers=HEADERS) raise_for_status(head) assert head.status_code == 200 self._session, self._url, self._chunk_size = session, url, chunk_size self._length = int(head.headers["Content-Length"]) self._file = NamedTemporaryFile() self.truncate(self._length) self._left: List[int] = [] self._right: List[int] = [] if "bytes" not in head.headers.get("Accept-Ranges", "none"): raise HTTPRangeRequestUnsupported("range request is not supported") self._check_zip() @property def mode(self) -> str: """Opening mode, which is always rb.""" return "rb" @property def name(self) -> str: """Path to the underlying file.""" return self._file.name def seekable(self) -> bool: """Return whether random access is supported, which is True.""" return True def close(self) -> None: """Close the file.""" self._file.close() @property def closed(self) -> bool: """Whether the file is closed.""" return self._file.closed def read(self, size: int = -1) -> bytes: """Read up to size bytes from the object and return them. As a convenience, if size is unspecified or -1, all bytes until EOF are returned. Fewer than size bytes may be returned if EOF is reached. """ download_size = max(size, self._chunk_size) start, length = self.tell(), self._length stop = length if size < 0 else min(start + download_size, length) start = max(0, stop - download_size) self._download(start, stop - 1) return self._file.read(size) def readable(self) -> bool: """Return whether the file is readable, which is True.""" return True def seek(self, offset: int, whence: int = 0) -> int: """Change stream position and return the new absolute position. Seek to offset relative position indicated by whence: * 0: Start of stream (the default). pos should be >= 0; * 1: Current position - pos may be negative; * 2: End of stream - pos usually negative. """ return self._file.seek(offset, whence) def tell(self) -> int: """Return the current position.""" return self._file.tell() def truncate(self, size: Optional[int] = None) -> int: """Resize the stream to the given size in bytes. If size is unspecified resize to the current position. The current stream position isn't changed. Return the new file size. """ return self._file.truncate(size) def writable(self) -> bool: """Return False.""" return False def __enter__(self) -> "LazyZipOverHTTP": self._file.__enter__() return self def __exit__(self, *exc: Any) -> Optional[bool]: return self._file.__exit__(*exc) @contextmanager def _stay(self) -> Iterator[None]: """Return a context manager keeping the position. At the end of the block, seek back to original position. """ pos = self.tell() try: yield finally: self.seek(pos) def _check_zip(self) -> None: """Check and download until the file is a valid ZIP.""" end = self._length - 1 for start in reversed(range(0, end, self._chunk_size)): self._download(start, end) with self._stay(): try: # For read-only ZIP files, ZipFile only needs # methods read, seek, seekable and tell. ZipFile(self) # type: ignore except BadZipfile: pass else: break def _stream_response( self, start: int, end: int, base_headers: Dict[str, str] = HEADERS ) -> Response: """Return HTTP response to a range request from start to end.""" headers = base_headers.copy() headers["Range"] = f"bytes={start}-{end}" # TODO: Get range requests to be correctly cached headers["Cache-Control"] = "no-cache" return self._session.get(self._url, headers=headers, stream=True) def _merge( self, start: int, end: int, left: int, right: int ) -> Iterator[Tuple[int, int]]: """Return an iterator of intervals to be fetched. Args: start (int): Start of needed interval end (int): End of needed interval left (int): Index of first overlapping downloaded data right (int): Index after last overlapping downloaded data """ lslice, rslice = self._left[left:right], self._right[left:right] i = start = min([start] + lslice[:1]) end = max([end] + rslice[-1:]) for j, k in zip(lslice, rslice): if j > i: yield i, j - 1 i = k + 1 if i <= end: yield i, end self._left[left:right], self._right[left:right] = [start], [end] def _download(self, start: int, end: int) -> None: """Download bytes from start to end inclusively.""" with self._stay(): left = bisect_left(self._right, start) right = bisect_right(self._left, end) for start, end in self._merge(start, end, left, right): response = self._stream_response(start, end) response.raise_for_status() self.seek(start) for chunk in response_chunks(response, self._chunk_size): self._file.write(chunk) PKH];tSpython3.10/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-310.pycnu[o ain@s<dZddlZddlZddlZddlZddlZddlZddlZddlmZddl m Z m Z m Z m Z mZddlmZddlmZddlmZmZddlmZmZmZmZdd lmZmZmZmZm Z m!Z!dd l"m#Z#dd l$m%Z%m&Z&dd l'm(Z(m)Z)dd l*m+Z,ddl*m-Z-m.Z.ddl/m0Z0dgZ1e2e3Z4GdddeZ5dS)z(Base Command class, and related routinesN)Values)AnyCallableListOptionalTuple) cmdoptions)CommandContextMixIn)ConfigOptionParserUpdatingDefaultsHelpFormatter)ERRORPREVIOUS_BUILD_DIR_ERROR UNKNOWN_ERRORVIRTUALENV_NOT_FOUND) BadCommand CommandErrorInstallationErrorNetworkConnectionErrorPreviousBuildDirErrorUninstallationError)check_path_owner)BrokenStdoutLoggingError setup_logging)get_prognormalize_path)TempDirectoryTypeRegistry)global_tempdir_managertempdir_registry)running_under_virtualenvCommandc seZdZUdZeed<dZeed<ddedededd ffd d Zdd d Z de dd fddZ de de ede fddZde edee e effddZde ede fddZde ede fddZZS)rusageFignore_require_venvnamesummaryisolatedreturnNc st||_||_t|jtd|td||j|d|_ d|_ |j d}t |j ||_ttj|j }|j ||dS)N F)r!prog formatteradd_help_optionr# descriptionr%z Options)super__init__r#r$r r!rr __doc__parserr capitalizeoptparse OptionGroupcmd_optsrmake_option_group general_groupadd_option_group add_options)selfr#r$r% optgroup_namegen_opts __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/base_command.pyr-.s*    zCommand.__init__cCsdSNr=)r8r=r=r>r7LzCommand.add_optionsoptionscCst|drJdS)zf This is a no-op so that commands by default do not do the pip version check. no_indexN)hasattr)r8rAr=r=r>handle_pip_version_checkOsz Command.handle_pip_version_checkargscCstr?)NotImplementedError)r8rArEr=r=r>runXr@z Command.runcCs |j|Sr?)r/ parse_argsr8rEr=r=r>rH[s zCommand.parse_argscCsVz%|||WdWtS1swYWtdStwr?) main_context_mainloggingshutdownrIr=r=r>main_s  z Command.mainc s>|t|_|t||\}}|j|j|_t|j|j|j d|j r-dt j d<|j r9d|j t j d<|jrL|jsLtsLtdtt|jrdt|j|_t|jsdtd|jd|_d|jvrntd d td tfd td tfffd d }z|js||j}n|j}|||W| |S| |w)N) verbosityno_color user_log_file1 PIP_NO_INPUTr'PIP_EXISTS_ACTIONz2Could not find an activated virtualenv (required).zThe directory '%s' or its parent directory is not owned or is not writable by the current user. The cache has been disabled. Check the permissions and owner of that directory. If executing pip with sudo, you should use sudo's -H flag.z 2020-resolverz--use-feature=2020-resolver no longer has any effect, since it is now the default dependency resolver in pip. This will become an error in pip 21.0.run_func.r&cs&tdtdtffdd }|S)NrEr&c stz|}t|ts J|WSty0}ztt|tjdddtWYd}~Sd}~wtt t t fyU}ztt|tjdddt WYd}~Sd}~wt yu}ztd|tjdddt WYd}~Sd}~wtytdtjdtjkrtjtjdt YStytdtjdddt YStytjdddtYSw) NzException information:T)exc_infoz%sz ERROR: Pipe to stdout was broken)filezOperation cancelled by userz Exception:) isinstanceintrloggercriticalstrdebugr rrrrr rrprintsysstderrrLDEBUG traceback print_excKeyboardInterrupt BaseExceptionr)rEstatusexc) level_numberrUr=r>exc_logging_wrappersJ       zLCommand._main..intercepts_unhandled_exc..exc_logging_wrapper) functoolswrapsrrY)rUrirh)rUr>intercepts_unhandled_excs+z/Command._main..intercepts_unhandled_exc)! enter_contextrrrHverbosequietrOrrPlogno_inputosenviron exists_actionjoin require_venvr"rrZr[r_exitr cache_dirrrwarningfeatures_enabledrrY debug_moderGrD)r8rErArmrGr=rlr>rKfsP          1  z Command._main)F)r&N)__name__ __module__ __qualname__r!r\__annotations__r"boolr-r7rrDrrYrGrrHrNrK __classcell__r=r=r;r>r*s     ")6r.rjrLlogging.configr1rsr_rbrtypingrrrrrpip._internal.clir!pip._internal.cli.command_contextr pip._internal.cli.parserr r pip._internal.cli.status_codesr r rrpip._internal.exceptionsrrrrrrpip._internal.utils.filesystemrpip._internal.utils.loggingrrpip._internal.utils.miscrrpip._internal.utils.temp_dirrTempDirRegistryrrpip._internal.utils.virtualenvr__all__ getLoggerr}rZrr=r=r=r>s0        PKH]W]Tpython3.10/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-310.pycnu[o ail @sUddlZddlZddlmZmZmZddlmZddlmZm Z m Z ddl m Z ddl mZddlmZddlmZzdd lmZWn eyNdZYnwd ed ed efd dZee eZeed<GdddZGdddeZGddde ZGdddZGdddZGdddeeeZGdddeeZGdddeeZ Gd d!d!eeZ!Gd"d#d#ee Z"Gd$d%d%eeZ#Gd&d'd'eeee Z$e e fee$fe!e$fe"e$fe#e$fd(Z%d+d)d*Z&dS),N)SIGINTdefault_int_handlersignal)Any)BarFillingCirclesBarIncrementalBar)Spinner)WINDOWS)get_indentation) format_size)colorama preferredfallbackreturncCspt|jdd}|s |St|ddt|ddg}|tt|dg7}z d||W|Sty7|YSw)Nencoding empty_fillfillphases)getattrfilelistjoinencodeUnicodeEncodeError)rrr charactersr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/progress_bars.py_select_progress_classs   r_BaseBarcsDeZdZdZdededdffdd Zd fdd Zd d ZZS) InterruptibleMixina Helper to ensure that self.finish() gets called on keyboard interrupt. This allows downloads to be interrupted without leaving temporary state (like hidden cursors) behind. This class is similar to the progress library's existing SigIntMixin helper, but as of version 1.2, that helper has the following problems: 1. It calls sys.exit(). 2. It discards the existing SIGINT handler completely. 3. It leaves its own handler in place even after an uninterrupted finish, which will have unexpected delayed effects if the user triggers an unrelated keyboard interrupt some time after a progress-displaying download has already completed, for example. argskwargsrNcs8tj|i|tt|j|_|jdurt|_dSdS)z= Save the original SIGINT handler for later. N)super__init__rr handle_sigintoriginal_handlerrselfr"r# __class__rrr%Es   zInterruptibleMixin.__init__csttt|jdS)z Restore the original SIGINT handler after finishing. This should happen regardless of whether the progress display finishes normally, or gets interrupted. N)r$finishrrr'r)r*rrr,Vs zInterruptibleMixin.finishcCs||||dS)z Call self.finish() before delegating to the original SIGINT handler. This handler should only be in place while the progress display is active. N)r,r')r)signumframerrrr&`sz InterruptibleMixin.handle_sigintrN) __name__ __module__ __qualname____doc__rr%r,r& __classcell__rrr*rr!3s  r!c@seZdZdddZdS) SilentBarrNcCsdSNrr-rrrupdatelszSilentBar.updater0)r1r2r3r8rrrrr6ksr6c@seZdZdZdZdZdZdS) BlueEmojiBar %(percent)d%% )u🔹u🔷u🔵N)r1r2r3suffix bar_prefix bar_suffixrrrrrr9ps r9csheZdZdededdffdd ZedefddZedefd d Zedefd d Z d dZ Z S)DownloadProgressMixinr"r#rNcs,tj|i|dtd|j|_dS)Nr;)r$r%r messager(r*rrr%yszDownloadProgressMixin.__init__cCs t|jSr7)r indexr-rrr downloaded~s z DownloadProgressMixin.downloadedcCs |jdkrdStd|jdS)Ngz...z/s)avgr r-rrrdownload_speeds z$DownloadProgressMixin.download_speedcCs|jr d|jSdS)Nzeta r)etaeta_tdr-rrr pretty_etas z DownloadProgressMixin.pretty_etaccs,|D] }|V|t|q|dSr7)nextlenr,)r)itxrrriters  zDownloadProgressMixin.iter) r1r2r3rr%propertystrrCrFrIrNr5rrr*rr?xsr?cs*eZdZdededdffdd ZZS) WindowsMixinr"r#rNcsdtrjrd_tj|i|tr.tr0tj_fddj_fddj_dSdSdS)NFc jjSr7)rwrappedisattyrr-rr z'WindowsMixin.__init__..crRr7)rrSflushrr-rrrUrV) r hide_cursorr$r%r AnsiToWin32rrTrWr(r*r-rr%s zWindowsMixin.__init__)r1r2r3rr%r5rrr*rrQs"rQc@seZdZejZdZdZdS)BaseDownloadProgressBarr:z0%(downloaded)s %(download_speed)s %(pretty_eta)sN)r1r2r3sysstdoutrrAr<rrrrrZsrZc@ eZdZdS)DefaultDownloadProgressBarNr1r2r3rrrrr^r^c@r])DownloadSilentBarNr_rrrrrar`rac@r]) DownloadBarNr_rrrrrbr`rbc@r])DownloadFillingCirclesBarNr_rrrrrcr`rcc@r])DownloadBlueEmojiProgressBarNr_rrrrrdr`rdc@s.eZdZejZdZdefddZdddZ dS) DownloadProgressSpinnerz!%(downloaded)s %(download_speed)srcCs"t|ds t|j|_t|jS)N_phaser)hasattr itertoolscyclerrfrJr-rrr next_phases  z"DownloadProgressSpinner.next_phaseNcCsN|j|}|}|j|}d||rdnd||rdnd|g}||dS)Nrr;)rArjr<rwriteln)r)rAphaser<linerrrr8s     zDownloadProgressSpinner.updater0) r1r2r3r[r\rr<rPrjr8rrrrres re)offonasciiprettyemojicCs4|dus|dkrt|djSt|d|djS)NrrD)max) BAR_TYPESrN) progress_barrsrrrDownloadProgressProvidersrvr7)'rhr[rrrtypingrpip._vendor.progress.barrrrpip._vendor.progress.spinnerr pip._internal.utils.compatr pip._internal.utils.loggingr pip._internal.utils.miscr pip._vendorr Exceptionrr __annotations__r!r6r9r?rQrZr^rarbrcrdrertrvrrrrsJ       8   PKH]*$TggUpython3.10/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-310.pycnu[o ai @sdZddlZddlZddlZddlmZddlmZmZm Z m Z ddl m Z ddl mZmZddlmZdd d Zd e ed ed eede efddZdededeefddZdS)zBLogic that powers autocompletion installed by ``pip completion``. N)chain)AnyIterableListOptional)create_main_parser) commands_dictcreate_command)get_default_environmentreturncsdtjvrdStjdddttjd}z|dWn ty,dYnwt}tt}g}d}D] }||vrD|}nq:|dur|dkrRt d d o[|d v}|rt } fd d |j d d D}|r|D]} t| qwt dt|} | jjD]} | jtjkr| j| jD] } || | jfqqdd d|dDfdd |D}fdd |D}t|| jj} | rt| }dd |D}|D]}|d}|dr|ddddkr|d7}t|qnMdd |jD}||jt|} dr)|D]} | jtjkr&|| j| j7}qnt||} | r9tt| }tdfdd |Dt ddS)z:Entry Point for completion of main and subcommand options.PIP_AUTO_COMPLETEN COMP_WORDS COMP_CWORDhelp-)show uninstallcs0g|]}|jr|jddvr|jqS)rN)canonical_name startswith).0dist)cwordslc/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/autocompletion.py 2s z autocomplete..T) local_onlycSsg|] }|ddqS)=r)splitrxrrrrFcs g|] \}}|vr||fqSrr)rr"v) prev_optsrrrGs cs"g|] \}}|r||fqSrr)rkr$currentrrrIs"cSsg|]}|dfqS)rr)rpathrrrrTsrz--rcSsg|]}|jqSr) option_list)rirrrr^s csg|] }|r|qSrr&r!r(rrrkr#) osenvironr int IndexErrorrlistrsysexitrr loweriter_installed_distributionsprintr parseroption_list_allroptparse SUPPRESS_HELP _long_opts _short_optsappendnargsget_path_completion_typeauto_complete_paths option_groupsr,r from_iterablejoin)cwordr9 subcommandsoptionssubcommand_namewordshould_list_installedenv installedr subcommandoptopt_strcompletion_typepathsoption opt_labeloptsflattened_optsr)r)rrr%r autocompletes               rWrrFrUcCs|dks ||ddsdS|D]7}|jtjkrqt|dD]&}||ddd|krG|jr@tdd|jdDrG|jSq!qdS) aLGet the type of path completion (``file``, ``dir``, ``path`` or None) :param cwords: same as the environmental variable ``COMP_WORDS`` :param cword: same as the environmental variable ``COMP_CWORD`` :param opts: The available options to check :return: path completion type (``file``, ``dir``, ``path`` or None) r+rN/rrcss|]}|dvVqdS))r*filedirNrr!rrr s z+get_path_completion_type..)rrr;r<strr metavarany)rrFrUrOorrrrAos   rAr)rQc#stj|\}tj|}t|tjsdStjfddt|D}|D]0}tj||}tjtj||}|dkrNtj |rN|Vq,tj |r\tj|dVq,dS)aoIf ``completion_type`` is ``file`` or ``path``, list all regular files and directories starting with ``current``; otherwise only list directories starting with ``current``. :param current: The word to be completed :param completion_type: path completion type(`file`, `path` or `dir`)i :return: A generator of regular files and/or directories Nc3s&|]}tj|r|VqdS)N)r/r*normcaserr!filenamerrr[s  z&auto_complete_paths..rZr) r/r*r abspathaccessR_OKr`listdirrEisfileisdir)r)rQ directory current_path file_listfrO comp_filerrarrBs$    rB)r N)__doc__r;r/r4 itertoolsrtypingrrrrpip._internal.cli.main_parserrpip._internal.commandsrr pip._internal.metadatar rWr\r1rArBrrrrs(    ` PKH]2~<<Opython3.10/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-310.pycnu[o ai@sdZdS)zGSubpackage containing all of pip's command line interface related code N)__doc__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/__init__.pysPKH]a00Rpython3.10/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-310.pycnu[o aiB@sdZddlZddlZddlZddlmZddlmZddlm Z m Z m Z m Z ddl mZddlmZddlmZdd lmZdd lmZmZdd lmZdd lmZdd lmZddlmZddl m!Z!ddl"m#Z#ddl$m%Z%m&Z&m'Z'm(Z(ddl)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0ddl1m2Z2ddl3m4Z4ddl5m6Z6m7Z7m8Z8ddl9m:Z:e;e<Z=GdddeZ>Gdddee>Z?e8j@e8jAe8jBgZCd&dd ZDd!e de fd"d#ZEGd$d%d%e?ZFdS)'aContains the Command base classes that depend on PipSession. The classes in this module are in a separate module so the commands not needing download / PackageFinder capability don't unnecessarily import the PackageFinder machinery and all its vendored dependencies, etc. N)partial)Values)AnyListOptionalTuple) WheelCache) cmdoptions)Command)CommandContextMixIn) CommandErrorPreviousBuildDirError) LinkCollector) PackageFinder)SelectionPreferences) TargetPython) PipSession)RequirementPreparer)install_req_from_editableinstall_req_from_line#install_req_from_parsed_requirementinstall_req_from_req_string)parse_requirements)InstallRequirement)RequirementTracker) BaseResolver)pip_self_version_check) deprecated) TempDirectoryTempDirectoryTypeRegistry tempdir_kinds)running_under_virtualenvc szeZdZdZdfdd Zededeee fddZ dede fd d Z  dded ee d ee de fd dZZS)SessionCommandMixinzE A class mixin for command classes needing _build_session(). returnNcstd|_dSN)super__init___session)self __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/req_command.pyr&6s  zSessionCommandMixin.__init__optionscCsLg}t|ddst|dd}|r||t|dd}|r"|||p%dS)z7Return a list of index urls from user-provided options.no_indexF index_urlNextra_index_urls)getattrappendextend)clsr- index_urlsurlurlsr+r+r,_get_index_urls:s     z#SessionCommandMixin._get_index_urlscCs0|jdur||||_|jdusJ|jS)zGet a default-managed session.N)r' enter_context_build_session)r(r-r+r+r,get_default_sessionHs z'SessionCommandMixin.get_default_sessionretriestimeoutcCs|jr tj|js Jt|jrtj|jdnd|dur|n|j|j||d}|j r1|j |_ |j r8|j |_ |j s=|rG|durC|n|j |_ |j rR|j |j d|_|j |j_|S)Nhttp)cacher< trusted_hostsr5)r>https) cache_dirospathisabsrjoinr<r@r8certverify client_certr=proxyproxiesno_inputauth prompting)r(r-r<r=sessionr+r+r,r:Rs&   z"SessionCommandMixin._build_sessionr#NNN)__name__ __module__ __qualname____doc__r& classmethodrrrstrr8rr;intr: __classcell__r+r+r)r,r"0s"  r"c@s"eZdZdZdeddfddZdS)IndexGroupCommandz Abstract base class for commands with the index_group options. This also corresponds to the commands that permit the pip version check. r-r#NcCsjt|dsJ|js |jrdS|j|dtd|jd}|t||WddS1s.wYdS)z Do the pip version check if not disabled. This overrides the default behavior of not doing the check. r.Nr)r<r=)hasattrdisable_pip_version_checkr.r:minr=r)r(r-rOr+r+r,handle_pip_version_checks  "z*IndexGroupCommand.handle_pip_version_check)rRrSrTrUrr_r+r+r+r,rZ{srZr#cCsNtrdSttds dStjdkstjdkrdStdkr dStddS)zOutput a warning for sudo users on Unix. In a virtual environment, sudo pip still writes to virtualenv. On Windows, users may run pip as Administrator without issues. This warning only applies to Unix root users outside of virtualenv. Ngetuidwin32cygwinrzRunning pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv)r!r\rCsysplatformr`loggerwarningr+r+r+r,warn_if_run_as_roots  rgfuncc s>dtddfdddtdtdttdttffd d }|S) zNDecorator for common logic related to managing temporary directories. registryr#NcSstD]}||dqdS)NF)KEEPABLE_TEMPDIR_TYPES set_delete)ritr+r+r,configure_tempdir_registrysz0with_cleanup..configure_tempdir_registryr(r-argscsH|jdusJ|jr|jz|||WSty#|jwr$)tempdir_registryno_cleanr )r(r-rnrmrhr+r,wrappers   zwith_cleanup..wrapper)rRequirementCommandrrrrrX)rhrrr+rqr, with_cleanupsrtcsBeZdZdededdffdd Zededefdd Ze d'd e ded e d e d e dedeedefddZe        d(ded e dedeededededededeedeeedfdefddZdeeded e d e deef d d!Zed e ddfd"d#Z  d)ded e d$eedeede f d%d&ZZS)*rsrnkwr#Ncs&tj|i||jtdSr$)r%r&cmd_opts add_optionr rp)r(rnrur)r+r,r&szRequirementCommand.__init__r-cCsd|jvrdSdS)zEDetermines which resolver should be used, based on the given options.zlegacy-resolverlegacy 2020-resolver)deprecated_features_enabledr-r+r+r,determine_resolver_variants z-RequirementCommand.determine_resolver_varianttemp_build_dir req_trackerrOfinder use_user_site download_dirc Cs|j}|dus J||} | dkrd|jv} | rtdn d} d|jvr+tdd|jv} d|jvrsz6RequirementCommand.get_requirements..namezXYou must give at least one requirement to {name} (maybe you meant "pip {name} {links}"?) )linkszHYou must give at least one requirement to {name} (see "pip help {name}")r+) constraintsrrrr2rr editablesr requirementsanyrr find_linksr formatdictrF) r(rnr-rrOrfilename parsed_req req_to_addroptsr+r+r,get_requirementsas           z#RequirementCommand.get_requirementscCs$|j}|}|rt|dSdS)zE Trace basic information about the provided objects. N) search_scopeget_formatted_locationsreinfo)rr locationsr+r+r,trace_basic_infos z#RequirementCommand.trace_basic_info target_pythoncCs6tj||d}td|j|j|j|d}tj|||dS)z Create a package finder appropriate to this requirement command. :param ignore_requires_python: Whether to ignore incompatible "Requires-Python" values in links. Defaults to False. r{T) allow_yankedformat_controlallow_all_prereleases prefer_binaryr)link_collectorselection_prefsr)rcreaterrprerr)r(r-rOrrrrr+r+r,_build_package_finders z(RequirementCommand._build_package_finderr$)NFTFFrNNrQ)rRrSrTrr& staticmethodrrWr|rVrrrrboolrrrrrrXrrrrrrrrrYr+r+r)r,rss  ?     : OrsrP)GrUloggingrCrc functoolsroptparsertypingrrrrpip._internal.cacherpip._internal.clir pip._internal.cli.base_commandr !pip._internal.cli.command_contextr pip._internal.exceptionsr r pip._internal.index.collectorr"pip._internal.index.package_finderr$pip._internal.models.selection_prefsr"pip._internal.models.target_pythonrpip._internal.network.sessionr pip._internal.operations.preparerpip._internal.req.constructorsrrrrZpip._internal.req.req_filerpip._internal.req.req_installrpip._internal.req.req_trackerrpip._internal.resolution.baser!pip._internal.self_outdated_checkrpip._internal.utils.deprecationrpip._internal.utils.temp_dirrrr pip._internal.utils.virtualenvr! getLoggerrRrer"rZ BUILD_ENVEPHEM_WHEEL_CACHE REQ_BUILDrjrgrtrsr+r+r+r,sJ                    K PKH]3UGKpython3.10/site-packages/pip/_internal/cli/__pycache__/main.cpython-310.pycnu[o ai @sdZddlZddlZddlZddlZddlmZmZddlm Z ddl m Z ddl m Z ddlmZddlmZeeZd d eeed efd d ZdS)z Primary application entrypoint. N)ListOptional) autocomplete) parse_command)create_command)PipError) deprecationargsreturnc Cs|dur tjdd}ttzt|\}}Wn'tyA}ztjd|tjt j t dWYd}~nd}~wwz t t jdWnt jyd}z td|WYd}~nd}~wwt|d|vd}||S)NzERROR: z%Ignoring error %s when setting localez --isolated)isolated)sysargvrinstall_warning_loggerrrrstderrwriteoslinesepexitlocale setlocaleLC_ALLErrorloggerdebugrmain)r cmd_namecmd_argsexcecommandr"/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/main.pyr-s( r)N)__doc__rloggingrrtypingrr pip._internal.cli.autocompletionrpip._internal.cli.main_parserrpip._internal.commandsrpip._internal.exceptionsrpip._internal.utilsr getLogger__name__rstrintrr"r"r"r#s       PKH]?Spython3.10/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-310.pycnu[o ait@sdZdZdZdZdZdZdS)N)SUCCESSERROR UNKNOWN_ERRORVIRTUALENV_NOT_FOUNDPREVIOUS_BUILD_DIR_ERRORNO_MATCHES_FOUNDr r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/status_codes.pys PKH]^ WWQpython3.10/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pycnu[o ain@s UdZddlZddlZddlZddlmZddlmZmZm Z m Z m Z ddlm Z ddl mZmZmZmZmZddlmZddlmZdd lmZdd lmZdd lmZmZdd lmZdd l m!Z!ddl"m#Z#ddl$m%Z%ddl&m'Z'de dede(ddfddZ)dee(efdede fddZ* d(de dee ddfddZ+d)de de,ddfd d!Z-ded"e(d#e(de(fd$d%Z.ded"e(d#e(de(fd&d'Z/Gd(d)d)eZ0eed*d+d,d,d-d.Z1ed/efe2d0<eed1d2d3dd4d5Z3ed/efe2d2<eed6d7d3dd8d5Z4ed/efe2d7<eed9d:d;d3ded5Z5ed/efe2d<<eed=d>d?d@ddAd5Z6ed/efe2d?<eedBdCd3ddDd5Z7ed/efe2dC<eedEdFdGd3dHd.Z8ed/efe2dG<eedIdJdKd@ddLd5Z9ed/efe2dK<eedMdNdOe:e;dPdQdRed/efe2dX<eed\d]d3dd^d5Z?ed/efe2d]<eed_d`dadbdcddZ@ed/efe2d`<eededfdgdhdiddZAed/efe2df<eedjdkdldmdndodpdqZBed/efe2dm<defdrdsZCee0dtdudYdYdvdwZDed/efe2du<ee0dxdydYddYdzd{ZEed/efe2dy<eed|d}d~dde!jFddZGed/efe2d<defddZHeeddd3ddd5ZIed/efe2d<defddZJdefddZKdefddZLdefddZMdefddZNdede(d#e(de ddf ddZOee0ddddddYdedeOdd ZPed/efe2d<de dedefddZQdede(d#e(de ddf ddZRdede(d#e(de ddf ddZSdefddZTdefddZUeedddddddZVed/efe2d<d#e(deeeWd/fee(ffddZXdede(d#e(de ddf ddZYeeddddeYdade dd ZZed/efe2d<eeddddddZ[ed/efe2d<eedddddddZ\ed/efe2d<de ddfddZ]de de#fddÄZ^defddńZ_ee0ddeddYddɍZ`ed/efe2d<ded"e(d#e(de ddf dd˄Zaeedddeadd΍Zbed/efe2d<eedddd3ddd5Zced/efe2d<eeddd3dd.Zded/efe2d<eedddddd5Zeed/efe2d<ded"e(d#e(de ddf dd߄Zfeeddd3ddd5Zgee2d<eedddefdedZhee2d<eeddddddZied/efe2d<eeddddddZjed/efe2d<eeddddddZked/efe2d<eedd3dddZled/efe2d<eedd3dddZmed/efe2d<eeddd3ddd5Zned/efe2d<dede(d#e(de ddf ddZoeedddeodddZped/efe2d<eeddd3ddd5Zqed/efe2d<ee0ddYdYdddZred/efe2d <de ddfd d Zsee0d d dddddZted/efe2d<eeddd3ddd5Zued/efe2d<eeddddggdddZved/efe2d<eeddddgdd gd!dZwed/efe2d"<d#e1e3e4e5e6e8e9e>e?e@eAeBeCeKeDeEe`ebene7euevewgd$Zxee(efe2d%<d&eGeHeIeJgd$Zyee(efe2d'<dS(*aC shared options and groups The principle here is to define options once, but *not* instantiate them globally. One reason being that options with action='append' can carry state between parses. pip parses general options twice internally, and shouldn't pass on state. To be consistent, all options will follow this design. N)partial) SUPPRESS_HELPOption OptionGroup OptionParserValues)dedent)AnyCallableDictOptionalTuplecanonicalize_name)ConfigOptionParser) BAR_TYPES) CommandError)USER_CACHE_DIRget_src_prefix) FormatControl)PyPI) TargetPython) STRONG_HASHES) strtoboolparseroptionmsgreturncCs0|d|}td|}||dS)z Raise an option parsing error using parser.error(). Args: parser: an OptionParser instance. option: an Option instance. msg: the error text. z error:  N)textwrapfilljoinspliterror)rrrr$/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/cmdoptions.pyraise_option_error"s r&groupcCs,t||d}|dD]}||q |S)z Return an OptionGroup object group -- assumed to be dict with 'name' and 'options' keys parser -- an optparse Parser nameoptions)r add_option)r'r option_grouprr$r$r%make_option_group0s r,r) check_optionscs`dur|dtdttffdd }gd}tt||r.|j}|tjddd dSdS) zDisable wheels if per-setup.py call options are set. :param options: The OptionParser options to update. :param check_options: The options to check, if not supplied defaults to options. Nnrcs t|dSN)getattr)r.r-r$r%getnameH z+check_install_build_global..getname) build_optionsglobal_optionsinstall_optionszbDisabling all use of wheels due to the use of --build-option / --global-option / --install-option.) stacklevel) strr r anymapformat_controldisallow_binarieswarningswarn)r)r-r2namescontrolr$r1r%check_install_build_global<s  rBF check_targetcCsjt|j|j|j|jg}ttdh}|j|ko|j }|r$|r$t d|r/|r1|j s3t ddSdSdS)zFunction for determining if custom platform options are allowed. :param options: The OptionParser options. :param check_target: Whether or not to check if --target is being used. z:all:zWhen restricting platform and interpreter constraints using --python-version, --platform, --abi, or --implementation, either --no-deps must be set, or --only-binary=:all: must be set and --no-binary must not be set (or must be set to :none:).zQCan not use any platform or abi specific options unless installing via '--target'N) r:python_version platformsabisimplementationrsetr<ignore_dependenciesr target_dir)r)rCdist_restriction_set binary_onlysdist_dependencies_allowedr$r$r%check_dist_restrictionVs*  rNoptvaluecCs tj|Sr/)ospath expanduserrrOrPr$r$r%_path_option_check~r3rUcCst|Sr/rrTr$r$r%_package_name_option_checksrVc@s0eZdZejdZejZeed<eed<dS) PipOption)rR package_namerXrRN) __name__ __module__ __qualname__rTYPES TYPE_CHECKERcopyrVrUr$r$r$r%rWs    rWz-hz--helphelpz Show help.)destactionr_.help_z--debug debug_mode store_truezbLet unhandled exceptions propagate outside the main subroutine, instead of logging them to stderr.r`radefaultr_z --isolated isolated_modezSRun pip in an isolated mode, ignoring environment variables and user configuration.z--require-virtualenvz--require-venv require_venvrequire_virtualenvz-vz --verboseverbosecountzDGive more output. Option is additive, and can be used up to 3 times.z --no-colorno_colorzSuppress colored output.z-Vz --versionversionzShow version and exit.z-qz--quietquietzGive less output. Option is additive, and can be used up to 3 times (corresponding to WARNING, ERROR, and CRITICAL logging levels).z--progress-bar progress_barchoiceonz*Specify type of progress to be displayed [|z] (default: %default))r`typechoicesrfr_z--logz --log-filez --local-loglogrRz Path to a verbose appending log.)r`metavarrsr_z --no-inputno_inputzDisable prompting for input.z--proxyproxyr9z/src". The default for global installs is "/src".)r`rsrvrfrarr_srcrcCs t||jS)zGet a format_control object.)r0r`)rrr$r$r%_get_format_controls rcC"t|j|}t||j|jdSr/)rrrhandle_mutual_excludes no_binary only_binaryrrrPrexistingr$r$r%_handle_no_binary rcCrr/)rrrrrrrr$r$r%_handle_only_binaryrrc C$ttt}tdddtd|ddS)Nz --no-binaryr<rr9avDo not use binary packages. Can be supplied multiple times, and each time adds to the existing value. Accepts either ":all:" to disable all binary packages, ":none:" to empty the set (notice the colons), or one or more package names with commas between them (no colons). Note that some packages are tricky to compile and may fail to install when this option is used on them.r`rarrsrfr_)rrHrrr<r$r$r%rrc Cr)Nz --only-binaryr<rr9aKDo not use source packages. Can be supplied multiple times, and each time adds to the existing value. Accepts either ":all:" to disable all source packages, ":none:" to empty the set, or one or more package names with commas between them. Packages without binary distributions will fail to install when this option is used on them.r)rrHrrrr$r$r%rrrz --platformrEplatformrzOnly use wheels compatible with . Defaults to the platform of the running system. Use this option multiple times to specify multiple platforms supported by the target interpreter.rcCs|sdS|d}t|dkrdSt|dkr+|d}t|dkr+|d|ddg}ztdd |D}W|dfStyCYd Sw) z Convert a version string like "3", "37", or "3.7.3" into a tuple of ints. :return: A 2-tuple (version_info, error_msg), where `error_msg` is non-None if and only if there was a parsing error. )NN.)r$z'at most three version parts are allowedrNcss|]}t|VqdSr/)r{).0partr$r$r% 8sz*_convert_python_version..)r$z$each version part must be an integer)r"lentuple ValueError)rPparts version_infor$r$r%_convert_python_version"s     rcCs:t|\}}|durd||}t|||d||j_dS)z3 Handle a provided --python-version value. Nz(invalid --python-version value: {!r}: {}rr)rformatr&rrD)rrrPrr error_msgrr$r$r%_handle_python_version?s  rz--python-versionrDa The Python interpreter version to use for wheel and "Requires-Python" compatibility checks. Defaults to a version derived from the running interpreter. The version can be specified using up to three dot-separated integers (e.g. "3" for 3.0.0, "3.7" for 3.7.0, or "3.7.3"). A major-minor version can also be given as a string without dots (e.g. "37" for 3.7.0). )r`rvrarrsrfr_z--implementationrGzOnly use wheels compatible with Python implementation , e.g. 'pp', 'jy', 'cp', or 'ip'. If not specified, then the current interpreter implementation is used. Use 'py' to force implementation-agnostic wheels.z--abirFabiaLOnly use wheels compatible with Python abi , e.g. 'pypy_41'. If not specified, then the current interpreter abi tag is used. Use this option multiple times to specify multiple abis supported by the target interpreter. Generally you will need to specify --implementation, --platform, and --python-version when using this option.cmd_optscCs4|t|t|t|tdSr/)r*rErDrGrF)rr$r$r%add_target_python_optionss   rcCst|j|j|j|jd}|S)N)rEpy_version_inforFrG)rrErDrFrG)r) target_pythonr$r$r%make_target_pythonsrcCstddddddS)Nz--prefer-binary prefer_binaryrdFz8Prefer older binary packages over newer source packages.rerr$r$r$r%rsrz --cache-dir cache_dirzStore the cache data in .)r`rfrvrsr_c CsX|dur&zt|Wnty%}zt||t|dWYd}~nd}~wwd|j_dS)z Process a value provided for the --no-cache-dir option. This is an optparse.Option callback for the --no-cache-dir option. NrF)rrr&r9rr)rrOrPrexcr$r$r%_handle_no_cache_dirs   rz--no-cache-dirzDisable the cache.)r`rarr_no_cachez --no-depsz--no-dependenciesrIz#Don't install package dependencies.no_depsz--ignore-requires-pythonignore_requires_pythonz'Ignore the Requires-Python information.z--no-build-isolationbuild_isolation store_falseTzDisable isolation when building a modern source distribution. Build dependencies specified by PEP 518 must be already installed if this option is used.no_build_isolationcCs&|dur d}t|||dd|j_dS)z Process a value provided for the --no-use-pep517 option. This is an optparse.Option callback for the no_use_pep517 option. Na0A value was passed for --no-use-pep517, probably using either the PIP_NO_USE_PEP517 environment variable or the "no-use-pep517" config file option. Use an appropriate value of the PIP_USE_PEP517 environment variable or the "use-pep517" config file option instead. rF)r&r use_pep517)rrOrPrrr$r$r%_handle_no_use_pep517s  rz --use-pep517rz^Use PEP 517 for building source distributions (use --no-use-pep517 to force legacy behaviour).z--no-use-pep517)r`rarrfr_ no_use_pep517z--install-optionr6a"Extra arguments to be supplied to the setup.py install command (use like --install-option="--install-scripts=/usr/local/bin"). Use multiple --install-option options to pass multiple options to setup.py install. If you are using an option with a directory path, be sure to use absolute path.)r`rarvr_z--build-optionr4z9Extra arguments to be supplied to 'setup.py bdist_wheel'.)r`rvrar_z--global-optionr5zcExtra global options to be supplied to the setup.py call before the install or bdist_wheel command.z --no-cleanz!Don't clean up build directories.)rarfr_no_cleanz--prezYInclude pre-release and development versions. By default, pip only finds stable versions.prez--disable-pip-version-checkdisable_pip_version_checkz{Don't periodically check PyPI to determine whether a new version of pip is available for download. Implied with --no-index.cCs|jjsi|j_z |dd\}}Wnty#|d|Ynw|tvr4|d|dt|jj|g |dS)zkGiven a value spelled "algo:digest", append the digest to a list pointed to in a dict by the algo name.:rzTArguments to {} must be a hash name followed by a value, like --hash=sha256:abcde...z&Allowed hash algorithms for {} are {}.z, N) rhashesr"rr#rrr! setdefaultr)rrrPralgodigestr$r$r%_handle_merge_hash[s"  rz--hashrstringzgVerify that the package's archive matches this hash before installing. Example: --hash=sha256:abcdef...)r`rarrsr_hashz--require-hashesrequire_hasheszRequire a hash to check each requirement against, for repeatable installs. This option is implied when any package in a requirements file has a --hash option.z--pathz^Restrict to the specified installation path for listing packages (can be used multiple times).)r`rsrar_ list_pathcCs"|jr |js |jrtddSdS)Nz2Cannot combine '--path' with '--user' or '--local')rRuserlocalr)r)r$r$r%check_list_path_optionsrz --excludeexcludespackagerXz)Exclude specified package from the output)r`rarvrsr_ list_excludez--no-python-version-warningno_python_version_warningz>Silence deprecation warnings for upcoming unsupported Pythons.z --use-featurefeatures_enabledfeature)z 2020-resolverz fast-depsz in-tree-buildz functoolsroptparserrrrrrtypingr r r r r pip._vendor.packaging.utilsrpip._internal.cli.parserrpip._internal.cli.progress_barsrpip._internal.exceptionsrpip._internal.locationsrr#pip._internal.models.format_controlrpip._internal.models.indexr"pip._internal.models.target_pythonrpip._internal.utils.hashesrpip._internal.utils.miscrr9r&r,rBboolrNrUrVrWrb__annotations__rcrgrirjrlrmrnlistkeysr!rorurwrxrzr~rrr simple_urlrrrrrrrrrrrrrrrrEr{rrrDrGrFrrrrrrrrrrrrr6r4r5rrrrrrrrrrrrrrr$r$r$r%s              (                         &                       PKH]g˜Rpython3.10/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-310.pycnu[o ai6 @sdZddlZddlZddlmZmZddlmZddlm Z m Z ddl m Z m Z ddlmZddlmZmZd d gZd e fd d Zd eed eeeeffdd ZdS)z=A single place for constructing and exposing the main parser N)ListTuple) cmdoptions)ConfigOptionParserUpdatingDefaultsHelpFormatter) commands_dictget_similar_commands) CommandError)get_pip_versionget_progcreate_main_parser parse_commandreturncCsltddtdtd}|t|_ttj|}| |d|_ dgddt D}d ||_|S) z1Creates and returns the main parser for pip's CLIz %prog [options]Fglobal)usageadd_help_option formatternameprogTcSs"g|] \}}|dd|jqS)27 )summary).0r command_infor/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/main_parser.py 'sz&create_main_parser.. )rrr disable_interspersed_argsr versionrmake_option_group general_groupadd_option_groupmainritemsjoin description)parsergen_optsr'rrrr s"   argscCst}||\}}|jrtj|jtjtjt|r-|ddkr5t |dkr5| t|d}|t vrZt |}d|dg}|rS| d|dtd||dd}||||fS)Nrhelpzunknown command ""zmaybe you meant "z - )r parse_argsr sysstdoutwriteoslinesepexitlen print_helprrappendr r&remove)r*r(general_options args_elsecmd_nameguessmsgcmd_argsrrrr 0s&   )__doc__r2r/typingrrpip._internal.clirpip._internal.cli.parserrrpip._internal.commandsrrpip._internal.exceptionsr pip._internal.utils.miscr r __all__r strr rrrrs  &PKH]l3FFVpython3.10/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-310.pycnu[o ai@sBddlmZmZddlmZmZmZedddZGdddZdS) ) ExitStackcontextmanager)ContextManagerIteratorTypeVar_TT) covariantcsJeZdZd fdd ZededfddZdeedefdd Z Z S) CommandContextMixInreturnNcstd|_t|_dS)NF)super__init___in_main_contextr _main_contextself __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/command_context.pyr s  zCommandContextMixIn.__init__ccs`|jrJd|_z"|j dVWdn1swYWd|_dSWd|_dSd|_w)NTF)r rrrrr main_context s  z CommandContextMixIn.main_contextcontext_providercCs|jsJ|j|S)N)r r enter_context)rrrrrrs  z!CommandContextMixIn.enter_context)r N) __name__ __module__ __qualname__r rrrrrr __classcell__rrrrr s  r N) contextlibrrtypingrrrrr rrrrs PKH]Or~~Opython3.10/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-310.pycnu[o ai@sddlZddlZddlZddlZddlZddlmZmZddlm Z m Z ddl m Z ddl mZeeZGdddZGdd d eZGd d d eZGd d d ZejdedeefddZejdeededfddZdS)N)IOIterator) HIDE_CURSOR SHOW_CURSOR)WINDOWS)get_indentationc@s(eZdZdddZdeddfddZdS) SpinnerInterfacereturnNcCtNNotImplementedErrorselfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/spinners.pyspinzSpinnerInterface.spin final_statuscCr r r rrrrrfinishrzSpinnerInterface.finishr N)__name__ __module__ __qualname__rstrrrrrrrs rc @s`eZdZ   ddedeededefdd Zd ed dfd d ZdddZded dfddZ dS)InteractiveSpinnerN-\|/?messagefile spin_charsmin_update_interval_secondscCs\||_|dur tj}||_t||_d|_t||_ |j dt |jdd|_ dS)NF z ... r) _messagesysstdout_file RateLimiter _rate_limiter _finished itertoolscycle _spin_cyclewriter_width)rrr r!r"rrr__init__s   zInteractiveSpinner.__init__statusr cCs\|jrJd|j}|j|d|j||j|t||_|j|jdS)Nr#)r*r/r'r.lenflushr)reset)rr1backuprrr_write-s     zInteractiveSpinner._writecCs,|jrdS|js dS|t|jdSr )r*r)readyr7nextr-rrrrr9s  zInteractiveSpinner.spinrcCs4|jrdS|||jd|jd|_dS)N T)r*r7r'r.r4rrrrr@s     zInteractiveSpinner.finish)Nrrr) rrrrrfloatr0r7rrrrrrrs   rc@sReZdZddededdfddZdeddfd d Zdd d Zd eddfddZdS)NonInteractiveSpinnerN@rr"r NcCs$||_d|_t||_|ddS)NFstarted)r$r*r(r)_update)rrr"rrrr0Ns zNonInteractiveSpinner.__init__r1cCs(|jrJ|jtd|j|dS)Nz%s: %s)r*r)r5loggerinfor$)rr1rrrr?Ts  zNonInteractiveSpinner._updatecCs&|jrdS|js dS|ddS)Nzstill running...)r*r)r8r?rrrrrYs  zNonInteractiveSpinner.spinrcCs&|jrdS|d|dd|_dS)Nzfinished with status ''T)r*r?rrrrr`s zNonInteractiveSpinner.finish)r=r) rrrrr;r0r?rrrrrrr<Ms  r<c@s6eZdZdeddfddZdefddZd dd ZdS) r(r"r NcCs||_d|_dS)Nr)_min_update_interval_seconds _last_update)rr"rrrr0hs zRateLimiter.__init__cCst}||j}||jkSr )timerDrC)rnowdeltarrrr8ls  zRateLimiter.readycCst|_dSr )rErDrrrrr5qszRateLimiter.resetr)rrrr;r0boolr8r5rrrrr(gsr(rr ccstjrttjkrt|}nt|}zt tj |VWdn1s*wYWnt y=| dt yI| dw| ddS)Ncancelederrordone) r%r&isattyr@getEffectiveLevelloggingINFOrr< hidden_cursorKeyboardInterruptr Exception)rspinnerrrr open_spinnerus"      rTr c cs^trdVdS|rttjkrdVdS|tz dVW|tdS|twr ) rrLr@rMrNrOr.rr)r rrrrPs   rP) contextlibr+rNr%rEtypingrrZpip._vendor.progressrrpip._internal.utils.compatrpip._internal.utils.loggingr getLoggerrr@rrr<r(contextmanagerrrTrPrrrrs$   5 PKH]S[''Mpython3.10/site-packages/pip/_internal/cli/__pycache__/parser.cpython-310.pycnu[o ai$*@sdZddlZddlZddlZddlZddlZddlmZddlm Z m Z m Z m Z m Z ddlmZddlmZmZddlmZmZeeZGdd d ejZGd d d eZGd d d ejZGdddeZdS)zBase option parser setupN)suppress)AnyDictIteratorListTuple) UNKNOWN_ERROR) ConfigurationConfigurationError)redact_auth_from_url strtoboolc seZdZdZdededdffdd Zdejdefd d Z d!dejd ededefddZ dedefddZ dedefddZ dedefddZ dedefddZdededefdd ZZS)"PrettyHelpFormatterz4A prettier/less verbose help formatter for optparse.argskwargsreturnNcs:d|d<d|d<tdd|d<tj|i|dS)Nmax_help_positionindent_incrementrwidth)shutilget_terminal_sizesuper__init__)selfrr __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/cli/parser.pyrszPrettyHelpFormatter.__init__optioncCs ||SN)_format_option_strings)rr rrrformat_option_stringss z)PrettyHelpFormatter.format_option_strings <{}>, mvarfmtoptsepcCsg}|jr ||jd|jr||jdt|dkr$|d||rA|jdus/J|jp6|j}|| |d |S)z Return a comma-separated list of option strings and metavars. :param option: tuple of (short opt, long opt), e.g: ('-f', '--format') :param mvarfmt: metavar format string :param optsep: separator rrN) _short_optsappend _long_optsleninsert takes_valuedestmetavarlowerformatjoin)rr r&r'optsr0rrrr"s    z*PrettyHelpFormatter._format_option_stringsheadingcCs|dkrdS|dS)NOptionsr(: r)rr5rrrformat_heading9sz"PrettyHelpFormatter.format_headingusagecCsd|t|d}|S)zz Ensure there is only one newline between usage and the first heading if there is no description. z Usage: {}  )r2 indent_linestextwrapdedent)rr9msgrrr format_usage>sz PrettyHelpFormatter.format_usage descriptioncCsV|r)t|jdr d}nd}|d}|}|t|d}|d|d}|SdS)NmainCommands Description r:r7r()hasattrparserlstriprstripr;r<r=)rr@labelrrrformat_descriptionFs  z&PrettyHelpFormatter.format_descriptionepilogcCs |r|SdS)Nr(r)rrKrrr format_epilogXsz!PrettyHelpFormatter.format_epilogtextindentcs"fdd|dD}d|S)Ncsg|]}|qSrr).0linerNrr `sz4PrettyHelpFormatter.indent_lines..rD)splitr3)rrMrN new_linesrrQrr;_s z PrettyHelpFormatter.indent_lines)r$r%)__name__ __module__ __qualname____doc__rroptparseOptionstrr#r"r8r?rJrLr; __classcell__rrrrr s& r cs,eZdZdZdejdeffdd ZZS)UpdatingDefaultsHelpFormatterzCustom help formatter for use in ConfigOptionParser. This is updates the defaults before expanding them, allowing them to show up correctly in the help listing. Also redact auth from url type options r rcsd}|jdur&t|jtsJ|j|jj|jdusJ|jj|j}t|}|rO|j dkrOt|t r;|g}t|t sBg}|D] }| |t |}qD|S)NURL)rF isinstanceConfigOptionParser_update_defaultsdefaultsr/getrexpand_defaultr0r[listreplacer )rr default_values help_textvalrrrrdms    z,UpdatingDefaultsHelpFormatter.expand_default) rUrVrWrXrYrZr[rdr\rrrrr]ds r]c@s@eZdZdedededejfddZede ej fddZ d S) CustomOptionParseridxrrrcOs,|j|i|}|j|j|||S)z*Insert an OptionGroup at a given position.)add_option_group option_groupspopr-)rrkrrgrouprrrinsert_option_groups z&CustomOptionParser.insert_option_groupcCs*|jdd}|jD]}||jq |S)zq8dS)Nglobalz:env:cSsi|]}|gqSrr)rOrzrrr szGConfigOptionParser._get_ordered_configuration_items..z7Ignoring configuration key '%s' as it's value is empty..r)rzr{itemsloggerdebugrSr*)roverride_order section_items section_keyrisectionr|rrr _get_ordered_configuration_itemss*  z3ConfigOptionParser._get_ordered_configuration_itemsrbc stj_t}D]\}ddurqjdus%JjdvrCzt |}Wnt yB d |Ynwjdkrt t  t |}Wdn1s[wYt t  t|}Wdn1sswYt|tr|dkr d |nRjdkr|}fd d |D}n=jd krֈjdusJ|j}||}jpd }jpi}j||g|Ri|n|}||j<q|D] tj|<qd_|S) zUpdates the given defaults with values from the config files and the environ. Does a little special handling for certain types of options (lists).z--N) store_true store_falsezm{} is not a valid value for {} option, please specify a boolean value like yes/no, true/false or 1/0 instead.countrz{} is not a valid value for {} option, please instead specify either a non-negative integer or a boolean value like yes/no or false/true which is equivalent to 1/0.r*csg|] }|qSr)r)rOvr|r rrrrRsz7ConfigOptionParser._update_defaults..callbackr)rYValuesrbvaluessetr get_optionr/actionr ValueErrorerrorr2rrvr_rSraddget_opt_string convert_value callback_argscallback_kwargsrgetattr)rrb late_evalriopt_strrrrrrras\                z#ConfigOptionParser._update_defaultsc Cs|js t|jSz|jWnty*}z|tt |WYd}~nd}~ww| |j }| D]!}|j dus@J||j }t|t rX|}|||||j <q7t|S)zOverriding to make updating the defaults after instantiation of the option parser possible, _update_defaults() does the dirty work.N)process_default_valuesrYrrbr{loadr rrr[racopy_get_all_optionsr/rcr_rr~)rerrrbr defaultrrrrget_default_values s"     z%ConfigOptionParser.get_default_valuesr>cCs"|tj|t|ddS)NrD) print_usagerstderrrr)rr>rrrr"s zConfigOptionParser.error)rUrVrWrXrr[boolrrYrZrrrrrrarrrr\rrrrr`s& "@r`)rXloggingrYrrr< contextlibrtypingrrrrrpip._internal.cli.status_codesrpip._internal.configurationr r pip._internal.utils.miscr r getLoggerrUrIndentedHelpFormatterr r] OptionParserrjr`rrrrs    R PKH]$%6python3.10/site-packages/pip/_internal/cli/spinners.pynu[import contextlib import itertools import logging import sys import time from typing import IO, Iterator from pip._vendor.progress import HIDE_CURSOR, SHOW_CURSOR from pip._internal.utils.compat import WINDOWS from pip._internal.utils.logging import get_indentation logger = logging.getLogger(__name__) class SpinnerInterface: def spin(self) -> None: raise NotImplementedError() def finish(self, final_status: str) -> None: raise NotImplementedError() class InteractiveSpinner(SpinnerInterface): def __init__( self, message: str, file: IO[str] = None, spin_chars: str = "-\\|/", # Empirically, 8 updates/second looks nice min_update_interval_seconds: float = 0.125, ): self._message = message if file is None: file = sys.stdout self._file = file self._rate_limiter = RateLimiter(min_update_interval_seconds) self._finished = False self._spin_cycle = itertools.cycle(spin_chars) self._file.write(" " * get_indentation() + self._message + " ... ") self._width = 0 def _write(self, status: str) -> None: assert not self._finished # Erase what we wrote before by backspacing to the beginning, writing # spaces to overwrite the old text, and then backspacing again backup = "\b" * self._width self._file.write(backup + " " * self._width + backup) # Now we have a blank slate to add our status self._file.write(status) self._width = len(status) self._file.flush() self._rate_limiter.reset() def spin(self) -> None: if self._finished: return if not self._rate_limiter.ready(): return self._write(next(self._spin_cycle)) def finish(self, final_status: str) -> None: if self._finished: return self._write(final_status) self._file.write("\n") self._file.flush() self._finished = True # Used for dumb terminals, non-interactive installs (no tty), etc. # We still print updates occasionally (once every 60 seconds by default) to # act as a keep-alive for systems like Travis-CI that take lack-of-output as # an indication that a task has frozen. class NonInteractiveSpinner(SpinnerInterface): def __init__(self, message: str, min_update_interval_seconds: float = 60.0) -> None: self._message = message self._finished = False self._rate_limiter = RateLimiter(min_update_interval_seconds) self._update("started") def _update(self, status: str) -> None: assert not self._finished self._rate_limiter.reset() logger.info("%s: %s", self._message, status) def spin(self) -> None: if self._finished: return if not self._rate_limiter.ready(): return self._update("still running...") def finish(self, final_status: str) -> None: if self._finished: return self._update(f"finished with status '{final_status}'") self._finished = True class RateLimiter: def __init__(self, min_update_interval_seconds: float) -> None: self._min_update_interval_seconds = min_update_interval_seconds self._last_update: float = 0 def ready(self) -> bool: now = time.time() delta = now - self._last_update return delta >= self._min_update_interval_seconds def reset(self) -> None: self._last_update = time.time() @contextlib.contextmanager def open_spinner(message: str) -> Iterator[SpinnerInterface]: # Interactive spinner goes directly to sys.stdout rather than being routed # through the logging system, but it acts like it has level INFO, # i.e. it's only displayed if we're at level INFO or better. # Non-interactive spinner goes through the logging system, so it is always # in sync with logging configuration. if sys.stdout.isatty() and logger.getEffectiveLevel() <= logging.INFO: spinner: SpinnerInterface = InteractiveSpinner(message) else: spinner = NonInteractiveSpinner(message) try: with hidden_cursor(sys.stdout): yield spinner except KeyboardInterrupt: spinner.finish("canceled") raise except Exception: spinner.finish("error") raise else: spinner.finish("done") @contextlib.contextmanager def hidden_cursor(file: IO[str]) -> Iterator[None]: # The Windows terminal does not support the hide/show cursor ANSI codes, # even via colorama. So don't even try. if WINDOWS: yield # We don't want to clutter the output with control characters if we're # writing to a file, or if the user is running with --quiet. # See https://github.com/pypa/pip/issues/3418 elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO: yield else: file.write(HIDE_CURSOR) try: yield finally: file.write(SHOW_CURSOR) PKH]vnn:python3.10/site-packages/pip/_internal/cli/base_command.pynu["""Base Command class, and related routines""" import functools import logging import logging.config import optparse import os import sys import traceback from optparse import Values from typing import Any, Callable, List, Optional, Tuple from pip._internal.cli import cmdoptions from pip._internal.cli.command_context import CommandContextMixIn from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter from pip._internal.cli.status_codes import ( ERROR, PREVIOUS_BUILD_DIR_ERROR, UNKNOWN_ERROR, VIRTUALENV_NOT_FOUND, ) from pip._internal.exceptions import ( BadCommand, CommandError, InstallationError, NetworkConnectionError, PreviousBuildDirError, UninstallationError, ) from pip._internal.utils.filesystem import check_path_owner from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging from pip._internal.utils.misc import get_prog, normalize_path from pip._internal.utils.temp_dir import TempDirectoryTypeRegistry as TempDirRegistry from pip._internal.utils.temp_dir import global_tempdir_manager, tempdir_registry from pip._internal.utils.virtualenv import running_under_virtualenv __all__ = ["Command"] logger = logging.getLogger(__name__) class Command(CommandContextMixIn): usage: str = "" ignore_require_venv: bool = False def __init__(self, name: str, summary: str, isolated: bool = False) -> None: super().__init__() self.name = name self.summary = summary self.parser = ConfigOptionParser( usage=self.usage, prog=f"{get_prog()} {name}", formatter=UpdatingDefaultsHelpFormatter(), add_help_option=False, name=name, description=self.__doc__, isolated=isolated, ) self.tempdir_registry: Optional[TempDirRegistry] = None # Commands should add options to this option group optgroup_name = f"{self.name.capitalize()} Options" self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) # Add the general options gen_opts = cmdoptions.make_option_group( cmdoptions.general_group, self.parser, ) self.parser.add_option_group(gen_opts) self.add_options() def add_options(self) -> None: pass def handle_pip_version_check(self, options: Values) -> None: """ This is a no-op so that commands by default do not do the pip version check. """ # Make sure we do the pip version check if the index_group options # are present. assert not hasattr(options, "no_index") def run(self, options: Values, args: List[str]) -> int: raise NotImplementedError def parse_args(self, args: List[str]) -> Tuple[Values, List[str]]: # factored out for testability return self.parser.parse_args(args) def main(self, args: List[str]) -> int: try: with self.main_context(): return self._main(args) finally: logging.shutdown() def _main(self, args: List[str]) -> int: # We must initialize this before the tempdir manager, otherwise the # configuration would not be accessible by the time we clean up the # tempdir manager. self.tempdir_registry = self.enter_context(tempdir_registry()) # Intentionally set as early as possible so globally-managed temporary # directories are available to the rest of the code. self.enter_context(global_tempdir_manager()) options, args = self.parse_args(args) # Set verbosity so that it can be used elsewhere. self.verbosity = options.verbose - options.quiet level_number = setup_logging( verbosity=self.verbosity, no_color=options.no_color, user_log_file=options.log, ) # TODO: Try to get these passing down from the command? # without resorting to os.environ to hold these. # This also affects isolated builds and it should. if options.no_input: os.environ["PIP_NO_INPUT"] = "1" if options.exists_action: os.environ["PIP_EXISTS_ACTION"] = " ".join(options.exists_action) if options.require_venv and not self.ignore_require_venv: # If a venv is required check if it can really be found if not running_under_virtualenv(): logger.critical("Could not find an activated virtualenv (required).") sys.exit(VIRTUALENV_NOT_FOUND) if options.cache_dir: options.cache_dir = normalize_path(options.cache_dir) if not check_path_owner(options.cache_dir): logger.warning( "The directory '%s' or its parent directory is not owned " "or is not writable by the current user. The cache " "has been disabled. Check the permissions and owner of " "that directory. If executing pip with sudo, you should " "use sudo's -H flag.", options.cache_dir, ) options.cache_dir = None if "2020-resolver" in options.features_enabled: logger.warning( "--use-feature=2020-resolver no longer has any effect, " "since it is now the default dependency resolver in pip. " "This will become an error in pip 21.0." ) def intercepts_unhandled_exc( run_func: Callable[..., int] ) -> Callable[..., int]: @functools.wraps(run_func) def exc_logging_wrapper(*args: Any) -> int: try: status = run_func(*args) assert isinstance(status, int) return status except PreviousBuildDirError as exc: logger.critical(str(exc)) logger.debug("Exception information:", exc_info=True) return PREVIOUS_BUILD_DIR_ERROR except ( InstallationError, UninstallationError, BadCommand, NetworkConnectionError, ) as exc: logger.critical(str(exc)) logger.debug("Exception information:", exc_info=True) return ERROR except CommandError as exc: logger.critical("%s", exc) logger.debug("Exception information:", exc_info=True) return ERROR except BrokenStdoutLoggingError: # Bypass our logger and write any remaining messages to # stderr because stdout no longer works. print("ERROR: Pipe to stdout was broken", file=sys.stderr) if level_number <= logging.DEBUG: traceback.print_exc(file=sys.stderr) return ERROR except KeyboardInterrupt: logger.critical("Operation cancelled by user") logger.debug("Exception information:", exc_info=True) return ERROR except BaseException: logger.critical("Exception:", exc_info=True) return UNKNOWN_ERROR return exc_logging_wrapper try: if not options.debug_mode: run = intercepts_unhandled_exc(self.run) else: run = self.run return run(options, args) finally: self.handle_pip_version_check(options) PKH]jYd| 2python3.10/site-packages/pip/_internal/cli/main.pynu["""Primary application entrypoint. """ import locale import logging import os import sys from typing import List, Optional from pip._internal.cli.autocompletion import autocomplete from pip._internal.cli.main_parser import parse_command from pip._internal.commands import create_command from pip._internal.exceptions import PipError from pip._internal.utils import deprecation logger = logging.getLogger(__name__) # Do not import and use main() directly! Using it directly is actively # discouraged by pip's maintainers. The name, location and behavior of # this function is subject to change, so calling it directly is not # portable across different pip versions. # In addition, running pip in-process is unsupported and unsafe. This is # elaborated in detail at # https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program. # That document also provides suggestions that should work for nearly # all users that are considering importing and using main() directly. # However, we know that certain users will still want to invoke pip # in-process. If you understand and accept the implications of using pip # in an unsupported manner, the best approach is to use runpy to avoid # depending on the exact location of this entry point. # The following example shows how to use runpy to invoke pip in that # case: # # sys.argv = ["pip", your, args, here] # runpy.run_module("pip", run_name="__main__") # # Note that this will exit the process after running, unlike a direct # call to main. As it is not safe to do any processing after calling # main, this should not be an issue in practice. def main(args: Optional[List[str]] = None) -> int: if args is None: args = sys.argv[1:] # Configure our deprecation warnings to be sent through loggers deprecation.install_warning_logger() autocomplete() try: cmd_name, cmd_args = parse_command(args) except PipError as exc: sys.stderr.write(f"ERROR: {exc}") sys.stderr.write(os.linesep) sys.exit(1) # Needed for locale.getpreferredencoding(False) to work # in pip._internal.utils.encoding.auto_decode try: locale.setlocale(locale.LC_ALL, "") except locale.Error as e: # setlocale can apparently crash if locale are uninitialized logger.debug("Ignoring error %s when setting locale", e) command = create_command(cmd_name, isolated=("--isolated" in cmd_args)) return command.main(cmd_args) PKH]o6 6 9python3.10/site-packages/pip/_internal/cli/main_parser.pynu["""A single place for constructing and exposing the main parser """ import os import sys from typing import List, Tuple from pip._internal.cli import cmdoptions from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter from pip._internal.commands import commands_dict, get_similar_commands from pip._internal.exceptions import CommandError from pip._internal.utils.misc import get_pip_version, get_prog __all__ = ["create_main_parser", "parse_command"] def create_main_parser() -> ConfigOptionParser: """Creates and returns the main parser for pip's CLI""" parser = ConfigOptionParser( usage="\n%prog [options]", add_help_option=False, formatter=UpdatingDefaultsHelpFormatter(), name="global", prog=get_prog(), ) parser.disable_interspersed_args() parser.version = get_pip_version() # add the general options gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) parser.add_option_group(gen_opts) # so the help formatter knows parser.main = True # type: ignore # create command listing for description description = [""] + [ f"{name:27} {command_info.summary}" for name, command_info in commands_dict.items() ] parser.description = "\n".join(description) return parser def parse_command(args: List[str]) -> Tuple[str, List[str]]: parser = create_main_parser() # Note: parser calls disable_interspersed_args(), so the result of this # call is to split the initial args into the general options before the # subcommand and everything else. # For example: # args: ['--timeout=5', 'install', '--user', 'INITools'] # general_options: ['--timeout==5'] # args_else: ['install', '--user', 'INITools'] general_options, args_else = parser.parse_args(args) # --version if general_options.version: sys.stdout.write(parser.version) sys.stdout.write(os.linesep) sys.exit() # pip || pip help -> print_help() if not args_else or (args_else[0] == "help" and len(args_else) == 1): parser.print_help() sys.exit() # the subcommand name cmd_name = args_else[0] if cmd_name not in commands_dict: guess = get_similar_commands(cmd_name) msg = [f'unknown command "{cmd_name}"'] if guess: msg.append(f'maybe you meant "{guess}"') raise CommandError(" - ".join(msg)) # all the args without the subcommand cmd_args = args[:] cmd_args.remove(cmd_name) return cmd_name, cmd_args PKH]ñ$*$*4python3.10/site-packages/pip/_internal/cli/parser.pynu["""Base option parser setup""" import logging import optparse import shutil import sys import textwrap from contextlib import suppress from typing import Any, Dict, Iterator, List, Tuple from pip._internal.cli.status_codes import UNKNOWN_ERROR from pip._internal.configuration import Configuration, ConfigurationError from pip._internal.utils.misc import redact_auth_from_url, strtobool logger = logging.getLogger(__name__) class PrettyHelpFormatter(optparse.IndentedHelpFormatter): """A prettier/less verbose help formatter for optparse.""" def __init__(self, *args: Any, **kwargs: Any) -> None: # help position must be aligned with __init__.parseopts.description kwargs["max_help_position"] = 30 kwargs["indent_increment"] = 1 kwargs["width"] = shutil.get_terminal_size()[0] - 2 super().__init__(*args, **kwargs) def format_option_strings(self, option: optparse.Option) -> str: return self._format_option_strings(option) def _format_option_strings( self, option: optparse.Option, mvarfmt: str = " <{}>", optsep: str = ", " ) -> str: """ Return a comma-separated list of option strings and metavars. :param option: tuple of (short opt, long opt), e.g: ('-f', '--format') :param mvarfmt: metavar format string :param optsep: separator """ opts = [] if option._short_opts: opts.append(option._short_opts[0]) if option._long_opts: opts.append(option._long_opts[0]) if len(opts) > 1: opts.insert(1, optsep) if option.takes_value(): assert option.dest is not None metavar = option.metavar or option.dest.lower() opts.append(mvarfmt.format(metavar.lower())) return "".join(opts) def format_heading(self, heading: str) -> str: if heading == "Options": return "" return heading + ":\n" def format_usage(self, usage: str) -> str: """ Ensure there is only one newline between usage and the first heading if there is no description. """ msg = "\nUsage: {}\n".format(self.indent_lines(textwrap.dedent(usage), " ")) return msg def format_description(self, description: str) -> str: # leave full control over description to us if description: if hasattr(self.parser, "main"): label = "Commands" else: label = "Description" # some doc strings have initial newlines, some don't description = description.lstrip("\n") # some doc strings have final newlines and spaces, some don't description = description.rstrip() # dedent, then reindent description = self.indent_lines(textwrap.dedent(description), " ") description = f"{label}:\n{description}\n" return description else: return "" def format_epilog(self, epilog: str) -> str: # leave full control over epilog to us if epilog: return epilog else: return "" def indent_lines(self, text: str, indent: str) -> str: new_lines = [indent + line for line in text.split("\n")] return "\n".join(new_lines) class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): """Custom help formatter for use in ConfigOptionParser. This is updates the defaults before expanding them, allowing them to show up correctly in the help listing. Also redact auth from url type options """ def expand_default(self, option: optparse.Option) -> str: default_values = None if self.parser is not None: assert isinstance(self.parser, ConfigOptionParser) self.parser._update_defaults(self.parser.defaults) assert option.dest is not None default_values = self.parser.defaults.get(option.dest) help_text = super().expand_default(option) if default_values and option.metavar == "URL": if isinstance(default_values, str): default_values = [default_values] # If its not a list, we should abort and just return the help text if not isinstance(default_values, list): default_values = [] for val in default_values: help_text = help_text.replace(val, redact_auth_from_url(val)) return help_text class CustomOptionParser(optparse.OptionParser): def insert_option_group( self, idx: int, *args: Any, **kwargs: Any ) -> optparse.OptionGroup: """Insert an OptionGroup at a given position.""" group = self.add_option_group(*args, **kwargs) self.option_groups.pop() self.option_groups.insert(idx, group) return group @property def option_list_all(self) -> List[optparse.Option]: """Get a list of all options, including those in option groups.""" res = self.option_list[:] for i in self.option_groups: res.extend(i.option_list) return res class ConfigOptionParser(CustomOptionParser): """Custom option parser which updates its defaults by checking the configuration files and environmental variables""" def __init__( self, *args: Any, name: str, isolated: bool = False, **kwargs: Any, ) -> None: self.name = name self.config = Configuration(isolated) assert self.name super().__init__(*args, **kwargs) def check_default(self, option: optparse.Option, key: str, val: Any) -> Any: try: return option.check_value(key, val) except optparse.OptionValueError as exc: print(f"An error occurred during configuration: {exc}") sys.exit(3) def _get_ordered_configuration_items(self) -> Iterator[Tuple[str, Any]]: # Configuration gives keys in an unordered manner. Order them. override_order = ["global", self.name, ":env:"] # Pool the options into different groups section_items: Dict[str, List[Tuple[str, Any]]] = { name: [] for name in override_order } for section_key, val in self.config.items(): # ignore empty values if not val: logger.debug( "Ignoring configuration key '%s' as it's value is empty.", section_key, ) continue section, key = section_key.split(".", 1) if section in override_order: section_items[section].append((key, val)) # Yield each group in their override order for section in override_order: for key, val in section_items[section]: yield key, val def _update_defaults(self, defaults: Dict[str, Any]) -> Dict[str, Any]: """Updates the given defaults with values from the config files and the environ. Does a little special handling for certain types of options (lists).""" # Accumulate complex default state. self.values = optparse.Values(self.defaults) late_eval = set() # Then set the options with those values for key, val in self._get_ordered_configuration_items(): # '--' because configuration supports only long names option = self.get_option("--" + key) # Ignore options not present in this parser. E.g. non-globals put # in [global] by users that want them to apply to all applicable # commands. if option is None: continue assert option.dest is not None if option.action in ("store_true", "store_false"): try: val = strtobool(val) except ValueError: self.error( "{} is not a valid value for {} option, " # noqa "please specify a boolean value like yes/no, " "true/false or 1/0 instead.".format(val, key) ) elif option.action == "count": with suppress(ValueError): val = strtobool(val) with suppress(ValueError): val = int(val) if not isinstance(val, int) or val < 0: self.error( "{} is not a valid value for {} option, " # noqa "please instead specify either a non-negative integer " "or a boolean value like yes/no or false/true " "which is equivalent to 1/0.".format(val, key) ) elif option.action == "append": val = val.split() val = [self.check_default(option, key, v) for v in val] elif option.action == "callback": assert option.callback is not None late_eval.add(option.dest) opt_str = option.get_opt_string() val = option.convert_value(opt_str, val) # From take_action args = option.callback_args or () kwargs = option.callback_kwargs or {} option.callback(option, opt_str, val, self, *args, **kwargs) else: val = self.check_default(option, key, val) defaults[option.dest] = val for key in late_eval: defaults[key] = getattr(self.values, key) self.values = None return defaults def get_default_values(self) -> optparse.Values: """Overriding to make updating the defaults after instantiation of the option parser possible, _update_defaults() does the dirty work.""" if not self.process_default_values: # Old, pre-Optik 1.5 behaviour. return optparse.Values(self.defaults) # Load the configuration, or error out in case of an error try: self.config.load() except ConfigurationError as err: self.exit(UNKNOWN_ERROR, str(err)) defaults = self._update_defaults(self.defaults.copy()) # ours for option in self._get_all_options(): assert option.dest is not None default = defaults.get(option.dest) if isinstance(default, str): opt_str = option.get_opt_string() defaults[option.dest] = option.check_value(opt_str, default) return optparse.Values(defaults) def error(self, msg: str) -> None: self.print_usage(sys.stderr) self.exit(UNKNOWN_ERROR, f"{msg}\n") PKH]zKtt:python3.10/site-packages/pip/_internal/cli/status_codes.pynu[SUCCESS = 0 ERROR = 1 UNKNOWN_ERROR = 2 VIRTUALENV_NOT_FOUND = 3 PREVIOUS_BUILD_DIR_ERROR = 4 NO_MATCHES_FOUND = 23 PKH]p<python3.10/site-packages/pip/_internal/cli/autocompletion.pynu["""Logic that powers autocompletion installed by ``pip completion``. """ import optparse import os import sys from itertools import chain from typing import Any, Iterable, List, Optional from pip._internal.cli.main_parser import create_main_parser from pip._internal.commands import commands_dict, create_command from pip._internal.metadata import get_default_environment def autocomplete() -> None: """Entry Point for completion of main and subcommand options.""" # Don't complete if user hasn't sourced bash_completion file. if "PIP_AUTO_COMPLETE" not in os.environ: return cwords = os.environ["COMP_WORDS"].split()[1:] cword = int(os.environ["COMP_CWORD"]) try: current = cwords[cword - 1] except IndexError: current = "" parser = create_main_parser() subcommands = list(commands_dict) options = [] # subcommand subcommand_name: Optional[str] = None for word in cwords: if word in subcommands: subcommand_name = word break # subcommand options if subcommand_name is not None: # special case: 'help' subcommand has no options if subcommand_name == "help": sys.exit(1) # special case: list locally installed dists for show and uninstall should_list_installed = not current.startswith("-") and subcommand_name in [ "show", "uninstall", ] if should_list_installed: env = get_default_environment() lc = current.lower() installed = [ dist.canonical_name for dist in env.iter_installed_distributions(local_only=True) if dist.canonical_name.startswith(lc) and dist.canonical_name not in cwords[1:] ] # if there are no dists installed, fall back to option completion if installed: for dist in installed: print(dist) sys.exit(1) subcommand = create_command(subcommand_name) for opt in subcommand.parser.option_list_all: if opt.help != optparse.SUPPRESS_HELP: for opt_str in opt._long_opts + opt._short_opts: options.append((opt_str, opt.nargs)) # filter out previously specified options from available options prev_opts = [x.split("=")[0] for x in cwords[1 : cword - 1]] options = [(x, v) for (x, v) in options if x not in prev_opts] # filter options by current input options = [(k, v) for k, v in options if k.startswith(current)] # get completion type given cwords and available subcommand options completion_type = get_path_completion_type( cwords, cword, subcommand.parser.option_list_all, ) # get completion files and directories if ``completion_type`` is # ````, ```` or ```` if completion_type: paths = auto_complete_paths(current, completion_type) options = [(path, 0) for path in paths] for option in options: opt_label = option[0] # append '=' to options which require args if option[1] and option[0][:2] == "--": opt_label += "=" print(opt_label) else: # show main parser options only when necessary opts = [i.option_list for i in parser.option_groups] opts.append(parser.option_list) flattened_opts = chain.from_iterable(opts) if current.startswith("-"): for opt in flattened_opts: if opt.help != optparse.SUPPRESS_HELP: subcommands += opt._long_opts + opt._short_opts else: # get completion type given cwords and all available options completion_type = get_path_completion_type(cwords, cword, flattened_opts) if completion_type: subcommands = list(auto_complete_paths(current, completion_type)) print(" ".join([x for x in subcommands if x.startswith(current)])) sys.exit(1) def get_path_completion_type( cwords: List[str], cword: int, opts: Iterable[Any] ) -> Optional[str]: """Get the type of path completion (``file``, ``dir``, ``path`` or None) :param cwords: same as the environmental variable ``COMP_WORDS`` :param cword: same as the environmental variable ``COMP_CWORD`` :param opts: The available options to check :return: path completion type (``file``, ``dir``, ``path`` or None) """ if cword < 2 or not cwords[cword - 2].startswith("-"): return None for opt in opts: if opt.help == optparse.SUPPRESS_HELP: continue for o in str(opt).split("/"): if cwords[cword - 2].split("=")[0] == o: if not opt.metavar or any( x in ("path", "file", "dir") for x in opt.metavar.split("/") ): return opt.metavar return None def auto_complete_paths(current: str, completion_type: str) -> Iterable[str]: """If ``completion_type`` is ``file`` or ``path``, list all regular files and directories starting with ``current``; otherwise only list directories starting with ``current``. :param current: The word to be completed :param completion_type: path completion type(`file`, `path` or `dir`)i :return: A generator of regular files and/or directories """ directory, filename = os.path.split(current) current_path = os.path.abspath(directory) # Don't complete paths if they can't be accessed if not os.access(current_path, os.R_OK): return filename = os.path.normcase(filename) # list all files that start with ``filename`` file_list = ( x for x in os.listdir(current_path) if os.path.normcase(x).startswith(filename) ) for f in file_list: opt = os.path.join(current_path, f) comp_file = os.path.normcase(os.path.join(directory, f)) # complete regular files when there is not ```` after option # complete directories when there is ````, ```` or # ````after option if completion_type != "dir" and os.path.isfile(opt): yield comp_file elif os.path.isdir(opt): yield os.path.join(comp_file, "") PKH]%BB9python3.10/site-packages/pip/_internal/cli/req_command.pynu["""Contains the Command base classes that depend on PipSession. The classes in this module are in a separate module so the commands not needing download / PackageFinder capability don't unnecessarily import the PackageFinder machinery and all its vendored dependencies, etc. """ import logging import os import sys from functools import partial from optparse import Values from typing import Any, List, Optional, Tuple from pip._internal.cache import WheelCache from pip._internal.cli import cmdoptions from pip._internal.cli.base_command import Command from pip._internal.cli.command_context import CommandContextMixIn from pip._internal.exceptions import CommandError, PreviousBuildDirError from pip._internal.index.collector import LinkCollector from pip._internal.index.package_finder import PackageFinder from pip._internal.models.selection_prefs import SelectionPreferences from pip._internal.models.target_python import TargetPython from pip._internal.network.session import PipSession from pip._internal.operations.prepare import RequirementPreparer from pip._internal.req.constructors import ( install_req_from_editable, install_req_from_line, install_req_from_parsed_requirement, install_req_from_req_string, ) from pip._internal.req.req_file import parse_requirements from pip._internal.req.req_install import InstallRequirement from pip._internal.req.req_tracker import RequirementTracker from pip._internal.resolution.base import BaseResolver from pip._internal.self_outdated_check import pip_self_version_check from pip._internal.utils.deprecation import deprecated from pip._internal.utils.temp_dir import ( TempDirectory, TempDirectoryTypeRegistry, tempdir_kinds, ) from pip._internal.utils.virtualenv import running_under_virtualenv logger = logging.getLogger(__name__) class SessionCommandMixin(CommandContextMixIn): """ A class mixin for command classes needing _build_session(). """ def __init__(self) -> None: super().__init__() self._session: Optional[PipSession] = None @classmethod def _get_index_urls(cls, options: Values) -> Optional[List[str]]: """Return a list of index urls from user-provided options.""" index_urls = [] if not getattr(options, "no_index", False): url = getattr(options, "index_url", None) if url: index_urls.append(url) urls = getattr(options, "extra_index_urls", None) if urls: index_urls.extend(urls) # Return None rather than an empty list return index_urls or None def get_default_session(self, options: Values) -> PipSession: """Get a default-managed session.""" if self._session is None: self._session = self.enter_context(self._build_session(options)) # there's no type annotation on requests.Session, so it's # automatically ContextManager[Any] and self._session becomes Any, # then https://github.com/python/mypy/issues/7696 kicks in assert self._session is not None return self._session def _build_session( self, options: Values, retries: Optional[int] = None, timeout: Optional[int] = None, ) -> PipSession: assert not options.cache_dir or os.path.isabs(options.cache_dir) session = PipSession( cache=( os.path.join(options.cache_dir, "http") if options.cache_dir else None ), retries=retries if retries is not None else options.retries, trusted_hosts=options.trusted_hosts, index_urls=self._get_index_urls(options), ) # Handle custom ca-bundles from the user if options.cert: session.verify = options.cert # Handle SSL client certificate if options.client_cert: session.cert = options.client_cert # Handle timeouts if options.timeout or timeout: session.timeout = timeout if timeout is not None else options.timeout # Handle configured proxies if options.proxy: session.proxies = { "http": options.proxy, "https": options.proxy, } # Determine if we can prompt the user for authentication or not session.auth.prompting = not options.no_input return session class IndexGroupCommand(Command, SessionCommandMixin): """ Abstract base class for commands with the index_group options. This also corresponds to the commands that permit the pip version check. """ def handle_pip_version_check(self, options: Values) -> None: """ Do the pip version check if not disabled. This overrides the default behavior of not doing the check. """ # Make sure the index_group options are present. assert hasattr(options, "no_index") if options.disable_pip_version_check or options.no_index: return # Otherwise, check if we're using the latest version of pip available. session = self._build_session( options, retries=0, timeout=min(5, options.timeout) ) with session: pip_self_version_check(session, options) KEEPABLE_TEMPDIR_TYPES = [ tempdir_kinds.BUILD_ENV, tempdir_kinds.EPHEM_WHEEL_CACHE, tempdir_kinds.REQ_BUILD, ] def warn_if_run_as_root() -> None: """Output a warning for sudo users on Unix. In a virtual environment, sudo pip still writes to virtualenv. On Windows, users may run pip as Administrator without issues. This warning only applies to Unix root users outside of virtualenv. """ if running_under_virtualenv(): return if not hasattr(os, "getuid"): return # On Windows, there are no "system managed" Python packages. Installing as # Administrator via pip is the correct way of updating system environments. # # We choose sys.platform over utils.compat.WINDOWS here to enable Mypy platform # checks: https://mypy.readthedocs.io/en/stable/common_issues.html if sys.platform == "win32" or sys.platform == "cygwin": return if os.getuid() != 0: return logger.warning( "Running pip as the 'root' user can result in broken permissions and " "conflicting behaviour with the system package manager. " "It is recommended to use a virtual environment instead: " "https://pip.pypa.io/warnings/venv" ) def with_cleanup(func: Any) -> Any: """Decorator for common logic related to managing temporary directories. """ def configure_tempdir_registry(registry: TempDirectoryTypeRegistry) -> None: for t in KEEPABLE_TEMPDIR_TYPES: registry.set_delete(t, False) def wrapper( self: RequirementCommand, options: Values, args: List[Any] ) -> Optional[int]: assert self.tempdir_registry is not None if options.no_clean: configure_tempdir_registry(self.tempdir_registry) try: return func(self, options, args) except PreviousBuildDirError: # This kind of conflict can occur when the user passes an explicit # build directory with a pre-existing folder. In that case we do # not want to accidentally remove it. configure_tempdir_registry(self.tempdir_registry) raise return wrapper class RequirementCommand(IndexGroupCommand): def __init__(self, *args: Any, **kw: Any) -> None: super().__init__(*args, **kw) self.cmd_opts.add_option(cmdoptions.no_clean()) @staticmethod def determine_resolver_variant(options: Values) -> str: """Determines which resolver should be used, based on the given options.""" if "legacy-resolver" in options.deprecated_features_enabled: return "legacy" return "2020-resolver" @classmethod def make_requirement_preparer( cls, temp_build_dir: TempDirectory, options: Values, req_tracker: RequirementTracker, session: PipSession, finder: PackageFinder, use_user_site: bool, download_dir: Optional[str] = None, ) -> RequirementPreparer: """ Create a RequirementPreparer instance for the given parameters. """ temp_build_dir_path = temp_build_dir.path assert temp_build_dir_path is not None resolver_variant = cls.determine_resolver_variant(options) if resolver_variant == "2020-resolver": lazy_wheel = "fast-deps" in options.features_enabled if lazy_wheel: logger.warning( "pip is using lazily downloaded wheels using HTTP " "range requests to obtain dependency information. " "This experimental feature is enabled through " "--use-feature=fast-deps and it is not ready for " "production." ) else: lazy_wheel = False if "fast-deps" in options.features_enabled: logger.warning( "fast-deps has no effect when used with the legacy resolver." ) in_tree_build = "out-of-tree-build" not in options.deprecated_features_enabled if "in-tree-build" in options.features_enabled: deprecated( reason="In-tree builds are now the default.", replacement="to remove the --use-feature=in-tree-build flag", gone_in="22.1", ) if "out-of-tree-build" in options.deprecated_features_enabled: deprecated( reason="Out-of-tree builds are deprecated.", replacement=None, gone_in="22.1", ) return RequirementPreparer( build_dir=temp_build_dir_path, src_dir=options.src_dir, download_dir=download_dir, build_isolation=options.build_isolation, req_tracker=req_tracker, session=session, progress_bar=options.progress_bar, finder=finder, require_hashes=options.require_hashes, use_user_site=use_user_site, lazy_wheel=lazy_wheel, in_tree_build=in_tree_build, ) @classmethod def make_resolver( cls, preparer: RequirementPreparer, finder: PackageFinder, options: Values, wheel_cache: Optional[WheelCache] = None, use_user_site: bool = False, ignore_installed: bool = True, ignore_requires_python: bool = False, force_reinstall: bool = False, upgrade_strategy: str = "to-satisfy-only", use_pep517: Optional[bool] = None, py_version_info: Optional[Tuple[int, ...]] = None, ) -> BaseResolver: """ Create a Resolver instance for the given parameters. """ make_install_req = partial( install_req_from_req_string, isolated=options.isolated_mode, use_pep517=use_pep517, ) resolver_variant = cls.determine_resolver_variant(options) # The long import name and duplicated invocation is needed to convince # Mypy into correctly typechecking. Otherwise it would complain the # "Resolver" class being redefined. if resolver_variant == "2020-resolver": import pip._internal.resolution.resolvelib.resolver return pip._internal.resolution.resolvelib.resolver.Resolver( preparer=preparer, finder=finder, wheel_cache=wheel_cache, make_install_req=make_install_req, use_user_site=use_user_site, ignore_dependencies=options.ignore_dependencies, ignore_installed=ignore_installed, ignore_requires_python=ignore_requires_python, force_reinstall=force_reinstall, upgrade_strategy=upgrade_strategy, py_version_info=py_version_info, ) import pip._internal.resolution.legacy.resolver return pip._internal.resolution.legacy.resolver.Resolver( preparer=preparer, finder=finder, wheel_cache=wheel_cache, make_install_req=make_install_req, use_user_site=use_user_site, ignore_dependencies=options.ignore_dependencies, ignore_installed=ignore_installed, ignore_requires_python=ignore_requires_python, force_reinstall=force_reinstall, upgrade_strategy=upgrade_strategy, py_version_info=py_version_info, ) def get_requirements( self, args: List[str], options: Values, finder: PackageFinder, session: PipSession, ) -> List[InstallRequirement]: """ Parse command-line arguments into the corresponding requirements. """ requirements: List[InstallRequirement] = [] for filename in options.constraints: for parsed_req in parse_requirements( filename, constraint=True, finder=finder, options=options, session=session, ): req_to_add = install_req_from_parsed_requirement( parsed_req, isolated=options.isolated_mode, user_supplied=False, ) requirements.append(req_to_add) for req in args: req_to_add = install_req_from_line( req, None, isolated=options.isolated_mode, use_pep517=options.use_pep517, user_supplied=True, ) requirements.append(req_to_add) for req in options.editables: req_to_add = install_req_from_editable( req, user_supplied=True, isolated=options.isolated_mode, use_pep517=options.use_pep517, ) requirements.append(req_to_add) # NOTE: options.require_hashes may be set if --require-hashes is True for filename in options.requirements: for parsed_req in parse_requirements( filename, finder=finder, options=options, session=session ): req_to_add = install_req_from_parsed_requirement( parsed_req, isolated=options.isolated_mode, use_pep517=options.use_pep517, user_supplied=True, ) requirements.append(req_to_add) # If any requirement has hash options, enable hash checking. if any(req.has_hash_options for req in requirements): options.require_hashes = True if not (args or options.editables or options.requirements): opts = {"name": self.name} if options.find_links: raise CommandError( "You must give at least one requirement to {name} " '(maybe you meant "pip {name} {links}"?)'.format( **dict(opts, links=" ".join(options.find_links)) ) ) else: raise CommandError( "You must give at least one requirement to {name} " '(see "pip help {name}")'.format(**opts) ) return requirements @staticmethod def trace_basic_info(finder: PackageFinder) -> None: """ Trace basic information about the provided objects. """ # Display where finder is looking for packages search_scope = finder.search_scope locations = search_scope.get_formatted_locations() if locations: logger.info(locations) def _build_package_finder( self, options: Values, session: PipSession, target_python: Optional[TargetPython] = None, ignore_requires_python: Optional[bool] = None, ) -> PackageFinder: """ Create a package finder appropriate to this requirement command. :param ignore_requires_python: Whether to ignore incompatible "Requires-Python" values in links. Defaults to False. """ link_collector = LinkCollector.create(session, options=options) selection_prefs = SelectionPreferences( allow_yanked=True, format_control=options.format_control, allow_all_prereleases=options.pre, prefer_binary=options.prefer_binary, ignore_requires_python=ignore_requires_python, ) return PackageFinder.create( link_collector=link_collector, selection_prefs=selection_prefs, target_python=target_python, ) PKH]sOl l ;python3.10/site-packages/pip/_internal/cli/progress_bars.pynu[import itertools import sys from signal import SIGINT, default_int_handler, signal from typing import Any from pip._vendor.progress.bar import Bar, FillingCirclesBar, IncrementalBar from pip._vendor.progress.spinner import Spinner from pip._internal.utils.compat import WINDOWS from pip._internal.utils.logging import get_indentation from pip._internal.utils.misc import format_size try: from pip._vendor import colorama # Lots of different errors can come from this, including SystemError and # ImportError. except Exception: colorama = None def _select_progress_class(preferred: Bar, fallback: Bar) -> Bar: encoding = getattr(preferred.file, "encoding", None) # If we don't know what encoding this file is in, then we'll just assume # that it doesn't support unicode and use the ASCII bar. if not encoding: return fallback # Collect all of the possible characters we want to use with the preferred # bar. characters = [ getattr(preferred, "empty_fill", ""), getattr(preferred, "fill", ""), ] characters += list(getattr(preferred, "phases", [])) # Try to decode the characters we're using for the bar using the encoding # of the given file, if this works then we'll assume that we can use the # fancier bar and if not we'll fall back to the plaintext bar. try: "".join(characters).encode(encoding) except UnicodeEncodeError: return fallback else: return preferred _BaseBar: Any = _select_progress_class(IncrementalBar, Bar) class InterruptibleMixin: """ Helper to ensure that self.finish() gets called on keyboard interrupt. This allows downloads to be interrupted without leaving temporary state (like hidden cursors) behind. This class is similar to the progress library's existing SigIntMixin helper, but as of version 1.2, that helper has the following problems: 1. It calls sys.exit(). 2. It discards the existing SIGINT handler completely. 3. It leaves its own handler in place even after an uninterrupted finish, which will have unexpected delayed effects if the user triggers an unrelated keyboard interrupt some time after a progress-displaying download has already completed, for example. """ def __init__(self, *args: Any, **kwargs: Any) -> None: """ Save the original SIGINT handler for later. """ # https://github.com/python/mypy/issues/5887 super().__init__(*args, **kwargs) # type: ignore self.original_handler = signal(SIGINT, self.handle_sigint) # If signal() returns None, the previous handler was not installed from # Python, and we cannot restore it. This probably should not happen, # but if it does, we must restore something sensible instead, at least. # The least bad option should be Python's default SIGINT handler, which # just raises KeyboardInterrupt. if self.original_handler is None: self.original_handler = default_int_handler def finish(self) -> None: """ Restore the original SIGINT handler after finishing. This should happen regardless of whether the progress display finishes normally, or gets interrupted. """ super().finish() # type: ignore signal(SIGINT, self.original_handler) def handle_sigint(self, signum, frame): # type: ignore """ Call self.finish() before delegating to the original SIGINT handler. This handler should only be in place while the progress display is active. """ self.finish() self.original_handler(signum, frame) class SilentBar(Bar): def update(self) -> None: pass class BlueEmojiBar(IncrementalBar): suffix = "%(percent)d%%" bar_prefix = " " bar_suffix = " " phases = ("\U0001F539", "\U0001F537", "\U0001F535") class DownloadProgressMixin: def __init__(self, *args: Any, **kwargs: Any) -> None: # https://github.com/python/mypy/issues/5887 super().__init__(*args, **kwargs) # type: ignore self.message: str = (" " * (get_indentation() + 2)) + self.message @property def downloaded(self) -> str: return format_size(self.index) # type: ignore @property def download_speed(self) -> str: # Avoid zero division errors... if self.avg == 0.0: # type: ignore return "..." return format_size(1 / self.avg) + "/s" # type: ignore @property def pretty_eta(self) -> str: if self.eta: # type: ignore return f"eta {self.eta_td}" # type: ignore return "" def iter(self, it): # type: ignore for x in it: yield x # B305 is incorrectly raised here # https://github.com/PyCQA/flake8-bugbear/issues/59 self.next(len(x)) # noqa: B305 self.finish() class WindowsMixin: def __init__(self, *args: Any, **kwargs: Any) -> None: # The Windows terminal does not support the hide/show cursor ANSI codes # even with colorama. So we'll ensure that hide_cursor is False on # Windows. # This call needs to go before the super() call, so that hide_cursor # is set in time. The base progress bar class writes the "hide cursor" # code to the terminal in its init, so if we don't set this soon # enough, we get a "hide" with no corresponding "show"... if WINDOWS and self.hide_cursor: # type: ignore self.hide_cursor = False # https://github.com/python/mypy/issues/5887 super().__init__(*args, **kwargs) # type: ignore # Check if we are running on Windows and we have the colorama module, # if we do then wrap our file with it. if WINDOWS and colorama: self.file = colorama.AnsiToWin32(self.file) # type: ignore # The progress code expects to be able to call self.file.isatty() # but the colorama.AnsiToWin32() object doesn't have that, so we'll # add it. self.file.isatty = lambda: self.file.wrapped.isatty() # The progress code expects to be able to call self.file.flush() # but the colorama.AnsiToWin32() object doesn't have that, so we'll # add it. self.file.flush = lambda: self.file.wrapped.flush() class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, DownloadProgressMixin): file = sys.stdout message = "%(percent)d%%" suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s" class DefaultDownloadProgressBar(BaseDownloadProgressBar, _BaseBar): pass class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): pass class DownloadBar(BaseDownloadProgressBar, Bar): pass class DownloadFillingCirclesBar(BaseDownloadProgressBar, FillingCirclesBar): pass class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, BlueEmojiBar): pass class DownloadProgressSpinner( WindowsMixin, InterruptibleMixin, DownloadProgressMixin, Spinner ): file = sys.stdout suffix = "%(downloaded)s %(download_speed)s" def next_phase(self) -> str: if not hasattr(self, "_phaser"): self._phaser = itertools.cycle(self.phases) return next(self._phaser) def update(self) -> None: message = self.message % self phase = self.next_phase() suffix = self.suffix % self line = "".join( [ message, " " if message else "", phase, " " if suffix else "", suffix, ] ) self.writeln(line) BAR_TYPES = { "off": (DownloadSilentBar, DownloadSilentBar), "on": (DefaultDownloadProgressBar, DownloadProgressSpinner), "ascii": (DownloadBar, DownloadProgressSpinner), "pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner), "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner), } def DownloadProgressProvider(progress_bar, max=None): # type: ignore if max is None or max == 0: return BAR_TYPES[progress_bar][1]().iter else: return BAR_TYPES[progress_bar][0](max=max).iter PKH]IDnn8python3.10/site-packages/pip/_internal/cli/cmdoptions.pynu[""" shared options and groups The principle here is to define options once, but *not* instantiate them globally. One reason being that options with action='append' can carry state between parses. pip parses general options twice internally, and shouldn't pass on state. To be consistent, all options will follow this design. """ # The following comment should be removed at some point in the future. # mypy: strict-optional=False import os import textwrap import warnings from functools import partial from optparse import SUPPRESS_HELP, Option, OptionGroup, OptionParser, Values from textwrap import dedent from typing import Any, Callable, Dict, Optional, Tuple from pip._vendor.packaging.utils import canonicalize_name from pip._internal.cli.parser import ConfigOptionParser from pip._internal.cli.progress_bars import BAR_TYPES from pip._internal.exceptions import CommandError from pip._internal.locations import USER_CACHE_DIR, get_src_prefix from pip._internal.models.format_control import FormatControl from pip._internal.models.index import PyPI from pip._internal.models.target_python import TargetPython from pip._internal.utils.hashes import STRONG_HASHES from pip._internal.utils.misc import strtobool def raise_option_error(parser: OptionParser, option: Option, msg: str) -> None: """ Raise an option parsing error using parser.error(). Args: parser: an OptionParser instance. option: an Option instance. msg: the error text. """ msg = f"{option} error: {msg}" msg = textwrap.fill(" ".join(msg.split())) parser.error(msg) def make_option_group(group: Dict[str, Any], parser: ConfigOptionParser) -> OptionGroup: """ Return an OptionGroup object group -- assumed to be dict with 'name' and 'options' keys parser -- an optparse Parser """ option_group = OptionGroup(parser, group["name"]) for option in group["options"]: option_group.add_option(option()) return option_group def check_install_build_global( options: Values, check_options: Optional[Values] = None ) -> None: """Disable wheels if per-setup.py call options are set. :param options: The OptionParser options to update. :param check_options: The options to check, if not supplied defaults to options. """ if check_options is None: check_options = options def getname(n: str) -> Optional[Any]: return getattr(check_options, n, None) names = ["build_options", "global_options", "install_options"] if any(map(getname, names)): control = options.format_control control.disallow_binaries() warnings.warn( "Disabling all use of wheels due to the use of --build-option " "/ --global-option / --install-option.", stacklevel=2, ) def check_dist_restriction(options: Values, check_target: bool = False) -> None: """Function for determining if custom platform options are allowed. :param options: The OptionParser options. :param check_target: Whether or not to check if --target is being used. """ dist_restriction_set = any( [ options.python_version, options.platforms, options.abis, options.implementation, ] ) binary_only = FormatControl(set(), {":all:"}) sdist_dependencies_allowed = ( options.format_control != binary_only and not options.ignore_dependencies ) # Installations or downloads using dist restrictions must not combine # source distributions and dist-specific wheels, as they are not # guaranteed to be locally compatible. if dist_restriction_set and sdist_dependencies_allowed: raise CommandError( "When restricting platform and interpreter constraints using " "--python-version, --platform, --abi, or --implementation, " "either --no-deps must be set, or --only-binary=:all: must be " "set and --no-binary must not be set (or must be set to " ":none:)." ) if check_target: if dist_restriction_set and not options.target_dir: raise CommandError( "Can not use any platform or abi specific options unless " "installing via '--target'" ) def _path_option_check(option: Option, opt: str, value: str) -> str: return os.path.expanduser(value) def _package_name_option_check(option: Option, opt: str, value: str) -> str: return canonicalize_name(value) class PipOption(Option): TYPES = Option.TYPES + ("path", "package_name") TYPE_CHECKER = Option.TYPE_CHECKER.copy() TYPE_CHECKER["package_name"] = _package_name_option_check TYPE_CHECKER["path"] = _path_option_check ########### # options # ########### help_: Callable[..., Option] = partial( Option, "-h", "--help", dest="help", action="help", help="Show help.", ) debug_mode: Callable[..., Option] = partial( Option, "--debug", dest="debug_mode", action="store_true", default=False, help=( "Let unhandled exceptions propagate outside the main subroutine, " "instead of logging them to stderr." ), ) isolated_mode: Callable[..., Option] = partial( Option, "--isolated", dest="isolated_mode", action="store_true", default=False, help=( "Run pip in an isolated mode, ignoring environment variables and user " "configuration." ), ) require_virtualenv: Callable[..., Option] = partial( Option, # Run only if inside a virtualenv, bail if not. "--require-virtualenv", "--require-venv", dest="require_venv", action="store_true", default=False, help=SUPPRESS_HELP, ) verbose: Callable[..., Option] = partial( Option, "-v", "--verbose", dest="verbose", action="count", default=0, help="Give more output. Option is additive, and can be used up to 3 times.", ) no_color: Callable[..., Option] = partial( Option, "--no-color", dest="no_color", action="store_true", default=False, help="Suppress colored output.", ) version: Callable[..., Option] = partial( Option, "-V", "--version", dest="version", action="store_true", help="Show version and exit.", ) quiet: Callable[..., Option] = partial( Option, "-q", "--quiet", dest="quiet", action="count", default=0, help=( "Give less output. Option is additive, and can be used up to 3" " times (corresponding to WARNING, ERROR, and CRITICAL logging" " levels)." ), ) progress_bar: Callable[..., Option] = partial( Option, "--progress-bar", dest="progress_bar", type="choice", choices=list(BAR_TYPES.keys()), default="on", help=( "Specify type of progress to be displayed [" + "|".join(BAR_TYPES.keys()) + "] (default: %default)" ), ) log: Callable[..., Option] = partial( PipOption, "--log", "--log-file", "--local-log", dest="log", metavar="path", type="path", help="Path to a verbose appending log.", ) no_input: Callable[..., Option] = partial( Option, # Don't ask for input "--no-input", dest="no_input", action="store_true", default=False, help="Disable prompting for input.", ) proxy: Callable[..., Option] = partial( Option, "--proxy", dest="proxy", type="str", default="", help="Specify a proxy in the form [user:passwd@]proxy.server:port.", ) retries: Callable[..., Option] = partial( Option, "--retries", dest="retries", type="int", default=5, help="Maximum number of retries each connection should attempt " "(default %default times).", ) timeout: Callable[..., Option] = partial( Option, "--timeout", "--default-timeout", metavar="sec", dest="timeout", type="float", default=15, help="Set the socket timeout (default %default seconds).", ) def exists_action() -> Option: return Option( # Option when path already exist "--exists-action", dest="exists_action", type="choice", choices=["s", "i", "w", "b", "a"], default=[], action="append", metavar="action", help="Default action when a path already exists: " "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort.", ) cert: Callable[..., Option] = partial( PipOption, "--cert", dest="cert", type="path", metavar="path", help=( "Path to PEM-encoded CA certificate bundle. " "If provided, overrides the default. " "See 'SSL Certificate Verification' in pip documentation " "for more information." ), ) client_cert: Callable[..., Option] = partial( PipOption, "--client-cert", dest="client_cert", type="path", default=None, metavar="path", help="Path to SSL client certificate, a single file containing the " "private key and the certificate in PEM format.", ) index_url: Callable[..., Option] = partial( Option, "-i", "--index-url", "--pypi-url", dest="index_url", metavar="URL", default=PyPI.simple_url, help="Base URL of the Python Package Index (default %default). " "This should point to a repository compliant with PEP 503 " "(the simple repository API) or a local directory laid out " "in the same format.", ) def extra_index_url() -> Option: return Option( "--extra-index-url", dest="extra_index_urls", metavar="URL", action="append", default=[], help="Extra URLs of package indexes to use in addition to " "--index-url. Should follow the same rules as " "--index-url.", ) no_index: Callable[..., Option] = partial( Option, "--no-index", dest="no_index", action="store_true", default=False, help="Ignore package index (only looking at --find-links URLs instead).", ) def find_links() -> Option: return Option( "-f", "--find-links", dest="find_links", action="append", default=[], metavar="url", help="If a URL or path to an html file, then parse for links to " "archives such as sdist (.tar.gz) or wheel (.whl) files. " "If a local path or file:// URL that's a directory, " "then look for archives in the directory listing. " "Links to VCS project URLs are not supported.", ) def trusted_host() -> Option: return Option( "--trusted-host", dest="trusted_hosts", action="append", metavar="HOSTNAME", default=[], help="Mark this host or host:port pair as trusted, even though it " "does not have valid or any HTTPS.", ) def constraints() -> Option: return Option( "-c", "--constraint", dest="constraints", action="append", default=[], metavar="file", help="Constrain versions using the given constraints file. " "This option can be used multiple times.", ) def requirements() -> Option: return Option( "-r", "--requirement", dest="requirements", action="append", default=[], metavar="file", help="Install from the given requirements file. " "This option can be used multiple times.", ) def editable() -> Option: return Option( "-e", "--editable", dest="editables", action="append", default=[], metavar="path/url", help=( "Install a project in editable mode (i.e. setuptools " '"develop mode") from a local project path or a VCS url.' ), ) def _handle_src(option: Option, opt_str: str, value: str, parser: OptionParser) -> None: value = os.path.abspath(value) setattr(parser.values, option.dest, value) src: Callable[..., Option] = partial( PipOption, "--src", "--source", "--source-dir", "--source-directory", dest="src_dir", type="path", metavar="dir", default=get_src_prefix(), action="callback", callback=_handle_src, help="Directory to check out editable projects into. " 'The default in a virtualenv is "/src". ' 'The default for global installs is "/src".', ) def _get_format_control(values: Values, option: Option) -> Any: """Get a format_control object.""" return getattr(values, option.dest) def _handle_no_binary( option: Option, opt_str: str, value: str, parser: OptionParser ) -> None: existing = _get_format_control(parser.values, option) FormatControl.handle_mutual_excludes( value, existing.no_binary, existing.only_binary, ) def _handle_only_binary( option: Option, opt_str: str, value: str, parser: OptionParser ) -> None: existing = _get_format_control(parser.values, option) FormatControl.handle_mutual_excludes( value, existing.only_binary, existing.no_binary, ) def no_binary() -> Option: format_control = FormatControl(set(), set()) return Option( "--no-binary", dest="format_control", action="callback", callback=_handle_no_binary, type="str", default=format_control, help="Do not use binary packages. Can be supplied multiple times, and " 'each time adds to the existing value. Accepts either ":all:" to ' 'disable all binary packages, ":none:" to empty the set (notice ' "the colons), or one or more package names with commas between " "them (no colons). Note that some packages are tricky to compile " "and may fail to install when this option is used on them.", ) def only_binary() -> Option: format_control = FormatControl(set(), set()) return Option( "--only-binary", dest="format_control", action="callback", callback=_handle_only_binary, type="str", default=format_control, help="Do not use source packages. Can be supplied multiple times, and " 'each time adds to the existing value. Accepts either ":all:" to ' 'disable all source packages, ":none:" to empty the set, or one ' "or more package names with commas between them. Packages " "without binary distributions will fail to install when this " "option is used on them.", ) platforms: Callable[..., Option] = partial( Option, "--platform", dest="platforms", metavar="platform", action="append", default=None, help=( "Only use wheels compatible with . Defaults to the " "platform of the running system. Use this option multiple times to " "specify multiple platforms supported by the target interpreter." ), ) # This was made a separate function for unit-testing purposes. def _convert_python_version(value: str) -> Tuple[Tuple[int, ...], Optional[str]]: """ Convert a version string like "3", "37", or "3.7.3" into a tuple of ints. :return: A 2-tuple (version_info, error_msg), where `error_msg` is non-None if and only if there was a parsing error. """ if not value: # The empty string is the same as not providing a value. return (None, None) parts = value.split(".") if len(parts) > 3: return ((), "at most three version parts are allowed") if len(parts) == 1: # Then we are in the case of "3" or "37". value = parts[0] if len(value) > 1: parts = [value[0], value[1:]] try: version_info = tuple(int(part) for part in parts) except ValueError: return ((), "each version part must be an integer") return (version_info, None) def _handle_python_version( option: Option, opt_str: str, value: str, parser: OptionParser ) -> None: """ Handle a provided --python-version value. """ version_info, error_msg = _convert_python_version(value) if error_msg is not None: msg = "invalid --python-version value: {!r}: {}".format( value, error_msg, ) raise_option_error(parser, option=option, msg=msg) parser.values.python_version = version_info python_version: Callable[..., Option] = partial( Option, "--python-version", dest="python_version", metavar="python_version", action="callback", callback=_handle_python_version, type="str", default=None, help=dedent( """\ The Python interpreter version to use for wheel and "Requires-Python" compatibility checks. Defaults to a version derived from the running interpreter. The version can be specified using up to three dot-separated integers (e.g. "3" for 3.0.0, "3.7" for 3.7.0, or "3.7.3"). A major-minor version can also be given as a string without dots (e.g. "37" for 3.7.0). """ ), ) implementation: Callable[..., Option] = partial( Option, "--implementation", dest="implementation", metavar="implementation", default=None, help=( "Only use wheels compatible with Python " "implementation , e.g. 'pp', 'jy', 'cp', " " or 'ip'. If not specified, then the current " "interpreter implementation is used. Use 'py' to force " "implementation-agnostic wheels." ), ) abis: Callable[..., Option] = partial( Option, "--abi", dest="abis", metavar="abi", action="append", default=None, help=( "Only use wheels compatible with Python abi , e.g. 'pypy_41'. " "If not specified, then the current interpreter abi tag is used. " "Use this option multiple times to specify multiple abis supported " "by the target interpreter. Generally you will need to specify " "--implementation, --platform, and --python-version when using this " "option." ), ) def add_target_python_options(cmd_opts: OptionGroup) -> None: cmd_opts.add_option(platforms()) cmd_opts.add_option(python_version()) cmd_opts.add_option(implementation()) cmd_opts.add_option(abis()) def make_target_python(options: Values) -> TargetPython: target_python = TargetPython( platforms=options.platforms, py_version_info=options.python_version, abis=options.abis, implementation=options.implementation, ) return target_python def prefer_binary() -> Option: return Option( "--prefer-binary", dest="prefer_binary", action="store_true", default=False, help="Prefer older binary packages over newer source packages.", ) cache_dir: Callable[..., Option] = partial( PipOption, "--cache-dir", dest="cache_dir", default=USER_CACHE_DIR, metavar="dir", type="path", help="Store the cache data in .", ) def _handle_no_cache_dir( option: Option, opt: str, value: str, parser: OptionParser ) -> None: """ Process a value provided for the --no-cache-dir option. This is an optparse.Option callback for the --no-cache-dir option. """ # The value argument will be None if --no-cache-dir is passed via the # command-line, since the option doesn't accept arguments. However, # the value can be non-None if the option is triggered e.g. by an # environment variable, like PIP_NO_CACHE_DIR=true. if value is not None: # Then parse the string value to get argument error-checking. try: strtobool(value) except ValueError as exc: raise_option_error(parser, option=option, msg=str(exc)) # Originally, setting PIP_NO_CACHE_DIR to a value that strtobool() # converted to 0 (like "false" or "no") caused cache_dir to be disabled # rather than enabled (logic would say the latter). Thus, we disable # the cache directory not just on values that parse to True, but (for # backwards compatibility reasons) also on values that parse to False. # In other words, always set it to False if the option is provided in # some (valid) form. parser.values.cache_dir = False no_cache: Callable[..., Option] = partial( Option, "--no-cache-dir", dest="cache_dir", action="callback", callback=_handle_no_cache_dir, help="Disable the cache.", ) no_deps: Callable[..., Option] = partial( Option, "--no-deps", "--no-dependencies", dest="ignore_dependencies", action="store_true", default=False, help="Don't install package dependencies.", ) ignore_requires_python: Callable[..., Option] = partial( Option, "--ignore-requires-python", dest="ignore_requires_python", action="store_true", help="Ignore the Requires-Python information.", ) no_build_isolation: Callable[..., Option] = partial( Option, "--no-build-isolation", dest="build_isolation", action="store_false", default=True, help="Disable isolation when building a modern source distribution. " "Build dependencies specified by PEP 518 must be already installed " "if this option is used.", ) def _handle_no_use_pep517( option: Option, opt: str, value: str, parser: OptionParser ) -> None: """ Process a value provided for the --no-use-pep517 option. This is an optparse.Option callback for the no_use_pep517 option. """ # Since --no-use-pep517 doesn't accept arguments, the value argument # will be None if --no-use-pep517 is passed via the command-line. # However, the value can be non-None if the option is triggered e.g. # by an environment variable, for example "PIP_NO_USE_PEP517=true". if value is not None: msg = """A value was passed for --no-use-pep517, probably using either the PIP_NO_USE_PEP517 environment variable or the "no-use-pep517" config file option. Use an appropriate value of the PIP_USE_PEP517 environment variable or the "use-pep517" config file option instead. """ raise_option_error(parser, option=option, msg=msg) # Otherwise, --no-use-pep517 was passed via the command-line. parser.values.use_pep517 = False use_pep517: Any = partial( Option, "--use-pep517", dest="use_pep517", action="store_true", default=None, help="Use PEP 517 for building source distributions " "(use --no-use-pep517 to force legacy behaviour).", ) no_use_pep517: Any = partial( Option, "--no-use-pep517", dest="use_pep517", action="callback", callback=_handle_no_use_pep517, default=None, help=SUPPRESS_HELP, ) install_options: Callable[..., Option] = partial( Option, "--install-option", dest="install_options", action="append", metavar="options", help="Extra arguments to be supplied to the setup.py install " 'command (use like --install-option="--install-scripts=/usr/local/' 'bin"). Use multiple --install-option options to pass multiple ' "options to setup.py install. If you are using an option with a " "directory path, be sure to use absolute path.", ) build_options: Callable[..., Option] = partial( Option, "--build-option", dest="build_options", metavar="options", action="append", help="Extra arguments to be supplied to 'setup.py bdist_wheel'.", ) global_options: Callable[..., Option] = partial( Option, "--global-option", dest="global_options", action="append", metavar="options", help="Extra global options to be supplied to the setup.py " "call before the install or bdist_wheel command.", ) no_clean: Callable[..., Option] = partial( Option, "--no-clean", action="store_true", default=False, help="Don't clean up build directories.", ) pre: Callable[..., Option] = partial( Option, "--pre", action="store_true", default=False, help="Include pre-release and development versions. By default, " "pip only finds stable versions.", ) disable_pip_version_check: Callable[..., Option] = partial( Option, "--disable-pip-version-check", dest="disable_pip_version_check", action="store_true", default=False, help="Don't periodically check PyPI to determine whether a new version " "of pip is available for download. Implied with --no-index.", ) def _handle_merge_hash( option: Option, opt_str: str, value: str, parser: OptionParser ) -> None: """Given a value spelled "algo:digest", append the digest to a list pointed to in a dict by the algo name.""" if not parser.values.hashes: parser.values.hashes = {} try: algo, digest = value.split(":", 1) except ValueError: parser.error( "Arguments to {} must be a hash name " # noqa "followed by a value, like --hash=sha256:" "abcde...".format(opt_str) ) if algo not in STRONG_HASHES: parser.error( "Allowed hash algorithms for {} are {}.".format( # noqa opt_str, ", ".join(STRONG_HASHES) ) ) parser.values.hashes.setdefault(algo, []).append(digest) hash: Callable[..., Option] = partial( Option, "--hash", # Hash values eventually end up in InstallRequirement.hashes due to # __dict__ copying in process_line(). dest="hashes", action="callback", callback=_handle_merge_hash, type="string", help="Verify that the package's archive matches this " "hash before installing. Example: --hash=sha256:abcdef...", ) require_hashes: Callable[..., Option] = partial( Option, "--require-hashes", dest="require_hashes", action="store_true", default=False, help="Require a hash to check each requirement against, for " "repeatable installs. This option is implied when any package in a " "requirements file has a --hash option.", ) list_path: Callable[..., Option] = partial( PipOption, "--path", dest="path", type="path", action="append", help="Restrict to the specified installation path for listing " "packages (can be used multiple times).", ) def check_list_path_option(options: Values) -> None: if options.path and (options.user or options.local): raise CommandError("Cannot combine '--path' with '--user' or '--local'") list_exclude: Callable[..., Option] = partial( PipOption, "--exclude", dest="excludes", action="append", metavar="package", type="package_name", help="Exclude specified package from the output", ) no_python_version_warning: Callable[..., Option] = partial( Option, "--no-python-version-warning", dest="no_python_version_warning", action="store_true", default=False, help="Silence deprecation warnings for upcoming unsupported Pythons.", ) use_new_feature: Callable[..., Option] = partial( Option, "--use-feature", dest="features_enabled", metavar="feature", action="append", default=[], choices=["2020-resolver", "fast-deps", "in-tree-build"], help="Enable new functionality, that may be backward incompatible.", ) use_deprecated_feature: Callable[..., Option] = partial( Option, "--use-deprecated", dest="deprecated_features_enabled", metavar="feature", action="append", default=[], choices=["legacy-resolver", "out-of-tree-build"], help=("Enable deprecated functionality, that will be removed in the future."), ) ########## # groups # ########## general_group: Dict[str, Any] = { "name": "General Options", "options": [ help_, debug_mode, isolated_mode, require_virtualenv, verbose, version, quiet, log, no_input, proxy, retries, timeout, exists_action, trusted_host, cert, client_cert, cache_dir, no_cache, disable_pip_version_check, no_color, no_python_version_warning, use_new_feature, use_deprecated_feature, ], } index_group: Dict[str, Any] = { "name": "Package Index Options", "options": [ index_url, extra_index_url, no_index, find_links, ], } PKH]w46python3.10/site-packages/pip/_internal/cli/__init__.pynu["""Subpackage containing all of pip's command line interface related code """ # This file intentionally does not import submodules PKH] f=python3.10/site-packages/pip/_internal/cli/command_context.pynu[from contextlib import ExitStack, contextmanager from typing import ContextManager, Iterator, TypeVar _T = TypeVar("_T", covariant=True) class CommandContextMixIn: def __init__(self) -> None: super().__init__() self._in_main_context = False self._main_context = ExitStack() @contextmanager def main_context(self) -> Iterator[None]: assert not self._in_main_context self._in_main_context = True try: with self._main_context: yield finally: self._in_main_context = False def enter_context(self, context_provider: ContextManager[_T]) -> _T: assert self._in_main_context return self._main_context.enter_context(context_provider) PKH]ߗ6python3.10/site-packages/pip/_internal/models/index.pynu[import urllib.parse class PackageIndex: """Represents a Package Index and provides easier access to endpoints""" __slots__ = ["url", "netloc", "simple_url", "pypi_url", "file_storage_domain"] def __init__(self, url: str, file_storage_domain: str) -> None: super().__init__() self.url = url self.netloc = urllib.parse.urlsplit(url).netloc self.simple_url = self._url_for_path("simple") self.pypi_url = self._url_for_path("pypi") # This is part of a temporary hack used to block installs of PyPI # packages which depend on external urls only necessary until PyPI can # block such packages themselves self.file_storage_domain = file_storage_domain def _url_for_path(self, path: str) -> str: return urllib.parse.urljoin(self.url, path) PyPI = PackageIndex("https://pypi.org/", file_storage_domain="files.pythonhosted.org") TestPyPI = PackageIndex( "https://test.pypi.org/", file_storage_domain="test-files.pythonhosted.org" ) PKH]bc ?python3.10/site-packages/pip/_internal/models/format_control.pynu[from typing import FrozenSet, Optional, Set from pip._vendor.packaging.utils import canonicalize_name from pip._internal.exceptions import CommandError class FormatControl: """Helper for managing formats from which a package can be installed.""" __slots__ = ["no_binary", "only_binary"] def __init__( self, no_binary: Optional[Set[str]] = None, only_binary: Optional[Set[str]] = None, ) -> None: if no_binary is None: no_binary = set() if only_binary is None: only_binary = set() self.no_binary = no_binary self.only_binary = only_binary def __eq__(self, other: object) -> bool: if not isinstance(other, self.__class__): return NotImplemented if self.__slots__ != other.__slots__: return False return all(getattr(self, k) == getattr(other, k) for k in self.__slots__) def __repr__(self) -> str: return "{}({}, {})".format( self.__class__.__name__, self.no_binary, self.only_binary ) @staticmethod def handle_mutual_excludes(value: str, target: Set[str], other: Set[str]) -> None: if value.startswith("-"): raise CommandError( "--no-binary / --only-binary option requires 1 argument." ) new = value.split(",") while ":all:" in new: other.clear() target.clear() target.add(":all:") del new[: new.index(":all:") + 1] # Without a none, we want to discard everything as :all: covers it if ":none:" not in new: return for name in new: if name == ":none:": target.clear() continue name = canonicalize_name(name) other.discard(name) target.add(name) def get_allowed_formats(self, canonical_name: str) -> FrozenSet[str]: result = {"binary", "source"} if canonical_name in self.only_binary: result.discard("source") elif canonical_name in self.no_binary: result.discard("binary") elif ":all:" in self.only_binary: result.discard("source") elif ":all:" in self.no_binary: result.discard("binary") return frozenset(result) def disallow_binaries(self) -> None: self.handle_mutual_excludes( ":all:", self.no_binary, self.only_binary, ) PKH],KYpython3.10/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-310.pycnu[o ais@s*ddlmZddlmZGdddZdS))Optional) FormatControlc @sLeZdZdZgdZ    d dededeeded eed df d d ZdS)SelectionPreferenceszd Encapsulates the candidate selection preferences for downloading and installing files.  allow_yankedallow_all_prereleasesformat_control prefer_binaryignore_requires_pythonFNrrrr r returncCs.|durd}||_||_||_||_||_dS)awCreate a SelectionPreferences object. :param allow_yanked: Whether files marked as yanked (in the sense of PEP 592) are permitted to be candidates for install. :param format_control: A FormatControl object or None. Used to control the selection of source packages / binary packages when consulting the index and links. :param prefer_binary: Whether to prefer an old, but valid, binary dist over a new source dist. :param ignore_requires_python: Whether to ignore incompatible "Requires-Python" values in links. Defaults to False. NFr)selfrrrr r r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/models/selection_prefs.py__init__s zSelectionPreferences.__init__)FNFN) __name__ __module__ __qualname____doc__ __slots__boolrrrr r r rrs(rN)typingr#pip._internal.models.format_controlrrr r r rs PKH]1JOpython3.10/site-packages/pip/_internal/models/__pycache__/index.cpython-310.pycnu[o ai@s2ddlZGdddZedddZedddZdS) NcsHeZdZdZgdZdededdffdd Zd edefd d ZZS) PackageIndexzBRepresents a Package Index and provides easier access to endpoints)urlnetloc simple_urlpypi_urlfile_storage_domainrrreturnNcsBt||_tj|j|_|d|_|d|_ ||_ dS)Nsimplepypi) super__init__rurllibparseurlsplitr _url_for_pathrrr)selfrr __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/models/index.pyr s    zPackageIndex.__init__pathcCstj|j|S)N)r rurljoinr)rrrrrrszPackageIndex._url_for_path) __name__ __module__ __qualname____doc__ __slots__strr r __classcell__rrrrrs  rzhttps://pypi.org/zfiles.pythonhosted.org)rzhttps://test.pypi.org/ztest-files.pythonhosted.org) urllib.parser rPyPITestPyPIrrrrs   PKH]Spython3.10/site-packages/pip/_internal/models/__pycache__/candidate.cpython-310.pycnu[o ai@s8ddlmZddlmZddlmZGdddeZdS))parse)Link)KeyBasedCompareMixincsVeZdZdZgdZdedededdffdd Zdefd d Zdefd d Z Z S)InstallationCandidatez4Represents a potential "candidate" for installation.)nameversionlinkrrrreturnNcs6||_t||_||_tj|j|j|jftddS)N)keydefining_class)r parse_versionrrsuper__init__r)selfrrr __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/models/candidate.pyr s  zInstallationCandidate.__init__cCd|j|j|jS)Nz)formatrrrrrrr__repr__ zInstallationCandidate.__repr__cCr)Nz!{!r} candidate (version {} at {})rrrrr__str__rzInstallationCandidate.__str__) __name__ __module__ __qualname____doc__ __slots__strrrrr __classcell__rrrrrs  rN)Zpip._vendor.packaging.versionrr pip._internal.models.linkrpip._internal.utils.modelsrrrrrrs  PKH]5q00Rpython3.10/site-packages/pip/_internal/models/__pycache__/__init__.cpython-310.pycnu[o ai?@sdZdS)z8A package that contains models that represent entities. N)__doc__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/models/__init__.pysPKH]B) Xpython3.10/site-packages/pip/_internal/models/__pycache__/format_control.cpython-310.pycnu[o ai @s>ddlmZmZmZddlmZddlmZGdddZdS)) FrozenSetOptionalSet)canonicalize_name) CommandErrorc @seZdZdZddgZ  ddeeedeeeddfddZde de fd d Z defd d Z e d edeedeeddfddZdedeefddZdddZdS) FormatControlzBHelper for managing formats from which a package can be installed. no_binary only_binaryNreturncCs,|durt}|durt}||_||_dSN)setrr )selfrr r/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/models/format_control.py__init__ s  zFormatControl.__init__othercs:tjstSjjkrdStfddjDS)NFc3s$|] }t|t|kVqdSr )getattr).0krr rr !s"z'FormatControl.__eq__..) isinstance __class__NotImplemented __slots__all)r rrrr__eq__s  zFormatControl.__eq__cCsd|jj|j|jS)Nz {}({}, {}))formatr__name__rr r rrr__repr__#szFormatControl.__repr__valuetargetcCs|dr td|d}d|vr3|||d|d|dd=d|vr/dSd|vs|D]}|dkr@|q5t|}||||q5dS)N-z7--no-binary / --only-binary option requires 1 argument.,:all:z:none:) startswithrsplitclearaddindexrdiscard)r!r"rnewnamerrrhandle_mutual_excludes(s*     z$FormatControl.handle_mutual_excludescanonical_namecCsxddh}||jvr|dt|S||jvr |dt|Sd|jvr.|dt|Sd|jvr8|dt|S)Nbinarysourcer%)r r,r frozenset)r r0resultrrrget_allowed_formats?s     z!FormatControl.get_allowed_formatscCs|d|j|jdS)Nr%)r/rr rrrrdisallow_binariesKs zFormatControl.disallow_binaries)NN)r N)r __module__ __qualname____doc__rrrstrrobjectboolrr staticmethodr/rr5r6rrrrrs$     $ rN) typingrrrpip._vendor.packaging.utilsrpip._internal.exceptionsrrrrrrs  PKH]@Н Wpython3.10/site-packages/pip/_internal/models/__pycache__/target_python.cpython-310.pycnu[o ai@sVddlZddlmZmZmZddlmZddlmZm Z ddl m Z GdddZ dS)N)ListOptionalTuple)Tag) get_supportedversion_info_to_nodot)normalize_version_infoc @seZdZdZgdZ    ddeeedeee dfdeeedeed df d d Z d efd d Z d ee fddZ dS) TargetPythonzx Encapsulates the properties of a Python interpreter one is targeting for a package install, download, etc. )_given_py_version_infoabisimplementation platforms py_versionpy_version_info _valid_tagsNr r.r r returncCsf||_|durtjdd}nt|}dtt|dd}||_||_||_ ||_ ||_ d|_ dS)a< :param platforms: A list of strings or None. If None, searches for packages that are supported by the current system. Otherwise, will find packages that can be built on the platforms passed in. These packages will only be downloaded for distribution: they will not be built locally. :param py_version_info: An optional tuple of ints representing the Python version information to use (e.g. `sys.version_info[:3]`). This can have length 1, 2, or 3 when provided. :param abis: A list of strings or None. This is passed to compatibility_tags.py's get_supported() function as is. :param implementation: A string or None. This is passed to compatibility_tags.py's get_supported() function as is. N.) r sys version_inforjoinmapstrr r r rrr)selfr rr r rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/models/target_python.py__init__s zTargetPython.__init__cCsZd}|jdurddd|jD}d|jfd|fd|jfd|jfg}d d d|DS) zD Format the given, non-None attributes for display. Nrcss|]}t|VqdS)N)r).0partrrr Is z,TargetPython.format_given..r rr r  css*|]\}}|dur|d|VqdS)N=r)rkeyvaluerrrr Ss )r rr r r )rdisplay_version key_valuesrrr format_givenCs   zTargetPython.format_givencCsH|jdur!|j}|durd}nt|}t||j|j|jd}||_|jS)z Return the supported PEP 425 tags to check wheel candidates against. The tags are returned in order of preference (most preferred first). N)versionr r impl)rr rrr r r )rrr(tagsrrrget_tagsWs zTargetPython.get_tags)NNNN)__name__ __module__ __qualname____doc__ __slots__rrrrintrr'rr+rrrrr s(    (r ) rtypingrrrZpip._vendor.packaging.tagsr&pip._internal.utils.compatibility_tagsrrpip._internal.utils.miscrr rrrrs   PKH]M>d?Tpython3.10/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-310.pycnu[o ai @sTdZddlZddlZddlZddlmZmZmZm Z m Z m Z m Z gdZ e dZdZedZGdd d eZ d"d eeefd e ed ed e ede ef ddZ d"d eeefd e ed ed e edef ddZdee dddfddZdedeeeffddZGdddZGdddZGdddZe eeefZGd d!d!ZdS)#z PEP 610 N)AnyDictIterableOptionalTypeTypeVarUnion) DirectUrlDirectUrlValidationErrorDirInfo ArchiveInfoVcsInfoTzdirect_url.jsonz.^\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?$c@s eZdZdS)r N)__name__ __module__ __qualname__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/models/direct_url.pyr sr d expected_typekeydefaultreturncCs4||vr|S||}t||std||||S)z3Get value from dictionary and verify expected type.z-{!r} has unexpected type for {} (expected {})) isinstancer formatrrrrvaluerrr_gets rcCs(t||||}|durt|d|S)Nz must have a value)rr rrrr _get_required)srinfosInfoTypecCsFdd|D}|s tdt|dkrtd|ddusJ|dS)NcSsg|]}|dur|qSNr).0inforrr 3sz#_exactly_one_of..z/missing one of archive_info, dir_info, vcs_infoz1more than one of archive_info, dir_info, vcs_infor)r len)rrrr_exactly_one_of2s r'kwargscKsdd|DS)z Make dict excluding None values.cSsi|] \}}|dur||qSr!r)r"kvrrr Bsz _filter_none..)items)r(rrr _filter_none@sr-c @seZdZdZ   ddededeedeedeeddf d d Zed eeee fdedfd d Z deee ffddZ dS)r vcs_infoNvcs commit_idrequested_revisionresolved_revisionresolved_revision_typercCs"||_||_||_||_||_dSr!r/r1r0r2r3)selfr/r0r1r2r3rrr__init__Hs  zVcsInfo.__init__rc CsF|durdS|t|tdt|tdt|tdt|tdt|tddS)Nr/r0r1r2r3)r/r0r1r2r3)rstrrclsrrrr _from_dictVs     zVcsInfo._from_dictcCst|j|j|j|j|jdS)Nr4)r-r/r1r0r2r3r5rrr_to_dictbszVcsInfo._to_dict)NNN) rrrnamer7rr6 classmethodrrr:r<rrrrr Es* $ r c@sfeZdZdZ d deeddfddZedeeee fdedfdd Z deee ffd d Z dS) r archive_infoNhashrcC ||_dSr!r@)r5r@rrrr6o zArchiveInfo.__init__rcCs|durdS|t|tddS)Nr@rB)rr7r8rrrr:uszArchiveInfo._from_dictcCs t|jdS)NrB)r-r@r;rrrr<{s zArchiveInfo._to_dictr!) rrrr=rr7r6r>rrr:r<rrrrr ls $r c@sbeZdZdZ d deddfddZedeee e fdedfd d Z dee e ffd d Z dS)r dir_infoFeditablerNcCrAr!rE)r5rErrrr6rCzDirInfo.__init__rcCs"|durdS|t|tddddS)NrEF)rrF)rboolr8rrrr:szDirInfo._from_dictcCst|jpddS)NrF)r-rEr;rrrr<szDirInfo._to_dict)F) rrrr=rGr6r>rrr7rr:r<rrrrr s $r c @seZdZ ddededeeddfddZdedefd d Zedefd d Z dd dZ e de ee fddfddZde ee ffddZe deddfddZdefddZdefddZdS)r Nurlr# subdirectoryrcCs||_||_||_dSr!)rHr#rI)r5rHr#rIrrrr6s zDirectUrl.__init__netloccCsRd|vr|S|dd\}}t|jtr |jjdkr |dkr |St|r'|S|S)N@r%git)splitrr#r r/ ENV_VAR_REmatch)r5rJ user_passnetloc_no_user_passrrr_remove_auth_from_netlocs   z"DirectUrl._remove_auth_from_netloccCs<tj|j}||j}tj|j||j|j |j f}|S)zurl with user:password part removed unless it is formed with environment variables as specified in PEP 610, or it is ``git`` in the case of a git URL. ) urllibparseurlsplitrHrRrJ urlunsplitschemepathqueryfragment)r5purlrJsurlrrr redacted_urls  zDirectUrl.redacted_urlcCs||dSr!) from_dictto_dictr;rrrvalidatezDirectUrl.validaterc CsRtt|tdt|tdttt|tdtt|tdt t|tdgdS)NrHrIr?rDr.)rHrIr#) r rr7rr'r r:dictr r r8rrrr^s  zDirectUrl.from_dictcCs&t|j|jd}|j||jj<|S)N)rHrI)r-r]rIr#r<r=)r5resrrrr_s zDirectUrl.to_dictscCs|t|Sr!)r^jsonloads)r9rdrrr from_jsonszDirectUrl.from_jsoncCstj|ddS)NT) sort_keys)redumpsr_r;rrrto_jsonrazDirectUrl.to_jsoncCst|jto |jjSr!)rr#r rEr;rrris_local_editableszDirectUrl.is_local_editabler!)rN)rrrr7r rr6rRpropertyr]r`r>rrr^r_rgrjrGrkrrrrr s,    r r!)__doc__rere urllib.parserStypingrrrrrrr__all__rDIRECT_URL_METADATA_NAMEcompilerN Exceptionr r7rrr'r-r r r r r rrrrsR$      'PKH]pH5 Vpython3.10/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-310.pycnu[o ai@sddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z ddl m Z ddlmZmZeeZGdddZdS) N)List)canonicalize_name)PyPI)has_tls)normalize_pathredact_auth_from_urlc@s|eZdZdZddgZedeedeeddfddZdeedeeddfdd Z defd d Z d edeefd dZ dS) SearchScopezF Encapsulates the locations that pip is configured to search. find_links index_urlsreturncCsg}|D]}|drt|}tj|r|}||qts;t||D]}t j |}|j dkr:t dnq&|||dS)zQ Create a SearchScope object after normalizing the `find_links`. ~httpszipip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.r r ) startswithrospathexistsappendr itertoolschainurllibparseurlparseschemeloggerwarning)clsr r built_find_linkslinknew_linkparsedr!/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/models/search_scope.pycreates(     zSearchScope.createNcCs||_||_dSNr)selfr r r!r!r"__init__As zSearchScope.__init__cCsg}g}|jr:|jtjgkr:|jD]}t|}tj|}|js)|js)t d|| |q| d d ||jrN| d d dd|jDd |S)Nz:The index url "%s" seems invalid, please provide a scheme.zLooking in indexes: {}z, zLooking in links: {}css|]}t|VqdSr$)r.0urlr!r!r" hsz6SearchScope.get_formatted_locations.. )r r simple_urlrrrurlsplitrnetlocrrrformatjoinr )r%linesredacted_index_urlsr)redacted_index_urlpurlr!r!r"get_formatted_locationsIs,     z#SearchScope.get_formatted_locations project_namecs*dtdtffdd fdd|jDS)zReturns the locations found via self.index_urls Checks the url_name on the main (first in the list) index and use this url_name to produce all locations r)r cs.t|tjt}|ds|d}|S)N/) posixpathr0rrquoterendswith)r)loc)r6r!r"mkurl_pypi_urlts  z.mkurl_pypi_urlcsg|]}|qSr!r!r')r<r!r" sz8SearchScope.get_index_urls_locations..)strr )r%r6r!)r<r6r"get_index_urls_locationsms z$SearchScope.get_index_urls_locations) __name__ __module__ __qualname____doc__ __slots__ classmethodrr>r#r&r5r?r!r!r!r"rs( ' $r)rloggingrr8 urllib.parsertypingrpip._vendor.packaging.utilsrpip._internal.models.indexrpip._internal.utils.compatrpip._internal.utils.miscrr getLoggerr@rrr!r!r!r"s     PKH]00Ppython3.10/site-packages/pip/_internal/models/__pycache__/scheme.cpython-310.pycnu[o ai@sdZgdZGdddZdS)z For types associated with installation schemes. For a general overview of available schemes and their context, see https://docs.python.org/3/install/index.html#alternate-installation. platlibpurelibheadersscriptsdatac @s6eZdZdZeZdedededededdf d d ZdS) SchemeztA Scheme holds paths which are used as the base directories for artifacts associated with a Python package. rrrrrreturnNcCs"||_||_||_||_||_dS)Nr)selfrrrrrr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/models/scheme.py__init__s  zScheme.__init__)__name__ __module__ __qualname____doc__ SCHEME_KEYS __slots__strr r r r r r s rN)rrrr r r r sPKH] yQOpython3.10/site-packages/pip/_internal/models/__pycache__/wheel.cpython-310.pycnu[o ai @sJdZddlZddlmZmZmZddlmZddlm Z GdddZ dS)z`Represents a wheel file and provides access to the various parts of the name that have meaning. N)DictIterableList)Tag)InvalidWheelFilenamec@seZdZdZedejZdeddfddZ de efdd Z d e e de fd d Zd e e d ee e fde fddZd ee defddZdS)Wheelz A wheel filez^(?P(?P.+?)-(?P.*?)) ((-(?P\d[^-]*?))?-(?P.+?)-(?P.+?)-(?P.+?) \.whl|\.dist-info)$filenamereturnNcsj|}|st|d|_|ddd_|ddd_|d_|d d_ |d  d_ |d  d_ fd d j D_ d S)zX :raises InvalidWheelFilename: when the filename is invalid for a wheel z is not a valid wheel filename.name_-verbuildpyver.abiplatcs0h|]}jD]}jD]}t|||q qqS)abisplatsr).0xyzselfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/models/wheel.py (s  z!Wheel.__init__..N) wheel_file_rematchrrgroupreplacer version build_tagsplit pyversionsrr file_tags)rr wheel_inforrr__init__s    zWheel.__init__cCstdd|jDS)z4Return the wheel's tags as a sorted list of strings.css|]}t|VqdSN)strrtagrrr .sz0Wheel.get_formatted_file_tags..)sortedr&rrrrget_formatted_file_tags,szWheel.get_formatted_file_tagstagsctfdd|jDS)aReturn the lowest index that one of the wheel's file_tag combinations achieves in the given list of supported tags. For example, if there are 8 supported tags and one of the file tags is first in the list, then return 0. :param tags: the PEP 425 tags to check the wheel against, in order with most preferred first. :raises ValueError: If none of the wheel's file tags match one of the supported tags. c3s"|] }|vr|VqdSr))indexr+r0rrr-=s z*Wheel.support_index_min..minr&rr0rr3rsupport_index_min0s zWheel.support_index_mintag_to_prioritycr1)aReturn the priority of the most preferred tag that one of the wheel's file tag combinations achieves in the given list of supported tags using the given tag_to_priority mapping, where lower priorities are more-preferred. This is used in place of support_index_min in some cases in order to avoid an expensive linear scan of a large list of tags. :param tags: the PEP 425 tags to check the wheel against. :param tag_to_priority: a mapping from tag to priority of that tag, where lower is more preferred. :raises ValueError: If none of the wheel's file tags match one of the supported tags. c3s |] }|vr|VqdSr)rr+r8rrr-Psz0Wheel.find_most_preferred_tag..r4)rr0r8rr9rfind_most_preferred_tag?s zWheel.find_most_preferred_tagcCs|j| S)zReturn whether the wheel is compatible with one of the given tags. :param tags: the PEP 425 tags to check the wheel against. )r& isdisjointr6rrr supportedTszWheel.supported)__name__ __module__ __qualname____doc__recompileVERBOSErr*r(rr/rintr7rr:rboolr<rrrrr s"  r) r@rAtypingrrrZpip._vendor.packaging.tagsrpip._internal.exceptionsrrrrrrs   PKH]MN''Npython3.10/site-packages/pip/_internal/models/__pycache__/link.cpython-310.pycnu[o aiY&@sddlZddlZddlZddlZddlZddlZddlmZm Z m Z m Z m Z m Z mZddlmZddlmZddlmZmZmZddlmZddlmZmZerVddlmZeeZ d Z!Gd d d eZ"Gd d d e Z#de"de#fddZ$ej%ddde"de"de&fddZ'dS)N) TYPE_CHECKINGDictList NamedTupleOptionalTupleUnion)WHEEL_EXTENSION)Hashes)redact_auth_from_urlsplit_auth_from_netlocsplitext)KeyBasedCompareMixin) path_to_url url_to_path)HTMLPage)sha1sha224sha384sha256sha512md5c s6eZdZdZgdZ    dBdedeeedfdeed eed ed df fd d Z d efddZ d efddZ e d efddZ e d efddZe d efddZe d efddZe d efddZe d efddZd eeeffddZe d efd d!Ze d efd"d#Zed$Ze d eefd%d&Zed'Ze d eefd(d)Zed*jd+ed,Z e d eefd-d.Z!e d eefd/d0Z"e d efd1d2Z#e d efd3d4Z$d efd5d6Z%e d efd7d8Z&e d efd9d:Z'e d efd;d<Z(e d efd=d>Z)d?ee*d efd@dAZ+Z,S)CLinkz:Represents a parsed link from a Package Index's simple URL) _parsed_url_url comes_fromrequires_python yanked_reasoncache_link_parsingNTurlrrrrrreturncsZ|dr t|}tj||_||_||_|r|nd|_||_ t j |t d||_ dS)a :param url: url of the resource pointed to (href of the link) :param comes_from: instance of HTMLPage where the link was found, or string. :param requires_python: String containing the `Requires-Python` metadata field, specified in PEP 345. This may be specified by a data-requires-python attribute in the HTML link tag, as described in PEP 503. :param yanked_reason: the reason the file has been yanked, if the file has been yanked, or None if the file hasn't been yanked. This is the value of the "data-yanked" attribute, if present, in a simple repository HTML link. If the file has been yanked but no reason was provided, this should be the empty string. See PEP 592 for more information and the specification. :param cache_link_parsing: A flag that is used elsewhere to determine whether resources retrieved from this link should be cached. PyPI index urls should generally have this set to False, for example. z\\N)keydefining_class) startswithrurllibparseurlsplitrrrrrsuper__init__rr)selfrrrrr __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/models/link.pyr((s  z Link.__init__cCsD|jr d|jd}nd}|jrdt|j|j|Stt|jS)Nz (requires-python:)z{} (from {}){})rrformatr rstr)r)rpr,r,r-__str__Vsz Link.__str__cCs d|dS)Nzr,r)r,r,r-__repr__bs z Link.__repr__cCs|jSN)rr5r,r,r-reszLink.urlcCsR|jd}t|}|st|j\}}|Stj|}|s'Jd|j d|S)N/zURL z produced no filename) pathrstrip posixpathbasenamer netlocr$r%unquoter)r)r9namer= user_passr,r,r-filenameis   z Link.filenamecCs t|jSr7)rrr5r,r,r- file_pathw zLink.file_pathcC|jjSr7)rschemer5r,r,r-rE{sz Link.schemecCrD)z4 This can contain auth information. )rr=r5r,r,r-r=sz Link.netloccCstj|jjSr7)r$r%r>rr9r5r,r,r-r9z Link.pathcCstt|jdS)Nr8)r r;r<r9r:r5r,r,r-r sz Link.splitextcCs |dSN)r r5r,r,r-exts zLink.extcCs&|j\}}}}}tj||||dfS)Nr/)rr$r% urlunsplit)r)rEr=r9queryfragmentr,r,r-url_without_fragmentszLink.url_without_fragmentz[#&]egg=([^&]*)cC |j|j}|s dS|dSrG)_egg_fragment_researchrgroupr)matchr,r,r- egg_fragment zLink.egg_fragmentz[#&]subdirectory=([^&]*)cCrNrG)_subdirectory_fragment_rerPrrQrRr,r,r-subdirectory_fragmentrUzLink.subdirectory_fragmentz({choices})=([a-f0-9]+)|)choicescC |j|j}|r|dSdS)N_hash_rerPrrQrRr,r,r-hash z Link.hashcCrZrGr\rRr,r,r- hash_namer_zLink.hash_namecCs$t|jddddddS)N#rHr?)r;r<rsplitr5r,r,r-show_urls$z Link.show_urlcCs |jdkS)Nfile)rEr5r,r,r-is_filerCz Link.is_filecCs|jo tj|jSr7)rfosr9isdirrBr5r,r,r-is_existing_dirszLink.is_existing_dircCs |jtkSr7)rIr r5r,r,r-is_wheelrCz Link.is_wheelcCsddlm}|j|jvS)Nr)vcs)pip._internal.vcsrkrE all_schemes)r)rkr,r,r-is_vcss  z Link.is_vcscC |jduSr7)rr5r,r,r- is_yankedrCzLink.is_yankedcCror7)r`r5r,r,r-has_hashrCz Link.has_hashhashescCs@|dus|js dS|jdusJ|jdusJ|j|j|jdS)zG Return True if the link has a hash and it is allowed. NF) hex_digest)rqr`r^is_hash_allowed)r)rrr,r,r-rts zLink.is_hash_allowed)NNNT)-__name__ __module__ __qualname____doc__ __slots__r1rrboolr(r3r6propertyrrArBrEr=r9rr rIrMrecompilerOrTrVrWr0join_SUPPORTED_HASHESr]r^r`rdrfrirjrnrprqr rt __classcell__r,r,r*r-rs .    rc@sJeZdZUdZejjed<ee e e fed<e ed<ee e fed<dS) _CleanResultaConvert link for equivalency check. This is used in the resolver to check whether two URL-specified requirements likely point to the same distribution and can be considered equivalent. This equivalency logic avoids comparing URLs literally, which can be too strict (e.g. "a=1&b=2" vs "b=2&a=1") and produce conflicts unexpecting to users. Currently this does three things: 1. Drop the basic auth part. This is technically wrong since a server can serve different content based on auth, but if it does that, it is even impossible to guarantee two URLs without auth are equivalent, since the user can input different auth information when prompted. So the practical solution is to assume the auth doesn't affect the response. 2. Parse the query to avoid the ordering issue. Note that ordering under the same key in the query are NOT cleaned; i.e. "a=1&a=2" and "a=2&a=1" are still considered different. 3. Explicitly drop most of the fragment part, except ``subdirectory=`` and hash values, since it should have no impact the downloaded content. Note that this drops the "egg=" part historically used to denote the requested project (and extras), which is wrong in the strictest sense, but too many people are supplying it inconsistently to cause superfluous resolution conflicts, so we choose to also ignore them. parsedrK subdirectoryrrN) rurvrwrxr$r% SplitResult__annotations__rr1rr,r,r,r-rs  rlinkr c s|j}|jddd}|jdkr|sd}tj|jdvr&t d|zdd }Wn t t fy;d }Ynwfd d t D}t |j|d d d tj|j||dS)N@rHre localhosteggzIgnoring egg= fragment in %srrr/cs"i|] }|vr||dqS)rr,).0krLr,r- s"z_clean_link..)r=rKrL)rrKrrr)rr=rsplitrEr$r%parse_qsrLloggerdebug IndexErrorKeyErrorrr_replacerK)rrr=rrrr,rr- _clean_links&  r)maxsizelink1link2cCst|t|kSr7)r)rrr,r,r-links_equivalentrFr)( functoolsloggingrgr;r| urllib.parser$typingrrrrrrrpip._internal.utils.filetypesr pip._internal.utils.hashesr pip._internal.utils.miscr r r pip._internal.utils.modelsrpip._internal.utils.urlsrrpip._internal.index.collectorr getLoggerrurrrrr lru_cacherzrr,r,r,r-s,$     I PKH]7python3.10/site-packages/pip/_internal/models/scheme.pynu[""" For types associated with installation schemes. For a general overview of available schemes and their context, see https://docs.python.org/3/install/index.html#alternate-installation. """ SCHEME_KEYS = ["platlib", "purelib", "headers", "scripts", "data"] class Scheme: """A Scheme holds paths which are used as the base directories for artifacts associated with a Python package. """ __slots__ = SCHEME_KEYS def __init__( self, platlib: str, purelib: str, headers: str, scripts: str, data: str, ) -> None: self.platlib = platlib self.purelib = purelib self.headers = headers self.scripts = scripts self.data = data PKH]0O:python3.10/site-packages/pip/_internal/models/candidate.pynu[from pip._vendor.packaging.version import parse as parse_version from pip._internal.models.link import Link from pip._internal.utils.models import KeyBasedCompareMixin class InstallationCandidate(KeyBasedCompareMixin): """Represents a potential "candidate" for installation.""" __slots__ = ["name", "version", "link"] def __init__(self, name: str, version: str, link: Link) -> None: self.name = name self.version = parse_version(version) self.link = link super().__init__( key=(self.name, self.version, self.link), defining_class=InstallationCandidate, ) def __repr__(self) -> str: return "".format( self.name, self.version, self.link, ) def __str__(self) -> str: return "{!r} candidate (version {} at {})".format( self.name, self.version, self.link, ) PKH]'TA 6python3.10/site-packages/pip/_internal/models/wheel.pynu["""Represents a wheel file and provides access to the various parts of the name that have meaning. """ import re from typing import Dict, Iterable, List from pip._vendor.packaging.tags import Tag from pip._internal.exceptions import InvalidWheelFilename class Wheel: """A wheel file""" wheel_file_re = re.compile( r"""^(?P(?P.+?)-(?P.*?)) ((-(?P\d[^-]*?))?-(?P.+?)-(?P.+?)-(?P.+?) \.whl|\.dist-info)$""", re.VERBOSE, ) def __init__(self, filename: str) -> None: """ :raises InvalidWheelFilename: when the filename is invalid for a wheel """ wheel_info = self.wheel_file_re.match(filename) if not wheel_info: raise InvalidWheelFilename(f"{filename} is not a valid wheel filename.") self.filename = filename self.name = wheel_info.group("name").replace("_", "-") # we'll assume "_" means "-" due to wheel naming scheme # (https://github.com/pypa/pip/issues/1150) self.version = wheel_info.group("ver").replace("_", "-") self.build_tag = wheel_info.group("build") self.pyversions = wheel_info.group("pyver").split(".") self.abis = wheel_info.group("abi").split(".") self.plats = wheel_info.group("plat").split(".") # All the tag combinations from this file self.file_tags = { Tag(x, y, z) for x in self.pyversions for y in self.abis for z in self.plats } def get_formatted_file_tags(self) -> List[str]: """Return the wheel's tags as a sorted list of strings.""" return sorted(str(tag) for tag in self.file_tags) def support_index_min(self, tags: List[Tag]) -> int: """Return the lowest index that one of the wheel's file_tag combinations achieves in the given list of supported tags. For example, if there are 8 supported tags and one of the file tags is first in the list, then return 0. :param tags: the PEP 425 tags to check the wheel against, in order with most preferred first. :raises ValueError: If none of the wheel's file tags match one of the supported tags. """ return min(tags.index(tag) for tag in self.file_tags if tag in tags) def find_most_preferred_tag( self, tags: List[Tag], tag_to_priority: Dict[Tag, int] ) -> int: """Return the priority of the most preferred tag that one of the wheel's file tag combinations achieves in the given list of supported tags using the given tag_to_priority mapping, where lower priorities are more-preferred. This is used in place of support_index_min in some cases in order to avoid an expensive linear scan of a large list of tags. :param tags: the PEP 425 tags to check the wheel against. :param tag_to_priority: a mapping from tag to priority of that tag, where lower is more preferred. :raises ValueError: If none of the wheel's file tags match one of the supported tags. """ return min( tag_to_priority[tag] for tag in self.file_tags if tag in tag_to_priority ) def supported(self, tags: Iterable[Tag]) -> bool: """Return whether the wheel is compatible with one of the given tags. :param tags: the PEP 425 tags to check the wheel against. """ return not self.file_tags.isdisjoint(tags) PKH]QGe>python3.10/site-packages/pip/_internal/models/target_python.pynu[import sys from typing import List, Optional, Tuple from pip._vendor.packaging.tags import Tag from pip._internal.utils.compatibility_tags import get_supported, version_info_to_nodot from pip._internal.utils.misc import normalize_version_info class TargetPython: """ Encapsulates the properties of a Python interpreter one is targeting for a package install, download, etc. """ __slots__ = [ "_given_py_version_info", "abis", "implementation", "platforms", "py_version", "py_version_info", "_valid_tags", ] def __init__( self, platforms: Optional[List[str]] = None, py_version_info: Optional[Tuple[int, ...]] = None, abis: Optional[List[str]] = None, implementation: Optional[str] = None, ) -> None: """ :param platforms: A list of strings or None. If None, searches for packages that are supported by the current system. Otherwise, will find packages that can be built on the platforms passed in. These packages will only be downloaded for distribution: they will not be built locally. :param py_version_info: An optional tuple of ints representing the Python version information to use (e.g. `sys.version_info[:3]`). This can have length 1, 2, or 3 when provided. :param abis: A list of strings or None. This is passed to compatibility_tags.py's get_supported() function as is. :param implementation: A string or None. This is passed to compatibility_tags.py's get_supported() function as is. """ # Store the given py_version_info for when we call get_supported(). self._given_py_version_info = py_version_info if py_version_info is None: py_version_info = sys.version_info[:3] else: py_version_info = normalize_version_info(py_version_info) py_version = ".".join(map(str, py_version_info[:2])) self.abis = abis self.implementation = implementation self.platforms = platforms self.py_version = py_version self.py_version_info = py_version_info # This is used to cache the return value of get_tags(). self._valid_tags: Optional[List[Tag]] = None def format_given(self) -> str: """ Format the given, non-None attributes for display. """ display_version = None if self._given_py_version_info is not None: display_version = ".".join( str(part) for part in self._given_py_version_info ) key_values = [ ("platforms", self.platforms), ("version_info", display_version), ("abis", self.abis), ("implementation", self.implementation), ] return " ".join( f"{key}={value!r}" for key, value in key_values if value is not None ) def get_tags(self) -> List[Tag]: """ Return the supported PEP 425 tags to check wheel candidates against. The tags are returned in order of preference (most preferred first). """ if self._valid_tags is None: # Pass versions=None if no py_version_info was given since # versions=None uses special default logic. py_version_info = self._given_py_version_info if py_version_info is None: version = None else: version = version_info_to_nodot(py_version_info) tags = get_supported( version=version, platforms=self.platforms, abis=self.abis, impl=self.implementation, ) self._valid_tags = tags return self._valid_tags PKH]U=*;python3.10/site-packages/pip/_internal/models/direct_url.pynu[""" PEP 610 """ import json import re import urllib.parse from typing import Any, Dict, Iterable, Optional, Type, TypeVar, Union __all__ = [ "DirectUrl", "DirectUrlValidationError", "DirInfo", "ArchiveInfo", "VcsInfo", ] T = TypeVar("T") DIRECT_URL_METADATA_NAME = "direct_url.json" ENV_VAR_RE = re.compile(r"^\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?$") class DirectUrlValidationError(Exception): pass def _get( d: Dict[str, Any], expected_type: Type[T], key: str, default: Optional[T] = None ) -> Optional[T]: """Get value from dictionary and verify expected type.""" if key not in d: return default value = d[key] if not isinstance(value, expected_type): raise DirectUrlValidationError( "{!r} has unexpected type for {} (expected {})".format( value, key, expected_type ) ) return value def _get_required( d: Dict[str, Any], expected_type: Type[T], key: str, default: Optional[T] = None ) -> T: value = _get(d, expected_type, key, default) if value is None: raise DirectUrlValidationError(f"{key} must have a value") return value def _exactly_one_of(infos: Iterable[Optional["InfoType"]]) -> "InfoType": infos = [info for info in infos if info is not None] if not infos: raise DirectUrlValidationError( "missing one of archive_info, dir_info, vcs_info" ) if len(infos) > 1: raise DirectUrlValidationError( "more than one of archive_info, dir_info, vcs_info" ) assert infos[0] is not None return infos[0] def _filter_none(**kwargs: Any) -> Dict[str, Any]: """Make dict excluding None values.""" return {k: v for k, v in kwargs.items() if v is not None} class VcsInfo: name = "vcs_info" def __init__( self, vcs: str, commit_id: str, requested_revision: Optional[str] = None, resolved_revision: Optional[str] = None, resolved_revision_type: Optional[str] = None, ) -> None: self.vcs = vcs self.requested_revision = requested_revision self.commit_id = commit_id self.resolved_revision = resolved_revision self.resolved_revision_type = resolved_revision_type @classmethod def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["VcsInfo"]: if d is None: return None return cls( vcs=_get_required(d, str, "vcs"), commit_id=_get_required(d, str, "commit_id"), requested_revision=_get(d, str, "requested_revision"), resolved_revision=_get(d, str, "resolved_revision"), resolved_revision_type=_get(d, str, "resolved_revision_type"), ) def _to_dict(self) -> Dict[str, Any]: return _filter_none( vcs=self.vcs, requested_revision=self.requested_revision, commit_id=self.commit_id, resolved_revision=self.resolved_revision, resolved_revision_type=self.resolved_revision_type, ) class ArchiveInfo: name = "archive_info" def __init__( self, hash: Optional[str] = None, ) -> None: self.hash = hash @classmethod def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["ArchiveInfo"]: if d is None: return None return cls(hash=_get(d, str, "hash")) def _to_dict(self) -> Dict[str, Any]: return _filter_none(hash=self.hash) class DirInfo: name = "dir_info" def __init__( self, editable: bool = False, ) -> None: self.editable = editable @classmethod def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["DirInfo"]: if d is None: return None return cls(editable=_get_required(d, bool, "editable", default=False)) def _to_dict(self) -> Dict[str, Any]: return _filter_none(editable=self.editable or None) InfoType = Union[ArchiveInfo, DirInfo, VcsInfo] class DirectUrl: def __init__( self, url: str, info: InfoType, subdirectory: Optional[str] = None, ) -> None: self.url = url self.info = info self.subdirectory = subdirectory def _remove_auth_from_netloc(self, netloc: str) -> str: if "@" not in netloc: return netloc user_pass, netloc_no_user_pass = netloc.split("@", 1) if ( isinstance(self.info, VcsInfo) and self.info.vcs == "git" and user_pass == "git" ): return netloc if ENV_VAR_RE.match(user_pass): return netloc return netloc_no_user_pass @property def redacted_url(self) -> str: """url with user:password part removed unless it is formed with environment variables as specified in PEP 610, or it is ``git`` in the case of a git URL. """ purl = urllib.parse.urlsplit(self.url) netloc = self._remove_auth_from_netloc(purl.netloc) surl = urllib.parse.urlunsplit( (purl.scheme, netloc, purl.path, purl.query, purl.fragment) ) return surl def validate(self) -> None: self.from_dict(self.to_dict()) @classmethod def from_dict(cls, d: Dict[str, Any]) -> "DirectUrl": return DirectUrl( url=_get_required(d, str, "url"), subdirectory=_get(d, str, "subdirectory"), info=_exactly_one_of( [ ArchiveInfo._from_dict(_get(d, dict, "archive_info")), DirInfo._from_dict(_get(d, dict, "dir_info")), VcsInfo._from_dict(_get(d, dict, "vcs_info")), ] ), ) def to_dict(self) -> Dict[str, Any]: res = _filter_none( url=self.redacted_url, subdirectory=self.subdirectory, ) res[self.info.name] = self.info._to_dict() return res @classmethod def from_json(cls, s: str) -> "DirectUrl": return cls.from_dict(json.loads(s)) def to_json(self) -> str: return json.dumps(self.to_dict(), sort_keys=True) def is_local_editable(self) -> bool: return isinstance(self.info, DirInfo) and self.info.editable PKH]Z0tTY&Y&5python3.10/site-packages/pip/_internal/models/link.pynu[import functools import logging import os import posixpath import re import urllib.parse from typing import TYPE_CHECKING, Dict, List, NamedTuple, Optional, Tuple, Union from pip._internal.utils.filetypes import WHEEL_EXTENSION from pip._internal.utils.hashes import Hashes from pip._internal.utils.misc import ( redact_auth_from_url, split_auth_from_netloc, splitext, ) from pip._internal.utils.models import KeyBasedCompareMixin from pip._internal.utils.urls import path_to_url, url_to_path if TYPE_CHECKING: from pip._internal.index.collector import HTMLPage logger = logging.getLogger(__name__) _SUPPORTED_HASHES = ("sha1", "sha224", "sha384", "sha256", "sha512", "md5") class Link(KeyBasedCompareMixin): """Represents a parsed link from a Package Index's simple URL""" __slots__ = [ "_parsed_url", "_url", "comes_from", "requires_python", "yanked_reason", "cache_link_parsing", ] def __init__( self, url: str, comes_from: Optional[Union[str, "HTMLPage"]] = None, requires_python: Optional[str] = None, yanked_reason: Optional[str] = None, cache_link_parsing: bool = True, ) -> None: """ :param url: url of the resource pointed to (href of the link) :param comes_from: instance of HTMLPage where the link was found, or string. :param requires_python: String containing the `Requires-Python` metadata field, specified in PEP 345. This may be specified by a data-requires-python attribute in the HTML link tag, as described in PEP 503. :param yanked_reason: the reason the file has been yanked, if the file has been yanked, or None if the file hasn't been yanked. This is the value of the "data-yanked" attribute, if present, in a simple repository HTML link. If the file has been yanked but no reason was provided, this should be the empty string. See PEP 592 for more information and the specification. :param cache_link_parsing: A flag that is used elsewhere to determine whether resources retrieved from this link should be cached. PyPI index urls should generally have this set to False, for example. """ # url can be a UNC windows share if url.startswith("\\\\"): url = path_to_url(url) self._parsed_url = urllib.parse.urlsplit(url) # Store the url as a private attribute to prevent accidentally # trying to set a new value. self._url = url self.comes_from = comes_from self.requires_python = requires_python if requires_python else None self.yanked_reason = yanked_reason super().__init__(key=url, defining_class=Link) self.cache_link_parsing = cache_link_parsing def __str__(self) -> str: if self.requires_python: rp = f" (requires-python:{self.requires_python})" else: rp = "" if self.comes_from: return "{} (from {}){}".format( redact_auth_from_url(self._url), self.comes_from, rp ) else: return redact_auth_from_url(str(self._url)) def __repr__(self) -> str: return f"" @property def url(self) -> str: return self._url @property def filename(self) -> str: path = self.path.rstrip("/") name = posixpath.basename(path) if not name: # Make sure we don't leak auth information if the netloc # includes a username and password. netloc, user_pass = split_auth_from_netloc(self.netloc) return netloc name = urllib.parse.unquote(name) assert name, f"URL {self._url!r} produced no filename" return name @property def file_path(self) -> str: return url_to_path(self.url) @property def scheme(self) -> str: return self._parsed_url.scheme @property def netloc(self) -> str: """ This can contain auth information. """ return self._parsed_url.netloc @property def path(self) -> str: return urllib.parse.unquote(self._parsed_url.path) def splitext(self) -> Tuple[str, str]: return splitext(posixpath.basename(self.path.rstrip("/"))) @property def ext(self) -> str: return self.splitext()[1] @property def url_without_fragment(self) -> str: scheme, netloc, path, query, fragment = self._parsed_url return urllib.parse.urlunsplit((scheme, netloc, path, query, "")) _egg_fragment_re = re.compile(r"[#&]egg=([^&]*)") @property def egg_fragment(self) -> Optional[str]: match = self._egg_fragment_re.search(self._url) if not match: return None return match.group(1) _subdirectory_fragment_re = re.compile(r"[#&]subdirectory=([^&]*)") @property def subdirectory_fragment(self) -> Optional[str]: match = self._subdirectory_fragment_re.search(self._url) if not match: return None return match.group(1) _hash_re = re.compile( r"({choices})=([a-f0-9]+)".format(choices="|".join(_SUPPORTED_HASHES)) ) @property def hash(self) -> Optional[str]: match = self._hash_re.search(self._url) if match: return match.group(2) return None @property def hash_name(self) -> Optional[str]: match = self._hash_re.search(self._url) if match: return match.group(1) return None @property def show_url(self) -> str: return posixpath.basename(self._url.split("#", 1)[0].split("?", 1)[0]) @property def is_file(self) -> bool: return self.scheme == "file" def is_existing_dir(self) -> bool: return self.is_file and os.path.isdir(self.file_path) @property def is_wheel(self) -> bool: return self.ext == WHEEL_EXTENSION @property def is_vcs(self) -> bool: from pip._internal.vcs import vcs return self.scheme in vcs.all_schemes @property def is_yanked(self) -> bool: return self.yanked_reason is not None @property def has_hash(self) -> bool: return self.hash_name is not None def is_hash_allowed(self, hashes: Optional[Hashes]) -> bool: """ Return True if the link has a hash and it is allowed. """ if hashes is None or not self.has_hash: return False # Assert non-None so mypy knows self.hash_name and self.hash are str. assert self.hash_name is not None assert self.hash is not None return hashes.is_hash_allowed(self.hash_name, hex_digest=self.hash) class _CleanResult(NamedTuple): """Convert link for equivalency check. This is used in the resolver to check whether two URL-specified requirements likely point to the same distribution and can be considered equivalent. This equivalency logic avoids comparing URLs literally, which can be too strict (e.g. "a=1&b=2" vs "b=2&a=1") and produce conflicts unexpecting to users. Currently this does three things: 1. Drop the basic auth part. This is technically wrong since a server can serve different content based on auth, but if it does that, it is even impossible to guarantee two URLs without auth are equivalent, since the user can input different auth information when prompted. So the practical solution is to assume the auth doesn't affect the response. 2. Parse the query to avoid the ordering issue. Note that ordering under the same key in the query are NOT cleaned; i.e. "a=1&a=2" and "a=2&a=1" are still considered different. 3. Explicitly drop most of the fragment part, except ``subdirectory=`` and hash values, since it should have no impact the downloaded content. Note that this drops the "egg=" part historically used to denote the requested project (and extras), which is wrong in the strictest sense, but too many people are supplying it inconsistently to cause superfluous resolution conflicts, so we choose to also ignore them. """ parsed: urllib.parse.SplitResult query: Dict[str, List[str]] subdirectory: str hashes: Dict[str, str] def _clean_link(link: Link) -> _CleanResult: parsed = link._parsed_url netloc = parsed.netloc.rsplit("@", 1)[-1] # According to RFC 8089, an empty host in file: means localhost. if parsed.scheme == "file" and not netloc: netloc = "localhost" fragment = urllib.parse.parse_qs(parsed.fragment) if "egg" in fragment: logger.debug("Ignoring egg= fragment in %s", link) try: # If there are multiple subdirectory values, use the first one. # This matches the behavior of Link.subdirectory_fragment. subdirectory = fragment["subdirectory"][0] except (IndexError, KeyError): subdirectory = "" # If there are multiple hash values under the same algorithm, use the # first one. This matches the behavior of Link.hash_value. hashes = {k: fragment[k][0] for k in _SUPPORTED_HASHES if k in fragment} return _CleanResult( parsed=parsed._replace(netloc=netloc, query="", fragment=""), query=urllib.parse.parse_qs(parsed.query), subdirectory=subdirectory, hashes=hashes, ) @functools.lru_cache(maxsize=None) def links_equivalent(link1: Link, link2: Link) -> bool: return _clean_link(link1) == _clean_link(link2) PKH]ss@python3.10/site-packages/pip/_internal/models/selection_prefs.pynu[from typing import Optional from pip._internal.models.format_control import FormatControl class SelectionPreferences: """ Encapsulates the candidate selection preferences for downloading and installing files. """ __slots__ = [ "allow_yanked", "allow_all_prereleases", "format_control", "prefer_binary", "ignore_requires_python", ] # Don't include an allow_yanked default value to make sure each call # site considers whether yanked releases are allowed. This also causes # that decision to be made explicit in the calling code, which helps # people when reading the code. def __init__( self, allow_yanked: bool, allow_all_prereleases: bool = False, format_control: Optional[FormatControl] = None, prefer_binary: bool = False, ignore_requires_python: Optional[bool] = None, ) -> None: """Create a SelectionPreferences object. :param allow_yanked: Whether files marked as yanked (in the sense of PEP 592) are permitted to be candidates for install. :param format_control: A FormatControl object or None. Used to control the selection of source packages / binary packages when consulting the index and links. :param prefer_binary: Whether to prefer an old, but valid, binary dist over a new source dist. :param ignore_requires_python: Whether to ignore incompatible "Requires-Python" values in links. Defaults to False. """ if ignore_requires_python is None: ignore_requires_python = False self.allow_yanked = allow_yanked self.allow_all_prereleases = allow_all_prereleases self.format_control = format_control self.prefer_binary = prefer_binary self.ignore_requires_python = ignore_requires_python PKH]{(??9python3.10/site-packages/pip/_internal/models/__init__.pynu["""A package that contains models that represent entities. """ PKH] W7=python3.10/site-packages/pip/_internal/models/search_scope.pynu[import itertools import logging import os import posixpath import urllib.parse from typing import List from pip._vendor.packaging.utils import canonicalize_name from pip._internal.models.index import PyPI from pip._internal.utils.compat import has_tls from pip._internal.utils.misc import normalize_path, redact_auth_from_url logger = logging.getLogger(__name__) class SearchScope: """ Encapsulates the locations that pip is configured to search. """ __slots__ = ["find_links", "index_urls"] @classmethod def create( cls, find_links: List[str], index_urls: List[str], ) -> "SearchScope": """ Create a SearchScope object after normalizing the `find_links`. """ # Build find_links. If an argument starts with ~, it may be # a local file relative to a home directory. So try normalizing # it and if it exists, use the normalized version. # This is deliberately conservative - it might be fine just to # blindly normalize anything starting with a ~... built_find_links: List[str] = [] for link in find_links: if link.startswith("~"): new_link = normalize_path(link) if os.path.exists(new_link): link = new_link built_find_links.append(link) # If we don't have TLS enabled, then WARN if anyplace we're looking # relies on TLS. if not has_tls(): for link in itertools.chain(index_urls, built_find_links): parsed = urllib.parse.urlparse(link) if parsed.scheme == "https": logger.warning( "pip is configured with locations that require " "TLS/SSL, however the ssl module in Python is not " "available." ) break return cls( find_links=built_find_links, index_urls=index_urls, ) def __init__( self, find_links: List[str], index_urls: List[str], ) -> None: self.find_links = find_links self.index_urls = index_urls def get_formatted_locations(self) -> str: lines = [] redacted_index_urls = [] if self.index_urls and self.index_urls != [PyPI.simple_url]: for url in self.index_urls: redacted_index_url = redact_auth_from_url(url) # Parse the URL purl = urllib.parse.urlsplit(redacted_index_url) # URL is generally invalid if scheme and netloc is missing # there are issues with Python and URL parsing, so this test # is a bit crude. See bpo-20271, bpo-23505. Python doesn't # always parse invalid URLs correctly - it should raise # exceptions for malformed URLs if not purl.scheme and not purl.netloc: logger.warning( 'The index url "%s" seems invalid, please provide a scheme.', redacted_index_url, ) redacted_index_urls.append(redacted_index_url) lines.append( "Looking in indexes: {}".format(", ".join(redacted_index_urls)) ) if self.find_links: lines.append( "Looking in links: {}".format( ", ".join(redact_auth_from_url(url) for url in self.find_links) ) ) return "\n".join(lines) def get_index_urls_locations(self, project_name: str) -> List[str]: """Returns the locations found via self.index_urls Checks the url_name on the main (first in the list) index and use this url_name to produce all locations """ def mkurl_pypi_url(url: str) -> str: loc = posixpath.join( url, urllib.parse.quote(canonicalize_name(project_name)) ) # For maximum compatibility with easy_install, ensure the path # ends in a trailing slash. Although this isn't in the spec # (and PyPI can handle it without the slash) some other index # implementations might break if they relied on easy_install's # behavior. if not loc.endswith("/"): loc = loc + "/" return loc return [mkurl_pypi_url(url) for url in self.index_urls] PKH]!&Ypython3.10/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-310.pycnu[o ai@sddlZddlZddlmZmZmZmZmZm Z ddl m Z ddl m Z ddlmZmZddlmZddlmZddlmZmZdd lmZd d lmZmZmZmZm Z e!e"Z#Gd d d eZ$GdddeZ%GdddeZ&dS)N) CollectionIterableIteratorList NamedTupleOptional) pkg_resources) Requirement)NormalizedNamecanonicalize_name)parse)misc) get_installer get_metadata)$pkg_resources_distribution_for_wheel)BaseDistributionBaseEntryPointBaseEnvironmentDistributionVersionWheelc@s&eZdZUeed<eed<eed<dS) EntryPointnamevaluegroupN)__name__ __module__ __qualname__str__annotations__r r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/metadata/pkg_resources.pyrs  rc@s:eZdZdejddfddZedededdfdd Z e de efd d Z e de efd d Z e defddZe defddZe defddZe defddZe defddZe defddZdedefddZdeefddZe dejjfddZd&d!eedee fd"d#Z!deefd$d%Z"dS)' DistributiondistreturnNcC ||_dSN)_distselfr#r r r!__init__  zDistribution.__init__wheelrcCsD|}t|||j}Wd||S1swY||Sr&) as_zipfilerlocation)clsr,rzfr#r r r! from_wheel#s  zDistribution.from_wheelcC|jjSr&)r'r.r)r r r!r.)zDistribution.locationcCr2r&)r'egg_infor3r r r!info_directory-r4zDistribution.info_directorycC t|jjSr&)r r' project_namer3r r r!canonical_name1 zDistribution.canonical_namecCr7r&) parse_versionr'versionr3r r r!r<5r:zDistribution.versioncC t|jSr&)rr'r3r r r! installer9 zDistribution.installercC t|jSr&)r dist_is_localr'r3r r r!local=r:zDistribution.localcCr@r&)r dist_in_usersiter'r3r r r! in_usersiteAr:zDistribution.in_usersitecCr@r&)r dist_in_site_packagesr'r3r r r!in_site_packagesEr:zDistribution.in_site_packagescCs |j|s t||j|Sr&)r' has_metadataFileNotFoundErrorr)r)rr r r! read_textIs  zDistribution.read_textccs\|jD]#\}}|D]\}}t|d\}}}t|||dVqqdS)N=)rrr)r' get_entry_mapitemsr partitionrstrip)r)rentriesr entry_point_rr r r!iter_entry_pointsNszDistribution.iter_entry_pointscCr=r&)rr'r3r r r!metadataTr?zDistribution.metadatar extrascCs"|r t||jj}|j|Sr&) frozenset intersectionr'rTrequires)r)rTr r r!iter_dependenciesXs zDistribution.iter_dependenciescCr2r&)r'rTr3r r r!iter_provided_extras]sz!Distribution.iter_provided_extras)r )#rrrrr"r* classmethodrrr1propertyrr.r6r r9rr<r>boolrBrDrFrIrrrRemailmessageMessagerSrr rXrYr r r r!r"s4r"c@seZdZdejddfddZedefddZede e e defd d Z d e de e fd d Zd e de e fddZdee fddZdS) Environmentwsr$NcCr%r&)_ws)r)rar r r!r*br+zEnvironment.__init__cCs |tjSr&)r working_set)r/r r r!defaulter?zEnvironment.defaultpathscCs|t|Sr&)r WorkingSet)r/rer r r! from_pathsiszEnvironment.from_pathsrcCs,t|}|D] }|j|kr|SqdS)zFind a distribution matching the ``name`` in the environment. This searches from *all* distributions available in the environment, to match the behavior of ``pkg_resources.get_distribution()``. N)r iter_distributionsr9)r)rr9r#r r r!_search_distributionms   z Environment._search_distributioncCsD||}|r |Sz|j|Wn tjyYdSw||Sr&)rirbrequirerDistributionNotFound)r)rr#r r r!get_distributionys   zEnvironment.get_distributionccs|jD]}t|VqdSr&)rbr"r(r r r!_iter_distributionss  zEnvironment._iter_distributions)rrrrrfr*rZrrdrrrrgrrirlrrmr r r r!r`as r`)' email.messager]loggingtypingrrrrrr pip._vendorrZ"pip._vendor.packaging.requirementsr pip._vendor.packaging.utilsr r Zpip._vendor.packaging.versionr r;pip._internal.utilsr pip._internal.utils.packagingrrpip._internal.utils.wheelrbaserrrrr getLoggerrloggerrr"r`r r r r!s       BPKH][Tpython3.10/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-310.pycnu[o ai|@svddlmZmZddlmZmZmZmZmZgdZ defddZ deee defd d Z d ed e defd dZ dS))ListOptional)BaseDistributionBaseEnvironmentFilesystemWheel MemoryWheelWheel)rrrrr get_default_environmentget_environmentget_wheel_distributionreturncCsddlm}|S)a Get the default representation for the current environment. This returns an Environment instance from the chosen backend. The default Environment instance should be built from ``sys.path`` and may use caching to share instance state accorss calls. r Environment) pkg_resourcesrdefaultrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/metadata/__init__.pyr s r pathscCsddlm}||S)a'Get a representation of the environment specified by ``paths``. This returns an Environment instance from the chosen backend based on the given import paths. The backend must build a fresh instance representing the state of installed distributions when this function is called. rr)rr from_paths)rrrrrr s  r wheelcanonical_namecCsddlm}|||S)aGet the representation of the specified wheel's distribution metadata. This returns a Distribution instance from the chosen backend based on the given wheel's ``.dist-info`` directory. :param canonical_name: Normalized project name of the given wheel. r) Distribution)rr from_wheel)rrrrrrr )s  r N)typingrrbaserrrrr __all__r strr r rrrrs    PKH].11Ppython3.10/site-packages/pip/_internal/metadata/__pycache__/base.cpython-310.pycnu[o ai_+@sRddlZddlZddlZddlZddlZddlmZmZm Z m Z m Z m Z m Z mZmZddlmZddlmZmZddlmZddlmZmZddlmZmZmZddlmZdd l m!Z!dd l"m#Z#erkdd lm$Z$ne%Z$eeefZ&e'e(Z)Gd d d e$Z*Gddde$Z+GdddZ,Gddde$Z-Gddde-Z.Gddde-Z/dS)N) IO TYPE_CHECKING Collection ContainerIterableIteratorListOptionalUnion) Requirement)InvalidSpecifier SpecifierSet)NormalizedName) LegacyVersionVersion)DIRECT_URL_METADATA_NAME DirectUrlDirectUrlValidationError) stdlib_pkgs)egg_link_path_from_sys_path) url_to_path)Protocolc@sBeZdZedefddZedefddZedefddZdS) BaseEntryPointreturncCtNNotImplementedErrorselfr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/metadata/base.pyname+zBaseEntryPoint.namecCrrrrr r r!value/r#zBaseEntryPoint.valuecCrrrrr r r!group3r#zBaseEntryPoint.groupN)__name__ __module__ __qualname__propertystrr"r$r%r r r r!r*src@seZdZdefddZdefddZedeefddZedeefdd Z edeefd d Z ede fd d Z ede fddZedeefddZedefddZedefddZedefddZedefddZedefddZdedefddZdeefdd Zedejjfd!d"Zedeefd#d$Zedefd%d&Z ede!fd'd(Z"d0d*e#edee$fd+d,Z%deefd-d.Z&d/S)1BaseDistributionrcCs|jd|jd|jdS)N z ())raw_nameversionlocationrr r r!__repr__9szBaseDistribution.__repr__cCs|jd|jS)Nr,)r.r/rr r r!__str__<szBaseDistribution.__str__cCr)aWhere the distribution is loaded from. A string value is not necessarily a filesystem path, since distributions can be loaded from other sources, e.g. arbitrary zip archives. ``None`` means the distribution is created in-memory. Do not canonicalize this value with e.g. ``pathlib.Path.resolve()``. If this is a symbolic link, we want to preserve the relative path between it and files in the distribution. rrr r r!r0?s zBaseDistribution.locationcCs8|j}|r|rt|jSdSt|j}|r|jSdS)zThe project location for editable distributions. This is the directory where pyproject.toml or setup.py is located. None if the distribution is not installed in editable mode. N) direct_urlis_local_editablerurlrr.r0)rr3 egg_link_pathr r r!editable_project_locationMs  z*BaseDistribution.editable_project_locationcCr)a'Location of the .[egg|dist]-info directory. Similarly to ``location``, a string value is not necessarily a filesystem path. ``None`` means the distribution is created in-memory. For a modern .dist-info installation on disk, this should be something like ``{location}/{raw_name}-{version}.dist-info``. Do not canonicalize this value with e.g. ``pathlib.Path.resolve()``. If this is a symbolic link, we want to preserve the relative path between it and other files in the distribution. rrr r r!info_directorycszBaseDistribution.info_directorycCrrrrr r r!canonical_namesr#zBaseDistribution.canonical_namecCrrrrr r r!r/wr#zBaseDistribution.versionc Csrz|t}Wn tyYdSwzt|WSttjtfy8}zt dt|j |WYd}~dSd}~ww)zObtain a DirectUrl from this distribution. Returns None if the distribution has no `direct_url.json` metadata, or if `direct_url.json` is invalid. NzError parsing %s for %s: %s) read_textrFileNotFoundErrorr from_jsonUnicodeDecodeErrorjsonJSONDecodeErrorrloggerwarningr9)rcontenter r r!r3{s*   zBaseDistribution.direct_urlcCrrrrr r r! installerr#zBaseDistribution.installercCs t|jSr)boolr7rr r r!editables zBaseDistribution.editablecCrrrrr r r!localr#zBaseDistribution.localcCrrrrr r r! in_usersiter#zBaseDistribution.in_usersitecCrrrrr r r!in_site_packagesr#z!BaseDistribution.in_site_packagesr"cCr)zRead a file in the .dist-info (or .egg-info) directory. Should raise ``FileNotFoundError`` if ``name`` does not exist in the metadata directory. rrr"r r r!r:zBaseDistribution.read_textcCrrrrr r r!iter_entry_pointsz"BaseDistribution.iter_entry_pointscCr)z?Metadata of distribution parsed from e.g. METADATA or PKG-INFO.rrr r r!metadataszBaseDistribution.metadatacCs |jdS)zDValue of "Metadata-Version:" in distribution metadata, if available.zMetadata-Version)rNgetrr r r!metadata_versions z!BaseDistribution.metadata_versioncCs|jd|jS)z*Value of "Name:" in distribution metadata.Name)rNrOr9rr r r!r.szBaseDistribution.raw_namec Csl|jd}|dur tSz tt|}W|Sty5}zd}t||j|tWYd}~Sd}~ww)zValue of "Requires-Python:" in distribution metadata. If the key does not exist or contains an invalid value, an empty SpecifierSet should be returned. zRequires-PythonNz-Package %r has an invalid Requires-Python: %s)rNrOr r*r r@rAr.)rr$specrCmessager r r!requires_pythons z BaseDistribution.requires_pythonr extrascCr)zDependencies of this distribution. For modern .dist-info distributions, this is the collection of "Requires-Dist:" entries in distribution metadata. r)rrUr r r!iter_dependenciesrKz"BaseDistribution.iter_dependenciescCr)zExtras provided by this distribution. For modern .dist-info distributions, this is the collection of "Provides-Extra:" entries in distribution metadata. rrr r r!iter_provided_extrasrKz%BaseDistribution.iter_provided_extrasN)r )'r&r'r(r*r1r2r)r r0r7r8rr9DistributionVersionr/rr3rDrErFrGrHrIr:rrrLemailrSMessagerNrPr.r rTrr rVrWr r r r!r+8sJ r+c@seZdZdZedddZedeeeddfddZ deded fd d Z de d fd d Z de d fddZ dedddfdedeedededede ef ddZdS)BaseEnvironmentz6An environment containing distributions to introspect.rcCrrr)clsr r r!defaultr#zBaseEnvironment.defaultpathscCrrr)r\r^r r r! from_pathsr#zBaseEnvironment.from_pathsr"r+cCr)z=Given a requirement name, return the installed distributions.rrJr r r!get_distributionr#z BaseEnvironment.get_distributioncCr)aIterate through installed distributions. This function should be implemented by subclass, but never called directly. Use the public ``iter_distribution()`` instead, which implements additional logic to make sure the distributions are valid. rrr r r!_iter_distributionssz#BaseEnvironment._iter_distributionsccsF|D]}tjd|jtjd}|std|j|jq|VqdS)z(Iterate through installed distributions.z)^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$)flagsz%Ignoring invalid distribution %s (%s)N)rarematchr9 IGNORECASEr@rAr0)rdistproject_name_validr r r!iter_distributionss  z"BaseEnvironment.iter_distributionsTF local_onlyskipinclude_editableseditables_only user_onlycsb|}|r dd|D}|sdd|D}|rdd|D}|r(dd|D}fdd|DS)aReturn a list of installed distributions. :param local_only: If True (default), only return installations local to the current virtualenv, if in a virtualenv. :param skip: An iterable of canonicalized project names to ignore; defaults to ``stdlib_pkgs``. :param include_editables: If False, don't report editables. :param editables_only: If True, only report editables. :param user_only: If True, only report installations in the user site directory. cs|]}|jr|VqdSr)rG.0dr r r! +z?BaseEnvironment.iter_installed_distributions..css|]}|js|VqdSrrFror r r!rr-rscsrnrrtror r r!rr/rscsrnr)rHror r r!rr1rsc3s|] }|jvr|VqdSr)r9rorjr r!rr2s)rh)rrirjrkrlrmitr rur!iter_installed_distributionssz,BaseEnvironment.iter_installed_distributionsN)rr[)r&r'r(__doc__ classmethodr]r rr*r_r`rrarhrrErr+rwr r r r!r[s6  r[c@s&eZdZUeed<dejfddZdS)Wheelr0rcCrrrrr r r! as_zipfile8rMzWheel.as_zipfileN)r&r'r(r*__annotations__zipfileZipFiler{r r r r!rz5s rzc@s.eZdZdeddfddZdejfddZdS)FilesystemWheelr0rNcCs ||_dSr)r0)rr0r r r!__init__=s zFilesystemWheel.__init__cCtj|jddSNT) allowZip64)r}r~r0rr r r!r{@zFilesystemWheel.as_zipfile)r&r'r(r*rr}r~r{r r r r!r<src@s6eZdZdedeeddfddZdejfddZ dS) MemoryWheelr0streamrNcCs||_||_dSr)r0r)rr0rr r r!rEs zMemoryWheel.__init__cCrr)r}r~rrr r r!r{IrzMemoryWheel.as_zipfile) r&r'r(r*rbytesrr}r~r{r r r r!rDsr)0 email.messagerYr>loggingrcr}typingrrrrrrrr r Z"pip._vendor.packaging.requirementsr Z pip._vendor.packaging.specifiersr r pip._vendor.packaging.utilsrZpip._vendor.packaging.versionrrpip._internal.models.direct_urlrrrpip._internal.utils.compatrpip._internal.utils.egg_linkrpip._internal.utils.urlsrrobjectrX getLoggerr&r@rr+r[rzrrr r r r!s4,       2LPKH] /3:@python3.10/site-packages/pip/_internal/metadata/pkg_resources.pynu[import email.message import logging from typing import Collection, Iterable, Iterator, List, NamedTuple, Optional from pip._vendor import pkg_resources from pip._vendor.packaging.requirements import Requirement from pip._vendor.packaging.utils import NormalizedName, canonicalize_name from pip._vendor.packaging.version import parse as parse_version from pip._internal.utils import misc # TODO: Move definition here. from pip._internal.utils.packaging import get_installer, get_metadata from pip._internal.utils.wheel import pkg_resources_distribution_for_wheel from .base import ( BaseDistribution, BaseEntryPoint, BaseEnvironment, DistributionVersion, Wheel, ) logger = logging.getLogger(__name__) class EntryPoint(NamedTuple): name: str value: str group: str class Distribution(BaseDistribution): def __init__(self, dist: pkg_resources.Distribution) -> None: self._dist = dist @classmethod def from_wheel(cls, wheel: Wheel, name: str) -> "Distribution": with wheel.as_zipfile() as zf: dist = pkg_resources_distribution_for_wheel(zf, name, wheel.location) return cls(dist) @property def location(self) -> Optional[str]: return self._dist.location @property def info_directory(self) -> Optional[str]: return self._dist.egg_info @property def canonical_name(self) -> NormalizedName: return canonicalize_name(self._dist.project_name) @property def version(self) -> DistributionVersion: return parse_version(self._dist.version) @property def installer(self) -> str: return get_installer(self._dist) @property def local(self) -> bool: return misc.dist_is_local(self._dist) @property def in_usersite(self) -> bool: return misc.dist_in_usersite(self._dist) @property def in_site_packages(self) -> bool: return misc.dist_in_site_packages(self._dist) def read_text(self, name: str) -> str: if not self._dist.has_metadata(name): raise FileNotFoundError(name) return self._dist.get_metadata(name) def iter_entry_points(self) -> Iterable[BaseEntryPoint]: for group, entries in self._dist.get_entry_map().items(): for name, entry_point in entries.items(): name, _, value = str(entry_point).partition("=") yield EntryPoint(name=name.strip(), value=value.strip(), group=group) @property def metadata(self) -> email.message.Message: return get_metadata(self._dist) def iter_dependencies(self, extras: Collection[str] = ()) -> Iterable[Requirement]: if extras: # pkg_resources raises on invalid extras, so we sanitize. extras = frozenset(extras).intersection(self._dist.extras) return self._dist.requires(extras) def iter_provided_extras(self) -> Iterable[str]: return self._dist.extras class Environment(BaseEnvironment): def __init__(self, ws: pkg_resources.WorkingSet) -> None: self._ws = ws @classmethod def default(cls) -> BaseEnvironment: return cls(pkg_resources.working_set) @classmethod def from_paths(cls, paths: Optional[List[str]]) -> BaseEnvironment: return cls(pkg_resources.WorkingSet(paths)) def _search_distribution(self, name: str) -> Optional[BaseDistribution]: """Find a distribution matching the ``name`` in the environment. This searches from *all* distributions available in the environment, to match the behavior of ``pkg_resources.get_distribution()``. """ canonical_name = canonicalize_name(name) for dist in self.iter_distributions(): if dist.canonical_name == canonical_name: return dist return None def get_distribution(self, name: str) -> Optional[BaseDistribution]: # Search the distribution by looking through the working set. dist = self._search_distribution(name) if dist: return dist # If distribution could not be found, call working_set.require to # update the working set, and try to find the distribution again. # This might happen for e.g. when you install a package twice, once # using setup.py develop and again using setup.py install. Now when # running pip uninstall twice, the package gets removed from the # working set in the first uninstall, so we have to populate the # working set again so that pip knows about it and the packages gets # picked up and is successfully uninstalled the second time too. try: # We didn't pass in any version specifiers, so this can never # raise pkg_resources.VersionConflict. self._ws.require(name) except pkg_resources.DistributionNotFound: return None return self._search_distribution(name) def _iter_distributions(self) -> Iterator[BaseDistribution]: for dist in self._ws: yield Distribution(dist) PKH]._+_+7python3.10/site-packages/pip/_internal/metadata/base.pynu[import email.message import json import logging import re import zipfile from typing import ( IO, TYPE_CHECKING, Collection, Container, Iterable, Iterator, List, Optional, Union, ) from pip._vendor.packaging.requirements import Requirement from pip._vendor.packaging.specifiers import InvalidSpecifier, SpecifierSet from pip._vendor.packaging.utils import NormalizedName from pip._vendor.packaging.version import LegacyVersion, Version from pip._internal.models.direct_url import ( DIRECT_URL_METADATA_NAME, DirectUrl, DirectUrlValidationError, ) from pip._internal.utils.compat import stdlib_pkgs # TODO: Move definition here. from pip._internal.utils.egg_link import egg_link_path_from_sys_path from pip._internal.utils.urls import url_to_path if TYPE_CHECKING: from typing import Protocol else: Protocol = object DistributionVersion = Union[LegacyVersion, Version] logger = logging.getLogger(__name__) class BaseEntryPoint(Protocol): @property def name(self) -> str: raise NotImplementedError() @property def value(self) -> str: raise NotImplementedError() @property def group(self) -> str: raise NotImplementedError() class BaseDistribution(Protocol): def __repr__(self) -> str: return f"{self.raw_name} {self.version} ({self.location})" def __str__(self) -> str: return f"{self.raw_name} {self.version}" @property def location(self) -> Optional[str]: """Where the distribution is loaded from. A string value is not necessarily a filesystem path, since distributions can be loaded from other sources, e.g. arbitrary zip archives. ``None`` means the distribution is created in-memory. Do not canonicalize this value with e.g. ``pathlib.Path.resolve()``. If this is a symbolic link, we want to preserve the relative path between it and files in the distribution. """ raise NotImplementedError() @property def editable_project_location(self) -> Optional[str]: """The project location for editable distributions. This is the directory where pyproject.toml or setup.py is located. None if the distribution is not installed in editable mode. """ # TODO: this property is relatively costly to compute, memoize it ? direct_url = self.direct_url if direct_url: if direct_url.is_local_editable(): return url_to_path(direct_url.url) else: # Search for an .egg-link file by walking sys.path, as it was # done before by dist_is_editable(). egg_link_path = egg_link_path_from_sys_path(self.raw_name) if egg_link_path: # TODO: get project location from second line of egg_link file # (https://github.com/pypa/pip/issues/10243) return self.location return None @property def info_directory(self) -> Optional[str]: """Location of the .[egg|dist]-info directory. Similarly to ``location``, a string value is not necessarily a filesystem path. ``None`` means the distribution is created in-memory. For a modern .dist-info installation on disk, this should be something like ``{location}/{raw_name}-{version}.dist-info``. Do not canonicalize this value with e.g. ``pathlib.Path.resolve()``. If this is a symbolic link, we want to preserve the relative path between it and other files in the distribution. """ raise NotImplementedError() @property def canonical_name(self) -> NormalizedName: raise NotImplementedError() @property def version(self) -> DistributionVersion: raise NotImplementedError() @property def direct_url(self) -> Optional[DirectUrl]: """Obtain a DirectUrl from this distribution. Returns None if the distribution has no `direct_url.json` metadata, or if `direct_url.json` is invalid. """ try: content = self.read_text(DIRECT_URL_METADATA_NAME) except FileNotFoundError: return None try: return DirectUrl.from_json(content) except ( UnicodeDecodeError, json.JSONDecodeError, DirectUrlValidationError, ) as e: logger.warning( "Error parsing %s for %s: %s", DIRECT_URL_METADATA_NAME, self.canonical_name, e, ) return None @property def installer(self) -> str: raise NotImplementedError() @property def editable(self) -> bool: return bool(self.editable_project_location) @property def local(self) -> bool: raise NotImplementedError() @property def in_usersite(self) -> bool: raise NotImplementedError() @property def in_site_packages(self) -> bool: raise NotImplementedError() def read_text(self, name: str) -> str: """Read a file in the .dist-info (or .egg-info) directory. Should raise ``FileNotFoundError`` if ``name`` does not exist in the metadata directory. """ raise NotImplementedError() def iter_entry_points(self) -> Iterable[BaseEntryPoint]: raise NotImplementedError() @property def metadata(self) -> email.message.Message: """Metadata of distribution parsed from e.g. METADATA or PKG-INFO.""" raise NotImplementedError() @property def metadata_version(self) -> Optional[str]: """Value of "Metadata-Version:" in distribution metadata, if available.""" return self.metadata.get("Metadata-Version") @property def raw_name(self) -> str: """Value of "Name:" in distribution metadata.""" # The metadata should NEVER be missing the Name: key, but if it somehow # does, fall back to the known canonical name. return self.metadata.get("Name", self.canonical_name) @property def requires_python(self) -> SpecifierSet: """Value of "Requires-Python:" in distribution metadata. If the key does not exist or contains an invalid value, an empty SpecifierSet should be returned. """ value = self.metadata.get("Requires-Python") if value is None: return SpecifierSet() try: # Convert to str to satisfy the type checker; this can be a Header object. spec = SpecifierSet(str(value)) except InvalidSpecifier as e: message = "Package %r has an invalid Requires-Python: %s" logger.warning(message, self.raw_name, e) return SpecifierSet() return spec def iter_dependencies(self, extras: Collection[str] = ()) -> Iterable[Requirement]: """Dependencies of this distribution. For modern .dist-info distributions, this is the collection of "Requires-Dist:" entries in distribution metadata. """ raise NotImplementedError() def iter_provided_extras(self) -> Iterable[str]: """Extras provided by this distribution. For modern .dist-info distributions, this is the collection of "Provides-Extra:" entries in distribution metadata. """ raise NotImplementedError() class BaseEnvironment: """An environment containing distributions to introspect.""" @classmethod def default(cls) -> "BaseEnvironment": raise NotImplementedError() @classmethod def from_paths(cls, paths: Optional[List[str]]) -> "BaseEnvironment": raise NotImplementedError() def get_distribution(self, name: str) -> Optional["BaseDistribution"]: """Given a requirement name, return the installed distributions.""" raise NotImplementedError() def _iter_distributions(self) -> Iterator["BaseDistribution"]: """Iterate through installed distributions. This function should be implemented by subclass, but never called directly. Use the public ``iter_distribution()`` instead, which implements additional logic to make sure the distributions are valid. """ raise NotImplementedError() def iter_distributions(self) -> Iterator["BaseDistribution"]: """Iterate through installed distributions.""" for dist in self._iter_distributions(): # Make sure the distribution actually comes from a valid Python # packaging distribution. Pip's AdjacentTempDirectory leaves folders # e.g. ``~atplotlib.dist-info`` if cleanup was interrupted. The # valid project name pattern is taken from PEP 508. project_name_valid = re.match( r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", dist.canonical_name, flags=re.IGNORECASE, ) if not project_name_valid: logger.warning( "Ignoring invalid distribution %s (%s)", dist.canonical_name, dist.location, ) continue yield dist def iter_installed_distributions( self, local_only: bool = True, skip: Container[str] = stdlib_pkgs, include_editables: bool = True, editables_only: bool = False, user_only: bool = False, ) -> Iterator[BaseDistribution]: """Return a list of installed distributions. :param local_only: If True (default), only return installations local to the current virtualenv, if in a virtualenv. :param skip: An iterable of canonicalized project names to ignore; defaults to ``stdlib_pkgs``. :param include_editables: If False, don't report editables. :param editables_only: If True, only report editables. :param user_only: If True, only report installations in the user site directory. """ it = self.iter_distributions() if local_only: it = (d for d in it if d.local) if not include_editables: it = (d for d in it if not d.editable) if editables_only: it = (d for d in it if d.editable) if user_only: it = (d for d in it if d.in_usersite) return (d for d in it if d.canonical_name not in skip) class Wheel(Protocol): location: str def as_zipfile(self) -> zipfile.ZipFile: raise NotImplementedError() class FilesystemWheel(Wheel): def __init__(self, location: str) -> None: self.location = location def as_zipfile(self) -> zipfile.ZipFile: return zipfile.ZipFile(self.location, allowZip64=True) class MemoryWheel(Wheel): def __init__(self, location: str, stream: IO[bytes]) -> None: self.location = location self.stream = stream def as_zipfile(self) -> zipfile.ZipFile: return zipfile.ZipFile(self.stream, allowZip64=True) PKH] s||;python3.10/site-packages/pip/_internal/metadata/__init__.pynu[from typing import List, Optional from .base import BaseDistribution, BaseEnvironment, FilesystemWheel, MemoryWheel, Wheel __all__ = [ "BaseDistribution", "BaseEnvironment", "FilesystemWheel", "MemoryWheel", "Wheel", "get_default_environment", "get_environment", "get_wheel_distribution", ] def get_default_environment() -> BaseEnvironment: """Get the default representation for the current environment. This returns an Environment instance from the chosen backend. The default Environment instance should be built from ``sys.path`` and may use caching to share instance state accorss calls. """ from .pkg_resources import Environment return Environment.default() def get_environment(paths: Optional[List[str]]) -> BaseEnvironment: """Get a representation of the environment specified by ``paths``. This returns an Environment instance from the chosen backend based on the given import paths. The backend must build a fresh instance representing the state of installed distributions when this function is called. """ from .pkg_resources import Environment return Environment.from_paths(paths) def get_wheel_distribution(wheel: Wheel, canonical_name: str) -> BaseDistribution: """Get the representation of the specified wheel's distribution metadata. This returns a Distribution instance from the chosen backend based on the given wheel's ``.dist-info`` directory. :param canonical_name: Normalized project name of the given wheel. """ from .pkg_resources import Distribution return Distribution.from_wheel(wheel, canonical_name) PKH]pcK1Vpython3.10/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-310.pycnu[o ai@sdS)Nrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/__init__.pysPKH]!nDDRpython3.10/site-packages/pip/_internal/resolution/__pycache__/base.cpython-310.pycnu[o aiG@sRddlmZmZmZddlmZddlmZeeeegefZ GdddZ dS))CallableListOptional)InstallRequirement)RequirementSetc@s<eZdZdeededefddZdedeefddZd S) BaseResolver root_reqscheck_supported_wheelsreturncCtNNotImplementedError)selfrr r/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/base.pyresolve zBaseResolver.resolvereq_setcCr r r )rrrrrget_installation_orderrz#BaseResolver.get_installation_orderN) __name__ __module__ __qualname__rrboolrrrrrrrr s rN) typingrrrpip._internal.req.req_installrZpip._internal.req.req_setrstrInstallRequirementProviderrrrrrs  PKH]0Ao apython3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-310.pycnu[o ai @spddlmZddlmZddlmZmZddlmZddl m Z m Z ee Z GdddeZGd d d eZd S) ) defaultdict) getLogger)Any DefaultDict) BaseReporter) Candidate Requirementc@s(eZdZdddZdeddfddZdS) PipReporterreturnNcCstt|_dddd|_dS)Nzpip is looking at multiple versions of {package_name} to determine which version is compatible with other requirements. This could take a while.zThis is taking longer than usual. You might need to provide the dependency resolver with stricter constraints to reduce runtime. See https://pip.pypa.io/warnings/backtracking for guidance. If you want to abort this run, press Ctrl + C.)r )rintbacktracks_by_package_messages_at_backtrackselfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/reporter.py__init__ s  zPipReporter.__init__ candidatecCsR|j|jd7<|j|j}||jvrdS|j|}td|j|jddS)NrzINFO: %s) package_name)rnamerloggerinfoformat)rrcountmessagerrr backtracking#s    zPipReporter.backtrackingr N)__name__ __module__ __qualname__rrrrrrrr s r c@seZdZdZdddZdeddfddZded eddfd d Zd eddfd d Z de de ddfddZ de ddfddZ de ddfddZdS)PipDebuggingReporterz9A reporter that does an info log for every event it sees.r NcCstddS)NzReporter.starting()rrrrrrstarting1szPipDebuggingReporter.startingindexcCtd|dS)NzReporter.starting_round(%r)r$)rr&rrrstarting_round4z#PipDebuggingReporter.starting_roundstatecCr')Nz Reporter.ending_round(%r, state)r$)rr&r*rrr ending_round7r)z!PipDebuggingReporter.ending_roundcCr')NzReporter.ending(%r)r$)rr*rrrending:r)zPipDebuggingReporter.ending requirementparentcCstd||dS)Nz#Reporter.adding_requirement(%r, %r)r$)rr-r.rrradding_requirement=sz'PipDebuggingReporter.adding_requirementrcCr')NzReporter.backtracking(%r)r$rrrrrr@r)z!PipDebuggingReporter.backtrackingcCr')NzReporter.pinning(%r)r$r0rrrpinningCr)zPipDebuggingReporter.pinningr)r r!r"__doc__r%rr(rr+r,r rr/rr1rrrrr#.s r#N) collectionsrloggingrtypingrrZ pip._vendor.resolvelib.reportersrbaserr r rr r#rrrrs  "PKH]9zjapython3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-310.pycnu[o ai@sdS)Nrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__init__.pysPKH]0''apython3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-310.pycnu[o ai#@sddlZddlZddlmZmZmZmZmZmZm Z ddl m Z ddl m Z mZmZddlmZddlmZerRddl mZdd lmZeee fZe ee efZne ZGd d d eZdS) N) TYPE_CHECKINGDictIterableIteratorMappingSequenceUnion)AbstractProvider) Candidate Constraint Requirement)REQUIRES_PYTHON_IDENTIFIER)Factory) Preference)RequirementInformationc @s4eZdZdZdedeeefdededeee fddf d d Z d e e e fdefd d Zdedeee fdeeee fdeeedfdedddf ddZdedefddZdedeeee fdeeee fdee fddZde de defdd Zde dee fd!d"Zedededdefd#d$ZdS)% PipProvideraPip's provider implementation for resolvelib. :params constraints: A mapping of constraints specified by the user. Keys are canonicalized project names. :params ignore_dependencies: Whether the user specified ``--no-deps``. :params upgrade_strategy: The user-specified upgrade strategy. :params user_requested: A set of canonicalized package names that the user supplied for pip to install/upgrade. factory constraintsignore_dependenciesupgrade_strategyuser_requestedreturnNcCs2||_||_||_||_||_tdd|_dS)NcSstjSN)mathinfrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/provider.py@sz&PipProvider.__init__..)_factory _constraints_ignore_dependencies_upgrade_strategy_user_requested collections defaultdict _known_depths)selfrrrrrrrr__init__3s zPipProvider.__init__requirement_or_candidatecCs|jSrname)r'r)rrridentifyBszPipProvider.identify identifier resolutions candidates informationPreferenceInformationbacktrack_causesrc sdd||D}t|\}}dddd|DD} |du} tdd| D} t| } zj|} Wn"tyUtj} fdd||D}td d|Dd }Ynwd }|j|<j |tj} |t k}|d k} ||}| || | | || | |f S) a[Produce a sort key for given requirement based on preference. The lower the return value is, the more preferred this group of arguments is. Currently pip considers the followings in order: * Prefer if any of the known requirements is "direct", e.g. points to an explicit URL. * If equal, prefer if any requirement is "pinned", i.e. contains operator ``===`` or ``==``. * If equal, calculate an approximate "depth" and resolve requirements closer to the user-specified requirements first. * Order user-specified requirements by the order they are specified. * If equal, prefers "non-free" requirements, i.e. contains at least one operator, such as ``>=`` or ``<``. * If equal, order alphabetically for consistency (helps debuggability). css|] \}}|VqdSr)get_candidate_lookup).0r_rrr _sz-PipProvider.get_preference..cSsg|] }|D]}|jqqSr)operator)r4 specifier_set specifierrrr asz.PipProvider.get_preference..css|]}|r|jVqdSr)r:)r4ireqrrrr7csNcss |] }|dddkVqdS)Nz==r)r4oprrrr7hsc3s,|]\}}|durj|jndVqdS)Ng)r&r+)r4r6parentr'rrr7os  css|]}|VqdSrr)r4drrrr7ssg? setuptools) zipanyboolr#KeyErrorrrminr&getris_backtrack_cause)r'r-r.r/r0r2lookups candidateireqs operatorsdirectpinnedunfreerequested_order parent_depthsinferred_depthrequires_python delay_thisbacktrack_causerr@rget_preferenceEsB      zPipProvider.get_preferencecCsD||jvr |j|S|d\}}}|r||jvr|j|StS)N[)r partitionr empty)r'r-r+ open_bracketr6rrr_get_constraints   zPipProvider._get_constraint requirementsincompatibilitiescs8dtdtffdd }jj||||| |dS)Nr+rcs&jdkrdSjdkr|jvSdS)aAre upgrades allowed for this project? This checks the upgrade strategy, and whether the project was one that the user specified in the command line, in order to decide whether we should upgrade if there's a newer version available. (Note that we don't need access to the `--upgrade` flag, because an upgrade strategy of "to-satisfy-only" means that `--upgrade` was not specified). eagerTzonly-if-neededF)r"r#r*r@rr_eligible_for_upgrades   z7PipProvider.find_matches.._eligible_for_upgrade)r-r] constraintprefers_installedr^)strrErfind_candidatesr\)r'r-r]r^r`rr@r find_matchesszPipProvider.find_matches requirementrKcCs ||Sr)is_satisfied_by)r'rfrKrrrrgs zPipProvider.is_satisfied_bycCs|j }dd||DS)NcSsg|]}|dur|qSrr)r4r5rrrr;sz0PipProvider.get_dependencies..)r!iter_dependencies)r'rK with_requiresrrrget_dependenciesszPipProvider.get_dependenciescCs8|D]}||jjkr dS|jr||jjkrdSqdS)NTF)rfr+r?)r-r2rVrrrrIs zPipProvider.is_backtrack_cause)__name__ __module__ __qualname____doc__rrrcr rEintr(rr r r,rrrrrWr\rergrj staticmethodrIrrrrr(sb      T r)r$rtypingrrrrrrrZ pip._vendor.resolvelib.providersr baser r r r/rrrrZ pip._vendor.resolvelib.resolversrr1rc _ProviderBaserrrrrs$      PKH]BR^^]python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-310.pycnu[o aid@sddlmZmZmZmZmZddlmZddlm Z m Z ddl m Z m Z ddlmZmZddlmZddlmZeedeefZee e fZd ed eed efd d ZGdddZGdddZdeddd efddZGdddZdS)) FrozenSetIterableOptionalTupleUnion) SpecifierSet)NormalizedNamecanonicalize_name) LegacyVersionVersion)Linklinks_equivalent)InstallRequirement)Hashes CandidateprojectextrasreturncCs,|s|Stdd|D}d|d|S)Ncss|]}t|VqdSN)r ).0er/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/base.py szformat_name..z{}[{}],)sortedformatjoin)rrcanonical_extrasrrr format_namesrc@seZdZdededeeddfddZeddd Z ed e ddfd d Z de fd dZ de ddfddZddde fddZdS) Constraint specifierhasheslinksrNcCs||_||_||_dSr)r!r"r#)selfr!r"r#rrr__init__s zConstraint.__init__cCsttttSr)r rr frozenset)clsrrremptyszConstraint.emptyireqcCs.|jr t|jgnt}t|j|jdd|SNF)trust_internet)linkr&r r!r")r'r)r#rrr from_ireq"szConstraint.from_ireqcCst|jpt|jpt|jSr)boolr!r"r#r$rrr__bool__'szConstraint.__bool__othercCsRt|tstS|j|j@}|j|jdd@}|j}|jr#||jg}t|||Sr*) isinstancerNotImplementedr!r"r#r,unionr )r$r1r!r"r#rrr__and__*s   zConstraint.__and__ candidatercs4|jrtfdd|jDsdS|jjjddS)Nc3s|]}t|VqdSr) _match_link)rr,r6rrr6sz-Constraint.is_satisfied_by..FT) prereleases)r#allr!containsversionr$r6rr8ris_satisfied_by4szConstraint.is_satisfied_by)rr )__name__ __module__ __qualname__rrrr r% classmethodr(rr-r.r0r5r>rrrrr s"   r c@s^eZdZedefddZedefddZdddefdd Z de fd d Z defd d Z dS) RequirementrcCtd)zThe "project name" of a requirement. This is different from ``name`` if this requirement contains extras, in which case ``name`` would contain the ``[...]`` part, while this refers to the name of the project. Subclass should overrideNotImplementedErrorr/rrr project_name?zRequirement.project_namecCrD)zThe name identifying this requirement in the resolver. This is different from ``project_name`` if this requirement contains extras, where ``project_name`` would not contain the ``[...]`` part. rErFr/rrrnameIzRequirement.namer6rcCsdSNFrr=rrrr>RszRequirement.is_satisfied_bycCrDNrErFr/rrrget_candidate_lookupUz Requirement.get_candidate_lookupcCrDrMrFr/rrrformat_for_errorXrOzRequirement.format_for_errorN) r?r@rApropertyrrHstrrJr.r>CandidateLookuprNrPrrrrrC>s rCr,r6cCs|jr t||jSdSrL) source_linkr )r,r6rrrr7\s r7c@seZdZedefddZedefddZedefddZ ede fdd Z ede fd d Z ede efd d Zde dee efddZde efddZdefddZdS)rrcCrD)zThe "project name" of the candidate. This is different from ``name`` if this candidate contains extras, in which case ``name`` would contain the ``[...]`` part, while this refers to the name of the project. Override in subclassrFr/rrrrHcrIzCandidate.project_namecCrD)zThe name identifying this candidate in the resolver. This is different from ``project_name`` if this candidate contains extras, where ``project_name`` would not contain the ``[...]`` part. rUrFr/rrrrJmrKzCandidate.namecCrDNrUrFr/rrrr<vzCandidate.versioncCrDrVrFr/rrr is_installedzrWzCandidate.is_installedcCrDrVrFr/rrr is_editable~rWzCandidate.is_editablecCrDrVrFr/rrrrTrWzCandidate.source_link with_requirescCrDrVrF)r$rZrrriter_dependenciesrOzCandidate.iter_dependenciescCrDrVrFr/rrrget_install_requirementrOz!Candidate.get_install_requirementcCrDrMrFr/rrrrPrOzCandidate.format_for_errorN)r?r@rArQrrHrRrJCandidateVersionr<r.rXrYrr rTrrCr[rr\rPrrrrrbs  N)typingrrrrrZ pip._vendor.packaging.specifiersrpip._vendor.packaging.utilsrr Zpip._vendor.packaging.versionr r pip._internal.models.linkr r pip._internal.req.req_installrpip._internal.utils.hashesrrSr]rRrr rCr.r7rrrrrs    (PKH]DUUepython3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-310.pycnu[o aiO@sddlmZddlmZmZddlmZddlmZm Z m Z m Z Gddde Z Gdd d e Z Gd d d e ZGd d d e ZdS)) SpecifierSet)NormalizedNamecanonicalize_name)InstallRequirement) CandidateCandidateLookup Requirement format_namec@seZdZdeddfddZdefddZdefdd Zede fd d Z edefd d Z defddZ de fddZdedefddZdS)ExplicitRequirement candidatereturnNcC ||_dSNr selfr r/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/requirements.py__init__  zExplicitRequirement.__init__cCs t|jSr)strr rrrr__str__ rzExplicitRequirement.__str__cCsdj|jj|jdS)Nz{class_name}({candidate!r})) class_namer )format __class____name__r rrrr__repr__szExplicitRequirement.__repr__cC|jjSr)r project_namerrrrr z ExplicitRequirement.project_namecCrr)r namerrrrr"r!zExplicitRequirement.namecCs |jSr)r format_for_errorrrrrr# rz$ExplicitRequirement.format_for_errorcCs |jdfSrrrrrrget_candidate_lookup#rz(ExplicitRequirement.get_candidate_lookupcCs ||jkSrrrrrris_satisfied_by&rz#ExplicitRequirement.is_satisfied_by)r __module__ __qualname__rrrrrpropertyrr r"r#rr$boolr%rrrrr sr c@seZdZdeddfddZdefddZdefdd Zede fd d Z edefd d Z defddZ de fddZdedefddZdS)SpecifierRequirementireqr NcCs(|jdus Jd||_t|j|_dS)NzThis is a link, not a specifier)link_ireq frozensetextras_extras)rr+rrrr+szSpecifierRequirement.__init__cCs t|jjSr)rr-reqrrrrr0 zSpecifierRequirement.__str__cCsdj|jjt|jjdS)Nz{class_name}({requirement!r}))r requirement)rrrrr-r1rrrrr3s zSpecifierRequirement.__repr__cCs|jjsJdt|jjjS)N'Specifier-backed ireq is always PEP 508)r-r1rr"rrrrr 9sz!SpecifierRequirement.project_namecCst|j|jSr)r r r0rrrrr">szSpecifierRequirement.namecCsZddt|dD}t|dkrdSt|dkr|dSd|ddd |dS) NcSsg|]}|qSr)strip).0srrr Hsz9SpecifierRequirement.format_for_error..,rrz, z and )rsplitlenjoin)rpartsrrrr#Bs   z%SpecifierRequirement.format_for_errorcCs d|jfSr)r-rrrrr$Prz)SpecifierRequirement.get_candidate_lookupr cCsN|j|jksJd|jd|j|jjsJd|jjj}|j|jddS)Nz6Internal issue: Candidate is not for this requirement z vs r4T prereleases)r"r-r1 specifiercontainsversion)rr specrrrr%Ss z$SpecifierRequirement.is_satisfied_by)rr&r'rrrrrr(rr r"r#rr$rr)r%rrrrr**sr*c@seZdZdZdededdfddZdefdd Zdefd d Z e de fd d Z e defddZ defddZdefddZdedefddZdS)RequiresPythonRequirementz4A requirement representing Requires-Python metadata.rBmatchr NcCs||_||_dSr)rB _candidate)rrBrGrrrrcs z"RequiresPythonRequirement.__init__cCs d|jS)NzPython )rBrrrrrgr2z!RequiresPythonRequirement.__str__cCdj|jjt|jdS)Nz{class_name}({specifier!r}))rrB)rrrrrBrrrrrjz"RequiresPythonRequirement.__repr__cCrr)rHr rrrrr pz&RequiresPythonRequirement.project_namecCrr)rHr"rrrrr"trKzRequiresPythonRequirement.namecCt|Srrrrrrr#xz*RequiresPythonRequirement.format_for_errorcCs"|jj|jjddr|jdfSdS)NTr@NN)rBrCrHrDrrrrr${s z.RequiresPythonRequirement.get_candidate_lookupr cCs(|j|jjks Jd|jj|jddS)NzNot Python candidateTr@)r"rHrBrCrDrrrrr%sz)RequiresPythonRequirement.is_satisfied_by)rr&r'__doc__rrrrrrr(rr r"r#rr$r)r%rrrrrF`srFc@seZdZdZdeddfddZdefddZdefd d Ze defd d Z e defd dZ defddZ de fddZdedefddZdS)UnsatisfiableRequirementz'A requirement that cannot be satisfied.r"r NcCrr_name)rr"rrrrrz!UnsatisfiableRequirement.__init__cCs |jdS)Nz (unavailable)rRrrrrrr2z UnsatisfiableRequirement.__str__cCrI)Nz{class_name}({name!r}))rr")rrrrrSrrrrrrJz!UnsatisfiableRequirement.__repr__cC|jSrrRrrrrr z%UnsatisfiableRequirement.project_namecCrTrrRrrrrr"rUzUnsatisfiableRequirement.namecCrLrrMrrrrr#rNz)UnsatisfiableRequirement.format_for_errorcCdS)NrOrrrrrr$z-UnsatisfiableRequirement.get_candidate_lookupr cCrV)NFrrrrrr%rWz(UnsatisfiableRequirement.is_satisfied_by)rr&r'rPrrrrrr(r r"r#rr$rr)r%rrrrrQsrQN)Z pip._vendor.packaging.specifiersrpip._vendor.packaging.utilsrrpip._internal.req.req_installrbaserrr r r r*rFrQrrrrs  !6(PKH]j /apython3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-310.pycnu[o ail%@sddlZddlZddlZddlmZmZmZmZmZm Z m Z ddl m Z ddl mZmZddl mZddlmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZm Z dd l!m"Z"ddl#m$Z$m%Z%ddl&m'Z'm(Z(ddl)m*Z*erddl+m,Z-e-e(e'e.fZ,e/e0Z1GdddeZddde2deee.e2ffddZ3de e.efdeee.e2fde e2e.ffddZ4dS)N) TYPE_CHECKINGDictListOptionalSetTuplecastcanonicalize_name) BaseReporterResolutionImpossible)Resolver) DirectedGraph) WheelCache) PackageFinder)RequirementPreparer)InstallRequirement)RequirementSet) BaseResolverInstallRequirementProvider) PipProvider)PipDebuggingReporter PipReporter) Candidate Requirement)Factory)ResultcseZdZhdZ ddededeedede de d e d e d e d e d ee e dfffdd Z deede defddZdedeefddZZS)r >eagerzonly-if-neededzto-satisfy-onlyNpreparerfinder wheel_cachemake_install_req use_user_siteignore_dependenciesignore_installedignore_requires_pythonforce_reinstallupgrade_strategypy_version_info.c sJt| |jvs Jt|||||| ||| d |_||_| |_d|_dS)N) r rr"r!r#r'r%r&r))super__init___allowed_strategiesrfactoryr$r(_result) selfrr r!r"r#r$r%r&r'r(r) __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/resolver.pyr+&s   zResolver.__init__ root_reqscheck_supported_wheelsreturnc Cs|j|}t|j|j|j|j|jd}dtjvrt }nt }t ||}zd}|j |j |d}|_WntyN} z|jtd| |j} | | d} ~ wwt|d} |jD]m} | } | durdqY|j| }|durrd| _n4|jjrzd| _n,|j| jkrd| _n"| js|jrd| _n| jr| jjr| jjrt d | j!qYd| _nqY| j}|r|j"rd j#| j!| j||j$pd d }t%|| &| qY| j'}|jj()|| S) N)r- constraintsr$r(user_requestedPIP_RESOLVER_DEBUGi) max_roundsz,ResolutionImpossible[Requirement, Candidate])r5FTz%s is already installed with the same version as the provided wheel. Use --force-reinstall to force an installation of the wheel.zThe candidate selected for download or install is a yanked version: {name!r} candidate (version {version} at {link}) Reason for being yanked: {reason}z )nameversionlinkreason)*r-collect_root_requirementsrr7r$r(r8osenvironrr RLResolverresolve requirementsr.r get_installation_errorrrmappingvaluesget_install_requirementget_dist_to_uninstallshould_reinstallr'r< is_editableeditable source_linkis_fileis_wheelloggerinfor; is_yankedformat yanked_reasonwarningadd_named_requirementall_requirementsr prepare_linked_requirements_more)r/r4r5 collectedproviderreporterresolver try_to_avoid_resolution_too_deepresulteerrorreq_set candidateireqinstalled_distr=msgreqsr2r2r3rCFs        zResolver.resolveracCs^|jdus Jd|jj}t|t|jjdd}t|jtj t |ddd}dd |DS) aGet order for installation of requirements in RequirementSet. The returned list contains a requirement before another that depends on it. This helps ensure that the environment is kept consistent as they get installed one-by-one. The current implementation creates a topological ordering of the dependency graph, while breaking any cycles in the graph at arbitrary points. We make no guarantees about where the cycle would be broken, other than they would be broken. Nzmust call resolve() firstr)expected_node_count)weightsT)keyreversecSsg|]\}}|qSr2r2).0_rcr2r2r3 sz3Resolver.get_installation_order..) r.graphget_topological_weightslenrFsortedrDitems functoolspartial_req_set_item_sorter)r/rarnrh sorted_itemsr2r2r3get_installation_orders zResolver.get_installation_order)N)__name__ __module__ __qualname__r,rrrrrboolstrrintr+rrrrCrw __classcell__r2r2r0r3r #sL      ^r rnzDirectedGraph[Optional[str]]rgr6csVtidttddffdd dddks!Jt|ks)JS)aAssign weights to each node based on how "deep" they are. This implementation may change at any point in the future without prior notice. We take the length for the longest path to any node from root, ignoring any paths that contain a single node twice (i.e. cycles). This is done through a depth-first search through the graph, while keeping track of the path to the node. Cycles in the graph result would result in node being revisited while also being it's own path. In this case, take no action. This helps ensure we don't get stuck in a cycle. When assigning weight, the longer path (i.e. larger length) is preferred. noder6NcsZ|vrdS||D]}|q||d}t|t|<dS)Nr)add iter_childrenremovegetmaxrp)rchildlast_known_parent_countrnpathvisitrhr2r3rs    z&get_topological_weights..visitr)setrr|rp)rnrgr2rr3ros roitemrhcCst|d}|||fS)a)Key function used to sort install requirements for installation. Based on the "weight" mapping calculated in ``get_installation_order()``. The canonical package name is returned as the second member as a tie- breaker to ensure the result is predictable, which is useful in tests. rr )rrhr;r2r2r3rus ru)5rsloggingr@typingrrrrrrrpip._vendor.packaging.utilsr pip._vendor.resolvelibr r r rBZpip._vendor.resolvelib.structsrpip._internal.cacher"pip._internal.index.package_finderr pip._internal.operations.preparerpip._internal.req.req_installrZpip._internal.req.req_setrpip._internal.resolution.baserr,pip._internal.resolution.resolvelib.providerr,pip._internal.resolution.resolvelib.reporterrrbaserrr-rZ pip._vendor.resolvelib.resolversrZRLResultr| getLoggerrxrPr}rorur2r2r2r3sL$              .  PKH]>GGcpython3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-310.pycnu[o ai"G@sddlZddlZddlmZmZmZmZmZmZm Z m Z ddl m Z m Z ddlmZddlmZmZddlmZddlmZmZddlmZdd lmZmZdd lmZdd lm Z d d l!m"Z"m#Z#m$Z$m%Z%ernd dl&m'Z'e(e)Z*e dZ+e e dZ,de"dee+fddZ-dededefddZ.dededefddZ/dededefddZ0Gddde"Z1Gd d!d!e1Z2Gd"d#d#e1Z3Gd$d%d%e"Z4Gd&d'd'e"Z5Gd(d)d)e"Z6dS)*N) TYPE_CHECKINGAny FrozenSetIterableOptionalTupleUnioncast)NormalizedNamecanonicalize_name)Version) HashErrorMetadataInconsistent)BaseDistribution)Linklinks_equivalent)Wheel)install_req_from_editableinstall_req_from_line)InstallRequirement)normalize_version_info) CandidateCandidateVersion Requirement format_name)Factory)AlreadyInstalledCandidateEditableCandidate LinkCandidatez candidatereturncCstttf}t||r |SdS)z%The runtime version of BaseCandidate.N)rrr isinstance)r base_candidate_classesr$/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.pyas_base_candidate$s r&linktemplatec Csh|jrJd|jrt|j}n|j}t||j|j|j|j|j t |j |j |j dd}|j|_||_|S)Nztemplate is editableinstall_optionsglobal_optionshashes user_supplied comes_from use_pep517isolated constraintoptions)editablereqstrurlrr.r/r0r1r2dictr*r+ hash_options original_linkr')r'r(lineireqr$r$r%make_install_req_from_link0s(  r=c CsD|jsJdt|j|j|j|j|j|j|jt |j |j |j ddS)Nztemplate not editabler))r.r/r0r1r2permit_editable_wheelsr3) r4rr7r.r/r0r1r2r>r8r*r+r9)r'r(r$r$r%make_install_req_from_editableJsr?distc Csddlm}|jrt|j}n|jr|jd|jj}n |jd|j}t||j |j |j |j |j t|j|j|jdd}t||j|_|S)Nr) Distributionz @ z==r)r-)$pip._internal.metadata.pkg_resourcesrAr5r6r'canonical_namer7versionrr.r/r0r1r2r8r*r+r9r _dist satisfied_by)r@r(_Distr;r<r$r$r%_make_install_req_from_dist^s*   rHc@sBeZdZUdZeed<dZ  d-dedededd d e e d e e d dfd dZ d e fddZd e fddZd efddZded efddZed e efddZed e fddZed e fddZed e fddZd e fd d!Zd efd"d#Zded dfd$d%Zd efd&d'Zd(ed ee efd)d*Z d e efd+d,Z!dS)."_InstallRequirementBackedCandidateaA candidate backed by an ``InstallRequirement``. This represents a package request with the target not being already in the environment, and needs to be fetched and installed. The backing ``InstallRequirement`` is responsible for most of the leg work; this class exposes appropriate information to the resolver. :param link: The link passed to the ``InstallRequirement``. The backing ``InstallRequirement`` will use this link to fetch the distribution. :param source_link: The link this candidate "originates" from. This is different from ``link`` when the link is found in the wheel cache. ``link`` would point to the wheel cache, while this points to the found remote link (e.g. from pypi.org). r@FNr' source_linkr<factoryrnamerDr!cCs2||_||_||_||_||_||_||_dSN)_link _source_link_factory_ireq_name_version_preparer@)selfr'rJr<rKrLrDr$r$r%__init__s z+_InstallRequirementBackedCandidate.__init__cCs|jd|jS)N rLrDrUr$r$r%__str__sz*_InstallRequirementBackedCandidate.__str__cCsdj|jjt|jdS)Nz{class_name}({link!r})) class_namer')format __class____name__r6rNrYr$r$r%__repr__sz+_InstallRequirementBackedCandidate.__repr__cCt|j|jfSrM)hashr]rNrYr$r$r%__hash__z+_InstallRequirementBackedCandidate.__hash__othercCst||jr t|j|jSdSNF)r"r]rrNrUrdr$r$r%__eq__s z)_InstallRequirementBackedCandidate.__eq__cC|jSrM)rOrYr$r$r%rJz._InstallRequirementBackedCandidate.source_linkcCs|jdur |jj|_|jS):The normalised name of the project the candidate refers toN)rRr@rCrYr$r$r% project_names  z/_InstallRequirementBackedCandidate.project_namecCrhrMrkrYr$r$r%rLriz'_InstallRequirementBackedCandidate.namecCs|jdur |jj|_|jSrM)rSr@rDrYr$r$r%rDs  z*_InstallRequirementBackedCandidate.versioncCs&d|j|j|jjr|jjS|jS)Nz{} {} (from {}))r\rLrDrNis_file file_pathrYr$r$r%format_for_errorsz3_InstallRequirementBackedCandidate.format_for_errorcCstd)NzOverride in subclass)NotImplementedErrorrYr$r$r%_prepare_distributionsz8_InstallRequirementBackedCandidate._prepare_distributioncCsd|jdur|j|jkrt|jd|j|j|jdur.|j|jkr0t|jdt|jt|jdSdS)z:Check for consistency of project name and version of dist.NrLrD)rRrCrrQrSrDr6)rUr@r$r$r%_check_metadata_consistencysz>_InstallRequirementBackedCandidate._check_metadata_consistencyc Cs>z|}Wnty}z|j|_d}~ww|||SrM)rqr rQr5rr)rUr@er$r$r%rTs  z+_InstallRequirementBackedCandidate._prepare with_requiresccsJ|r|jnd}|D] }|jt||jVq |j|jjVdSNr$)r@iter_dependenciesrPmake_requirement_from_specr6rQ make_requires_python_requirementrequires_python)rUrtrequiresrr$r$r%rvs z4_InstallRequirementBackedCandidate.iter_dependenciescCrhrM)rQrYr$r$r%get_install_requirementsz:_InstallRequirementBackedCandidate.get_install_requirementNN)"r^ __module__ __qualname____doc__r__annotations__ is_installedrrrr rrVr6rZr_intrbrboolrgpropertyrJrkrLrDrorqrrrTrrrvr|r$r$r$r%rIzsN   rIc VeZdZdZ  ddededddeedeed df fd d Z d e fd d Z Z S)rFNr'r(rKrrLrDr!c s|}|||}|durtd|j|j}t||}|j|ks"J|jjrY|jjsYt|jj} t | j } || ksCJ|d| d|durYt | j } || ksYJd || ||duri|jri|j|jurid|_tj||||||ddS)NzUsing cached wheel link: %sz != z for wheelz{!r} != {!r} for wheel {}Tr'rJr<rKrLrD)get_wheel_cache_entryloggerdebugr'r=is_wheelrmrfilenamer rLr rDr\ persistentr:original_link_is_in_wheel_cachesuperrV) rUr'r(rKrLrDrJ cache_entryr<wheel wheel_name wheel_versionr]r$r%rVs:       zLinkCandidate.__init__cCs|jj}|j|jddS)NT)parallel_builds)rPpreparerprepare_linked_requirementrQ)rUrr$r$r%rq"sz#LinkCandidate._prepare_distributionr} r^r~r is_editablerrrr rrVrrq __classcell__r$r$rr%rs$*rc r)rTNr'r(rKrrLrDr!cs"tj||t|||||ddS)Nr)rrVr?)rUr'r(rKrLrDrr$r%rV*s zEditableCandidate.__init__cCs|jj|jSrM)rPrprepare_editable_requirementrQrYr$r$r%rq;rcz'EditableCandidate._prepare_distributionr}rr$r$rr%r's$rc@seZdZdZdZdededdddfdd Zdefd d Z defd d Z de fddZ de defddZedefddZedefddZedefddZedefddZdefddZdedeeefddZdeefd d!ZdS)"rTNr@r(rKrr!cCs0||_t|||_||_d}|j|j|dS)Nzalready satisfied)r@rHrQrPrprepare_installed_requirement)rUr@r(rK skip_reasonr$r$r%rVCs  z"AlreadyInstalledCandidate.__init__cCs t|jSrM)r6r@rYr$r$r%rZTs z!AlreadyInstalledCandidate.__str__cCsdj|jj|jdS)Nz{class_name}({distribution!r}))r[ distribution)r\r]r^r@rYr$r$r%r_Wsz"AlreadyInstalledCandidate.__repr__cCst|j|j|jfSrM)rar]rLrDrYr$r$r%rb]z"AlreadyInstalledCandidate.__hash__rdcC(t||jr|j|jko|j|jkSdSre)r"r]rLrDrfr$r$r%rg` z AlreadyInstalledCandidate.__eq__cC|jjSrM)r@rCrYr$r$r%rkez&AlreadyInstalledCandidate.project_namecCrhrMrlrYr$r$r%rLirizAlreadyInstalledCandidate.namecCrrM)r@rDrYr$r$r%rDmrz!AlreadyInstalledCandidate.versioncCrrM)r@r4rYr$r$r%rqrz%AlreadyInstalledCandidate.is_editablecCs|jd|jdS)NrWz (Installed)rXrYr$r$r%rourz*AlreadyInstalledCandidate.format_for_errorrtccs4|sdS|jD] }|jt||jVq dSrM)r@rvrPrwr6rQ)rUrtr{r$r$r%rvxs z+AlreadyInstalledCandidate.iter_dependenciescCdSrMr$rYr$r$r%r|~z1AlreadyInstalledCandidate.get_install_requirement)r^r~rrrJrrrVr6rZr_rrbrrrgrr rkrLrrDrrorrrrvr|r$r$r$r%r?s6 rc@seZdZdZdedeeddfddZdefdd Zdefd d Z de fd d Z de de fddZedefddZedefddZedefddZdefddZede fddZede fddZedeefddZde deeefd d!Zdeefd"d#ZdS)$ExtrasCandidateaA candidate that has 'extras', indicating additional dependencies. Requirements can be for a project with dependencies, something like foo[extra]. The extras don't affect the project/version being installed directly, but indicate that we need additional dependencies. We model that by having an artificial ExtrasCandidate that wraps the "base" candidate. The ExtrasCandidate differs from the base in the following ways: 1. It has a unique name, of the form foo[extra]. This causes the resolver to treat it as a separate node in the dependency graph. 2. When we're getting the candidate's dependencies, a) We specify that we want the extra dependencies as well. b) We add a dependency on the base candidate. See below for why this is needed. 3. We return None for the underlying InstallRequirement, as the base candidate will provide it, and we don't want to end up with duplicates. The dependency on the base candidate is needed so that the resolver can't decide that it should recommend foo[extra1] version 1.0 and foo[extra2] version 2.0. Having those candidates depend on foo=1.0 and foo=2.0 respectively forces the resolver to recognise that this is a conflict. baseextrasr!NcCs||_||_dSrM)rr)rUrrr$r$r%rVs zExtrasCandidate.__init__cCs,t|jdd\}}d|d|j|S)NrWrz {}[{}] {},)r6rsplitr\joinr)rUrLrestr$r$r%rZszExtrasCandidate.__str__cCsdj|jj|j|jdS)Nz.{class_name}(base={base!r}, extras={extras!r}))r[rr)r\r]r^rrrYr$r$r%r_s zExtrasCandidate.__repr__cCr`rM)rarrrYr$r$r%rbrczExtrasCandidate.__hash__rdcCrre)r"r]rrrfr$r$r%rgrzExtrasCandidate.__eq__cCrrM)rrkrYr$r$r%rkrzExtrasCandidate.project_namecCst|jj|jS)rj)rrrkrrYr$r$r%rLszExtrasCandidate.namecCrrM)rrDrYr$r$r%rDrzExtrasCandidate.versioncCsd|jdt|jS)Nz{} [{}]z, )r\rrorsortedrrYr$r$r%rosz ExtrasCandidate.format_for_errorcCrrM)rrrYr$r$r%rrzExtrasCandidate.is_installedcCrrM)rrrYr$r$r%rrzExtrasCandidate.is_editablecCrrM)rrJrYr$r$r%rJrzExtrasCandidate.source_linkrtccs|jj}||jV|sdS|j|jj}|j|jj}t|D] }t d|jj |j |q(|jj |D]}|t||jj|}|rO|Vq=dS)Nz%%s %s does not provide the extra '%s')rrPmake_requirement_from_candidater intersectionr@iter_provided_extras differencerrwarningrLrDrvrwr6rQ)rUrtrK valid_extrasinvalid_extrasextrar{ requirementr$r$r%rvs, z!ExtrasCandidate.iter_dependenciescCrrMr$rYr$r$r%r|sz'ExtrasCandidate.get_install_requirement) r^r~rr BaseCandidaterr6rVrZr_rrbrrrgrr rkrLrrDrorrrrrJrrrvrr|r$r$r$r%rs8 rc@seZdZdZdZdeeedfddfddZde fdd Z e de fd d Z e de fd d Ze defddZde fddZdedeeefddZdeefddZdS)RequiresPythonCandidateFNpy_version_info.r!cCs>|dur t|}ntjdd}tddd|D|_dS)N.css|]}t|VqdSrM)r6).0cr$r$r% sz3RequiresPythonCandidate.__init__..)rsys version_infor rrS)rUrrr$r$r%rVs z RequiresPythonCandidate.__init__cC d|jSNzPython rSrYr$r$r%rZ zRequiresPythonCandidate.__str__cCtSrMREQUIRES_PYTHON_IDENTIFIERrYr$r$r%rk z$RequiresPythonCandidate.project_namecCrrMrrYr$r$r%rL rzRequiresPythonCandidate.namecCrhrMrrYr$r$r%rDrizRequiresPythonCandidate.versioncCrr)rDrYr$r$r%rorz(RequiresPythonCandidate.format_for_errorrtcCsdSrur$)rUrtr$r$r%rvrz)RequiresPythonCandidate.iter_dependenciescCrrMr$rYr$r$r%r|rz/RequiresPythonCandidate.get_install_requirement)r^r~rrrJrrrrVr6rZrr rkrLrrDrorrrrvrr|r$r$r$r%rs r)7loggingrtypingrrrrrrrr pip._vendor.packaging.utilsr r Zpip._vendor.packaging.versionr pip._internal.exceptionsr rpip._internal.metadatarpip._internal.models.linkrrpip._internal.models.wheelrpip._internal.req.constructorsrrpip._internal.req.req_installrpip._internal.utils.miscrrrrrrrKr getLoggerr^rrrr&r=r?rHrIrrrrrr$r$r$r%s`(            {2CuPKH]=3II`python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-310.pycnu[o aij@sBddlZddlZddlZddlZddlZddlmZmZmZm Z m Z m Z m Z m Z mZmZmZmZmZmZddlmZddlmZddlmZmZddlmZddlmZmZddl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&dd l'm(Z(dd l)m*Z*dd l+m,Z,m-Z-dd l.m/Z/dd l0m1Z1ddl2m3Z3ddl4m5Z5ddl6m7Z7m8Z8ddl9m:Z:ddl;mZ>ddl?m@Z@ddlAmBZBddlCmDZDddlEmFZFmGZGmHZHmIZIddlJmKZKmLZLmMZMmNZNmOZOmPZPmQZQddlRmSZSmTZTddlUmVZVmWZWmXZXmYZYerddlmZZZGdddeZZ[e\e]Z^edZ_ee/e_fZ`Gd d!d!e ZaGd"d#d#ZbdS)$N) TYPE_CHECKINGDict FrozenSetIterableIteratorListMapping NamedTupleOptionalSequenceSetTupleTypeVarcast)InvalidRequirement) SpecifierSet)NormalizedNamecanonicalize_name)ResolutionImpossible) CacheEntry WheelCache)DistributionNotFoundInstallationErrorInstallationSubprocessErrorMetadataInconsistentUnsupportedPythonVersionUnsupportedWheel) PackageFinder) get_scheme)BaseDistributionget_default_environment)Link)Wheel)RequirementPreparer)install_req_from_link_and_ireq)InstallRequirementcheck_invalid_constraint_type)InstallRequirementProvider) get_supported)Hashes) dist_location)get_requirement)running_under_virtualenv) CandidateCandidateVersion Constraint Requirement)AlreadyInstalledCandidate BaseCandidateEditableCandidateExtrasCandidate LinkCandidateRequiresPythonCandidateas_base_candidate)FoundCandidatesIndexCandidateInfo)ExplicitRequirementRequiresPythonRequirementSpecifierRequirementUnsatisfiableRequirement)Protocolc@seZdZUeed<eed<dS) ConflictCause requirementparentN)__name__ __module__ __qualname__r<__annotations__r.rGrG/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/factory.pyr@Ls  r@Cc@s:eZdZUeeed<eeefed<eee fed<dS)CollectedRootRequirements requirements constraintsuser_requestedN) rCrDrErr1rFrstrr0intrGrGrGrHrJWs rJc@seZdZ dSdedededeedededed ed ee e d fd dfd dZ e d efddZ ded dfddZdedeed efddZdedeeded efddZdedeededeedeed eef ddZd eed!ed"ed#ed$ee d e ef d%d&Z!d'e e"deed e#efd(d)Z$d*ed+e%ded e#efd,d-Z&d*ed.e'ee e"fd/e'ee#efd+e%d#ed e ef d0d1Z(d2ed3e ed ee"fd4d5Z)d6e*ed e+fd7d8Z,d9ed e-fd:d;Z. d?Z/d!ed ee"fd@dAZ0dedeed ee1fdBdCZ2d9ed eefdDdEZ3dFedGd e4fdHdIZ5dJe"dKeed e6fdLdMZ7dNdOdPe8ee%fd e9fdQdRZ:dS)UFactoryNfinderpreparermake_install_req wheel_cache use_user_siteforce_reinstallignore_installedignore_requires_pythonpy_version_info.returnc Cs||_||_||_t| |_||_||_||_||_i|_ i|_ i|_ i|_ i|_ |s}sz$Factory.__init__..F) local_only)_finderrR _wheel_cacher7_python_candidate_make_install_req_from_spec_use_user_site_force_reinstall_ignore_requires_python_build_failures_link_candidate_cache_editable_candidate_cache_installed_candidate_cache_extras_candidate_cacher iter_installed_distributions_installed_dists) selfrQrRrSrTrUrVrWrXrYenvrGrGrH__init__^s(    zFactory.__init__cCs|jSN)rernrGrGrHrVszFactory.force_reinstalllinkcCs>|jsdSt|j}||jjrdS|jd}t|)Nz+ is not a supported wheel on this platform.)is_wheelr"filename supportedr` target_pythonget_tagsr)rnrswheelmsgrGrGrH"_fail_if_link_is_unsupported_wheels  z*Factory._fail_if_link_is_unsupported_wheelbaseextrascCsFt||f}z|j|}W|Sty"t||}||j|<Y|Swrq)idrkKeyErrorr5)rnr|r} cache_key candidaterGrGrH_make_extras_candidates    zFactory._make_extras_candidater]templatecCsRz|j|j}Wntyt|||d}||j|j<Ynw|s#|S|||S)N)factory)rjr[rr2r)rnr]r}rr|rGrGrH_make_candidate_from_dists  z!Factory._make_candidate_from_distnameversionc Cs||jvrdS|jrE||jvr?zt|||||d|j|<Wn!ttfy>}ztd||||j|<WYd}~dSd}~ww|j|}n:||jvrzzt |||||d|j|<Wn!ttfyy}ztd||||j|<WYd}~dSd}~ww|j|}|s|S| ||S)N)rrrzDiscarding %s. %s) rgeditablerir4rrloggerwarningrhr6r)rnrsr}rrrer|rGrGrH_make_candidate_from_linksL        z!Factory._make_candidate_from_linkireqs specifierhashesprefers_installedincompatible_idsc s|sdS|djsJdtjjt|D]}|js#Jd|jjM|jddMt|jOqdttffdd }dt t ffd d }t |||S) NrGrz)Candidates found on index must be PEP 508F)trust_internetrZcsfjrdSzj}Wn tyYdSwj|jdds!dSj|d}t|vr1dS|S)z6Get the candidate for the currently-installed version.NT) prereleases)r]r}r)rermrcontainsrrr~)installed_distr)r}rrrnrrrGrH_get_installed_candidates"  z@Factory._iter_found_candidates.._get_installed_candidatec 3szjjd}t|}tdd|D}t|D]}|s&|jjr&qtj j |j|j d}|j |fVqdS)N) project_namerrcss|]}|jjVqdSrq)rs is_yanked)r\icanrGrGrH szUFactory._iter_found_candidates..iter_index_candidate_infos..)rsr}rrr) r`find_best_candidatelistiter_applicableallreversedrsr functoolspartialrr)resulticans all_yankedrfunc)r}rrrnrrrGrHiter_index_candidate_infoss*   zBFactory._iter_found_candidates..iter_index_candidate_infos) reqrr frozensetrrr}r r.rr:r9) rnrrrrrireqrrrG)r}rrrrnrrrH_iter_found_candidatess&    zFactory._iter_found_candidatesbase_requirementsccsL|D] }|\}}|durqt|}|dusJd|||VqdS)a8Produce explicit candidates from the base given an extra-ed package. :param base_requirements: Requirements known to the resolver. The requirements are guaranteed to not have extras. :param extras: The extras to inject into the explicit requirements' candidates. Nzno extras here)get_candidate_lookupr8r)rnrr}r lookup_cand_ base_candrGrGrH#_iter_explicit_candidates_from_base2s z+Factory._iter_explicit_candidates_from_base identifier constraintccsF|jD]}|||j|tt||t|dd}|r |VqdS)zProduce explicit candidates from constraints. This creates "fake" InstallRequirement objects that are basically clones of what "should" be the template, but with original_link set to link. Nr}rrr)linksr{rrr$r)rnrrrrsrrGrGrH!_iter_candidates_from_constraintsHs z)Factory._iter_candidates_from_constraintsrKincompatibilitiesc st}g}D]}|\} } | dur|| | dur#|| q ttt} ||  | j dt | j Wdn1sIwY|rjz||j|ddWn tyiYdSwdd| dD|s||jj|Sfdd|DS)NrGr)rcSsh|]}t|qSrG)r~r\crGrGrH z*Factory.find_candidates..c3sD|]tvrrtfddDrVqdS)c3s|]}|VqdSrq)is_satisfied_by)r\rrrGrHrsz4Factory.find_candidates...N)r~rr)r\rr incompat_idsrKrrHrs z*Factory.find_candidates..)setraddappend contextlibsuppressrr+updatergetrrr}rrrrr) rnrrKrrrexplicit_candidatesrrcandrparsed_requirementrGrrHfind_candidates_sT         zFactory.find_candidatesrrequested_extrascCs||std|j|jdS|jst|S||j|j|jt |j ||jr.t |jnddd}|durG|js@|j |jt t |jS||S)Nz6Ignoring %s: markers '%s' don't match your environmentr) match_markersrinformarkersrsr=r{rrr}rrgr>make_requirement_from_candidate)rnrrrrGrGrH"_make_requirement_from_install_reqs,    z*Factory._make_requirement_from_install_req root_ireqscCstgii}t|D][\}}|jrDt|}|rt||s q |js'Jdt|j}||jvr;|j||M<q t ||j|<q |j |dd}|durPq |j r_|j|j vr_||j |j<|j|q |S)NzConstraint must be namedrG)r)rJ enumeraterr&rrrrrLr0 from_ireqr user_suppliedrMrKr)rnr collectedirproblemrrrGrGrHcollect_root_requirementss.    z!Factory.collect_root_requirementsrcCst|Srq)r;)rnrrGrGrHrsz'Factory.make_requirement_from_candidaterG comes_fromcCs|||}|||Srq)rcr)rnrrrrrGrGrHmake_requirement_from_specs  z"Factory.make_requirement_from_speccCs"|jrdSt|s dSt||jSrq)rfrNr<rb)rnrrGrGrH make_requires_python_requirements  z(Factory.make_requires_python_requirementcCs*|jdus |jjr dS|jj||tdS)aLook up the link in the wheel cache. If ``preparer.require_hashes`` is True, don't use the wheel cache, because cached wheels, always built locally, have different hashes than the files downloaded from the index server and thus throw false hash mismatches. Furthermore, cached wheels at present have nondeterministic contents due to file modification times. N)rs package_namesupported_tags)rarRrequire_hashesget_cache_entryr()rnrsrrGrGrHget_wheel_cache_entrys zFactory.get_wheel_cache_entrycCs|j|j}|dur dSz t|jtjdddtjidtjdddtjidfvr,WdSWn t y6Ynw|j s<|S|j rA|St rU|j rUd|jd|j}t|dS)Npurelib rpm_prefixr|)schemevarsplatlibzNWill not install to the user site because it will lack sys.path precedence to z in )rmrrr*_dist sysconfigget_pathsys base_prefixrrd in_usersiter,in_site_packagesraw_namelocationr)rnrr]messagerGrGrHget_dist_to_uninstalls4  zFactory.get_dist_to_uninstallcausesr@cCs|sJd|jj}t|dkr+t|djj}d|djjd|d|}t|Sd|d}|D]}|j }t|jj}|d |d |d 7}q3t|S) Nz,Requires-Python error reported with no causer-rzPackage z requires a different Python: z not in z%Packages require a different Python. z not in: z (required by )) rbrlenrNrArrBrrformat_for_error)rnrrrrcausepackagerGrGrH_report_requires_python_error5s"     z%Factory._report_requires_python_errorrrBcCs|dur t|}n |d|jd}|j|j}ddtdd|DD}td|d|p1d t|d kr>t d t d |S) Nz (from rcSsg|]}t|qSrG)rN)r\vrGrGrH Trz?Factory._report_single_requirement_conflict..cSsh|]}|jqSrG)rrrGrGrHrTsz>Factory._report_single_requirement_conflict..zNCould not find a version that satisfies the requirement %s (from versions: %s), nonezrequirements.txtzHINT: You are attempting to install a package literally named "requirements.txt" (which cannot exist). Consider using the '-r' flag to install the packages listed in requirements.txtz#No matching distribution found for ) rNrr`find_all_candidatesrsortedrcriticaljoinrr)rnrrBreq_dispcandsversionsrGrGrH#_report_single_requirement_conflictKs   z+Factory._report_single_requirement_conflictrz,ResolutionImpossible[Requirement, Candidate]rLcs|jsJdfdd|jD}|rtd|St|jdkr4|jd\}}|j|vr4||Sdttdtfd d }d tdtfd d }t }|jD]\}}|dur[| } n||} | | qN|rn|t |} nd} d | } t| d} t } |jD],\}}|j|vr| |j| d} |r| |jd|jd} n| d} | | } q| D]} || j}| d| |7} q| ddddd} t| tdS)Nz)Installation error reported with no causecs*g|]}t|jtr|jjs|qSrG) isinstancerAr<rrb)r\rrrrGrHrps  z2Factory.get_installation_error..zSequence[ConflictCause]r-rpartsrZcSs2t|dkr |dSd|ddd|dS)Nr-rrz and )rr)rrGrGrH text_joins z1Factory.get_installation_error..text_joinrBcSsF|}|r |js|jd|jSt|jtrt|jjSt|jS)Nz==)get_install_requirementrrrrr%rN)rBrrGrGrHdescribe_triggers     z8Factory.get_installation_error..describe_triggerzthe requested packageszOCannot install {} because these package versions have conflicting dependencies.z The conflict is caused by:z  z depends on zThe user requested z% The user requested (constraint) z zTo fix this you could try to: z91. loosen the range of package versions you've specified z92. remove package versions to allow pip attempt to solve zthe dependency conflict znResolutionImpossible: for help visit https://pip.pypa.io/en/latest/user_guide/#fixing-conflicting-dependencies)rrrrrrrrNr.rrrrformatrrrrrr)rnrrLrequires_python_causesrrBrr triggerstriggerrrzrelevant_constraintskeyspecrGrrrHget_installation_errorfsp           zFactory.get_installation_errorrq)rG);rCrDrErr#r'r rboolr rOrppropertyrVr!r{r3rrNr5rrr%r.rrr/rr rr)r rrr1rrr0rrrrrrJrr;rrrrrrrrrrrrrrGrGrGrHrP]s8    &     3 T   F          &   rP)crrloggingrrtypingrrrrrrrr r r r r rrZ"pip._vendor.packaging.requirementsrZ pip._vendor.packaging.specifiersrpip._vendor.packaging.utilsrrpip._vendor.resolvelibrpip._internal.cacherrpip._internal.exceptionsrrrrrr"pip._internal.index.package_finderrpip._internal.locationsrpip._internal.metadatarr pip._internal.models.linkr!pip._internal.models.wheelr" pip._internal.operations.preparer#pip._internal.req.constructorsr$pip._internal.req.req_installr%r&pip._internal.resolution.baser'&pip._internal.utils.compatibility_tagsr(pip._internal.utils.hashesr)pip._internal.utils.miscr*pip._internal.utils.packagingr+pip._internal.utils.virtualenvr,r|r.r/r0r1 candidatesr2r3r4r5r6r7r8found_candidatesr9r:rKr;r<r=r>r?r@ getLoggerrCrrICacherJrPrGrGrGrHsL@                $    PKH]//ipython3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-310.pycnu[o aiI@sdZddlZddlmZddlmZmZmZmZm Z m Z m Z ddl m Z ddlmZe e ege effZer=eeZneZdeed eefd d Zd edeed eefd dZd edeed eefddZGdddeZdS)aUtilities to lazily create and visit candidates found. Creating and visiting a candidate is a *very* costly operation. It involves fetching, extracting, potentially building modules from source, and verifying distribution metadata. It is therefore crucial for performance to keep everything here lazy all the way down, so we only touch candidates that we absolutely need, and not "download the world" when we only need one version of something. N)Sequence) TYPE_CHECKINGAnyCallableIteratorOptionalSetTuple) _BaseVersion) CandidateinfosreturnccsDt}|D]\}}||vrq|}|durq|V||qdS)zIterator for ``FoundCandidates``. This iterator is used when the package is not already installed. Candidates from index come later in their normal ordering. N)setadd)r versions_foundversionfunc candidater/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py _iter_built%s  r installedccsL|V|jh}|D]\}}||vrq |}|durq |V||q dS)aKIterator for ``FoundCandidates``. This iterator is used when the resolver prefers the already-installed candidate and NOT to upgrade. The installed candidate is therefore always yielded first, and candidates from index come later in their normal ordering, except skipped when the version is already installed. N)rrrr rrrrrrr_iter_built_with_prepended6s   rccstt}|D]'\}}||vrq|j|kr|V||j|}|dur%q|V||q|j|vr8|VdSdS)aIterator for ``FoundCandidates``. This iterator is used when the resolver prefers to upgrade an already-installed package. Candidates from index are returned in their normal ordering, except replaced when the version is already installed. The implementation iterates through and yields other candidates, inserting the installed candidate exactly once before we start yielding older or equivalent candidates, or after all other candidates if they are all newer. N)rrrrrrr_iter_built_with_insertedLs       rc @seZdZdZdegeefdeede de e fddZ de d e fd d Zd eefd d Zd e fddZejddd e fddZdS)FoundCandidatesacA lazy sequence to provide candidates to the resolver. The intended usage is to return this from `find_matches()` so the resolver can iterate through the sequence multiple times, but only access the index page when remote packages are actually needed. This improve performances when suitable candidates are already installed on disk. get_infosrprefers_installedincompatible_idscCs||_||_||_||_dSN) _get_infos _installed_prefers_installed_incompatible_ids)selfrrrrrrr__init__us zFoundCandidates.__init__indexrcCtdNz don't do thisNotImplementedError)r%r'rrr __getitem__zFoundCandidates.__getitem__csJ}js t|}njrtj|}ntj|}fdd|DS)Nc3s"|] }t|jvr|VqdSr )idr$).0cr%rr s z+FoundCandidates.__iter__..)r!r"rr#rr)r%r iteratorrr1r__iter__s  zFoundCandidates.__iter__cCr(r)r*r1rrr__len__r-zFoundCandidates.__len__r )maxsizecCs|jr|jrdSt|S)NT)r#r"anyr1rrr__bool__s zFoundCandidates.__bool__N)__name__ __module__ __qualname____doc__rrIndexCandidateInforr boolrintr&rr,r4r5 functools lru_cacher8rrrrrls    r)r<r@collections.abcrtypingrrrrrrr Zpip._vendor.packaging.versionr baser r=SequenceCandidaterrrrrrrrs4 $       PKH]jk"G"GJpython3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.pynu[import logging import sys from typing import TYPE_CHECKING, Any, FrozenSet, Iterable, Optional, Tuple, Union, cast from pip._vendor.packaging.utils import NormalizedName, canonicalize_name from pip._vendor.packaging.version import Version from pip._internal.exceptions import HashError, MetadataInconsistent from pip._internal.metadata import BaseDistribution from pip._internal.models.link import Link, links_equivalent from pip._internal.models.wheel import Wheel from pip._internal.req.constructors import ( install_req_from_editable, install_req_from_line, ) from pip._internal.req.req_install import InstallRequirement from pip._internal.utils.misc import normalize_version_info from .base import Candidate, CandidateVersion, Requirement, format_name if TYPE_CHECKING: from .factory import Factory logger = logging.getLogger(__name__) BaseCandidate = Union[ "AlreadyInstalledCandidate", "EditableCandidate", "LinkCandidate", ] # Avoid conflicting with the PyPI package "Python". REQUIRES_PYTHON_IDENTIFIER = cast(NormalizedName, "") def as_base_candidate(candidate: Candidate) -> Optional[BaseCandidate]: """The runtime version of BaseCandidate.""" base_candidate_classes = ( AlreadyInstalledCandidate, EditableCandidate, LinkCandidate, ) if isinstance(candidate, base_candidate_classes): return candidate return None def make_install_req_from_link( link: Link, template: InstallRequirement ) -> InstallRequirement: assert not template.editable, "template is editable" if template.req: line = str(template.req) else: line = link.url ireq = install_req_from_line( line, user_supplied=template.user_supplied, comes_from=template.comes_from, use_pep517=template.use_pep517, isolated=template.isolated, constraint=template.constraint, options=dict( install_options=template.install_options, global_options=template.global_options, hashes=template.hash_options, ), ) ireq.original_link = template.original_link ireq.link = link return ireq def make_install_req_from_editable( link: Link, template: InstallRequirement ) -> InstallRequirement: assert template.editable, "template not editable" return install_req_from_editable( link.url, user_supplied=template.user_supplied, comes_from=template.comes_from, use_pep517=template.use_pep517, isolated=template.isolated, constraint=template.constraint, permit_editable_wheels=template.permit_editable_wheels, options=dict( install_options=template.install_options, global_options=template.global_options, hashes=template.hash_options, ), ) def _make_install_req_from_dist( dist: BaseDistribution, template: InstallRequirement ) -> InstallRequirement: from pip._internal.metadata.pkg_resources import Distribution as _Dist if template.req: line = str(template.req) elif template.link: line = f"{dist.canonical_name} @ {template.link.url}" else: line = f"{dist.canonical_name}=={dist.version}" ireq = install_req_from_line( line, user_supplied=template.user_supplied, comes_from=template.comes_from, use_pep517=template.use_pep517, isolated=template.isolated, constraint=template.constraint, options=dict( install_options=template.install_options, global_options=template.global_options, hashes=template.hash_options, ), ) ireq.satisfied_by = cast(_Dist, dist)._dist return ireq class _InstallRequirementBackedCandidate(Candidate): """A candidate backed by an ``InstallRequirement``. This represents a package request with the target not being already in the environment, and needs to be fetched and installed. The backing ``InstallRequirement`` is responsible for most of the leg work; this class exposes appropriate information to the resolver. :param link: The link passed to the ``InstallRequirement``. The backing ``InstallRequirement`` will use this link to fetch the distribution. :param source_link: The link this candidate "originates" from. This is different from ``link`` when the link is found in the wheel cache. ``link`` would point to the wheel cache, while this points to the found remote link (e.g. from pypi.org). """ dist: BaseDistribution is_installed = False def __init__( self, link: Link, source_link: Link, ireq: InstallRequirement, factory: "Factory", name: Optional[NormalizedName] = None, version: Optional[CandidateVersion] = None, ) -> None: self._link = link self._source_link = source_link self._factory = factory self._ireq = ireq self._name = name self._version = version self.dist = self._prepare() def __str__(self) -> str: return f"{self.name} {self.version}" def __repr__(self) -> str: return "{class_name}({link!r})".format( class_name=self.__class__.__name__, link=str(self._link), ) def __hash__(self) -> int: return hash((self.__class__, self._link)) def __eq__(self, other: Any) -> bool: if isinstance(other, self.__class__): return links_equivalent(self._link, other._link) return False @property def source_link(self) -> Optional[Link]: return self._source_link @property def project_name(self) -> NormalizedName: """The normalised name of the project the candidate refers to""" if self._name is None: self._name = self.dist.canonical_name return self._name @property def name(self) -> str: return self.project_name @property def version(self) -> CandidateVersion: if self._version is None: self._version = self.dist.version return self._version def format_for_error(self) -> str: return "{} {} (from {})".format( self.name, self.version, self._link.file_path if self._link.is_file else self._link, ) def _prepare_distribution(self) -> BaseDistribution: raise NotImplementedError("Override in subclass") def _check_metadata_consistency(self, dist: BaseDistribution) -> None: """Check for consistency of project name and version of dist.""" if self._name is not None and self._name != dist.canonical_name: raise MetadataInconsistent( self._ireq, "name", self._name, dist.canonical_name, ) if self._version is not None and self._version != dist.version: raise MetadataInconsistent( self._ireq, "version", str(self._version), str(dist.version), ) def _prepare(self) -> BaseDistribution: try: dist = self._prepare_distribution() except HashError as e: # Provide HashError the underlying ireq that caused it. This # provides context for the resulting error message to show the # offending line to the user. e.req = self._ireq raise self._check_metadata_consistency(dist) return dist def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]: requires = self.dist.iter_dependencies() if with_requires else () for r in requires: yield self._factory.make_requirement_from_spec(str(r), self._ireq) yield self._factory.make_requires_python_requirement(self.dist.requires_python) def get_install_requirement(self) -> Optional[InstallRequirement]: return self._ireq class LinkCandidate(_InstallRequirementBackedCandidate): is_editable = False def __init__( self, link: Link, template: InstallRequirement, factory: "Factory", name: Optional[NormalizedName] = None, version: Optional[CandidateVersion] = None, ) -> None: source_link = link cache_entry = factory.get_wheel_cache_entry(link, name) if cache_entry is not None: logger.debug("Using cached wheel link: %s", cache_entry.link) link = cache_entry.link ireq = make_install_req_from_link(link, template) assert ireq.link == link if ireq.link.is_wheel and not ireq.link.is_file: wheel = Wheel(ireq.link.filename) wheel_name = canonicalize_name(wheel.name) assert name == wheel_name, f"{name!r} != {wheel_name!r} for wheel" # Version may not be present for PEP 508 direct URLs if version is not None: wheel_version = Version(wheel.version) assert version == wheel_version, "{!r} != {!r} for wheel {}".format( version, wheel_version, name ) if ( cache_entry is not None and cache_entry.persistent and template.link is template.original_link ): ireq.original_link_is_in_wheel_cache = True super().__init__( link=link, source_link=source_link, ireq=ireq, factory=factory, name=name, version=version, ) def _prepare_distribution(self) -> BaseDistribution: preparer = self._factory.preparer return preparer.prepare_linked_requirement(self._ireq, parallel_builds=True) class EditableCandidate(_InstallRequirementBackedCandidate): is_editable = True def __init__( self, link: Link, template: InstallRequirement, factory: "Factory", name: Optional[NormalizedName] = None, version: Optional[CandidateVersion] = None, ) -> None: super().__init__( link=link, source_link=link, ireq=make_install_req_from_editable(link, template), factory=factory, name=name, version=version, ) def _prepare_distribution(self) -> BaseDistribution: return self._factory.preparer.prepare_editable_requirement(self._ireq) class AlreadyInstalledCandidate(Candidate): is_installed = True source_link = None def __init__( self, dist: BaseDistribution, template: InstallRequirement, factory: "Factory", ) -> None: self.dist = dist self._ireq = _make_install_req_from_dist(dist, template) self._factory = factory # This is just logging some messages, so we can do it eagerly. # The returned dist would be exactly the same as self.dist because we # set satisfied_by in _make_install_req_from_dist. # TODO: Supply reason based on force_reinstall and upgrade_strategy. skip_reason = "already satisfied" factory.preparer.prepare_installed_requirement(self._ireq, skip_reason) def __str__(self) -> str: return str(self.dist) def __repr__(self) -> str: return "{class_name}({distribution!r})".format( class_name=self.__class__.__name__, distribution=self.dist, ) def __hash__(self) -> int: return hash((self.__class__, self.name, self.version)) def __eq__(self, other: Any) -> bool: if isinstance(other, self.__class__): return self.name == other.name and self.version == other.version return False @property def project_name(self) -> NormalizedName: return self.dist.canonical_name @property def name(self) -> str: return self.project_name @property def version(self) -> CandidateVersion: return self.dist.version @property def is_editable(self) -> bool: return self.dist.editable def format_for_error(self) -> str: return f"{self.name} {self.version} (Installed)" def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]: if not with_requires: return for r in self.dist.iter_dependencies(): yield self._factory.make_requirement_from_spec(str(r), self._ireq) def get_install_requirement(self) -> Optional[InstallRequirement]: return None class ExtrasCandidate(Candidate): """A candidate that has 'extras', indicating additional dependencies. Requirements can be for a project with dependencies, something like foo[extra]. The extras don't affect the project/version being installed directly, but indicate that we need additional dependencies. We model that by having an artificial ExtrasCandidate that wraps the "base" candidate. The ExtrasCandidate differs from the base in the following ways: 1. It has a unique name, of the form foo[extra]. This causes the resolver to treat it as a separate node in the dependency graph. 2. When we're getting the candidate's dependencies, a) We specify that we want the extra dependencies as well. b) We add a dependency on the base candidate. See below for why this is needed. 3. We return None for the underlying InstallRequirement, as the base candidate will provide it, and we don't want to end up with duplicates. The dependency on the base candidate is needed so that the resolver can't decide that it should recommend foo[extra1] version 1.0 and foo[extra2] version 2.0. Having those candidates depend on foo=1.0 and foo=2.0 respectively forces the resolver to recognise that this is a conflict. """ def __init__( self, base: BaseCandidate, extras: FrozenSet[str], ) -> None: self.base = base self.extras = extras def __str__(self) -> str: name, rest = str(self.base).split(" ", 1) return "{}[{}] {}".format(name, ",".join(self.extras), rest) def __repr__(self) -> str: return "{class_name}(base={base!r}, extras={extras!r})".format( class_name=self.__class__.__name__, base=self.base, extras=self.extras, ) def __hash__(self) -> int: return hash((self.base, self.extras)) def __eq__(self, other: Any) -> bool: if isinstance(other, self.__class__): return self.base == other.base and self.extras == other.extras return False @property def project_name(self) -> NormalizedName: return self.base.project_name @property def name(self) -> str: """The normalised name of the project the candidate refers to""" return format_name(self.base.project_name, self.extras) @property def version(self) -> CandidateVersion: return self.base.version def format_for_error(self) -> str: return "{} [{}]".format( self.base.format_for_error(), ", ".join(sorted(self.extras)) ) @property def is_installed(self) -> bool: return self.base.is_installed @property def is_editable(self) -> bool: return self.base.is_editable @property def source_link(self) -> Optional[Link]: return self.base.source_link def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]: factory = self.base._factory # Add a dependency on the exact base # (See note 2b in the class docstring) yield factory.make_requirement_from_candidate(self.base) if not with_requires: return # The user may have specified extras that the candidate doesn't # support. We ignore any unsupported extras here. valid_extras = self.extras.intersection(self.base.dist.iter_provided_extras()) invalid_extras = self.extras.difference(self.base.dist.iter_provided_extras()) for extra in sorted(invalid_extras): logger.warning( "%s %s does not provide the extra '%s'", self.base.name, self.version, extra, ) for r in self.base.dist.iter_dependencies(valid_extras): requirement = factory.make_requirement_from_spec( str(r), self.base._ireq, valid_extras ) if requirement: yield requirement def get_install_requirement(self) -> Optional[InstallRequirement]: # We don't return anything here, because we always # depend on the base candidate, and we'll get the # install requirement from that. return None class RequiresPythonCandidate(Candidate): is_installed = False source_link = None def __init__(self, py_version_info: Optional[Tuple[int, ...]]) -> None: if py_version_info is not None: version_info = normalize_version_info(py_version_info) else: version_info = sys.version_info[:3] self._version = Version(".".join(str(c) for c in version_info)) # We don't need to implement __eq__() and __ne__() since there is always # only one RequiresPythonCandidate in a resolution, i.e. the host Python. # The built-in object.__eq__() and object.__ne__() do exactly what we want. def __str__(self) -> str: return f"Python {self._version}" @property def project_name(self) -> NormalizedName: return REQUIRES_PYTHON_IDENTIFIER @property def name(self) -> str: return REQUIRES_PYTHON_IDENTIFIER @property def version(self) -> CandidateVersion: return self._version def format_for_error(self) -> str: return f"Python {self.version}" def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]: return () def get_install_requirement(self) -> Optional[InstallRequirement]: return None PKH]jjGpython3.10/site-packages/pip/_internal/resolution/resolvelib/factory.pynu[import contextlib import functools import logging import sys import sysconfig from typing import ( TYPE_CHECKING, Dict, FrozenSet, Iterable, Iterator, List, Mapping, NamedTuple, Optional, Sequence, Set, Tuple, TypeVar, cast, ) from pip._vendor.packaging.requirements import InvalidRequirement from pip._vendor.packaging.specifiers import SpecifierSet from pip._vendor.packaging.utils import NormalizedName, canonicalize_name from pip._vendor.resolvelib import ResolutionImpossible from pip._internal.cache import CacheEntry, WheelCache from pip._internal.exceptions import ( DistributionNotFound, InstallationError, InstallationSubprocessError, MetadataInconsistent, UnsupportedPythonVersion, UnsupportedWheel, ) from pip._internal.index.package_finder import PackageFinder from pip._internal.locations import get_scheme from pip._internal.metadata import BaseDistribution, get_default_environment from pip._internal.models.link import Link from pip._internal.models.wheel import Wheel from pip._internal.operations.prepare import RequirementPreparer from pip._internal.req.constructors import install_req_from_link_and_ireq from pip._internal.req.req_install import ( InstallRequirement, check_invalid_constraint_type, ) from pip._internal.resolution.base import InstallRequirementProvider from pip._internal.utils.compatibility_tags import get_supported from pip._internal.utils.hashes import Hashes from pip._internal.utils.misc import dist_location from pip._internal.utils.packaging import get_requirement from pip._internal.utils.virtualenv import running_under_virtualenv from .base import Candidate, CandidateVersion, Constraint, Requirement from .candidates import ( AlreadyInstalledCandidate, BaseCandidate, EditableCandidate, ExtrasCandidate, LinkCandidate, RequiresPythonCandidate, as_base_candidate, ) from .found_candidates import FoundCandidates, IndexCandidateInfo from .requirements import ( ExplicitRequirement, RequiresPythonRequirement, SpecifierRequirement, UnsatisfiableRequirement, ) if TYPE_CHECKING: from typing import Protocol class ConflictCause(Protocol): requirement: RequiresPythonRequirement parent: Candidate logger = logging.getLogger(__name__) C = TypeVar("C") Cache = Dict[Link, C] class CollectedRootRequirements(NamedTuple): requirements: List[Requirement] constraints: Dict[str, Constraint] user_requested: Dict[str, int] class Factory: def __init__( self, finder: PackageFinder, preparer: RequirementPreparer, make_install_req: InstallRequirementProvider, wheel_cache: Optional[WheelCache], use_user_site: bool, force_reinstall: bool, ignore_installed: bool, ignore_requires_python: bool, py_version_info: Optional[Tuple[int, ...]] = None, ) -> None: self._finder = finder self.preparer = preparer self._wheel_cache = wheel_cache self._python_candidate = RequiresPythonCandidate(py_version_info) self._make_install_req_from_spec = make_install_req self._use_user_site = use_user_site self._force_reinstall = force_reinstall self._ignore_requires_python = ignore_requires_python self._build_failures: Cache[InstallationError] = {} self._link_candidate_cache: Cache[LinkCandidate] = {} self._editable_candidate_cache: Cache[EditableCandidate] = {} self._installed_candidate_cache: Dict[str, AlreadyInstalledCandidate] = {} self._extras_candidate_cache: Dict[ Tuple[int, FrozenSet[str]], ExtrasCandidate ] = {} if not ignore_installed: env = get_default_environment() self._installed_dists = { dist.canonical_name: dist for dist in env.iter_installed_distributions(local_only=False) } else: self._installed_dists = {} @property def force_reinstall(self) -> bool: return self._force_reinstall def _fail_if_link_is_unsupported_wheel(self, link: Link) -> None: if not link.is_wheel: return wheel = Wheel(link.filename) if wheel.supported(self._finder.target_python.get_tags()): return msg = f"{link.filename} is not a supported wheel on this platform." raise UnsupportedWheel(msg) def _make_extras_candidate( self, base: BaseCandidate, extras: FrozenSet[str] ) -> ExtrasCandidate: cache_key = (id(base), extras) try: candidate = self._extras_candidate_cache[cache_key] except KeyError: candidate = ExtrasCandidate(base, extras) self._extras_candidate_cache[cache_key] = candidate return candidate def _make_candidate_from_dist( self, dist: BaseDistribution, extras: FrozenSet[str], template: InstallRequirement, ) -> Candidate: try: base = self._installed_candidate_cache[dist.canonical_name] except KeyError: base = AlreadyInstalledCandidate(dist, template, factory=self) self._installed_candidate_cache[dist.canonical_name] = base if not extras: return base return self._make_extras_candidate(base, extras) def _make_candidate_from_link( self, link: Link, extras: FrozenSet[str], template: InstallRequirement, name: Optional[NormalizedName], version: Optional[CandidateVersion], ) -> Optional[Candidate]: # TODO: Check already installed candidate, and use it if the link and # editable flag match. if link in self._build_failures: # We already tried this candidate before, and it does not build. # Don't bother trying again. return None if template.editable: if link not in self._editable_candidate_cache: try: self._editable_candidate_cache[link] = EditableCandidate( link, template, factory=self, name=name, version=version, ) except (InstallationSubprocessError, MetadataInconsistent) as e: logger.warning("Discarding %s. %s", link, e) self._build_failures[link] = e return None base: BaseCandidate = self._editable_candidate_cache[link] else: if link not in self._link_candidate_cache: try: self._link_candidate_cache[link] = LinkCandidate( link, template, factory=self, name=name, version=version, ) except (InstallationSubprocessError, MetadataInconsistent) as e: logger.warning("Discarding %s. %s", link, e) self._build_failures[link] = e return None base = self._link_candidate_cache[link] if not extras: return base return self._make_extras_candidate(base, extras) def _iter_found_candidates( self, ireqs: Sequence[InstallRequirement], specifier: SpecifierSet, hashes: Hashes, prefers_installed: bool, incompatible_ids: Set[int], ) -> Iterable[Candidate]: if not ireqs: return () # The InstallRequirement implementation requires us to give it a # "template". Here we just choose the first requirement to represent # all of them. # Hopefully the Project model can correct this mismatch in the future. template = ireqs[0] assert template.req, "Candidates found on index must be PEP 508" name = canonicalize_name(template.req.name) extras: FrozenSet[str] = frozenset() for ireq in ireqs: assert ireq.req, "Candidates found on index must be PEP 508" specifier &= ireq.req.specifier hashes &= ireq.hashes(trust_internet=False) extras |= frozenset(ireq.extras) def _get_installed_candidate() -> Optional[Candidate]: """Get the candidate for the currently-installed version.""" # If --force-reinstall is set, we want the version from the index # instead, so we "pretend" there is nothing installed. if self._force_reinstall: return None try: installed_dist = self._installed_dists[name] except KeyError: return None # Don't use the installed distribution if its version does not fit # the current dependency graph. if not specifier.contains(installed_dist.version, prereleases=True): return None candidate = self._make_candidate_from_dist( dist=installed_dist, extras=extras, template=template, ) # The candidate is a known incompatiblity. Don't use it. if id(candidate) in incompatible_ids: return None return candidate def iter_index_candidate_infos() -> Iterator[IndexCandidateInfo]: result = self._finder.find_best_candidate( project_name=name, specifier=specifier, hashes=hashes, ) icans = list(result.iter_applicable()) # PEP 592: Yanked releases must be ignored unless only yanked # releases can satisfy the version range. So if this is false, # all yanked icans need to be skipped. all_yanked = all(ican.link.is_yanked for ican in icans) # PackageFinder returns earlier versions first, so we reverse. for ican in reversed(icans): if not all_yanked and ican.link.is_yanked: continue func = functools.partial( self._make_candidate_from_link, link=ican.link, extras=extras, template=template, name=name, version=ican.version, ) yield ican.version, func return FoundCandidates( iter_index_candidate_infos, _get_installed_candidate(), prefers_installed, incompatible_ids, ) def _iter_explicit_candidates_from_base( self, base_requirements: Iterable[Requirement], extras: FrozenSet[str], ) -> Iterator[Candidate]: """Produce explicit candidates from the base given an extra-ed package. :param base_requirements: Requirements known to the resolver. The requirements are guaranteed to not have extras. :param extras: The extras to inject into the explicit requirements' candidates. """ for req in base_requirements: lookup_cand, _ = req.get_candidate_lookup() if lookup_cand is None: # Not explicit. continue # We've stripped extras from the identifier, and should always # get a BaseCandidate here, unless there's a bug elsewhere. base_cand = as_base_candidate(lookup_cand) assert base_cand is not None, "no extras here" yield self._make_extras_candidate(base_cand, extras) def _iter_candidates_from_constraints( self, identifier: str, constraint: Constraint, template: InstallRequirement, ) -> Iterator[Candidate]: """Produce explicit candidates from constraints. This creates "fake" InstallRequirement objects that are basically clones of what "should" be the template, but with original_link set to link. """ for link in constraint.links: self._fail_if_link_is_unsupported_wheel(link) candidate = self._make_candidate_from_link( link, extras=frozenset(), template=install_req_from_link_and_ireq(link, template), name=canonicalize_name(identifier), version=None, ) if candidate: yield candidate def find_candidates( self, identifier: str, requirements: Mapping[str, Iterable[Requirement]], incompatibilities: Mapping[str, Iterator[Candidate]], constraint: Constraint, prefers_installed: bool, ) -> Iterable[Candidate]: # Collect basic lookup information from the requirements. explicit_candidates: Set[Candidate] = set() ireqs: List[InstallRequirement] = [] for req in requirements[identifier]: cand, ireq = req.get_candidate_lookup() if cand is not None: explicit_candidates.add(cand) if ireq is not None: ireqs.append(ireq) # If the current identifier contains extras, add explicit candidates # from entries from extra-less identifier. with contextlib.suppress(InvalidRequirement): parsed_requirement = get_requirement(identifier) explicit_candidates.update( self._iter_explicit_candidates_from_base( requirements.get(parsed_requirement.name, ()), frozenset(parsed_requirement.extras), ), ) # Add explicit candidates from constraints. We only do this if there are # kown ireqs, which represent requirements not already explicit. If # there are no ireqs, we're constraining already-explicit requirements, # which is handled later when we return the explicit candidates. if ireqs: try: explicit_candidates.update( self._iter_candidates_from_constraints( identifier, constraint, template=ireqs[0], ), ) except UnsupportedWheel: # If we're constrained to install a wheel incompatible with the # target architecture, no candidates will ever be valid. return () # Since we cache all the candidates, incompatibility identification # can be made quicker by comparing only the id() values. incompat_ids = {id(c) for c in incompatibilities.get(identifier, ())} # If none of the requirements want an explicit candidate, we can ask # the finder for candidates. if not explicit_candidates: return self._iter_found_candidates( ireqs, constraint.specifier, constraint.hashes, prefers_installed, incompat_ids, ) return ( c for c in explicit_candidates if id(c) not in incompat_ids and constraint.is_satisfied_by(c) and all(req.is_satisfied_by(c) for req in requirements[identifier]) ) def _make_requirement_from_install_req( self, ireq: InstallRequirement, requested_extras: Iterable[str] ) -> Optional[Requirement]: if not ireq.match_markers(requested_extras): logger.info( "Ignoring %s: markers '%s' don't match your environment", ireq.name, ireq.markers, ) return None if not ireq.link: return SpecifierRequirement(ireq) self._fail_if_link_is_unsupported_wheel(ireq.link) cand = self._make_candidate_from_link( ireq.link, extras=frozenset(ireq.extras), template=ireq, name=canonicalize_name(ireq.name) if ireq.name else None, version=None, ) if cand is None: # There's no way we can satisfy a URL requirement if the underlying # candidate fails to build. An unnamed URL must be user-supplied, so # we fail eagerly. If the URL is named, an unsatisfiable requirement # can make the resolver do the right thing, either backtrack (and # maybe find some other requirement that's buildable) or raise a # ResolutionImpossible eventually. if not ireq.name: raise self._build_failures[ireq.link] return UnsatisfiableRequirement(canonicalize_name(ireq.name)) return self.make_requirement_from_candidate(cand) def collect_root_requirements( self, root_ireqs: List[InstallRequirement] ) -> CollectedRootRequirements: collected = CollectedRootRequirements([], {}, {}) for i, ireq in enumerate(root_ireqs): if ireq.constraint: # Ensure we only accept valid constraints problem = check_invalid_constraint_type(ireq) if problem: raise InstallationError(problem) if not ireq.match_markers(): continue assert ireq.name, "Constraint must be named" name = canonicalize_name(ireq.name) if name in collected.constraints: collected.constraints[name] &= ireq else: collected.constraints[name] = Constraint.from_ireq(ireq) else: req = self._make_requirement_from_install_req( ireq, requested_extras=(), ) if req is None: continue if ireq.user_supplied and req.name not in collected.user_requested: collected.user_requested[req.name] = i collected.requirements.append(req) return collected def make_requirement_from_candidate( self, candidate: Candidate ) -> ExplicitRequirement: return ExplicitRequirement(candidate) def make_requirement_from_spec( self, specifier: str, comes_from: Optional[InstallRequirement], requested_extras: Iterable[str] = (), ) -> Optional[Requirement]: ireq = self._make_install_req_from_spec(specifier, comes_from) return self._make_requirement_from_install_req(ireq, requested_extras) def make_requires_python_requirement( self, specifier: SpecifierSet, ) -> Optional[Requirement]: if self._ignore_requires_python: return None # Don't bother creating a dependency for an empty Requires-Python. if not str(specifier): return None return RequiresPythonRequirement(specifier, self._python_candidate) def get_wheel_cache_entry( self, link: Link, name: Optional[str] ) -> Optional[CacheEntry]: """Look up the link in the wheel cache. If ``preparer.require_hashes`` is True, don't use the wheel cache, because cached wheels, always built locally, have different hashes than the files downloaded from the index server and thus throw false hash mismatches. Furthermore, cached wheels at present have nondeterministic contents due to file modification times. """ if self._wheel_cache is None or self.preparer.require_hashes: return None return self._wheel_cache.get_cache_entry( link=link, package_name=name, supported_tags=get_supported(), ) def get_dist_to_uninstall(self, candidate: Candidate) -> Optional[BaseDistribution]: # TODO: Are there more cases this needs to return True? Editable? dist = self._installed_dists.get(candidate.project_name) if dist is None: # Not installed, no uninstallation required. return None # Prevent uninstalling packages from /usr try: if dist_location(dist._dist) in ( sysconfig.get_path('purelib', scheme='rpm_prefix', vars={'base': sys.base_prefix}), sysconfig.get_path('platlib', scheme='rpm_prefix', vars={'base': sys.base_prefix}), ): return None except KeyError: # this Python doesn't have 'rpm_prefix' scheme yet pass # We're installing into global site. The current installation must # be uninstalled, no matter it's in global or user site, because the # user site installation has precedence over global. if not self._use_user_site: return dist # We're installing into user site. Remove the user site installation. if dist.in_usersite: return dist # We're installing into user site, but the installed incompatible # package is in global site. We can't uninstall that, and would let # the new user installation to "shadow" it. But shadowing won't work # in virtual environments, so we error out. if running_under_virtualenv() and dist.in_site_packages: message = ( f"Will not install to the user site because it will lack " f"sys.path precedence to {dist.raw_name} in {dist.location}" ) raise InstallationError(message) return None def _report_requires_python_error( self, causes: Sequence["ConflictCause"] ) -> UnsupportedPythonVersion: assert causes, "Requires-Python error reported with no cause" version = self._python_candidate.version if len(causes) == 1: specifier = str(causes[0].requirement.specifier) message = ( f"Package {causes[0].parent.name!r} requires a different " f"Python: {version} not in {specifier!r}" ) return UnsupportedPythonVersion(message) message = f"Packages require a different Python. {version} not in:" for cause in causes: package = cause.parent.format_for_error() specifier = str(cause.requirement.specifier) message += f"\n{specifier!r} (required by {package})" return UnsupportedPythonVersion(message) def _report_single_requirement_conflict( self, req: Requirement, parent: Optional[Candidate] ) -> DistributionNotFound: if parent is None: req_disp = str(req) else: req_disp = f"{req} (from {parent.name})" cands = self._finder.find_all_candidates(req.project_name) versions = [str(v) for v in sorted({c.version for c in cands})] logger.critical( "Could not find a version that satisfies the requirement %s " "(from versions: %s)", req_disp, ", ".join(versions) or "none", ) if str(req) == "requirements.txt": logger.info( "HINT: You are attempting to install a package literally " 'named "requirements.txt" (which cannot exist). Consider ' "using the '-r' flag to install the packages listed in " "requirements.txt" ) return DistributionNotFound(f"No matching distribution found for {req}") def get_installation_error( self, e: "ResolutionImpossible[Requirement, Candidate]", constraints: Dict[str, Constraint], ) -> InstallationError: assert e.causes, "Installation error reported with no cause" # If one of the things we can't solve is "we need Python X.Y", # that is what we report. requires_python_causes = [ cause for cause in e.causes if isinstance(cause.requirement, RequiresPythonRequirement) and not cause.requirement.is_satisfied_by(self._python_candidate) ] if requires_python_causes: # The comprehension above makes sure all Requirement instances are # RequiresPythonRequirement, so let's cast for convinience. return self._report_requires_python_error( cast("Sequence[ConflictCause]", requires_python_causes), ) # Otherwise, we have a set of causes which can't all be satisfied # at once. # The simplest case is when we have *one* cause that can't be # satisfied. We just report that case. if len(e.causes) == 1: req, parent = e.causes[0] if req.name not in constraints: return self._report_single_requirement_conflict(req, parent) # OK, we now have a list of requirements that can't all be # satisfied at once. # A couple of formatting helpers def text_join(parts: List[str]) -> str: if len(parts) == 1: return parts[0] return ", ".join(parts[:-1]) + " and " + parts[-1] def describe_trigger(parent: Candidate) -> str: ireq = parent.get_install_requirement() if not ireq or not ireq.comes_from: return f"{parent.name}=={parent.version}" if isinstance(ireq.comes_from, InstallRequirement): return str(ireq.comes_from.name) return str(ireq.comes_from) triggers = set() for req, parent in e.causes: if parent is None: # This is a root requirement, so we can report it directly trigger = req.format_for_error() else: trigger = describe_trigger(parent) triggers.add(trigger) if triggers: info = text_join(sorted(triggers)) else: info = "the requested packages" msg = ( "Cannot install {} because these package versions " "have conflicting dependencies.".format(info) ) logger.critical(msg) msg = "\nThe conflict is caused by:" relevant_constraints = set() for req, parent in e.causes: if req.name in constraints: relevant_constraints.add(req.name) msg = msg + "\n " if parent: msg = msg + f"{parent.name} {parent.version} depends on " else: msg = msg + "The user requested " msg = msg + req.format_for_error() for key in relevant_constraints: spec = constraints[key].specifier msg += f"\n The user requested (constraint) {key}{spec}" msg = ( msg + "\n\n" + "To fix this you could try to:\n" + "1. loosen the range of package versions you've specified\n" + "2. remove package versions to allow pip attempt to solve " + "the dependency conflict\n" ) logger.info(msg) return DistributionNotFound( "ResolutionImpossible: for help visit " "https://pip.pypa.io/en/latest/user_guide/" "#fixing-conflicting-dependencies" ) PKH]U##Hpython3.10/site-packages/pip/_internal/resolution/resolvelib/provider.pynu[import collections import math from typing import TYPE_CHECKING, Dict, Iterable, Iterator, Mapping, Sequence, Union from pip._vendor.resolvelib.providers import AbstractProvider from .base import Candidate, Constraint, Requirement from .candidates import REQUIRES_PYTHON_IDENTIFIER from .factory import Factory if TYPE_CHECKING: from pip._vendor.resolvelib.providers import Preference from pip._vendor.resolvelib.resolvers import RequirementInformation PreferenceInformation = RequirementInformation[Requirement, Candidate] _ProviderBase = AbstractProvider[Requirement, Candidate, str] else: _ProviderBase = AbstractProvider # Notes on the relationship between the provider, the factory, and the # candidate and requirement classes. # # The provider is a direct implementation of the resolvelib class. Its role # is to deliver the API that resolvelib expects. # # Rather than work with completely abstract "requirement" and "candidate" # concepts as resolvelib does, pip has concrete classes implementing these two # ideas. The API of Requirement and Candidate objects are defined in the base # classes, but essentially map fairly directly to the equivalent provider # methods. In particular, `find_matches` and `is_satisfied_by` are # requirement methods, and `get_dependencies` is a candidate method. # # The factory is the interface to pip's internal mechanisms. It is stateless, # and is created by the resolver and held as a property of the provider. It is # responsible for creating Requirement and Candidate objects, and provides # services to those objects (access to pip's finder and preparer). class PipProvider(_ProviderBase): """Pip's provider implementation for resolvelib. :params constraints: A mapping of constraints specified by the user. Keys are canonicalized project names. :params ignore_dependencies: Whether the user specified ``--no-deps``. :params upgrade_strategy: The user-specified upgrade strategy. :params user_requested: A set of canonicalized package names that the user supplied for pip to install/upgrade. """ def __init__( self, factory: Factory, constraints: Dict[str, Constraint], ignore_dependencies: bool, upgrade_strategy: str, user_requested: Dict[str, int], ) -> None: self._factory = factory self._constraints = constraints self._ignore_dependencies = ignore_dependencies self._upgrade_strategy = upgrade_strategy self._user_requested = user_requested self._known_depths: Dict[str, float] = collections.defaultdict(lambda: math.inf) def identify(self, requirement_or_candidate: Union[Requirement, Candidate]) -> str: return requirement_or_candidate.name def get_preference( # type: ignore self, identifier: str, resolutions: Mapping[str, Candidate], candidates: Mapping[str, Iterator[Candidate]], information: Mapping[str, Iterable["PreferenceInformation"]], backtrack_causes: Sequence["PreferenceInformation"], ) -> "Preference": """Produce a sort key for given requirement based on preference. The lower the return value is, the more preferred this group of arguments is. Currently pip considers the followings in order: * Prefer if any of the known requirements is "direct", e.g. points to an explicit URL. * If equal, prefer if any requirement is "pinned", i.e. contains operator ``===`` or ``==``. * If equal, calculate an approximate "depth" and resolve requirements closer to the user-specified requirements first. * Order user-specified requirements by the order they are specified. * If equal, prefers "non-free" requirements, i.e. contains at least one operator, such as ``>=`` or ``<``. * If equal, order alphabetically for consistency (helps debuggability). """ lookups = (r.get_candidate_lookup() for r, _ in information[identifier]) candidate, ireqs = zip(*lookups) operators = [ specifier.operator for specifier_set in (ireq.specifier for ireq in ireqs if ireq) for specifier in specifier_set ] direct = candidate is not None pinned = any(op[:2] == "==" for op in operators) unfree = bool(operators) try: requested_order: Union[int, float] = self._user_requested[identifier] except KeyError: requested_order = math.inf parent_depths = ( self._known_depths[parent.name] if parent is not None else 0.0 for _, parent in information[identifier] ) inferred_depth = min(d for d in parent_depths) + 1.0 else: inferred_depth = 1.0 self._known_depths[identifier] = inferred_depth requested_order = self._user_requested.get(identifier, math.inf) # Requires-Python has only one candidate and the check is basically # free, so we always do it first to avoid needless work if it fails. requires_python = identifier == REQUIRES_PYTHON_IDENTIFIER # HACK: Setuptools have a very long and solid backward compatibility # track record, and extremely few projects would request a narrow, # non-recent version range of it since that would break a lot things. # (Most projects specify it only to request for an installer feature, # which does not work, but that's another topic.) Intentionally # delaying Setuptools helps reduce branches the resolver has to check. # This serves as a temporary fix for issues like "apache-airlfow[all]" # while we work on "proper" branch pruning techniques. delay_this = identifier == "setuptools" # Prefer the causes of backtracking on the assumption that the problem # resolving the dependency tree is related to the failures that caused # the backtracking backtrack_cause = self.is_backtrack_cause(identifier, backtrack_causes) return ( not requires_python, delay_this, not direct, not pinned, not backtrack_cause, inferred_depth, requested_order, not unfree, identifier, ) def _get_constraint(self, identifier: str) -> Constraint: if identifier in self._constraints: return self._constraints[identifier] # HACK: Theoratically we should check whether this identifier is a valid # "NAME[EXTRAS]" format, and parse out the name part with packaging or # some regular expression. But since pip's resolver only spits out # three kinds of identifiers: normalized PEP 503 names, normalized names # plus extras, and Requires-Python, we can cheat a bit here. name, open_bracket, _ = identifier.partition("[") if open_bracket and name in self._constraints: return self._constraints[name] return Constraint.empty() def find_matches( self, identifier: str, requirements: Mapping[str, Iterator[Requirement]], incompatibilities: Mapping[str, Iterator[Candidate]], ) -> Iterable[Candidate]: def _eligible_for_upgrade(name: str) -> bool: """Are upgrades allowed for this project? This checks the upgrade strategy, and whether the project was one that the user specified in the command line, in order to decide whether we should upgrade if there's a newer version available. (Note that we don't need access to the `--upgrade` flag, because an upgrade strategy of "to-satisfy-only" means that `--upgrade` was not specified). """ if self._upgrade_strategy == "eager": return True elif self._upgrade_strategy == "only-if-needed": return name in self._user_requested return False return self._factory.find_candidates( identifier=identifier, requirements=requirements, constraint=self._get_constraint(identifier), prefers_installed=(not _eligible_for_upgrade(identifier)), incompatibilities=incompatibilities, ) def is_satisfied_by(self, requirement: Requirement, candidate: Candidate) -> bool: return requirement.is_satisfied_by(candidate) def get_dependencies(self, candidate: Candidate) -> Sequence[Requirement]: with_requires = not self._ignore_dependencies return [r for r in candidate.iter_dependencies(with_requires) if r is not None] @staticmethod def is_backtrack_cause( identifier: str, backtrack_causes: Sequence["PreferenceInformation"] ) -> bool: for backtrack_cause in backtrack_causes: if identifier == backtrack_cause.requirement.name: return True if backtrack_cause.parent and identifier == backtrack_cause.parent.name: return True return False PKH])ZIIPpython3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.pynu["""Utilities to lazily create and visit candidates found. Creating and visiting a candidate is a *very* costly operation. It involves fetching, extracting, potentially building modules from source, and verifying distribution metadata. It is therefore crucial for performance to keep everything here lazy all the way down, so we only touch candidates that we absolutely need, and not "download the world" when we only need one version of something. """ import functools from collections.abc import Sequence from typing import TYPE_CHECKING, Any, Callable, Iterator, Optional, Set, Tuple from pip._vendor.packaging.version import _BaseVersion from .base import Candidate IndexCandidateInfo = Tuple[_BaseVersion, Callable[[], Optional[Candidate]]] if TYPE_CHECKING: SequenceCandidate = Sequence[Candidate] else: # For compatibility: Python before 3.9 does not support using [] on the # Sequence class. # # >>> from collections.abc import Sequence # >>> Sequence[str] # Traceback (most recent call last): # File "", line 1, in # TypeError: 'ABCMeta' object is not subscriptable # # TODO: Remove this block after dropping Python 3.8 support. SequenceCandidate = Sequence def _iter_built(infos: Iterator[IndexCandidateInfo]) -> Iterator[Candidate]: """Iterator for ``FoundCandidates``. This iterator is used when the package is not already installed. Candidates from index come later in their normal ordering. """ versions_found: Set[_BaseVersion] = set() for version, func in infos: if version in versions_found: continue candidate = func() if candidate is None: continue yield candidate versions_found.add(version) def _iter_built_with_prepended( installed: Candidate, infos: Iterator[IndexCandidateInfo] ) -> Iterator[Candidate]: """Iterator for ``FoundCandidates``. This iterator is used when the resolver prefers the already-installed candidate and NOT to upgrade. The installed candidate is therefore always yielded first, and candidates from index come later in their normal ordering, except skipped when the version is already installed. """ yield installed versions_found: Set[_BaseVersion] = {installed.version} for version, func in infos: if version in versions_found: continue candidate = func() if candidate is None: continue yield candidate versions_found.add(version) def _iter_built_with_inserted( installed: Candidate, infos: Iterator[IndexCandidateInfo] ) -> Iterator[Candidate]: """Iterator for ``FoundCandidates``. This iterator is used when the resolver prefers to upgrade an already-installed package. Candidates from index are returned in their normal ordering, except replaced when the version is already installed. The implementation iterates through and yields other candidates, inserting the installed candidate exactly once before we start yielding older or equivalent candidates, or after all other candidates if they are all newer. """ versions_found: Set[_BaseVersion] = set() for version, func in infos: if version in versions_found: continue # If the installed candidate is better, yield it first. if installed.version >= version: yield installed versions_found.add(installed.version) candidate = func() if candidate is None: continue yield candidate versions_found.add(version) # If the installed candidate is older than all other candidates. if installed.version not in versions_found: yield installed class FoundCandidates(SequenceCandidate): """A lazy sequence to provide candidates to the resolver. The intended usage is to return this from `find_matches()` so the resolver can iterate through the sequence multiple times, but only access the index page when remote packages are actually needed. This improve performances when suitable candidates are already installed on disk. """ def __init__( self, get_infos: Callable[[], Iterator[IndexCandidateInfo]], installed: Optional[Candidate], prefers_installed: bool, incompatible_ids: Set[int], ): self._get_infos = get_infos self._installed = installed self._prefers_installed = prefers_installed self._incompatible_ids = incompatible_ids def __getitem__(self, index: Any) -> Any: # Implemented to satisfy the ABC check. This is not needed by the # resolver, and should not be used by the provider either (for # performance reasons). raise NotImplementedError("don't do this") def __iter__(self) -> Iterator[Candidate]: infos = self._get_infos() if not self._installed: iterator = _iter_built(infos) elif self._prefers_installed: iterator = _iter_built_with_prepended(self._installed, infos) else: iterator = _iter_built_with_inserted(self._installed, infos) return (c for c in iterator if id(c) not in self._incompatible_ids) def __len__(self) -> int: # Implemented to satisfy the ABC check. This is not needed by the # resolver, and should not be used by the provider either (for # performance reasons). raise NotImplementedError("don't do this") @functools.lru_cache(maxsize=1) def __bool__(self) -> bool: if self._prefers_installed and self._installed: return True return any(self) PKH]~p_ Hpython3.10/site-packages/pip/_internal/resolution/resolvelib/reporter.pynu[from collections import defaultdict from logging import getLogger from typing import Any, DefaultDict from pip._vendor.resolvelib.reporters import BaseReporter from .base import Candidate, Requirement logger = getLogger(__name__) class PipReporter(BaseReporter): def __init__(self) -> None: self.backtracks_by_package: DefaultDict[str, int] = defaultdict(int) self._messages_at_backtrack = { 1: ( "pip is looking at multiple versions of {package_name} to " "determine which version is compatible with other " "requirements. This could take a while." ), 8: ( "pip is looking at multiple versions of {package_name} to " "determine which version is compatible with other " "requirements. This could take a while." ), 13: ( "This is taking longer than usual. You might need to provide " "the dependency resolver with stricter constraints to reduce " "runtime. See https://pip.pypa.io/warnings/backtracking for " "guidance. If you want to abort this run, press Ctrl + C." ), } def backtracking(self, candidate: Candidate) -> None: self.backtracks_by_package[candidate.name] += 1 count = self.backtracks_by_package[candidate.name] if count not in self._messages_at_backtrack: return message = self._messages_at_backtrack[count] logger.info("INFO: %s", message.format(package_name=candidate.name)) class PipDebuggingReporter(BaseReporter): """A reporter that does an info log for every event it sees.""" def starting(self) -> None: logger.info("Reporter.starting()") def starting_round(self, index: int) -> None: logger.info("Reporter.starting_round(%r)", index) def ending_round(self, index: int, state: Any) -> None: logger.info("Reporter.ending_round(%r, state)", index) def ending(self, state: Any) -> None: logger.info("Reporter.ending(%r)", state) def adding_requirement(self, requirement: Requirement, parent: Candidate) -> None: logger.info("Reporter.adding_requirement(%r, %r)", requirement, parent) def backtracking(self, candidate: Candidate) -> None: logger.info("Reporter.backtracking(%r)", candidate) def pinning(self, candidate: Candidate) -> None: logger.info("Reporter.pinning(%r)", candidate) PKH]\OOLpython3.10/site-packages/pip/_internal/resolution/resolvelib/requirements.pynu[from pip._vendor.packaging.specifiers import SpecifierSet from pip._vendor.packaging.utils import NormalizedName, canonicalize_name from pip._internal.req.req_install import InstallRequirement from .base import Candidate, CandidateLookup, Requirement, format_name class ExplicitRequirement(Requirement): def __init__(self, candidate: Candidate) -> None: self.candidate = candidate def __str__(self) -> str: return str(self.candidate) def __repr__(self) -> str: return "{class_name}({candidate!r})".format( class_name=self.__class__.__name__, candidate=self.candidate, ) @property def project_name(self) -> NormalizedName: # No need to canonicalise - the candidate did this return self.candidate.project_name @property def name(self) -> str: # No need to canonicalise - the candidate did this return self.candidate.name def format_for_error(self) -> str: return self.candidate.format_for_error() def get_candidate_lookup(self) -> CandidateLookup: return self.candidate, None def is_satisfied_by(self, candidate: Candidate) -> bool: return candidate == self.candidate class SpecifierRequirement(Requirement): def __init__(self, ireq: InstallRequirement) -> None: assert ireq.link is None, "This is a link, not a specifier" self._ireq = ireq self._extras = frozenset(ireq.extras) def __str__(self) -> str: return str(self._ireq.req) def __repr__(self) -> str: return "{class_name}({requirement!r})".format( class_name=self.__class__.__name__, requirement=str(self._ireq.req), ) @property def project_name(self) -> NormalizedName: assert self._ireq.req, "Specifier-backed ireq is always PEP 508" return canonicalize_name(self._ireq.req.name) @property def name(self) -> str: return format_name(self.project_name, self._extras) def format_for_error(self) -> str: # Convert comma-separated specifiers into "A, B, ..., F and G" # This makes the specifier a bit more "human readable", without # risking a change in meaning. (Hopefully! Not all edge cases have # been checked) parts = [s.strip() for s in str(self).split(",")] if len(parts) == 0: return "" elif len(parts) == 1: return parts[0] return ", ".join(parts[:-1]) + " and " + parts[-1] def get_candidate_lookup(self) -> CandidateLookup: return None, self._ireq def is_satisfied_by(self, candidate: Candidate) -> bool: assert candidate.name == self.name, ( f"Internal issue: Candidate is not for this requirement " f"{candidate.name} vs {self.name}" ) # We can safely always allow prereleases here since PackageFinder # already implements the prerelease logic, and would have filtered out # prerelease candidates if the user does not expect them. assert self._ireq.req, "Specifier-backed ireq is always PEP 508" spec = self._ireq.req.specifier return spec.contains(candidate.version, prereleases=True) class RequiresPythonRequirement(Requirement): """A requirement representing Requires-Python metadata.""" def __init__(self, specifier: SpecifierSet, match: Candidate) -> None: self.specifier = specifier self._candidate = match def __str__(self) -> str: return f"Python {self.specifier}" def __repr__(self) -> str: return "{class_name}({specifier!r})".format( class_name=self.__class__.__name__, specifier=str(self.specifier), ) @property def project_name(self) -> NormalizedName: return self._candidate.project_name @property def name(self) -> str: return self._candidate.name def format_for_error(self) -> str: return str(self) def get_candidate_lookup(self) -> CandidateLookup: if self.specifier.contains(self._candidate.version, prereleases=True): return self._candidate, None return None, None def is_satisfied_by(self, candidate: Candidate) -> bool: assert candidate.name == self._candidate.name, "Not Python candidate" # We can safely always allow prereleases here since PackageFinder # already implements the prerelease logic, and would have filtered out # prerelease candidates if the user does not expect them. return self.specifier.contains(candidate.version, prereleases=True) class UnsatisfiableRequirement(Requirement): """A requirement that cannot be satisfied.""" def __init__(self, name: NormalizedName) -> None: self._name = name def __str__(self) -> str: return f"{self._name} (unavailable)" def __repr__(self) -> str: return "{class_name}({name!r})".format( class_name=self.__class__.__name__, name=str(self._name), ) @property def project_name(self) -> NormalizedName: return self._name @property def name(self) -> str: return self._name def format_for_error(self) -> str: return str(self) def get_candidate_lookup(self) -> CandidateLookup: return None, None def is_satisfied_by(self, candidate: Candidate) -> bool: return False PKH]"ddDpython3.10/site-packages/pip/_internal/resolution/resolvelib/base.pynu[from typing import FrozenSet, Iterable, Optional, Tuple, Union from pip._vendor.packaging.specifiers import SpecifierSet from pip._vendor.packaging.utils import NormalizedName, canonicalize_name from pip._vendor.packaging.version import LegacyVersion, Version from pip._internal.models.link import Link, links_equivalent from pip._internal.req.req_install import InstallRequirement from pip._internal.utils.hashes import Hashes CandidateLookup = Tuple[Optional["Candidate"], Optional[InstallRequirement]] CandidateVersion = Union[LegacyVersion, Version] def format_name(project: str, extras: FrozenSet[str]) -> str: if not extras: return project canonical_extras = sorted(canonicalize_name(e) for e in extras) return "{}[{}]".format(project, ",".join(canonical_extras)) class Constraint: def __init__( self, specifier: SpecifierSet, hashes: Hashes, links: FrozenSet[Link] ) -> None: self.specifier = specifier self.hashes = hashes self.links = links @classmethod def empty(cls) -> "Constraint": return Constraint(SpecifierSet(), Hashes(), frozenset()) @classmethod def from_ireq(cls, ireq: InstallRequirement) -> "Constraint": links = frozenset([ireq.link]) if ireq.link else frozenset() return Constraint(ireq.specifier, ireq.hashes(trust_internet=False), links) def __bool__(self) -> bool: return bool(self.specifier) or bool(self.hashes) or bool(self.links) def __and__(self, other: InstallRequirement) -> "Constraint": if not isinstance(other, InstallRequirement): return NotImplemented specifier = self.specifier & other.specifier hashes = self.hashes & other.hashes(trust_internet=False) links = self.links if other.link: links = links.union([other.link]) return Constraint(specifier, hashes, links) def is_satisfied_by(self, candidate: "Candidate") -> bool: # Reject if there are any mismatched URL constraints on this package. if self.links and not all(_match_link(link, candidate) for link in self.links): return False # We can safely always allow prereleases here since PackageFinder # already implements the prerelease logic, and would have filtered out # prerelease candidates if the user does not expect them. return self.specifier.contains(candidate.version, prereleases=True) class Requirement: @property def project_name(self) -> NormalizedName: """The "project name" of a requirement. This is different from ``name`` if this requirement contains extras, in which case ``name`` would contain the ``[...]`` part, while this refers to the name of the project. """ raise NotImplementedError("Subclass should override") @property def name(self) -> str: """The name identifying this requirement in the resolver. This is different from ``project_name`` if this requirement contains extras, where ``project_name`` would not contain the ``[...]`` part. """ raise NotImplementedError("Subclass should override") def is_satisfied_by(self, candidate: "Candidate") -> bool: return False def get_candidate_lookup(self) -> CandidateLookup: raise NotImplementedError("Subclass should override") def format_for_error(self) -> str: raise NotImplementedError("Subclass should override") def _match_link(link: Link, candidate: "Candidate") -> bool: if candidate.source_link: return links_equivalent(link, candidate.source_link) return False class Candidate: @property def project_name(self) -> NormalizedName: """The "project name" of the candidate. This is different from ``name`` if this candidate contains extras, in which case ``name`` would contain the ``[...]`` part, while this refers to the name of the project. """ raise NotImplementedError("Override in subclass") @property def name(self) -> str: """The name identifying this candidate in the resolver. This is different from ``project_name`` if this candidate contains extras, where ``project_name`` would not contain the ``[...]`` part. """ raise NotImplementedError("Override in subclass") @property def version(self) -> CandidateVersion: raise NotImplementedError("Override in subclass") @property def is_installed(self) -> bool: raise NotImplementedError("Override in subclass") @property def is_editable(self) -> bool: raise NotImplementedError("Override in subclass") @property def source_link(self) -> Optional[Link]: raise NotImplementedError("Override in subclass") def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]: raise NotImplementedError("Override in subclass") def get_install_requirement(self) -> Optional[InstallRequirement]: raise NotImplementedError("Override in subclass") def format_for_error(self) -> str: raise NotImplementedError("Subclass should override") PKH]Wcl%l%Hpython3.10/site-packages/pip/_internal/resolution/resolvelib/resolver.pynu[import functools import logging import os from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, cast from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.resolvelib import BaseReporter, ResolutionImpossible from pip._vendor.resolvelib import Resolver as RLResolver from pip._vendor.resolvelib.structs import DirectedGraph from pip._internal.cache import WheelCache from pip._internal.index.package_finder import PackageFinder from pip._internal.operations.prepare import RequirementPreparer from pip._internal.req.req_install import InstallRequirement from pip._internal.req.req_set import RequirementSet from pip._internal.resolution.base import BaseResolver, InstallRequirementProvider from pip._internal.resolution.resolvelib.provider import PipProvider from pip._internal.resolution.resolvelib.reporter import ( PipDebuggingReporter, PipReporter, ) from .base import Candidate, Requirement from .factory import Factory if TYPE_CHECKING: from pip._vendor.resolvelib.resolvers import Result as RLResult Result = RLResult[Requirement, Candidate, str] logger = logging.getLogger(__name__) class Resolver(BaseResolver): _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} def __init__( self, preparer: RequirementPreparer, finder: PackageFinder, wheel_cache: Optional[WheelCache], make_install_req: InstallRequirementProvider, use_user_site: bool, ignore_dependencies: bool, ignore_installed: bool, ignore_requires_python: bool, force_reinstall: bool, upgrade_strategy: str, py_version_info: Optional[Tuple[int, ...]] = None, ): super().__init__() assert upgrade_strategy in self._allowed_strategies self.factory = Factory( finder=finder, preparer=preparer, make_install_req=make_install_req, wheel_cache=wheel_cache, use_user_site=use_user_site, force_reinstall=force_reinstall, ignore_installed=ignore_installed, ignore_requires_python=ignore_requires_python, py_version_info=py_version_info, ) self.ignore_dependencies = ignore_dependencies self.upgrade_strategy = upgrade_strategy self._result: Optional[Result] = None def resolve( self, root_reqs: List[InstallRequirement], check_supported_wheels: bool ) -> RequirementSet: collected = self.factory.collect_root_requirements(root_reqs) provider = PipProvider( factory=self.factory, constraints=collected.constraints, ignore_dependencies=self.ignore_dependencies, upgrade_strategy=self.upgrade_strategy, user_requested=collected.user_requested, ) if "PIP_RESOLVER_DEBUG" in os.environ: reporter: BaseReporter = PipDebuggingReporter() else: reporter = PipReporter() resolver: RLResolver[Requirement, Candidate, str] = RLResolver( provider, reporter, ) try: try_to_avoid_resolution_too_deep = 2000000 result = self._result = resolver.resolve( collected.requirements, max_rounds=try_to_avoid_resolution_too_deep ) except ResolutionImpossible as e: error = self.factory.get_installation_error( cast("ResolutionImpossible[Requirement, Candidate]", e), collected.constraints, ) raise error from e req_set = RequirementSet(check_supported_wheels=check_supported_wheels) for candidate in result.mapping.values(): ireq = candidate.get_install_requirement() if ireq is None: continue # Check if there is already an installation under the same name, # and set a flag for later stages to uninstall it, if needed. installed_dist = self.factory.get_dist_to_uninstall(candidate) if installed_dist is None: # There is no existing installation -- nothing to uninstall. ireq.should_reinstall = False elif self.factory.force_reinstall: # The --force-reinstall flag is set -- reinstall. ireq.should_reinstall = True elif installed_dist.version != candidate.version: # The installation is different in version -- reinstall. ireq.should_reinstall = True elif candidate.is_editable or installed_dist.editable: # The incoming distribution is editable, or different in # editable-ness to installation -- reinstall. ireq.should_reinstall = True elif candidate.source_link and candidate.source_link.is_file: # The incoming distribution is under file:// if candidate.source_link.is_wheel: # is a local wheel -- do nothing. logger.info( "%s is already installed with the same version as the " "provided wheel. Use --force-reinstall to force an " "installation of the wheel.", ireq.name, ) continue # is a local sdist or path -- reinstall ireq.should_reinstall = True else: continue link = candidate.source_link if link and link.is_yanked: # The reason can contain non-ASCII characters, Unicode # is required for Python 2. msg = ( "The candidate selected for download or install is a " "yanked version: {name!r} candidate (version {version} " "at {link})\nReason for being yanked: {reason}" ).format( name=candidate.name, version=candidate.version, link=link, reason=link.yanked_reason or "", ) logger.warning(msg) req_set.add_named_requirement(ireq) reqs = req_set.all_requirements self.factory.preparer.prepare_linked_requirements_more(reqs) return req_set def get_installation_order( self, req_set: RequirementSet ) -> List[InstallRequirement]: """Get order for installation of requirements in RequirementSet. The returned list contains a requirement before another that depends on it. This helps ensure that the environment is kept consistent as they get installed one-by-one. The current implementation creates a topological ordering of the dependency graph, while breaking any cycles in the graph at arbitrary points. We make no guarantees about where the cycle would be broken, other than they would be broken. """ assert self._result is not None, "must call resolve() first" graph = self._result.graph weights = get_topological_weights( graph, expected_node_count=len(self._result.mapping) + 1, ) sorted_items = sorted( req_set.requirements.items(), key=functools.partial(_req_set_item_sorter, weights=weights), reverse=True, ) return [ireq for _, ireq in sorted_items] def get_topological_weights( graph: "DirectedGraph[Optional[str]]", expected_node_count: int ) -> Dict[Optional[str], int]: """Assign weights to each node based on how "deep" they are. This implementation may change at any point in the future without prior notice. We take the length for the longest path to any node from root, ignoring any paths that contain a single node twice (i.e. cycles). This is done through a depth-first search through the graph, while keeping track of the path to the node. Cycles in the graph result would result in node being revisited while also being it's own path. In this case, take no action. This helps ensure we don't get stuck in a cycle. When assigning weight, the longer path (i.e. larger length) is preferred. """ path: Set[Optional[str]] = set() weights: Dict[Optional[str], int] = {} def visit(node: Optional[str]) -> None: if node in path: # We hit a cycle, so we'll break it here. return # Time to visit the children! path.add(node) for child in graph.iter_children(node): visit(child) path.remove(node) last_known_parent_count = weights.get(node, 0) weights[node] = max(last_known_parent_count, len(path)) # `None` is guaranteed to be the root node by resolvelib. visit(None) # Sanity checks assert weights[None] == 0 assert len(weights) == expected_node_count return weights def _req_set_item_sorter( item: Tuple[str, InstallRequirement], weights: Dict[Optional[str], int], ) -> Tuple[int, str]: """Key function used to sort install requirements for installation. Based on the "weight" mapping calculated in ``get_installation_order()``. The canonical package name is returned as the second member as a tie- breaker to ensure the result is predictable, which is useful in tests. """ name = canonicalize_name(item[0]) return weights[name], name PKH]Hpython3.10/site-packages/pip/_internal/resolution/resolvelib/__init__.pynu[PKH].]python3.10/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-310.pycnu[o ai@sdS)Nrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/resolution/legacy/__init__.pysPKH]aJޅ00]python3.10/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-310.pycnu[o aiH @sdZddlZddlZddlmZddlmZddlmZm Z m Z m Z m Z m Z ddlmZddlmZddlmZdd lmZmZmZmZmZmZdd lmZdd lmZdd lm Z dd l!m"Z"ddl#m$Z$m%Z%ddl&m'Z'ddl(m)Z)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0m1Z1ddl/m2Z2ddl3m4Z4e5e6Z7ee8e e$fZ9 ddede e:e:e:fde;ddfddZeageronly-if-neededto-satisfy-onlyNpreparerfinder wheel_cachemake_install_req use_user_siteignore_dependenciesignore_installedr$force_reinstallupgrade_strategypy_version_info.r%c st| |jvs J| durtjdd} nt| } | |_||_||_||_ | |_ | |_ ||_ ||_ ||_||_||_tt|_dS)N)super__init___allowed_strategiessysr#r_py_version_infor=r>r?rErDrBrCr$rA_make_install_reqrlist_discovered_dependencies) selfr=r>r?r@rArBrCr$rDrErF __class__r6r7rIus" zResolver.__init__ root_reqscheck_supported_wheelsc Cst|d}|D]}|jrt|||qg}t}t|j|D]'}z ||||Wq!t yH}z||_ | |WYd}~q!d}~ww|rM||S)aResolve what operations need to be done As a side-effect of this method, the packages (and their dependencies) are downloaded, unpacked and prepared for installation. This preparation is done by ``pip.operations.prepare``. Once PyPI has static dependency metadata available, it would be possible to move the preparation to become a step separated from dependency resolution. )rTN) r constraintradd_requirementrrall_requirementsextend _resolve_onerreqappend)rPrSrTrequirement_setrZZdiscovered_reqsZ hash_errorsr4r6r6r7resolves$  zResolver.resolverZcCs6|jdkrdS|jdkrdS|jdksJ|jp|jS)Nr<Fr:Tr;)rE user_suppliedrUrPrZr6r6r7_is_upgrade_alloweds   zResolver._is_upgrade_allowedcCs*|jrt|jrt|jrd|_d|_dS)z4 Set a requirement to be installed. TN)rAr satisfied_byr should_reinstallr_r6r6r7_set_req_to_reinstalls zResolver._set_req_to_reinstallreq_to_installcCs|jrdS||j|jsdS|jr||dS||s(|jdkr&dSdS|jsHz |j j |ddWnt y?YdSt yGYnw||dS)aCheck if req_to_install should be skipped. This will check if the req is installed, and whether we should upgrade or reinstall it, taking into account all the relevant user options. After calling this req_to_install will only have satisfied_by set to None if the req_to_install is to be upgraded/reinstalled etc. Any other value will be a dist recording the current thing installed that satisfies the requirement. Note that for vcs urls and the like we can't assess skipping in this routine - we simply identify that we need to pull the thing down, then later on it is pulled down and introspected to assess upgrade/ reinstalls etc. :return: A text reason for why it was skipped, or None. Nr;z#already satisfied, skipping upgradezalready satisfiedT)upgradezalready up-to-date) rCcheck_if_existsrArarDrcr`rElinkr>find_requirementr r)rPrdr6r6r7_check_skip_installeds,       zResolver._check_skip_installedcCsR||}|j||}|sdS|j}|jr'|jpd}dj||d}t||S)Nz zqThe candidate selected for download or install is a yanked version: {candidate} Reason for being yanked: {reason}) candidatereason) r`r>rhrg is_yanked yanked_reasonr1r+r,)rPrZrebest_candidatergrkmsgr6r6r7_find_requirement_link s   zResolver._find_requirement_linkcCs|jdur |||_|jdus|jjrdS|jj|j|jtd}|dur?t d|j|j|j ur9|j r9d|_ |j|_dSdS)afEnsure that if a link can be found for this, that it is found. Note that req.link may still be None - if the requirement is already installed and not needed to be upgraded based on the return value of _is_upgrade_allowed(). If preparer.require_hashes is True, don't use the wheel cache, because cached wheels, always built locally, have different hashes than the files downloaded from the index server and thus throw false hash mismatches. Furthermore, cached wheels at present have undeterministic contents due to file modification times. N)rg package_namesupported_tagszUsing cached wheel link: %sT) rgrpr?r=require_hashesget_cache_entrynamerr+r0 original_link persistentoriginal_link_is_in_wheel_cache)rPrZ cache_entryr6r6r7_populate_link!s  zResolver._populate_linkcCs|jr |j|S|jdusJ||}|jr|j||S|||j|}|js3| |j |jrV|j dkpF|j pF|jpF|j jdk}|rP|||Std||S)zzTakes a InstallRequirement and returns a single AbstractDist representing a prepared variant of the same. Nr<filezs4        zResolver._get_dist_forr\c sHjsjrgSd_}t|jjdgdtdttddffdd }t j j sCj s.add_req)rz!Installing extra requirements: %r,z%%s %s does not provide the extra '%s')r)rUpreparedrr8rLr$r rr'rhas_requirementrur^rVrBextrasr+r0r.sortedsetiter_provided_extrasr,r-r5iter_dependencies) rPr\rdr"rZmissing_requestedmissingZavailable_requestedrr6rr7rYlsX  $    ! !!zResolver._resolve_onereq_setcsBgtdtddffdd |jD]}|qS)zCreate the installation order. The installation order is topological - requirements are installed before the requiring thing. We break cycles at an arbitrary point, and make no other guarantees. rZr%NcsN|js|vr dS|jrdS|j|jD]}|q|dSN)rarUaddrOrur[)rZdeporderZ ordered_reqsschedulerPr6r7rs  z1Resolver.get_installation_order..schedule)rr requirementsvalues)rPr install_reqr6rr7get_installation_orders   zResolver.get_installation_orderr)__name__ __module__ __qualname____doc__rJrrrr rboolr'r intrIrrrr]r`rcrirrprzrrrYr __classcell__r6r6rQr7r9nst     & %   6. Or9)F)>rloggingrK collectionsr itertoolsrtypingrrrrrr Zpip._vendor.packagingr Z"pip._vendor.packaging.requirementsr pip._internal.cacher pip._internal.exceptionsr rrrrr"pip._internal.index.package_finderrpip._internal.metadatarpip._internal.models.linkr pip._internal.operations.preparerpip._internal.req.req_installrrZpip._internal.req.req_setrpip._internal.resolution.baserr&pip._internal.utils.compatibility_tagsrpip._internal.utils.loggingrpip._internal.utils.miscrrr pip._internal.utils.packagingr! getLoggerrr+r'ZDiscoveredDependenciesrrr8r9r6r6r6r7sF                   7PKH]!4_HHDpython3.10/site-packages/pip/_internal/resolution/legacy/resolver.pynu["""Dependency Resolution The dependency resolution in pip is performed as follows: for top-level requirements: a. only one spec allowed per project, regardless of conflicts or not. otherwise a "double requirement" exception is raised b. they override sub-dependency requirements. for sub-dependencies a. "first found, wins" (where the order is breadth first) """ # The following comment should be removed at some point in the future. # mypy: strict-optional=False import logging import sys from collections import defaultdict from itertools import chain from typing import DefaultDict, Iterable, List, Optional, Set, Tuple from pip._vendor.packaging import specifiers from pip._vendor.packaging.requirements import Requirement from pip._internal.cache import WheelCache from pip._internal.exceptions import ( BestVersionAlreadyInstalled, DistributionNotFound, HashError, HashErrors, NoneMetadataError, UnsupportedPythonVersion, ) from pip._internal.index.package_finder import PackageFinder from pip._internal.metadata import BaseDistribution from pip._internal.models.link import Link from pip._internal.operations.prepare import RequirementPreparer from pip._internal.req.req_install import ( InstallRequirement, check_invalid_constraint_type, ) from pip._internal.req.req_set import RequirementSet from pip._internal.resolution.base import BaseResolver, InstallRequirementProvider from pip._internal.utils.compatibility_tags import get_supported from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import dist_in_usersite, normalize_version_info from pip._internal.utils.misc import dist_in_install_path from pip._internal.utils.packaging import check_requires_python logger = logging.getLogger(__name__) DiscoveredDependencies = DefaultDict[str, List[InstallRequirement]] def _check_dist_requires_python( dist: BaseDistribution, version_info: Tuple[int, int, int], ignore_requires_python: bool = False, ) -> None: """ Check whether the given Python version is compatible with a distribution's "Requires-Python" value. :param version_info: A 3-tuple of ints representing the Python major-minor-micro version to check. :param ignore_requires_python: Whether to ignore the "Requires-Python" value if the given Python version isn't compatible. :raises UnsupportedPythonVersion: When the given Python version isn't compatible. """ # This idiosyncratically converts the SpecifierSet to str and let # check_requires_python then parse it again into SpecifierSet. But this # is the legacy resolver so I'm just not going to bother refactoring. try: requires_python = str(dist.requires_python) except FileNotFoundError as e: raise NoneMetadataError(dist, str(e)) try: is_compatible = check_requires_python( requires_python, version_info=version_info, ) except specifiers.InvalidSpecifier as exc: logger.warning( "Package %r has an invalid Requires-Python: %s", dist.raw_name, exc ) return if is_compatible: return version = ".".join(map(str, version_info)) if ignore_requires_python: logger.debug( "Ignoring failed Requires-Python check for package %r: %s not in %r", dist.raw_name, version, requires_python, ) return raise UnsupportedPythonVersion( "Package {!r} requires a different Python: {} not in {!r}".format( dist.raw_name, version, requires_python ) ) class Resolver(BaseResolver): """Resolves which packages need to be installed/uninstalled to perform \ the requested operation without breaking the requirements of any package. """ _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} def __init__( self, preparer: RequirementPreparer, finder: PackageFinder, wheel_cache: Optional[WheelCache], make_install_req: InstallRequirementProvider, use_user_site: bool, ignore_dependencies: bool, ignore_installed: bool, ignore_requires_python: bool, force_reinstall: bool, upgrade_strategy: str, py_version_info: Optional[Tuple[int, ...]] = None, ) -> None: super().__init__() assert upgrade_strategy in self._allowed_strategies if py_version_info is None: py_version_info = sys.version_info[:3] else: py_version_info = normalize_version_info(py_version_info) self._py_version_info = py_version_info self.preparer = preparer self.finder = finder self.wheel_cache = wheel_cache self.upgrade_strategy = upgrade_strategy self.force_reinstall = force_reinstall self.ignore_dependencies = ignore_dependencies self.ignore_installed = ignore_installed self.ignore_requires_python = ignore_requires_python self.use_user_site = use_user_site self._make_install_req = make_install_req self._discovered_dependencies: DiscoveredDependencies = defaultdict(list) def resolve( self, root_reqs: List[InstallRequirement], check_supported_wheels: bool ) -> RequirementSet: """Resolve what operations need to be done As a side-effect of this method, the packages (and their dependencies) are downloaded, unpacked and prepared for installation. This preparation is done by ``pip.operations.prepare``. Once PyPI has static dependency metadata available, it would be possible to move the preparation to become a step separated from dependency resolution. """ requirement_set = RequirementSet(check_supported_wheels=check_supported_wheels) for req in root_reqs: if req.constraint: check_invalid_constraint_type(req) requirement_set.add_requirement(req) # Actually prepare the files, and collect any exceptions. Most hash # exceptions cannot be checked ahead of time, because # _populate_link() needs to be called before we can make decisions # based on link type. discovered_reqs: List[InstallRequirement] = [] hash_errors = HashErrors() for req in chain(requirement_set.all_requirements, discovered_reqs): try: discovered_reqs.extend(self._resolve_one(requirement_set, req)) except HashError as exc: exc.req = req hash_errors.append(exc) if hash_errors: raise hash_errors return requirement_set def _is_upgrade_allowed(self, req: InstallRequirement) -> bool: if self.upgrade_strategy == "to-satisfy-only": return False elif self.upgrade_strategy == "eager": return True else: assert self.upgrade_strategy == "only-if-needed" return req.user_supplied or req.constraint def _set_req_to_reinstall(self, req: InstallRequirement) -> None: """ Set a requirement to be installed. """ # Don't uninstall the conflict if doing a user install and the # conflict is not a user install. if ((not self.use_user_site or dist_in_usersite(req.satisfied_by)) and dist_in_install_path(req.satisfied_by)): req.should_reinstall = True req.satisfied_by = None def _check_skip_installed( self, req_to_install: InstallRequirement ) -> Optional[str]: """Check if req_to_install should be skipped. This will check if the req is installed, and whether we should upgrade or reinstall it, taking into account all the relevant user options. After calling this req_to_install will only have satisfied_by set to None if the req_to_install is to be upgraded/reinstalled etc. Any other value will be a dist recording the current thing installed that satisfies the requirement. Note that for vcs urls and the like we can't assess skipping in this routine - we simply identify that we need to pull the thing down, then later on it is pulled down and introspected to assess upgrade/ reinstalls etc. :return: A text reason for why it was skipped, or None. """ if self.ignore_installed: return None req_to_install.check_if_exists(self.use_user_site) if not req_to_install.satisfied_by: return None if self.force_reinstall: self._set_req_to_reinstall(req_to_install) return None if not self._is_upgrade_allowed(req_to_install): if self.upgrade_strategy == "only-if-needed": return "already satisfied, skipping upgrade" return "already satisfied" # Check for the possibility of an upgrade. For link-based # requirements we have to pull the tree down and inspect to assess # the version #, so it's handled way down. if not req_to_install.link: try: self.finder.find_requirement(req_to_install, upgrade=True) except BestVersionAlreadyInstalled: # Then the best version is installed. return "already up-to-date" except DistributionNotFound: # No distribution found, so we squash the error. It will # be raised later when we re-try later to do the install. # Why don't we just raise here? pass self._set_req_to_reinstall(req_to_install) return None def _find_requirement_link(self, req: InstallRequirement) -> Optional[Link]: upgrade = self._is_upgrade_allowed(req) best_candidate = self.finder.find_requirement(req, upgrade) if not best_candidate: return None # Log a warning per PEP 592 if necessary before returning. link = best_candidate.link if link.is_yanked: reason = link.yanked_reason or "" msg = ( # Mark this as a unicode string to prevent # "UnicodeEncodeError: 'ascii' codec can't encode character" # in Python 2 when the reason contains non-ascii characters. "The candidate selected for download or install is a " "yanked version: {candidate}\n" "Reason for being yanked: {reason}" ).format(candidate=best_candidate, reason=reason) logger.warning(msg) return link def _populate_link(self, req: InstallRequirement) -> None: """Ensure that if a link can be found for this, that it is found. Note that req.link may still be None - if the requirement is already installed and not needed to be upgraded based on the return value of _is_upgrade_allowed(). If preparer.require_hashes is True, don't use the wheel cache, because cached wheels, always built locally, have different hashes than the files downloaded from the index server and thus throw false hash mismatches. Furthermore, cached wheels at present have undeterministic contents due to file modification times. """ if req.link is None: req.link = self._find_requirement_link(req) if self.wheel_cache is None or self.preparer.require_hashes: return cache_entry = self.wheel_cache.get_cache_entry( link=req.link, package_name=req.name, supported_tags=get_supported(), ) if cache_entry is not None: logger.debug("Using cached wheel link: %s", cache_entry.link) if req.link is req.original_link and cache_entry.persistent: req.original_link_is_in_wheel_cache = True req.link = cache_entry.link def _get_dist_for(self, req: InstallRequirement) -> BaseDistribution: """Takes a InstallRequirement and returns a single AbstractDist \ representing a prepared variant of the same. """ if req.editable: return self.preparer.prepare_editable_requirement(req) # satisfied_by is only evaluated by calling _check_skip_installed, # so it must be None here. assert req.satisfied_by is None skip_reason = self._check_skip_installed(req) if req.satisfied_by: return self.preparer.prepare_installed_requirement(req, skip_reason) # We eagerly populate the link, since that's our "legacy" behavior. self._populate_link(req) dist = self.preparer.prepare_linked_requirement(req) # NOTE # The following portion is for determining if a certain package is # going to be re-installed/upgraded or not and reporting to the user. # This should probably get cleaned up in a future refactor. # req.req is only avail after unpack for URL # pkgs repeat check_if_exists to uninstall-on-upgrade # (#14) if not self.ignore_installed: req.check_if_exists(self.use_user_site) if req.satisfied_by: should_modify = ( self.upgrade_strategy != "to-satisfy-only" or self.force_reinstall or self.ignore_installed or req.link.scheme == "file" ) if should_modify: self._set_req_to_reinstall(req) else: logger.info( "Requirement already satisfied (use --upgrade to upgrade): %s", req, ) return dist def _resolve_one( self, requirement_set: RequirementSet, req_to_install: InstallRequirement, ) -> List[InstallRequirement]: """Prepare a single requirements file. :return: A list of additional InstallRequirements to also install. """ # Tell user what we are doing for this requirement: # obtain (editable), skipping, processing (local url), collecting # (remote url or package name) if req_to_install.constraint or req_to_install.prepared: return [] req_to_install.prepared = True # Parse and return dependencies dist = self._get_dist_for(req_to_install) # This will raise UnsupportedPythonVersion if the given Python # version isn't compatible with the distribution's Requires-Python. _check_dist_requires_python( dist, version_info=self._py_version_info, ignore_requires_python=self.ignore_requires_python, ) more_reqs: List[InstallRequirement] = [] def add_req(subreq: Requirement, extras_requested: Iterable[str]) -> None: # This idiosyncratically converts the Requirement to str and let # make_install_req then parse it again into Requirement. But this is # the legacy resolver so I'm just not going to bother refactoring. sub_install_req = self._make_install_req(str(subreq), req_to_install) parent_req_name = req_to_install.name to_scan_again, add_to_parent = requirement_set.add_requirement( sub_install_req, parent_req_name=parent_req_name, extras_requested=extras_requested, ) if parent_req_name and add_to_parent: self._discovered_dependencies[parent_req_name].append(add_to_parent) more_reqs.extend(to_scan_again) with indent_log(): # We add req_to_install before its dependencies, so that we # can refer to it when adding dependencies. if not requirement_set.has_requirement(req_to_install.name): # 'unnamed' requirements will get added here # 'unnamed' requirements can only come from being directly # provided by the user. assert req_to_install.user_supplied requirement_set.add_requirement(req_to_install, parent_req_name=None) if not self.ignore_dependencies: if req_to_install.extras: logger.debug( "Installing extra requirements: %r", ",".join(req_to_install.extras), ) missing_requested = sorted( set(req_to_install.extras) - set(dist.iter_provided_extras()) ) for missing in missing_requested: logger.warning( "%s %s does not provide the extra '%s'", dist.raw_name, dist.version, missing, ) available_requested = sorted( set(dist.iter_provided_extras()) & set(req_to_install.extras) ) for subreq in dist.iter_dependencies(available_requested): add_req(subreq, extras_requested=available_requested) return more_reqs def get_installation_order( self, req_set: RequirementSet ) -> List[InstallRequirement]: """Create the installation order. The installation order is topological - requirements are installed before the requiring thing. We break cycles at an arbitrary point, and make no other guarantees. """ # The current implementation, which we may change at any point # installs the user specified things in the order given, except when # dependencies must come earlier to achieve topological order. order = [] ordered_reqs: Set[InstallRequirement] = set() def schedule(req: InstallRequirement) -> None: if req.satisfied_by or req in ordered_reqs: return if req.constraint: return ordered_reqs.add(req) for dep in self._discovered_dependencies[req.name]: schedule(dep) order.append(req) for install_req in req_set.requirements.values(): schedule(install_req) return order PKH]Dpython3.10/site-packages/pip/_internal/resolution/legacy/__init__.pynu[PKH]˩GG9python3.10/site-packages/pip/_internal/resolution/base.pynu[from typing import Callable, List, Optional from pip._internal.req.req_install import InstallRequirement from pip._internal.req.req_set import RequirementSet InstallRequirementProvider = Callable[ [str, Optional[InstallRequirement]], InstallRequirement ] class BaseResolver: def resolve( self, root_reqs: List[InstallRequirement], check_supported_wheels: bool ) -> RequirementSet: raise NotImplementedError() def get_installation_order( self, req_set: RequirementSet ) -> List[InstallRequirement]: raise NotImplementedError() PKH]=python3.10/site-packages/pip/_internal/resolution/__init__.pynu[PKH]I~D~D9python3.10/site-packages/pip/_internal/index/collector.pynu[""" The main purpose of this module is to expose LinkCollector.collect_sources(). """ import cgi import collections import functools import itertools import logging import os import re import urllib.parse import urllib.request import xml.etree.ElementTree from optparse import Values from typing import ( Callable, Iterable, List, MutableMapping, NamedTuple, Optional, Sequence, Union, ) from pip._vendor import html5lib, requests from pip._vendor.requests import Response from pip._vendor.requests.exceptions import RetryError, SSLError from pip._internal.exceptions import NetworkConnectionError from pip._internal.models.link import Link from pip._internal.models.search_scope import SearchScope from pip._internal.network.session import PipSession from pip._internal.network.utils import raise_for_status from pip._internal.utils.filetypes import is_archive_file from pip._internal.utils.misc import pairwise, redact_auth_from_url from pip._internal.vcs import vcs from .sources import CandidatesFromPage, LinkSource, build_source logger = logging.getLogger(__name__) HTMLElement = xml.etree.ElementTree.Element ResponseHeaders = MutableMapping[str, str] def _match_vcs_scheme(url: str) -> Optional[str]: """Look for VCS schemes in the URL. Returns the matched VCS scheme, or None if there's no match. """ for scheme in vcs.schemes: if url.lower().startswith(scheme) and url[len(scheme)] in "+:": return scheme return None class _NotHTML(Exception): def __init__(self, content_type: str, request_desc: str) -> None: super().__init__(content_type, request_desc) self.content_type = content_type self.request_desc = request_desc def _ensure_html_header(response: Response) -> None: """Check the Content-Type header to ensure the response contains HTML. Raises `_NotHTML` if the content type is not text/html. """ content_type = response.headers.get("Content-Type", "") if not content_type.lower().startswith("text/html"): raise _NotHTML(content_type, response.request.method) class _NotHTTP(Exception): pass def _ensure_html_response(url: str, session: PipSession) -> None: """Send a HEAD request to the URL, and ensure the response contains HTML. Raises `_NotHTTP` if the URL is not available for a HEAD request, or `_NotHTML` if the content type is not text/html. """ scheme, netloc, path, query, fragment = urllib.parse.urlsplit(url) if scheme not in {"http", "https"}: raise _NotHTTP() resp = session.head(url, allow_redirects=True) raise_for_status(resp) _ensure_html_header(resp) def _get_html_response(url: str, session: PipSession) -> Response: """Access an HTML page with GET, and return the response. This consists of three parts: 1. If the URL looks suspiciously like an archive, send a HEAD first to check the Content-Type is HTML, to avoid downloading a large file. Raise `_NotHTTP` if the content type cannot be determined, or `_NotHTML` if it is not HTML. 2. Actually perform the request. Raise HTTP exceptions on network failures. 3. Check the Content-Type header to make sure we got HTML, and raise `_NotHTML` otherwise. """ if is_archive_file(Link(url).filename): _ensure_html_response(url, session=session) logger.debug("Getting page %s", redact_auth_from_url(url)) resp = session.get( url, headers={ "Accept": "text/html", # We don't want to blindly returned cached data for # /simple/, because authors generally expecting that # twine upload && pip install will function, but if # they've done a pip install in the last ~10 minutes # it won't. Thus by setting this to zero we will not # blindly use any cached data, however the benefit of # using max-age=0 instead of no-cache, is that we will # still support conditional requests, so we will still # minimize traffic sent in cases where the page hasn't # changed at all, we will just always incur the round # trip for the conditional GET now instead of only # once per 10 minutes. # For more information, please see pypa/pip#5670. "Cache-Control": "max-age=0", }, ) raise_for_status(resp) # The check for archives above only works if the url ends with # something that looks like an archive. However that is not a # requirement of an url. Unless we issue a HEAD request on every # url we cannot know ahead of time for sure if something is HTML # or not. However we can check after we've downloaded it. _ensure_html_header(resp) return resp def _get_encoding_from_headers(headers: ResponseHeaders) -> Optional[str]: """Determine if we have any encoding information in our headers.""" if headers and "Content-Type" in headers: content_type, params = cgi.parse_header(headers["Content-Type"]) if "charset" in params: return params["charset"] return None def _determine_base_url(document: HTMLElement, page_url: str) -> str: """Determine the HTML document's base URL. This looks for a ```` tag in the HTML document. If present, its href attribute denotes the base URL of anchor tags in the document. If there is no such tag (or if it does not have a valid href attribute), the HTML file's URL is used as the base URL. :param document: An HTML document representation. The current implementation expects the result of ``html5lib.parse()``. :param page_url: The URL of the HTML document. """ for base in document.findall(".//base"): href = base.get("href") if href is not None: return href return page_url def _clean_url_path_part(part: str) -> str: """ Clean a "part" of a URL path (i.e. after splitting on "@" characters). """ # We unquote prior to quoting to make sure nothing is double quoted. return urllib.parse.quote(urllib.parse.unquote(part)) def _clean_file_url_path(part: str) -> str: """ Clean the first part of a URL path that corresponds to a local filesystem path (i.e. the first part after splitting on "@" characters). """ # We unquote prior to quoting to make sure nothing is double quoted. # Also, on Windows the path part might contain a drive letter which # should not be quoted. On Linux where drive letters do not # exist, the colon should be quoted. We rely on urllib.request # to do the right thing here. return urllib.request.pathname2url(urllib.request.url2pathname(part)) # percent-encoded: / _reserved_chars_re = re.compile("(@|%2F)", re.IGNORECASE) def _clean_url_path(path: str, is_local_path: bool) -> str: """ Clean the path portion of a URL. """ if is_local_path: clean_func = _clean_file_url_path else: clean_func = _clean_url_path_part # Split on the reserved characters prior to cleaning so that # revision strings in VCS URLs are properly preserved. parts = _reserved_chars_re.split(path) cleaned_parts = [] for to_clean, reserved in pairwise(itertools.chain(parts, [""])): cleaned_parts.append(clean_func(to_clean)) # Normalize %xx escapes (e.g. %2f -> %2F) cleaned_parts.append(reserved.upper()) return "".join(cleaned_parts) def _clean_link(url: str) -> str: """ Make sure a link is fully quoted. For example, if ' ' occurs in the URL, it will be replaced with "%20", and without double-quoting other characters. """ # Split the URL into parts according to the general structure # `scheme://netloc/path;parameters?query#fragment`. result = urllib.parse.urlparse(url) # If the netloc is empty, then the URL refers to a local filesystem path. is_local_path = not result.netloc path = _clean_url_path(result.path, is_local_path=is_local_path) return urllib.parse.urlunparse(result._replace(path=path)) def _create_link_from_element( anchor: HTMLElement, page_url: str, base_url: str, ) -> Optional[Link]: """ Convert an anchor element in a simple repository page to a Link. """ href = anchor.get("href") if not href: return None url = _clean_link(urllib.parse.urljoin(base_url, href)) pyrequire = anchor.get("data-requires-python") yanked_reason = anchor.get("data-yanked") link = Link( url, comes_from=page_url, requires_python=pyrequire, yanked_reason=yanked_reason, ) return link class CacheablePageContent: def __init__(self, page: "HTMLPage") -> None: assert page.cache_link_parsing self.page = page def __eq__(self, other: object) -> bool: return isinstance(other, type(self)) and self.page.url == other.page.url def __hash__(self) -> int: return hash(self.page.url) def with_cached_html_pages( fn: Callable[["HTMLPage"], Iterable[Link]], ) -> Callable[["HTMLPage"], List[Link]]: """ Given a function that parses an Iterable[Link] from an HTMLPage, cache the function's result (keyed by CacheablePageContent), unless the HTMLPage `page` has `page.cache_link_parsing == False`. """ @functools.lru_cache(maxsize=None) def wrapper(cacheable_page: CacheablePageContent) -> List[Link]: return list(fn(cacheable_page.page)) @functools.wraps(fn) def wrapper_wrapper(page: "HTMLPage") -> List[Link]: if page.cache_link_parsing: return wrapper(CacheablePageContent(page)) return list(fn(page)) return wrapper_wrapper @with_cached_html_pages def parse_links(page: "HTMLPage") -> Iterable[Link]: """ Parse an HTML document, and yield its anchor elements as Link objects. """ document = html5lib.parse( page.content, transport_encoding=page.encoding, namespaceHTMLElements=False, ) url = page.url base_url = _determine_base_url(document, url) for anchor in document.findall(".//a"): link = _create_link_from_element( anchor, page_url=url, base_url=base_url, ) if link is None: continue yield link class HTMLPage: """Represents one page, along with its URL""" def __init__( self, content: bytes, encoding: Optional[str], url: str, cache_link_parsing: bool = True, ) -> None: """ :param encoding: the encoding to decode the given content. :param url: the URL from which the HTML was downloaded. :param cache_link_parsing: whether links parsed from this page's url should be cached. PyPI index urls should have this set to False, for example. """ self.content = content self.encoding = encoding self.url = url self.cache_link_parsing = cache_link_parsing def __str__(self) -> str: return redact_auth_from_url(self.url) def _handle_get_page_fail( link: Link, reason: Union[str, Exception], meth: Optional[Callable[..., None]] = None, ) -> None: if meth is None: meth = logger.debug meth("Could not fetch URL %s: %s - skipping", link, reason) def _make_html_page(response: Response, cache_link_parsing: bool = True) -> HTMLPage: encoding = _get_encoding_from_headers(response.headers) return HTMLPage( response.content, encoding=encoding, url=response.url, cache_link_parsing=cache_link_parsing, ) def _get_html_page( link: Link, session: Optional[PipSession] = None ) -> Optional["HTMLPage"]: if session is None: raise TypeError( "_get_html_page() missing 1 required keyword argument: 'session'" ) url = link.url.split("#", 1)[0] # Check for VCS schemes that do not support lookup as web pages. vcs_scheme = _match_vcs_scheme(url) if vcs_scheme: logger.warning( "Cannot look at %s URL %s because it does not support lookup as web pages.", vcs_scheme, link, ) return None # Tack index.html onto file:// URLs that point to directories scheme, _, path, _, _, _ = urllib.parse.urlparse(url) if scheme == "file" and os.path.isdir(urllib.request.url2pathname(path)): # add trailing slash if not present so urljoin doesn't trim # final segment if not url.endswith("/"): url += "/" url = urllib.parse.urljoin(url, "index.html") logger.debug(" file: URL is directory, getting %s", url) try: resp = _get_html_response(url, session=session) except _NotHTTP: logger.warning( "Skipping page %s because it looks like an archive, and cannot " "be checked by a HTTP HEAD request.", link, ) except _NotHTML as exc: logger.warning( "Skipping page %s because the %s request got Content-Type: %s." "The only supported Content-Type is text/html", link, exc.request_desc, exc.content_type, ) except NetworkConnectionError as exc: _handle_get_page_fail(link, exc) except RetryError as exc: _handle_get_page_fail(link, exc) except SSLError as exc: reason = "There was a problem confirming the ssl certificate: " reason += str(exc) _handle_get_page_fail(link, reason, meth=logger.info) except requests.ConnectionError as exc: _handle_get_page_fail(link, f"connection error: {exc}") except requests.Timeout: _handle_get_page_fail(link, "timed out") else: return _make_html_page(resp, cache_link_parsing=link.cache_link_parsing) return None class CollectedSources(NamedTuple): find_links: Sequence[Optional[LinkSource]] index_urls: Sequence[Optional[LinkSource]] class LinkCollector: """ Responsible for collecting Link objects from all configured locations, making network requests as needed. The class's main method is its collect_sources() method. """ def __init__( self, session: PipSession, search_scope: SearchScope, ) -> None: self.search_scope = search_scope self.session = session @classmethod def create( cls, session: PipSession, options: Values, suppress_no_index: bool = False, ) -> "LinkCollector": """ :param session: The Session to use to make requests. :param suppress_no_index: Whether to ignore the --no-index option when constructing the SearchScope object. """ index_urls = [options.index_url] + options.extra_index_urls if options.no_index and not suppress_no_index: logger.debug( "Ignoring indexes: %s", ",".join(redact_auth_from_url(url) for url in index_urls), ) index_urls = [] # Make sure find_links is a list before passing to create(). find_links = options.find_links or [] search_scope = SearchScope.create( find_links=find_links, index_urls=index_urls, ) link_collector = LinkCollector( session=session, search_scope=search_scope, ) return link_collector @property def find_links(self) -> List[str]: return self.search_scope.find_links def fetch_page(self, location: Link) -> Optional[HTMLPage]: """ Fetch an HTML page containing package links. """ return _get_html_page(location, session=self.session) def collect_sources( self, project_name: str, candidates_from_page: CandidatesFromPage, ) -> CollectedSources: # The OrderedDict calls deduplicate sources by URL. index_url_sources = collections.OrderedDict( build_source( loc, candidates_from_page=candidates_from_page, page_validator=self.session.is_secure_origin, expand_dir=False, cache_link_parsing=False, ) for loc in self.search_scope.get_index_urls_locations(project_name) ).values() find_links_sources = collections.OrderedDict( build_source( loc, candidates_from_page=candidates_from_page, page_validator=self.session.is_secure_origin, expand_dir=True, cache_link_parsing=True, ) for loc in self.find_links ).values() if logger.isEnabledFor(logging.DEBUG): lines = [ f"* {s.link}" for s in itertools.chain(find_links_sources, index_url_sources) if s is not None and s.link is not None ] lines = [ f"{len(lines)} location(s) to search " f"for versions of {project_name}:" ] + lines logger.debug("\n".join(lines)) return CollectedSources( find_links=list(find_links_sources), index_urls=list(index_url_sources), ) PKH]_'>'>Rpython3.10/site-packages/pip/_internal/index/__pycache__/collector.cpython-310.pycnu[o ai~D @sRdZddlZddlZddlZddlZddlZddlZddlZddlZ ddl Z ddl Z ddl mZddlmZmZmZmZmZmZmZmZddlmZmZddlmZddlmZmZddl m!Z!dd l"m#Z#dd l$m%Z%dd l&m'Z'dd l(m)Z)dd l*m+Z+ddl,m-Z-m.Z.ddl/m0Z0ddl1m2Z2m3Z3m4Z4e5e6Z7e j8j9j:Z;eeGddde?Z@deddfddZAGddde?ZBdeZQeQd?dLsr>sessioncCsFtj|\}}}}}|dvrt|j|dd}t|t|dS)zSend a HEAD request to the URL, and ensure the response contains HTML. Raises `_NotHTTP` if the URL is not available for a HEAD request, or `_NotHTML` if the content type is not text/html. >httphttpsT)allow_redirectsN)urllibparseurlsplitr>headrr=)rr?r#netlocpathqueryfragmentrespr$r$r%_ensure_html_responsePs  rLcCsRtt|jr t||dtdt||j|dddd}t|t ||S)aAccess an HTML page with GET, and return the response. This consists of three parts: 1. If the URL looks suspiciously like an archive, send a HEAD first to check the Content-Type is HTML, to avoid downloading a large file. Raise `_NotHTTP` if the content type cannot be determined, or `_NotHTML` if it is not HTML. 2. Actually perform the request. Raise HTTP exceptions on network failures. 3. Check the Content-Type header to make sure we got HTML, and raise `_NotHTML` otherwise. r?zGetting page %sr8z max-age=0)Acceptz Cache-Control)r9) rrfilenamerLloggerdebugrr:rr=)rr?rKr$r$r%_get_html_response`s rRr9cCs2|rd|vrt|d\}}d|vr|dSdS)z=Determine if we have any encoding information in our headers.r6charsetN)cgi parse_header)r9r(paramsr$r$r%_get_encoding_from_headerss rWdocumentpage_urlcCs.|dD]}|d}|dur|Sq|S)aDetermine the HTML document's base URL. This looks for a ```` tag in the HTML document. If present, its href attribute denotes the base URL of anchor tags in the document. If there is no such tag (or if it does not have a valid href attribute), the HTML file's URL is used as the base URL. :param document: An HTML document representation. The current implementation expects the result of ``html5lib.parse()``. :param page_url: The URL of the HTML document. z.//basehrefN)findallr:)rXrYbaserZr$r$r%_determine_base_urls  r]partcCtjtj|S)zP Clean a "part" of a URL path (i.e. after splitting on "@" characters). )rCrDquoteunquoter^r$r$r%_clean_url_path_partsrccCr_)z Clean the first part of a URL path that corresponds to a local filesystem path (i.e. the first part after splitting on "@" characters). )rCr; pathname2url url2pathnamerbr$r$r%_clean_file_url_paths rfz(@|%2F)rH is_local_pathcCs^|rt}nt}t|}g}tt|dgD]\}}|||||qd |S)z* Clean the path portion of a URL. r7) rfrc_reserved_chars_resplitr itertoolschainappendupperjoin)rHrg clean_funcparts cleaned_partsto_cleanreservedr$r$r%_clean_url_paths  rtcCs6tj|}|j }t|j|d}tj|j|dS)z Make sure a link is fully quoted. For example, if ' ' occurs in the URL, it will be replaced with "%20", and without double-quoting other characters. )rg)rH)rCrDurlparserGrtrH urlunparse_replace)rresultrgrHr$r$r% _clean_links ryanchorbase_urlcCsL|d}|s dSttj||}|d}|d}t||||d}|S)zJ Convert an anchor element in a simple repository page to a Link. rZNzdata-requires-pythonz data-yanked) comes_fromrequires_python yanked_reason)r:ryrCrDurljoinr)rzrYr{rZr pyrequirer~linkr$r$r%_create_link_from_elements   rc@s6eZdZd ddZdedefdd Zdefd d ZdS) CacheablePageContentpageHTMLPagerNcCs|jsJ||_dSr*)cache_link_parsingr)r-rr$r$r%r,s  zCacheablePageContent.__init__othercCst|t|o|jj|jjkSr*) isinstancetyperr)r-rr$r$r%__eq__ szCacheablePageContent.__eq__cCs t|jjSr*)hashrrr-r$r$r%__hash__s zCacheablePageContent.__hash__)rrrN) r0r1r2r,objectboolrintrr$r$r$r%rs rfnrcsPtjdddtdttffdd tdddttffd d }|S) z Given a function that parses an Iterable[Link] from an HTMLPage, cache the function's result (keyed by CacheablePageContent), unless the HTMLPage `page` has `page.cache_link_parsing == False`. N)maxsizecacheable_pagercst|jSr*)listr)r)rr$r%wrappersz'with_cached_html_pages..wrapperrrcs|jr t|St|Sr*)rrr)rrrr$r%wrapper_wrappers  z/with_cached_html_pages..wrapper_wrapper) functools lru_cacherrrwraps)rrr$rr%with_cached_html_pagess rrccsXtj|j|jdd}|j}t||}|dD]}t|||d}|dur&q|VqdS)zP Parse an HTML document, and yield its anchor elements as Link objects. F)transport_encodingnamespaceHTMLElementsz.//a)rYr{N)r rDcontentencodingrr]r[r)rrXrr{rzrr$r$r% parse_links(s$ rc @sDeZdZdZ d dedeedededdf d d Zdefd d Z dS)rz'Represents one page, along with its URLTrrrrrNcCs||_||_||_||_dS)am :param encoding: the encoding to decode the given content. :param url: the URL from which the HTML was downloaded. :param cache_link_parsing: whether links parsed from this page's url should be cached. PyPI index urls should have this set to False, for example. N)rrrr)r-rrrrr$r$r%r,Cs zHTMLPage.__init__cCs t|jSr*)rrrr$r$r%__str__Vs zHTMLPage.__str__T) r0r1r2__doc__bytesrr3rr,rr$r$r$r%r@s rreasonmeth).NcCs|durtj}|d||dS)Nz%Could not fetch URL %s: %s - skipping)rPrQ)rrrr$r$r%_handle_get_page_failZsrTrcCst|j}t|j||j|dS)N)rrr)rWr9rrr)r5rrr$r$r%_make_html_pageds rc Cs |durtd|jddd}t|}|r td||dStj|\}}}}}}|dkrPt j tj |rP|dsC|d7}tj|d}td |zt||d }Wntyhtd |YdSty}ztd ||j|jWYd}~dSd}~wty}z t||WYd}~dSd}~wty}z t||WYd}~dSd}~wty}zd } | t|7} t|| tjdWYd}~dSd}~wtjy}zt|d|WYd}~dSd}~wtjyt|dYdSwt||j dS)Nz?_get_html_page() missing 1 required keyword argument: 'session'#rrzICannot look at %s URL %s because it does not support lookup as web pages.file/z index.htmlz# file: URL is directory, getting %srMz`Skipping page %s because it looks like an archive, and cannot be checked by a HTTP HEAD request.ziSkipping page %s because the %s request got Content-Type: %s.The only supported Content-Type is text/htmlz4There was a problem confirming the ssl certificate: )rzconnection error: z timed out)r)! TypeErrorrrir&rPwarningrCrDruosrHisdirr;reendswithrrQrRr>r'r)r(rrrrr3infor ConnectionErrorTimeoutrr) rr?r vcs_schemer#_rHrKexcrr$r$r%_get_html_pagensv       rc@s.eZdZUeeeed<eeeed<dS)CollectedSources find_links index_urlsN)r0r1r2r rr__annotations__r$r$r$r%rs rc @seZdZdZdededdfddZe dded ed e ddfd d Z e de e fd dZdedeefddZde dedefddZdS) LinkCollectorz Responsible for collecting Link objects from all configured locations, making network requests as needed. The class's main method is its collect_sources() method. r? search_scoperNcCs||_||_dSr*)rr?)r-r?rr$r$r%r,s zLinkCollector.__init__Foptionssuppress_no_indexcCs`|jg|j}|jr|stdddd|Dg}|jp g}tj||d}t ||d}|S)z :param session: The Session to use to make requests. :param suppress_no_index: Whether to ignore the --no-index option when constructing the SearchScope object. zIgnoring indexes: %s,css|]}t|VqdSr*)r).0rr$r$r% sz'LinkCollector.create..rr)r?r) index_urlextra_index_urlsno_indexrPrQrnrrcreater)clsr?rrrrrlink_collectorr$r$r%rs"  zLinkCollector.createcCs|jjSr*)rrrr$r$r%rszLinkCollector.find_linkslocationcCst||jdS)z> Fetch an HTML page containing package links. rM)rr?)r-rr$r$r% fetch_pageszLinkCollector.fetch_page project_namecandidates_from_pagecstfddj|D}tfddjD}ttj rIddt ||D}t |d|dg|}t d|tt|t|d S) Nc3&|]}t|jjdddVqdS)Frpage_validator expand_dirrNrr?is_secure_originrlocrr-r$r%r z0LinkCollector.collect_sources..c3r)TrNrrrr$r%rrcSs*g|]}|dur|jdurd|jqS)Nz* )r)rsr$r$r% s  z1LinkCollector.collect_sources..z' location(s) to search for versions of : r) collections OrderedDictrget_index_urls_locationsvaluesrrP isEnabledForloggingDEBUGrjrkr"rQrnrr)r-rrindex_url_sourcesfind_links_sourceslinesr$rr%collect_sourcess2       zLinkCollector.collect_sources)F)r0r1r2rrrr, classmethodrrrpropertyrr3rrrrrrrrr$r$r$r%rs<   rr*r)YrrTrrrjrrre urllib.parserCurllib.requestxml.etree.ElementTreexmloptparsertypingrrrrrrr r pip._vendorr r Zpip._vendor.requestsr Zpip._vendor.requests.exceptionsrrpip._internal.exceptionsrpip._internal.models.linkr!pip._internal.models.search_scoperpip._internal.network.sessionrpip._internal.network.utilsrpip._internal.utils.filetypesrpip._internal.utils.miscrrpip._internal.vcsrsourcesrrr getLoggerr0rPetree ElementTreeElement HTMLElementr3ResponseHeadersr& Exceptionr'r=r>rLrRrWr]rcrfcompile IGNORECASErhrrtryrrrrrrrrrrr$r$r$r%s (             2          ?PKH]FQpython3.10/site-packages/pip/_internal/index/__pycache__/__init__.cpython-310.pycnu[o ai@sdZdS)zIndex interaction code N)__doc__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/index/__init__.pysPKH]FgPpython3.10/site-packages/pip/_internal/index/__pycache__/sources.cpython-310.pycnu[o ai@s<ddlZddlZddlZddlZddlmZmZmZmZddl m Z ddl m Z ddl mZmZddlmZeeZee Zee Zee gee fZee gefZGdddZd ed efd d ZGd ddeZGdddeZGdddeZGdddeZ dededededed eeeeeff ddZ!dS)N)CallableIterableOptionalTuple)InstallationCandidate)Link) path_to_url url_to_path)is_urlc@s>eZdZedeefddZdefddZde fddZ dS) LinkSourcereturncCt)z,Returns the underlying link, if there's one.NotImplementedErrorselfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/index/sources.pylinkszLinkSource.linkcCr )z9Candidates found by parsing an archive listing HTML file.rrrrrpage_candidateszLinkSource.page_candidatescCr )z,Links found by specifying archives directly.rrrrr file_linksrzLinkSource.file_linksN) __name__ __module__ __qualname__propertyrrrFoundCandidatesr FoundLinksrrrrrr s r file_urlr cCstj|ddddkS)NF)strictrz text/html) mimetypes guess_type)rrrr _is_html_file#sr"c@sXeZdZdZdededdfddZedee fdd Z de fd d Z de fd d ZdS)_FlatDirectorySourcezLink source specified by ``--find-links=``. This looks the content of the directory, and returns: * ``page_candidates``: Links listed on each HTML file in the directory. * ``file_candidates``: Archives in the directory. candidates_from_pagepathr NcCs||_ttj||_dSN)_candidates_from_pagepathlibPathosr%realpath_path)rr$r%rrr__init__0sz_FlatDirectorySource.__init__cCsdSr&rrrrrr8sz_FlatDirectorySource.linkccs@|jD]}tt|}t|sq|t|EdHqdSr&)r,iterdirrstrr"r'rrr%urlrrrr<s z$_FlatDirectorySource.page_candidatesccs6|jD]}tt|}t|rqt|VqdSr&)r,r.rr/r"rr0rrrrCs  z_FlatDirectorySource.file_links)rrr__doc__CandidatesFromPager/r-rrrrrrrrrrrrr#'s r#c@XeZdZdZdededdfddZedeefdd Z de fd d Z de fd d Z dS)_LocalFileSourceaC``--find-links=`` or ``--[extra-]index-url=``. If a URL is supplied, it must be a ``file:`` URL. If a path is supplied to the option, it is converted to a URL first. This returns: * ``page_candidates``: Links listed on an HTML file. * ``file_candidates``: The non-HTML file. r$rr NcC||_||_dSr&r'_linkrr$rrrrr-U z_LocalFileSource.__init__cC|jSr&r8rrrrr]rz_LocalFileSource.linkccs(t|jjs dS||jEdHdSr&)r"r8r1r'rrrrra z _LocalFileSource.page_candidatesccst|jjr dS|jVdSr&)r"r8r1rrrrrfs  z_LocalFileSource.file_linksrrrr2r3rr-rrrrrrrrrrrr5Ks  r5c@s\eZdZdZdedededdfddZede efd d Z de fd d Z de fd dZdS)_RemoteFileSourcez``--find-links=`` or ``--[extra-]index-url=``. This returns: * ``page_candidates``: Links listed on an HTML file. * ``file_candidates``: The non-HTML file. r$page_validatorrr NcCs||_||_||_dSr&)r'_page_validatorr8)rr$r@rrrrr-us z_RemoteFileSource.__init__cCr;r&r<rrrrrrz_RemoteFileSource.linkccs(||js dS||jEdHdSr&)rAr8r'rrrrrr=z!_RemoteFileSource.page_candidatesccs|jVdSr&r<rrrrrs z_RemoteFileSource.file_links)rrrr2r3 PageValidatorrr-rrrrrrrrrrrr?ls  r?c@r4)_IndexDirectorySourcez``--[extra-]index-url=``. This is treated like a remote URL; ``candidates_from_page`` contains logic for this by appending ``index.html`` to the link. r$rr NcCr6r&r7r9rrrr-r:z_IndexDirectorySource.__init__cCr;r&r<rrrrrrz_IndexDirectorySource.linkccs||jEdHdSr&r7rrrrrsz%_IndexDirectorySource.page_candidatescCsdS)Nrrrrrrrsz _IndexDirectorySource.file_linksr>rrrrrCs rClocationr$r@ expand_dircache_link_parsingc Csd}d}tj|rt|}|}n|dr|}t|}nt|r#|}|dur1d}t||dS|durDt ||t ||dd}||fStj |rd|rVt ||d}||fSt |t ||dd}||fStj|rxt|t ||dd}||fStd||dfS) Nzfile:zVLocation '%s' is ignored: it is either a non-existing path or lacks a specific scheme.)NN)rF)r$r@r)r$r%)r$rz?Location '%s' is ignored: it is neither a file nor a directory.)r*r%existsr startswithr r loggerwarningr?risdirr#rCisfiler5) rDr$r@rErFr%r1msgsourcerrr build_sourcesZ           rO)"loggingr r*r(typingrrrrpip._internal.models.candidaterpip._internal.models.linkrpip._internal.utils.urlsrr pip._internal.vcsr getLoggerrrIrrr3boolrBr r/r"r#r5r?rCrOrrrrsB    $! PKH]_ n nWpython3.10/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-310.pycnu[o ai @spdZddlZddlZddlZddlZddlmZmZmZm Z m Z m Z m Z ddl mZddlmZddlmZddlmZddlmZdd lmZmZmZmZdd lmZmZdd lm Z dd l!m"Z"dd l#m$Z$ddl%m&Z&ddl'm(Z(ddl)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0ddl1m2Z2ddl3m4Z4ddl5m6Z6ddl7m8Z8ddl9m:Z:ddl;mZ>gdZ?e0e@ZAe e de eBeCffZDe eBeBeBee eBeDfZE d9de$de eBeBeBfd eFd!eFfd"d#ZGGd$d%d%ZHd&ee d'e4d(eCd!ee fd)d*ZIGd+d,d,ZJGd-d.d.ZKGd/d0d0ZLGd1d2d2ZMd3eCd4eCd!eBfd5d6ZNd3eCd4eCd!e eCfd7d8ZOdS):z!Routines related to PyPI, indexesN) FrozenSetIterableListOptionalSetTupleUnion) specifiers)Tag)canonicalize_name) _BaseVersion)parse)BestVersionAlreadyInstalledDistributionNotFoundInvalidWheelFilenameUnsupportedWheel) LinkCollector parse_links)InstallationCandidate) FormatControl)Link) SearchScope)SelectionPreferences) TargetPython)Wheel)InstallRequirement) getLogger)WHEEL_EXTENSION)Hashes) indent_log) build_netloc)check_requires_python)SUPPORTED_EXTENSIONS) url_to_path)rBestCandidateResult PackageFinderFlink version_infoignore_requires_pythonreturncCs~z t|j|d}Wntjytd|j|YdSw|s=dtt|}|s4t d||j|dStd||j|dS)aa Return whether the given Python version is compatible with a link's "Requires-Python" value. :param version_info: A 3-tuple of ints representing the Python major-minor-micro version to check. :param ignore_requires_python: Whether to ignore the "Requires-Python" value if the given Python version isn't compatible. )r(z2Ignoring invalid Requires-Python (%r) for link: %s.z4Link requires a different Python (%s not in: %r): %sFzBIgnoring failed Requires-Python check (%s not in: %r) for link: %sT) r!requires_pythonr InvalidSpecifierloggerdebugjoinmapstrverbose)r'r(r) is_compatibleversionr&r&/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/index/package_finder.py_check_link_requires_python3s< r7c@sjeZdZdZedZ ddededeede de d e e d dfd d Z d e d ee e effddZdS) LinkEvaluatorzD Responsible for evaluating links for a particular project. z-py([123]\.?[0-9]?)$N project_namecanonical_nameformats target_python allow_yankedr)r*cCs4|durd}||_||_||_||_||_||_dS)a :param project_name: The user supplied package name. :param canonical_name: The canonical package name. :param formats: The formats allowed for this package. Should be a set with 'binary' or 'source' or both in it. :param target_python: The target Python interpreter to use when evaluating link compatibility. This is used, for example, to check wheel compatibility, as well as when checking the Python version, e.g. the Python version embedded in a link filename (or egg fragment) and against an HTML link's optional PEP 503 "data-requires-python" attribute. :param allow_yanked: Whether files marked as yanked (in the sense of PEP 592) are permitted to be candidates for install. :param ignore_requires_python: Whether to ignore incompatible PEP 503 "data-requires-python" values in HTML links. Defaults to False. NF) _allow_yanked_canonical_name_ignore_requires_python_formats_target_pythonr9)selfr9r:r;r<r=r)r&r&r6__init__ns zLinkEvaluator.__init__r'c Csd}|jr|js|jp d}dd|fS|jr|j}|j}nx|\}}|s(dS|tvr3dd|fSd|jvrF|tkrFd |j }d|fSd |j vrQ|d krQd S|tkrzt |j }Wn tyfYd Swt|j|jkryd |j }d|fS|j}||s|}d d|}d|fS|j}d|jvr|tkrd|j }d|fS|st||j}|sd|j }d|fS|j|} | r|d| }| d} | |jjkrdSt||jj|j d} | sdSt!"d||d|fS)aG Determine whether a link is a candidate for installation. :return: A tuple (is_candidate, result), where `result` is (1) a version string if `is_candidate` is True, and (2) if `is_candidate` is False, an optional string to log the reason the link fails to qualify. Nz Fzyanked for reason: )Fz not a filezunsupported archive format: binaryzNo binaries permitted for {}macosx10z.zip)Fz macosx10 one)Fzinvalid wheel filenamezwrong project name (not {})z^none of the wheel's tags ({}) are compatible (run pip debug --verbose to show compatible tags), sourcezNo sources permitted for zMissing project version for )FzPython version is incorrect)r(r))FNzFound link %s, version: %sT)# is_yankedr> yanked_reason egg_fragmentextsplitextr"rArformatr9pathrfilenamerr namer?rBget_tags supportedget_formatted_file_tagsr0r5_extract_version_from_fragment_py_version_researchstartgroup py_versionr7py_version_infor@r.r/) rCr'r5reasonegg_inforMwheelsupported_tags file_tagsmatchr[supports_pythonr&r&r6 evaluate_links|             zLinkEvaluator.evaluate_linkN)__name__ __module__ __qualname____doc__recompilerWr2rrboolrrDrrrdr&r&r&r6r8bs(   "%r8 candidateshashesr9c Cs|stdt||t|Sg}g}d}|D]}|j}|js n|j|dr+|d7}n||q||q|r<|}nt|}t|t|krKd} ndt|d dd |D} td t|||j |t||| |S) a Filter out candidates whose hashes aren't allowed, and return a new list of candidates. If at least one candidate has an allowed hash, then all candidates with either an allowed hash or no hash specified are returned. Otherwise, the given candidates are returned. Including the candidates with no hash specified when there is a match allows a warning to be logged if there is a more preferred candidate with no hash specified. Returning all candidates in the case of no matches lets pip report the hash of the candidate that would otherwise have been installed (e.g. permitting the user to more easily update their requirements file with the desired hash). zJGiven no hashes to check %s links for project %r: discarding no candidatesr)rnrIzdiscarding no candidateszdiscarding {} non-matches: {}z cs|]}t|jVqdSre)r2r').0 candidater&r&r6 $z*filter_unallowed_hashes..zPChecked %s links for project %r against %s hashes (%s matches, %s no digest): %s) r.r/lenlistr'has_hashis_hash_allowedappendrOr0 digest_count) rmrnr9matches_or_no_digest non_matches match_countrqr'filtereddiscard_messager&r&r6filter_unallowed_hashessL      rc@s,eZdZdZ  d dededdfddZdS) CandidatePreferenceszk Encapsulates some of the preferences for filtering and sorting InstallationCandidate objects. F prefer_binaryallow_all_prereleasesr*NcCs||_||_dS)zR :param allow_all_prereleases: Whether to allow all pre-releases. N)rr)rCrrr&r&r6rD<s zCandidatePreferences.__init__)FF)rfrgrhrirlrDr&r&r&r6r5src@sZeZdZdZdeedeedeeddfddZdeefd d Z deefd d Z dS) r$zA collection of candidates, returned by `PackageFinder.find_best_candidate`. This class is only intended to be instantiated by CandidateEvaluator's `compute_best_candidate()` method. rmapplicable_candidatesbest_candidater*NcCsHt|t|ks J|dur|rJn||vsJ||_||_||_dS)a :param candidates: A sequence of all available candidates found. :param applicable_candidates: The applicable candidates. :param best_candidate: The most preferred candidate found, or None if no applicable candidates were found. N)set_applicable_candidates _candidatesrrCrmrrr&r&r6rDOs    zBestCandidateResult.__init__cC t|jS)zIterate through all candidates.)iterrrCr&r&r6iter_allg zBestCandidateResult.iter_allcCr)z*Iterate through the applicable candidates.)rrrr&r&r6iter_applicablekrz#BestCandidateResult.iter_applicable) rfrgrhrirrrrDrrrr&r&r&r6r$Hs r$c@seZdZdZe     ddedeedededee j d ee d dfd d Z   dded e ede j deded ee d dfddZde ed e efddZded efddZde ed eefddZde ed efddZdS)CandidateEvaluatorzm Responsible for filtering and sorting candidates for installation based on what tags are valid. NFr9r<rr specifierrnr*cCs:|durt}|durt}|}|||||||dS)aCreate a CandidateEvaluator object. :param target_python: The target Python interpreter to use when checking compatibility. If None (the default), a TargetPython object will be constructed from the running Python. :param specifier: An optional object implementing `filter` (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable versions. :param hashes: An optional collection of allowed hashes. N)r9r`rrrrn)rr SpecifierSetrS)clsr9r<rrrrnr`r&r&r6createwszCandidateEvaluator.creater`cCs<||_||_||_||_||_||_ddt|D|_dS)z :param supported_tags: The PEP 425 tags supported by the target Python in order of preference (most preferred first). cSsi|]\}}||qSr&r&)rpidxtagr&r&r6 s z/CandidateEvaluator.__init__..N)_allow_all_prereleases_hashes_prefer_binary _project_name _specifier_supported_tags enumerate_wheel_tag_preferences)rCr9r`rrrrnr&r&r6rDs  zCandidateEvaluator.__init__rmcsd|jpd}|j}dd|jdd|D|dDfdd|D}t||j|jd }t||jd S) zM Return the applicable candidates from a list of candidates. NcSsh|]}t|qSr&)r2)rpvr&r&r6 sz?CandidateEvaluator.get_applicable_candidates..csrorer2r5rpcr&r&r6rrrsz?CandidateEvaluator.get_applicable_candidates..) prereleasescsg|] }t|jvr|qSr&rrversionsr&r6 sz@CandidateEvaluator.get_applicable_candidates..)rmrnr9key)rrfilterrrrsorted _sort_key)rCrmallow_prereleasesrrfiltered_applicable_candidatesr&rr6get_applicable_candidatess  z,CandidateEvaluator.get_applicable_candidatesrqc Cs|j}t|}d}d}|j}|jrPt|j}z |||j }Wnty/t d |jw|j r5d}|j durOt d|j } | } t| d| df}n| }t||j} dt|j} | | ||j||fS)a) Function to pass as the `key` argument to a call to sorted() to sort InstallationCandidates by preference. Returns a tuple such that tuples sorting as greater using Python's default comparison operator are more preferred. The preference is as follows: First and foremost, candidates with allowed (matching) hashes are always preferred over candidates without matching hashes. This is because e.g. if the only candidate with an allowed hash is yanked, we still want to use that candidate. Second, excepting hash considerations, candidates that have been yanked (in the sense of PEP 592) are always less preferred than candidates that haven't been yanked. Then: If not finding wheels, they are sorted by version only. If finding wheels, then the sort order is by version, then: 1. existing installs 2. wheels ordered via Wheel.support_index_min(self._supported_tags) 3. source archives If prefer_binary was set, then all wheels are sorted above sources. Note: it was considered to embed this logic into the Link comparison operators, but then different sdist links with the same version, would have to be considered equal r&rzB{} is not a supported wheel for this platform. It can't be sorted.rINz ^(\d+)(.*)$)rrtr'is_wheelrrQfind_most_preferred_tagr ValueErrorrrOr build_tagrjrbgroupsintrwrrJr5) rCrq valid_tags support_numrbinary_preferencer'r_prirbbuild_tag_groupshas_allowed_hash yank_valuer&r&r6rsF   zCandidateEvaluator._sort_keycCs|sdSt||jd}|S)zy Return the best candidate per the instance's sort order, or None if no candidate is acceptable. Nr)maxr)rCrmrr&r&r6sort_best_candidatesz&CandidateEvaluator.sort_best_candidatecCs"||}||}t|||dS)zF Compute and return a `BestCandidateResult` instance. )rr)rrr$rr&r&r6compute_best_candidate*s  z)CandidateEvaluator.compute_best_candidate)NFFNN)FFN)rfrgrhri classmethodr2rrrlr BaseSpecifierrrrr rDrrCandidateSortingKeyrrr$rr&r&r&r6rpsr (  $D  rc@sVeZdZdZ   dBdedededeedee deed dfd d Z e dCded e deed dfd dZ ed efddZed efddZejded dfddZed eefddZed eefddZed eefddZed efddZdDddZed efdd ZdDd!d"Zd#ed efd$d%Zd&eed eefd'd(Z d)ed*ed dfd+d,Z!d-ed)ed ee"fd.d/Z#d-ed&eed ee"fd0d1Z$d2ed-ed ee"fd3d4Z%e&j'dd5d#ed ee"fd6d7Z(  dEd#ed8ee)j*d9ee+d e,fd:d;Z-e&j'dd5  dEd#ed8ee)j*d9ee+d e.fde0d?ed ee"fd@dAZ1dS)Fr%zThis finds packages. This is meant to match easy_install's technique for looking for packages, by reading pages and looking for appropriate links. Nlink_collectorr<r=format_controlcandidate_prefsr)r*cCsP|durt}|pttt}||_||_||_||_||_||_t|_ dS)a This constructor is primarily meant to be used by the create() class method and from tests. :param format_control: A FormatControl object, used to control the selection of source packages / binary packages when consulting the index and links. :param candidate_prefs: Options to use when creating a CandidateEvaluator object. N) rrrr>_candidate_prefsr@_link_collectorrBr _logged_links)rCrr<r=rrr)r&r&r6rDCs zPackageFinder.__init__selection_prefscCs8|durt}t|j|jd}|||||j|j|jdS)afCreate a PackageFinder. :param selection_prefs: The candidate selection preferences, as a SelectionPreferences object. :param target_python: The target Python interpreter to use when checking compatibility. If None (the default), a TargetPython object will be constructed from the running Python. N)rr)rrr<r=rr))rrrrr=rr))rrrr<rr&r&r6rjszPackageFinder.createcCs|jSre)rBrr&r&r6r<szPackageFinder.target_pythoncC|jjSrer search_scoperr&r&r6rzPackageFinder.search_scopercCs ||j_dSrer)rCrr&r&r6rs cCrre)r find_linksrr&r&r6rrzPackageFinder.find_linkscCrre)r index_urlsrr&r&r6rrzPackageFinder.index_urlsccs |jjjD]}t|VqdSre)rsessionpip_trusted_originsr )rC host_portr&r&r6 trusted_hostss zPackageFinder.trusted_hostscCrrerrrr&r&r6rrz#PackageFinder.allow_all_prereleasescC d|j_dSNTrrr&r&r6set_allow_all_prereleases z'PackageFinder.set_allow_all_prereleasescCrrerrrr&r&r6rrzPackageFinder.prefer_binarycCrrrrr&r&r6set_prefer_binaryrzPackageFinder.set_prefer_binaryr9cCs.t|}|j|}t||||j|j|jdS)N)r9r:r;r<r=r))r rget_allowed_formatsr8rBr>r@)rCr9r:r;r&r&r6make_link_evaluators z!PackageFinder.make_link_evaluatorlinkscCsPgg}}t}|D]}||vr#|||jr||q ||q ||S)z Returns elements of links in order, non-egg links first, egg links second, while eliminating duplicates )raddrLrx)rCreggsno_eggsseenr'r&r&r6 _sort_linkss    zPackageFinder._sort_linksr'r]cCs,||jvrtd|||j|dSdS)NzSkipping link: %s: %s)rr.r/r)rCr'r]r&r&r6_log_skipped_links zPackageFinder._log_skipped_linklink_evaluatorcCs8||\}}|s|r|j||ddSt|j||dS)z If the link is a candidate for install, convert it to an InstallationCandidate and return it. Otherwise, return None. )r]N)rRr'r5)rdrrr9)rCrr' is_candidateresultr&r&r6get_install_candidatesz#PackageFinder.get_install_candidatecCs6g}||D]}|||}|dur||q|S)zU Convert links that are candidates to InstallationCandidate objects. N)rrrx)rCrrrmr'rqr&r&r6evaluate_linkss  zPackageFinder.evaluate_links project_urlcCsjtd||j|}|durgStt|}t|j||d}Wd|S1s.wY|S)Nz-Fetching project page and analyzing links: %s)r)r.r/r fetch_pagerurrr)rCrr html_page page_links package_linksr&r&r6process_project_urls"   z!PackageFinder.process_project_url)maxsizec Cs||}|jj|tj|j|dd}tjdd|D}t |}tjdd|D}| |t |dd}t tjrO|rOdd |D}t d d |||S) aFind all available InstallationCandidate for project_name This checks index_urls and find_links. All versions found are returned as an InstallationCandidate list. See LinkEvaluator.evaluate_link() for details on which files are accepted. )r)r9candidates_from_pagecs*|]}|D] }|dur|VqqdSre)page_candidatesrpsourcesrHr&r&r6rrz4PackageFinder.find_all_candidates..csrre) file_linksrr&r&r6rr'rT)reversecSsg|]}t|jjqSr&)r#r'urlrr&r&r6r3sz5PackageFinder.find_all_candidates..zLocal files found: %srG)rrcollect_sources functoolspartialr itertoolschain from_iterablerurrr. isEnabledForloggingDEBUGr/r0) rCr9rcollected_sourcespage_candidates_itr file_links_itfile_candidatespathsr&r&r6find_all_candidates s.    z!PackageFinder.find_all_candidatesrrncCs"|j}tj||j|j|j||dS)z*Create a CandidateEvaluator object to use.)r9r<rrrrn)rrrrBrr)rCr9rrnrr&r&r6make_candidate_evaluator9sz&PackageFinder.make_candidate_evaluatorcCs$||}|j|||d}||S)aFind matches for the given project and specifier. :param specifier: An optional object implementing `filter` (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable versions. :return: A `BestCandidateResult` instance. )r9rrn)rr r)rCr9rrnrmcandidate_evaluatorr&r&r6find_best_candidateJs  z!PackageFinder.find_best_candidaterequpgradec Cs|jdd}|j|j|j|d}|j}d}|jdur t|jj}dtt dt fdd}|durE|durEt d ||| td |d}|rT|dusR|j|krTd }|sn|durn|rdt d |dSt d ||jdS|r}t d|||tt d|j|||S)zTry to find a Link matching req Expects req, an InstallRequirement and upgrade, a boolean Returns a InstallationCandidate if found, Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise F)trust_internet)rrnN cand_iterr*cSs dtdd|DtdpdS)NrGcSsh|]}t|jqSr&rrr&r&r6r~szKPackageFinder.find_requirement.._format_versions..rnone)r0r parse_version)rr&r&r6_format_versionsvs z8PackageFinder.find_requirement.._format_versionszNCould not find a version that satisfies the requirement %s (from versions: %s)z%No matching distribution found for {}TzLExisting installed version (%s) is most up-to-date and satisfies requirementzUExisting installed version (%s) satisfies requirement (most up-to-date version is %s)z=Installed version (%s) is most up-to-date (past versions: %s)z)Using version %s (newest of versions: %s))rnr rRrr satisfied_byrr5rrr2r.criticalrrrOr/rr) rCr r rnbest_candidate_resultrinstalled_versionrbest_installedr&r&r6find_requirementasd        zPackageFinder.find_requirement)NNNre)r*N)NN)2rfrgrhrirrrlrrrrDrrrpropertyr<rrsetterrr2rrrrrrrrr8rrrrrrrrr lru_cacherr rrrr r$r rrr&r&r&r6r%<s  '       0  r%fragmentr:cCsJt|D]\}}|dkr qt|d||kr|Sqt|d|)aFind the separator's index based on the package's canonical name. :param fragment: A + filename "fragment" (stem) or egg fragment. :param canonical_name: The package's canonical name. This function is needed since the canonicalized name does not necessarily have the same length as the egg info's name part. An example:: >>> fragment = 'foo__bar-1.0' >>> canonical_name = 'foo-bar' >>> _find_name_version_sep(fragment, canonical_name) 8 -Nz does not match )rr r)rr:irr&r&r6_find_name_version_sepsrcCs@z t||d}Wn tyYdSw||d}|sdS|S)zParse the version string from a + filename "fragment" (stem) or egg fragment. :param fragment: The string to parse. E.g. foo-2.1 :param canonical_name: The canonicalized name of the package this belongs to. rIN)rr)rr: version_startr5r&r&r6rVs  rV)F)PrirrrrjtypingrrrrrrrZpip._vendor.packagingr Zpip._vendor.packaging.tagsr pip._vendor.packaging.utilsr Zpip._vendor.packaging.versionr r rpip._internal.exceptionsrrrrpip._internal.index.collectorrrpip._internal.models.candidater#pip._internal.models.format_controlrpip._internal.models.linkr!pip._internal.models.search_scoper$pip._internal.models.selection_prefsr"pip._internal.models.target_pythonrpip._internal.models.wheelrpip._internal.reqrZpip._internal.utils._logrpip._internal.utils.filetypesrpip._internal.utils.hashesrpip._internal.utils.loggingrpip._internal.utils.miscr pip._internal.utils.packagingr!pip._internal.utils.unpackingr"pip._internal.utils.urlsr#__all__rfr.rr2BuildTagrrlr7r8rrr$rr%rrVr&r&r&r6s~$                       /  J(M~PKH]W>python3.10/site-packages/pip/_internal/index/package_finder.pynu["""Routines related to PyPI, indexes""" # The following comment should be removed at some point in the future. # mypy: strict-optional=False import functools import itertools import logging import re from typing import FrozenSet, Iterable, List, Optional, Set, Tuple, Union from pip._vendor.packaging import specifiers from pip._vendor.packaging.tags import Tag from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.packaging.version import _BaseVersion from pip._vendor.packaging.version import parse as parse_version from pip._internal.exceptions import ( BestVersionAlreadyInstalled, DistributionNotFound, InvalidWheelFilename, UnsupportedWheel, ) from pip._internal.index.collector import LinkCollector, parse_links from pip._internal.models.candidate import InstallationCandidate from pip._internal.models.format_control import FormatControl from pip._internal.models.link import Link from pip._internal.models.search_scope import SearchScope from pip._internal.models.selection_prefs import SelectionPreferences from pip._internal.models.target_python import TargetPython from pip._internal.models.wheel import Wheel from pip._internal.req import InstallRequirement from pip._internal.utils._log import getLogger from pip._internal.utils.filetypes import WHEEL_EXTENSION from pip._internal.utils.hashes import Hashes from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import build_netloc from pip._internal.utils.packaging import check_requires_python from pip._internal.utils.unpacking import SUPPORTED_EXTENSIONS from pip._internal.utils.urls import url_to_path __all__ = ["FormatControl", "BestCandidateResult", "PackageFinder"] logger = getLogger(__name__) BuildTag = Union[Tuple[()], Tuple[int, str]] CandidateSortingKey = Tuple[int, int, int, _BaseVersion, Optional[int], BuildTag] def _check_link_requires_python( link: Link, version_info: Tuple[int, int, int], ignore_requires_python: bool = False, ) -> bool: """ Return whether the given Python version is compatible with a link's "Requires-Python" value. :param version_info: A 3-tuple of ints representing the Python major-minor-micro version to check. :param ignore_requires_python: Whether to ignore the "Requires-Python" value if the given Python version isn't compatible. """ try: is_compatible = check_requires_python( link.requires_python, version_info=version_info, ) except specifiers.InvalidSpecifier: logger.debug( "Ignoring invalid Requires-Python (%r) for link: %s", link.requires_python, link, ) else: if not is_compatible: version = ".".join(map(str, version_info)) if not ignore_requires_python: logger.verbose( "Link requires a different Python (%s not in: %r): %s", version, link.requires_python, link, ) return False logger.debug( "Ignoring failed Requires-Python check (%s not in: %r) for link: %s", version, link.requires_python, link, ) return True class LinkEvaluator: """ Responsible for evaluating links for a particular project. """ _py_version_re = re.compile(r"-py([123]\.?[0-9]?)$") # Don't include an allow_yanked default value to make sure each call # site considers whether yanked releases are allowed. This also causes # that decision to be made explicit in the calling code, which helps # people when reading the code. def __init__( self, project_name: str, canonical_name: str, formats: FrozenSet[str], target_python: TargetPython, allow_yanked: bool, ignore_requires_python: Optional[bool] = None, ) -> None: """ :param project_name: The user supplied package name. :param canonical_name: The canonical package name. :param formats: The formats allowed for this package. Should be a set with 'binary' or 'source' or both in it. :param target_python: The target Python interpreter to use when evaluating link compatibility. This is used, for example, to check wheel compatibility, as well as when checking the Python version, e.g. the Python version embedded in a link filename (or egg fragment) and against an HTML link's optional PEP 503 "data-requires-python" attribute. :param allow_yanked: Whether files marked as yanked (in the sense of PEP 592) are permitted to be candidates for install. :param ignore_requires_python: Whether to ignore incompatible PEP 503 "data-requires-python" values in HTML links. Defaults to False. """ if ignore_requires_python is None: ignore_requires_python = False self._allow_yanked = allow_yanked self._canonical_name = canonical_name self._ignore_requires_python = ignore_requires_python self._formats = formats self._target_python = target_python self.project_name = project_name def evaluate_link(self, link: Link) -> Tuple[bool, Optional[str]]: """ Determine whether a link is a candidate for installation. :return: A tuple (is_candidate, result), where `result` is (1) a version string if `is_candidate` is True, and (2) if `is_candidate` is False, an optional string to log the reason the link fails to qualify. """ version = None if link.is_yanked and not self._allow_yanked: reason = link.yanked_reason or "" return (False, f"yanked for reason: {reason}") if link.egg_fragment: egg_info = link.egg_fragment ext = link.ext else: egg_info, ext = link.splitext() if not ext: return (False, "not a file") if ext not in SUPPORTED_EXTENSIONS: return (False, f"unsupported archive format: {ext}") if "binary" not in self._formats and ext == WHEEL_EXTENSION: reason = "No binaries permitted for {}".format(self.project_name) return (False, reason) if "macosx10" in link.path and ext == ".zip": return (False, "macosx10 one") if ext == WHEEL_EXTENSION: try: wheel = Wheel(link.filename) except InvalidWheelFilename: return (False, "invalid wheel filename") if canonicalize_name(wheel.name) != self._canonical_name: reason = "wrong project name (not {})".format(self.project_name) return (False, reason) supported_tags = self._target_python.get_tags() if not wheel.supported(supported_tags): # Include the wheel's tags in the reason string to # simplify troubleshooting compatibility issues. file_tags = wheel.get_formatted_file_tags() reason = ( "none of the wheel's tags ({}) are compatible " "(run pip debug --verbose to show compatible tags)".format( ", ".join(file_tags) ) ) return (False, reason) version = wheel.version # This should be up by the self.ok_binary check, but see issue 2700. if "source" not in self._formats and ext != WHEEL_EXTENSION: reason = f"No sources permitted for {self.project_name}" return (False, reason) if not version: version = _extract_version_from_fragment( egg_info, self._canonical_name, ) if not version: reason = f"Missing project version for {self.project_name}" return (False, reason) match = self._py_version_re.search(version) if match: version = version[: match.start()] py_version = match.group(1) if py_version != self._target_python.py_version: return (False, "Python version is incorrect") supports_python = _check_link_requires_python( link, version_info=self._target_python.py_version_info, ignore_requires_python=self._ignore_requires_python, ) if not supports_python: # Return None for the reason text to suppress calling # _log_skipped_link(). return (False, None) logger.debug("Found link %s, version: %s", link, version) return (True, version) def filter_unallowed_hashes( candidates: List[InstallationCandidate], hashes: Hashes, project_name: str, ) -> List[InstallationCandidate]: """ Filter out candidates whose hashes aren't allowed, and return a new list of candidates. If at least one candidate has an allowed hash, then all candidates with either an allowed hash or no hash specified are returned. Otherwise, the given candidates are returned. Including the candidates with no hash specified when there is a match allows a warning to be logged if there is a more preferred candidate with no hash specified. Returning all candidates in the case of no matches lets pip report the hash of the candidate that would otherwise have been installed (e.g. permitting the user to more easily update their requirements file with the desired hash). """ if not hashes: logger.debug( "Given no hashes to check %s links for project %r: " "discarding no candidates", len(candidates), project_name, ) # Make sure we're not returning back the given value. return list(candidates) matches_or_no_digest = [] # Collect the non-matches for logging purposes. non_matches = [] match_count = 0 for candidate in candidates: link = candidate.link if not link.has_hash: pass elif link.is_hash_allowed(hashes=hashes): match_count += 1 else: non_matches.append(candidate) continue matches_or_no_digest.append(candidate) if match_count: filtered = matches_or_no_digest else: # Make sure we're not returning back the given value. filtered = list(candidates) if len(filtered) == len(candidates): discard_message = "discarding no candidates" else: discard_message = "discarding {} non-matches:\n {}".format( len(non_matches), "\n ".join(str(candidate.link) for candidate in non_matches), ) logger.debug( "Checked %s links for project %r against %s hashes " "(%s matches, %s no digest): %s", len(candidates), project_name, hashes.digest_count, match_count, len(matches_or_no_digest) - match_count, discard_message, ) return filtered class CandidatePreferences: """ Encapsulates some of the preferences for filtering and sorting InstallationCandidate objects. """ def __init__( self, prefer_binary: bool = False, allow_all_prereleases: bool = False, ) -> None: """ :param allow_all_prereleases: Whether to allow all pre-releases. """ self.allow_all_prereleases = allow_all_prereleases self.prefer_binary = prefer_binary class BestCandidateResult: """A collection of candidates, returned by `PackageFinder.find_best_candidate`. This class is only intended to be instantiated by CandidateEvaluator's `compute_best_candidate()` method. """ def __init__( self, candidates: List[InstallationCandidate], applicable_candidates: List[InstallationCandidate], best_candidate: Optional[InstallationCandidate], ) -> None: """ :param candidates: A sequence of all available candidates found. :param applicable_candidates: The applicable candidates. :param best_candidate: The most preferred candidate found, or None if no applicable candidates were found. """ assert set(applicable_candidates) <= set(candidates) if best_candidate is None: assert not applicable_candidates else: assert best_candidate in applicable_candidates self._applicable_candidates = applicable_candidates self._candidates = candidates self.best_candidate = best_candidate def iter_all(self) -> Iterable[InstallationCandidate]: """Iterate through all candidates.""" return iter(self._candidates) def iter_applicable(self) -> Iterable[InstallationCandidate]: """Iterate through the applicable candidates.""" return iter(self._applicable_candidates) class CandidateEvaluator: """ Responsible for filtering and sorting candidates for installation based on what tags are valid. """ @classmethod def create( cls, project_name: str, target_python: Optional[TargetPython] = None, prefer_binary: bool = False, allow_all_prereleases: bool = False, specifier: Optional[specifiers.BaseSpecifier] = None, hashes: Optional[Hashes] = None, ) -> "CandidateEvaluator": """Create a CandidateEvaluator object. :param target_python: The target Python interpreter to use when checking compatibility. If None (the default), a TargetPython object will be constructed from the running Python. :param specifier: An optional object implementing `filter` (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable versions. :param hashes: An optional collection of allowed hashes. """ if target_python is None: target_python = TargetPython() if specifier is None: specifier = specifiers.SpecifierSet() supported_tags = target_python.get_tags() return cls( project_name=project_name, supported_tags=supported_tags, specifier=specifier, prefer_binary=prefer_binary, allow_all_prereleases=allow_all_prereleases, hashes=hashes, ) def __init__( self, project_name: str, supported_tags: List[Tag], specifier: specifiers.BaseSpecifier, prefer_binary: bool = False, allow_all_prereleases: bool = False, hashes: Optional[Hashes] = None, ) -> None: """ :param supported_tags: The PEP 425 tags supported by the target Python in order of preference (most preferred first). """ self._allow_all_prereleases = allow_all_prereleases self._hashes = hashes self._prefer_binary = prefer_binary self._project_name = project_name self._specifier = specifier self._supported_tags = supported_tags # Since the index of the tag in the _supported_tags list is used # as a priority, precompute a map from tag to index/priority to be # used in wheel.find_most_preferred_tag. self._wheel_tag_preferences = { tag: idx for idx, tag in enumerate(supported_tags) } def get_applicable_candidates( self, candidates: List[InstallationCandidate], ) -> List[InstallationCandidate]: """ Return the applicable candidates from a list of candidates. """ # Using None infers from the specifier instead. allow_prereleases = self._allow_all_prereleases or None specifier = self._specifier versions = { str(v) for v in specifier.filter( # We turn the version object into a str here because otherwise # when we're debundled but setuptools isn't, Python will see # packaging.version.Version and # pkg_resources._vendor.packaging.version.Version as different # types. This way we'll use a str as a common data interchange # format. If we stop using the pkg_resources provided specifier # and start using our own, we can drop the cast to str(). (str(c.version) for c in candidates), prereleases=allow_prereleases, ) } # Again, converting version to str to deal with debundling. applicable_candidates = [c for c in candidates if str(c.version) in versions] filtered_applicable_candidates = filter_unallowed_hashes( candidates=applicable_candidates, hashes=self._hashes, project_name=self._project_name, ) return sorted(filtered_applicable_candidates, key=self._sort_key) def _sort_key(self, candidate: InstallationCandidate) -> CandidateSortingKey: """ Function to pass as the `key` argument to a call to sorted() to sort InstallationCandidates by preference. Returns a tuple such that tuples sorting as greater using Python's default comparison operator are more preferred. The preference is as follows: First and foremost, candidates with allowed (matching) hashes are always preferred over candidates without matching hashes. This is because e.g. if the only candidate with an allowed hash is yanked, we still want to use that candidate. Second, excepting hash considerations, candidates that have been yanked (in the sense of PEP 592) are always less preferred than candidates that haven't been yanked. Then: If not finding wheels, they are sorted by version only. If finding wheels, then the sort order is by version, then: 1. existing installs 2. wheels ordered via Wheel.support_index_min(self._supported_tags) 3. source archives If prefer_binary was set, then all wheels are sorted above sources. Note: it was considered to embed this logic into the Link comparison operators, but then different sdist links with the same version, would have to be considered equal """ valid_tags = self._supported_tags support_num = len(valid_tags) build_tag: BuildTag = () binary_preference = 0 link = candidate.link if link.is_wheel: # can raise InvalidWheelFilename wheel = Wheel(link.filename) try: pri = -( wheel.find_most_preferred_tag( valid_tags, self._wheel_tag_preferences ) ) except ValueError: raise UnsupportedWheel( "{} is not a supported wheel for this platform. It " "can't be sorted.".format(wheel.filename) ) if self._prefer_binary: binary_preference = 1 if wheel.build_tag is not None: match = re.match(r"^(\d+)(.*)$", wheel.build_tag) build_tag_groups = match.groups() build_tag = (int(build_tag_groups[0]), build_tag_groups[1]) else: # sdist pri = -(support_num) has_allowed_hash = int(link.is_hash_allowed(self._hashes)) yank_value = -1 * int(link.is_yanked) # -1 for yanked. return ( has_allowed_hash, yank_value, binary_preference, candidate.version, pri, build_tag, ) def sort_best_candidate( self, candidates: List[InstallationCandidate], ) -> Optional[InstallationCandidate]: """ Return the best candidate per the instance's sort order, or None if no candidate is acceptable. """ if not candidates: return None best_candidate = max(candidates, key=self._sort_key) return best_candidate def compute_best_candidate( self, candidates: List[InstallationCandidate], ) -> BestCandidateResult: """ Compute and return a `BestCandidateResult` instance. """ applicable_candidates = self.get_applicable_candidates(candidates) best_candidate = self.sort_best_candidate(applicable_candidates) return BestCandidateResult( candidates, applicable_candidates=applicable_candidates, best_candidate=best_candidate, ) class PackageFinder: """This finds packages. This is meant to match easy_install's technique for looking for packages, by reading pages and looking for appropriate links. """ def __init__( self, link_collector: LinkCollector, target_python: TargetPython, allow_yanked: bool, format_control: Optional[FormatControl] = None, candidate_prefs: Optional[CandidatePreferences] = None, ignore_requires_python: Optional[bool] = None, ) -> None: """ This constructor is primarily meant to be used by the create() class method and from tests. :param format_control: A FormatControl object, used to control the selection of source packages / binary packages when consulting the index and links. :param candidate_prefs: Options to use when creating a CandidateEvaluator object. """ if candidate_prefs is None: candidate_prefs = CandidatePreferences() format_control = format_control or FormatControl(set(), set()) self._allow_yanked = allow_yanked self._candidate_prefs = candidate_prefs self._ignore_requires_python = ignore_requires_python self._link_collector = link_collector self._target_python = target_python self.format_control = format_control # These are boring links that have already been logged somehow. self._logged_links: Set[Link] = set() # Don't include an allow_yanked default value to make sure each call # site considers whether yanked releases are allowed. This also causes # that decision to be made explicit in the calling code, which helps # people when reading the code. @classmethod def create( cls, link_collector: LinkCollector, selection_prefs: SelectionPreferences, target_python: Optional[TargetPython] = None, ) -> "PackageFinder": """Create a PackageFinder. :param selection_prefs: The candidate selection preferences, as a SelectionPreferences object. :param target_python: The target Python interpreter to use when checking compatibility. If None (the default), a TargetPython object will be constructed from the running Python. """ if target_python is None: target_python = TargetPython() candidate_prefs = CandidatePreferences( prefer_binary=selection_prefs.prefer_binary, allow_all_prereleases=selection_prefs.allow_all_prereleases, ) return cls( candidate_prefs=candidate_prefs, link_collector=link_collector, target_python=target_python, allow_yanked=selection_prefs.allow_yanked, format_control=selection_prefs.format_control, ignore_requires_python=selection_prefs.ignore_requires_python, ) @property def target_python(self) -> TargetPython: return self._target_python @property def search_scope(self) -> SearchScope: return self._link_collector.search_scope @search_scope.setter def search_scope(self, search_scope: SearchScope) -> None: self._link_collector.search_scope = search_scope @property def find_links(self) -> List[str]: return self._link_collector.find_links @property def index_urls(self) -> List[str]: return self.search_scope.index_urls @property def trusted_hosts(self) -> Iterable[str]: for host_port in self._link_collector.session.pip_trusted_origins: yield build_netloc(*host_port) @property def allow_all_prereleases(self) -> bool: return self._candidate_prefs.allow_all_prereleases def set_allow_all_prereleases(self) -> None: self._candidate_prefs.allow_all_prereleases = True @property def prefer_binary(self) -> bool: return self._candidate_prefs.prefer_binary def set_prefer_binary(self) -> None: self._candidate_prefs.prefer_binary = True def make_link_evaluator(self, project_name: str) -> LinkEvaluator: canonical_name = canonicalize_name(project_name) formats = self.format_control.get_allowed_formats(canonical_name) return LinkEvaluator( project_name=project_name, canonical_name=canonical_name, formats=formats, target_python=self._target_python, allow_yanked=self._allow_yanked, ignore_requires_python=self._ignore_requires_python, ) def _sort_links(self, links: Iterable[Link]) -> List[Link]: """ Returns elements of links in order, non-egg links first, egg links second, while eliminating duplicates """ eggs, no_eggs = [], [] seen: Set[Link] = set() for link in links: if link not in seen: seen.add(link) if link.egg_fragment: eggs.append(link) else: no_eggs.append(link) return no_eggs + eggs def _log_skipped_link(self, link: Link, reason: str) -> None: if link not in self._logged_links: # Put the link at the end so the reason is more visible and because # the link string is usually very long. logger.debug("Skipping link: %s: %s", reason, link) self._logged_links.add(link) def get_install_candidate( self, link_evaluator: LinkEvaluator, link: Link ) -> Optional[InstallationCandidate]: """ If the link is a candidate for install, convert it to an InstallationCandidate and return it. Otherwise, return None. """ is_candidate, result = link_evaluator.evaluate_link(link) if not is_candidate: if result: self._log_skipped_link(link, reason=result) return None return InstallationCandidate( name=link_evaluator.project_name, link=link, version=result, ) def evaluate_links( self, link_evaluator: LinkEvaluator, links: Iterable[Link] ) -> List[InstallationCandidate]: """ Convert links that are candidates to InstallationCandidate objects. """ candidates = [] for link in self._sort_links(links): candidate = self.get_install_candidate(link_evaluator, link) if candidate is not None: candidates.append(candidate) return candidates def process_project_url( self, project_url: Link, link_evaluator: LinkEvaluator ) -> List[InstallationCandidate]: logger.debug( "Fetching project page and analyzing links: %s", project_url, ) html_page = self._link_collector.fetch_page(project_url) if html_page is None: return [] page_links = list(parse_links(html_page)) with indent_log(): package_links = self.evaluate_links( link_evaluator, links=page_links, ) return package_links @functools.lru_cache(maxsize=None) def find_all_candidates(self, project_name: str) -> List[InstallationCandidate]: """Find all available InstallationCandidate for project_name This checks index_urls and find_links. All versions found are returned as an InstallationCandidate list. See LinkEvaluator.evaluate_link() for details on which files are accepted. """ link_evaluator = self.make_link_evaluator(project_name) collected_sources = self._link_collector.collect_sources( project_name=project_name, candidates_from_page=functools.partial( self.process_project_url, link_evaluator=link_evaluator, ), ) page_candidates_it = itertools.chain.from_iterable( source.page_candidates() for sources in collected_sources for source in sources if source is not None ) page_candidates = list(page_candidates_it) file_links_it = itertools.chain.from_iterable( source.file_links() for sources in collected_sources for source in sources if source is not None ) file_candidates = self.evaluate_links( link_evaluator, sorted(file_links_it, reverse=True), ) if logger.isEnabledFor(logging.DEBUG) and file_candidates: paths = [url_to_path(c.link.url) for c in file_candidates] logger.debug("Local files found: %s", ", ".join(paths)) # This is an intentional priority ordering return file_candidates + page_candidates def make_candidate_evaluator( self, project_name: str, specifier: Optional[specifiers.BaseSpecifier] = None, hashes: Optional[Hashes] = None, ) -> CandidateEvaluator: """Create a CandidateEvaluator object to use.""" candidate_prefs = self._candidate_prefs return CandidateEvaluator.create( project_name=project_name, target_python=self._target_python, prefer_binary=candidate_prefs.prefer_binary, allow_all_prereleases=candidate_prefs.allow_all_prereleases, specifier=specifier, hashes=hashes, ) @functools.lru_cache(maxsize=None) def find_best_candidate( self, project_name: str, specifier: Optional[specifiers.BaseSpecifier] = None, hashes: Optional[Hashes] = None, ) -> BestCandidateResult: """Find matches for the given project and specifier. :param specifier: An optional object implementing `filter` (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable versions. :return: A `BestCandidateResult` instance. """ candidates = self.find_all_candidates(project_name) candidate_evaluator = self.make_candidate_evaluator( project_name=project_name, specifier=specifier, hashes=hashes, ) return candidate_evaluator.compute_best_candidate(candidates) def find_requirement( self, req: InstallRequirement, upgrade: bool ) -> Optional[InstallationCandidate]: """Try to find a Link matching req Expects req, an InstallRequirement and upgrade, a boolean Returns a InstallationCandidate if found, Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise """ hashes = req.hashes(trust_internet=False) best_candidate_result = self.find_best_candidate( req.name, specifier=req.specifier, hashes=hashes, ) best_candidate = best_candidate_result.best_candidate installed_version: Optional[_BaseVersion] = None if req.satisfied_by is not None: installed_version = parse_version(req.satisfied_by.version) def _format_versions(cand_iter: Iterable[InstallationCandidate]) -> str: # This repeated parse_version and str() conversion is needed to # handle different vendoring sources from pip and pkg_resources. # If we stop using the pkg_resources provided specifier and start # using our own, we can drop the cast to str(). return ( ", ".join( sorted( {str(c.version) for c in cand_iter}, key=parse_version, ) ) or "none" ) if installed_version is None and best_candidate is None: logger.critical( "Could not find a version that satisfies the requirement %s " "(from versions: %s)", req, _format_versions(best_candidate_result.iter_all()), ) raise DistributionNotFound( "No matching distribution found for {}".format(req) ) best_installed = False if installed_version and ( best_candidate is None or best_candidate.version <= installed_version ): best_installed = True if not upgrade and installed_version is not None: if best_installed: logger.debug( "Existing installed version (%s) is most up-to-date and " "satisfies requirement", installed_version, ) else: logger.debug( "Existing installed version (%s) satisfies requirement " "(most up-to-date version is %s)", installed_version, best_candidate.version, ) return None if best_installed: # We have an existing version, and its the best version logger.debug( "Installed version (%s) is most up-to-date (past versions: %s)", installed_version, _format_versions(best_candidate_result.iter_applicable()), ) raise BestVersionAlreadyInstalled logger.debug( "Using version %s (newest of versions: %s)", best_candidate.version, _format_versions(best_candidate_result.iter_applicable()), ) return best_candidate def _find_name_version_sep(fragment: str, canonical_name: str) -> int: """Find the separator's index based on the package's canonical name. :param fragment: A + filename "fragment" (stem) or egg fragment. :param canonical_name: The package's canonical name. This function is needed since the canonicalized name does not necessarily have the same length as the egg info's name part. An example:: >>> fragment = 'foo__bar-1.0' >>> canonical_name = 'foo-bar' >>> _find_name_version_sep(fragment, canonical_name) 8 """ # Project name and version must be separated by one single dash. Find all # occurrences of dashes; if the string in front of it matches the canonical # name, this is the one separating the name and version parts. for i, c in enumerate(fragment): if c != "-": continue if canonicalize_name(fragment[:i]) == canonical_name: return i raise ValueError(f"{fragment} does not match {canonical_name}") def _extract_version_from_fragment(fragment: str, canonical_name: str) -> Optional[str]: """Parse the version string from a + filename "fragment" (stem) or egg fragment. :param fragment: The string to parse. E.g. foo-2.1 :param canonical_name: The canonicalized name of the package this belongs to. """ try: version_start = _find_name_version_sep(fragment, canonical_name) + 1 except ValueError: return None version = fragment[version_start:] if not version: return None return version PKH]+7python3.10/site-packages/pip/_internal/index/sources.pynu[import logging import mimetypes import os import pathlib from typing import Callable, Iterable, Optional, Tuple from pip._internal.models.candidate import InstallationCandidate from pip._internal.models.link import Link from pip._internal.utils.urls import path_to_url, url_to_path from pip._internal.vcs import is_url logger = logging.getLogger(__name__) FoundCandidates = Iterable[InstallationCandidate] FoundLinks = Iterable[Link] CandidatesFromPage = Callable[[Link], Iterable[InstallationCandidate]] PageValidator = Callable[[Link], bool] class LinkSource: @property def link(self) -> Optional[Link]: """Returns the underlying link, if there's one.""" raise NotImplementedError() def page_candidates(self) -> FoundCandidates: """Candidates found by parsing an archive listing HTML file.""" raise NotImplementedError() def file_links(self) -> FoundLinks: """Links found by specifying archives directly.""" raise NotImplementedError() def _is_html_file(file_url: str) -> bool: return mimetypes.guess_type(file_url, strict=False)[0] == "text/html" class _FlatDirectorySource(LinkSource): """Link source specified by ``--find-links=``. This looks the content of the directory, and returns: * ``page_candidates``: Links listed on each HTML file in the directory. * ``file_candidates``: Archives in the directory. """ def __init__( self, candidates_from_page: CandidatesFromPage, path: str, ) -> None: self._candidates_from_page = candidates_from_page self._path = pathlib.Path(os.path.realpath(path)) @property def link(self) -> Optional[Link]: return None def page_candidates(self) -> FoundCandidates: for path in self._path.iterdir(): url = path_to_url(str(path)) if not _is_html_file(url): continue yield from self._candidates_from_page(Link(url)) def file_links(self) -> FoundLinks: for path in self._path.iterdir(): url = path_to_url(str(path)) if _is_html_file(url): continue yield Link(url) class _LocalFileSource(LinkSource): """``--find-links=`` or ``--[extra-]index-url=``. If a URL is supplied, it must be a ``file:`` URL. If a path is supplied to the option, it is converted to a URL first. This returns: * ``page_candidates``: Links listed on an HTML file. * ``file_candidates``: The non-HTML file. """ def __init__( self, candidates_from_page: CandidatesFromPage, link: Link, ) -> None: self._candidates_from_page = candidates_from_page self._link = link @property def link(self) -> Optional[Link]: return self._link def page_candidates(self) -> FoundCandidates: if not _is_html_file(self._link.url): return yield from self._candidates_from_page(self._link) def file_links(self) -> FoundLinks: if _is_html_file(self._link.url): return yield self._link class _RemoteFileSource(LinkSource): """``--find-links=`` or ``--[extra-]index-url=``. This returns: * ``page_candidates``: Links listed on an HTML file. * ``file_candidates``: The non-HTML file. """ def __init__( self, candidates_from_page: CandidatesFromPage, page_validator: PageValidator, link: Link, ) -> None: self._candidates_from_page = candidates_from_page self._page_validator = page_validator self._link = link @property def link(self) -> Optional[Link]: return self._link def page_candidates(self) -> FoundCandidates: if not self._page_validator(self._link): return yield from self._candidates_from_page(self._link) def file_links(self) -> FoundLinks: yield self._link class _IndexDirectorySource(LinkSource): """``--[extra-]index-url=``. This is treated like a remote URL; ``candidates_from_page`` contains logic for this by appending ``index.html`` to the link. """ def __init__( self, candidates_from_page: CandidatesFromPage, link: Link, ) -> None: self._candidates_from_page = candidates_from_page self._link = link @property def link(self) -> Optional[Link]: return self._link def page_candidates(self) -> FoundCandidates: yield from self._candidates_from_page(self._link) def file_links(self) -> FoundLinks: return () def build_source( location: str, *, candidates_from_page: CandidatesFromPage, page_validator: PageValidator, expand_dir: bool, cache_link_parsing: bool, ) -> Tuple[Optional[str], Optional[LinkSource]]: path: Optional[str] = None url: Optional[str] = None if os.path.exists(location): # Is a local path. url = path_to_url(location) path = location elif location.startswith("file:"): # A file: URL. url = location path = url_to_path(location) elif is_url(location): url = location if url is None: msg = ( "Location '%s' is ignored: " "it is either a non-existing path or lacks a specific scheme." ) logger.warning(msg, location) return (None, None) if path is None: source: LinkSource = _RemoteFileSource( candidates_from_page=candidates_from_page, page_validator=page_validator, link=Link(url, cache_link_parsing=cache_link_parsing), ) return (url, source) if os.path.isdir(path): if expand_dir: source = _FlatDirectorySource( candidates_from_page=candidates_from_page, path=path, ) else: source = _IndexDirectorySource( candidates_from_page=candidates_from_page, link=Link(url, cache_link_parsing=cache_link_parsing), ) return (url, source) elif os.path.isfile(path): source = _LocalFileSource( candidates_from_page=candidates_from_page, link=Link(url, cache_link_parsing=cache_link_parsing), ) return (url, source) logger.warning( "Location '%s' is ignored: it is neither a file nor a directory.", location, ) return (url, None) PKH]C?K8python3.10/site-packages/pip/_internal/index/__init__.pynu["""Index interaction code """ PKH]`_0_0Jpython3.10/site-packages/pip/_internal/vcs/__pycache__/git.cpython-310.pycnu[o aiE@sddlZddlZddlZddlZddlZddlZddlm Z m Z m Z ddl m Z mZddlmZmZmZddlmZddlmZmZmZmZmZmZmZejjZejjZe e!Z"e#dZ$e#dZ%e#d ej&Z'd e(d e)fd d Z*GdddeZ+e,e+dS)N)ListOptionalTuple) BadCommandInstallationError) HiddenText display_pathhide_url) make_command)AuthInfoRemoteNotFoundErrorRemoteNotValidError RevOptionsVersionControl(find_path_to_project_root_from_repo_rootvcsz(^git version (\d+)\.(\d+)(?:\.(\d+))?.*$z^[a-fA-F0-9]{40}$a/^ # Optional user, e.g. 'git@' (\w+@)? # Server, e.g. 'github.com'. ([^/:]+): # The server-side path. e.g. 'user/project.git'. Must start with an # alphanumeric character so as not to be confusable with a Windows paths # like 'C:/foo/bar' or 'C:\foo\bar'. (\w[^:]*) $shareturncCstt|SN)bool HASH_REGEXmatch)rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/vcs/git.pylooks_like_hash7src sDeZdZdZdZdZdZdZdZe de de e fd d Z d e d e de fd dZdeedffddZede dee fddZed e de deee e ffddZed e de de fddZed e d ededefddZed e dee de fddZd e d ededdfd d!Zd e d ededdfd"d#Zd e d ededdfd$d%Zede de fd&d'Ze d e de fd(d)Zede de de fd*d+Z ed9de dee de fd,d-Z!ede dee fd.d/Z"ed e dee ee e#fffd0d1 Z$ede ddfd2d3Z%ede dee ffd4d5 Z&e d6e de fd7d8Z'Z(S):Gitgitz.gitclone)zgit+httpz git+httpszgit+sshzgit+gitzgit+file)GIT_DIR GIT_WORK_TREEHEADrevrcCs|gSrrr!rrrget_base_rev_argsKszGit.get_base_rev_argsurldestcCsJ|t|\}}|jsdS|||jsdSt|||jd}| S)NFr)get_url_rev_optionsr r!is_commit_id_equalrget_revision_sha)selfr$r%_ rev_optionsis_tag_or_branchrrris_immutable_rev_checkoutOszGit.is_immutable_rev_checkout.cCsF|jdgddd}t|}|std|dStdd|DS) NversionFT) show_stdout stdout_onlyzCan't parse git version: %srcss|]}t|VqdSr)int).0crrr csz&Git.get_git_version..) run_commandGIT_VERSION_REGEXrloggerwarningtuplegroups)r)r.rrrrget_git_version]s   zGit.get_git_versionlocationcCsBgd}|j|ddd|d}|}|dr|tddSdS)zl Return the current branch, or None if HEAD isn't at a branch (e.g. detached HEAD). )z symbolic-ref-qr FTextra_ok_returncodesr/r0cwdz refs/heads/N)r5strip startswithlen)clsr<argsoutputrefrrrget_current_branches  zGit.get_current_branchc Cs|jd|g|dddd}i}|dD](}|d}|sqz |jdd d \}}Wnty8td |w|||<qd |}d |} ||} | durU| dfS|| } | dfS)z Return (sha_or_none, is_branch), where sha_or_none is a commit hash if the revision names a remote branch or tag, otherwise None. Args: dest: the repository directory. rev: the revision name. zshow-refFTignore)rBr/r0 on_returncode   )maxsplitzunexpected show-ref line: zrefs/remotes/origin/z refs/tags/N)r5rCsplitrstrip ValueErrorget) rFr%r!rHrefslineref_sharef_name branch_reftag_refrrrrr(~s2        zGit.get_revision_shacCs.|drdSt|s dS|||rdSdS)a$ Return true if rev is a ref or is a commit that we don't have locally. Branches and tags are not considered in this method because they are assumed to be always available locally (which is a normal outcome of ``git clone`` and ``git fetch --tags``). zrefs/TF)rDr has_commit)rFr%r!rrr _should_fetchs  zGit._should_fetchr+cCs|j}|dus J|||\}}|dur&||}|r!||_|Sd|_|St|s0td||||s8|S|jt dd|| |d|j |dd}||}|S)z Resolve a revision to a new RevOptions object with the SHA1 of the branch, tag, or ref if found. Args: rev_options: a RevOptions object. Nz:Did not find branch or tag '%s', assuming revision or ref.fetchr=rB FETCH_HEADr") arg_revr(make_new branch_namerr7r8r]r5r to_args get_revision)rFr%r$r+r!r is_branchrrrresolve_revisions.     zGit.resolve_revisionnamecCs|sdS|||kS)z Return whether the current commit hash equals the given name. Args: dest: the repository directory. name: a string name. F)re)rFr%rhrrrr's zGit.is_commit_id_equalNc Cs |}td||t||dkr |tddd||n |tdd|||jrw||||}t |dd}t d|||dur\| ||js[tdd| }|j||d n%| ||krvd |}dd |d |g}|j||d n ||}||}td ||j||dS)NzCloning %s%s to %s)rPrz--filter=blob:noner=rczRev options %s, branch_name %scheckoutr_zorigin/z-bz--trackzResolved %s to commit %s) to_displayr7inforr;r5r r!rggetattrdebugr'rdrJrerbupdate_submodules) r)r%r$r+ rev_displayrccmd_args track_branchrrrr fetch_newsP      z Git.fetch_newcCsB|jtdd||dtdd|}|j||d||dS)Nconfigzremote.origin.urlr_rjr=)r5r rdror)r%r$r+rqrrrswitch7s z Git.switchcCsn|dkr|jgd|dn |jddg|d||||}tddd|}|j||d||dS)N)r? )r^r=z--tagsr_r^r=resetz--hard)r;r5rgr rdrorurrrupdateAs z Git.updatecCsx|jgdddd|d}|}z|d}Wn tytw|D] }|dr-|}nq"|dd }||S) z Return URL of the first remote encountered. Raises RemoteNotFoundError if the repository does not have a remote url configured. )rtz --get-regexpzremote\..*\.urlr>FTr@rzremote.origin.url rOr?)r5 splitlines IndexErrorr rDrR_git_remote_to_pip_urlrC)rFr<stdoutremotes found_remoteremoter$rrrget_remote_urlOs(    zGit.get_remote_urlcCsJtd|r|Stj|rt|St|}|r!| dSt |)a8 Convert a remote url from what git uses to what pip accepts. There are 3 legal forms **url** may take: 1. A fully qualified url: ssh://git@example.com/foo/bar.git 2. A local project.git folder: /path/to/bare/repository.git 3. SCP shorthand for form 1: git@example.com:foo/bar.git Form 1 is output as-is. Form 2 must be converted to URI and form 3 must be converted to form 1. See the corresponding test test_git_remote_url_to_pip() for examples of sample inputs/outputs. z\w+://z ssh://\1\2/\3) rerospathexistspathlibPurePathas_uri SCP_REGEXexpandr )r$ scp_matchrrrr|ms    zGit._git_remote_to_pip_urlcCs8z|jdddd|g|ddWdStyYdSw)zU Check if rev is a commit that is available in the local repository. rev-parser=z--verifyzsha^F)rBlog_failed_cmdT)r5r)rFr<r!rrrr\s zGit.has_commitcCs*|durd}|jd|gdd|d}|S)Nr rFTr/r0rB)r5rC)rFr<r! current_revrrrreszGit.get_revisioncCsT|jddgdd|d}tj|stj||}tjtj|d}t||S)z Return the path to Python project root, relative to the repo root. Return None if the project root is in the repo root. rz --git-dirFTrz..)r5rCrrisabsjoinabspathr)rFr<git_dir repo_rootrrrget_subdirectorys  zGit.get_subdirectoryc st|\}}}}}|drC|dt|d }|tj|ddd}|dd} |d| t || d||||f}d|vrcd|vsMJ|d d }t |\}} } |d d }n t |\}} } || | fS) a9 Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. That's required because although they use SSH they sometimes don't work with a ssh:// scheme (e.g. GitHub). But we need a scheme for parsing. Hence we remove it again afterwards and return it as a stub. fileN/\+r?z://zfile:zgit+z git+ssh://zssh://) urlsplitendswithrElstripurllibrequest url2pathnamereplacefind urlunsplitsuperget_url_rev_and_auth) rFr$schemenetlocrqueryfragmentinitial_slashesnewpath after_plusr! user_pass __class__rrrs&     zGit.get_url_rev_and_authcCs0tjtj|ds dS|jgd|ddS)Nz .gitmodules) submoduleryz--initz --recursiver=r_)rrrrr5)rFr<rrrros  zGit.update_submodulescsxt|}|r |Sz|jddg|ddddd}Wnty)td|YdSty2YdSwtj | dS) Nrz--show-toplevelFTraise)rBr/r0rLrzKcould not determine if %s is under git control because git is not availablez ) rget_repository_rootr5rr7rnrrrnormpathrS)rFr<locrrrrrs,   zGit.get_repository_rootrepo_urlcCsdS)zEIn either https or ssh form, requirements must be prefixed with git+.Tr)rrrrshould_add_vcs_url_prefixszGit.should_add_vcs_url_prefixr))__name__ __module__ __qualname__rhdirname repo_nameschemes unset_environdefault_arg_rev staticmethodstrrr#rr-rr1r; classmethodrrJr(r]rrrgr'rsrvryrr|r\rerr rrorr __classcell__rrrrr;sd $- -7  &r)-loggingos.pathrrr urllib.parserurllib.requesttypingrrrpip._internal.exceptionsrrpip._internal.utils.miscrrr pip._internal.utils.subprocessr pip._internal.vcs.versioncontrolr r r rrrrparserr getLoggerrr7compiler6rVERBOSErrrrrregisterrrrrs8 $    IPKH]$gQQUpython3.10/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-310.pycnu[o aiW @sdZddlZddlZddlZddlZddlZddlmZm Z m Z m Z m Z m Z mZmZmZmZmZddlmZddlmZmZddlmZmZmZmZmZmZmZm Z ddl!m"Z"m#Z#m$Z$ddl%m&Z&erjdd lm'Z'd gZ(e)e*Z+eee,ee,fZ-d e,d e.fd dZ/ d#de,de,de,dee,d e,f ddZ0de,de,d ee,fddZ1Gddde2Z3Gddde2Z4GdddZ5Gdd d Z6e6Z7Gd!d"d"Z8dS)$z)Handles all VCS (version control) supportN) TYPE_CHECKINGAnyDictIterableIteratorListMappingOptionalTupleTypeUnion)SpinnerInterface) BadCommandInstallationError) HiddenTextask_path_exists backup_dir display_pathhide_url hide_valueis_installable_dirrmtree) CommandArgscall_subprocess make_command)get_url_scheme)LiteralvcsnamereturncCs&t|}|dur dS|gdtjvS)z3 Return true if the name looks like a URL. NF)httphttpsfileftp)rr all_schemes)rschemer&/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/vcs/versioncontrol.pyis_url4sr(repo_urlrev project_namesubdircCs6|dd}|d|d|}|r|d|7}|S)z Return the URL for a VCS requirement. Args: repo_url: the remote VCS url, with any needed VCS prefix (e.g. "git+"). project_name: the (unescaped) project name. -_@z#egg=z&subdirectory=)replace)r)r*r+r,egg_project_namereqr&r&r'make_vcs_requirement_url>s r3location repo_rootcCs\|}t|s|}tj|}||krtd|dSt|rtj||r'dStj||S)z Find the the Python project's root by searching up the filesystem from `location`. Return the path to project root relative to `repo_root`. Return None if the project root is `repo_root`, or cannot be found. zOCould not find a Python project for directory %s (tried all parent directories)N)rospathdirnameloggerwarningsamefilerelpath)r4r5 orig_location last_locationr&r&r'(find_path_to_project_root_from_repo_rootPs   r?c@s eZdZdS)RemoteNotFoundErrorN)__name__ __module__ __qualname__r&r&r&r'r@msr@cs"eZdZdeffdd ZZS)RemoteNotValidErrorurlcst|||_dSN)super__init__rE)selfrE __class__r&r'rHrs  zRemoteNotValidError.__init__)rArBrCstrrH __classcell__r&r&rJr'rDqsrDc @seZdZdZ  ddeddeedeeddfdd Zdefd d Z e deefd d Z defddZ defddZ deddfddZdS) RevOptionsz Encapsulates a VCS-specific revision to install, along with any VCS install options. Instances of this class should be treated as if immutable. Nvc_classVersionControlr* extra_argsrcCs(|durg}||_||_||_d|_dS)z Args: vc_class: a VersionControl subclass. rev: the name of the revision to install. extra_args: a list of extra options. N)rQr*rO branch_name)rIrOr*rQr&r&r'rHs   zRevOptions.__init__cCsd|jjd|jdS)Nz )rOrr*rIr&r&r'__repr__szRevOptions.__repr__cCs|jdur |jjS|jSrF)r*rOdefault_arg_revrTr&r&r'arg_revs zRevOptions.arg_revcCs0g}|j}|dur||j|7}||j7}|S)z< Return the VCS-specific command arguments. N)rWrOget_base_rev_argsrQ)rIargsr*r&r&r'to_argss  zRevOptions.to_argscCs|jsdSd|jdS)Nz (to revision )r*rTr&r&r' to_displayszRevOptions.to_displaycCs|jj||jdS)z Make a copy of the current instance, but with a new rev. Args: rev: the name of the revision for the new object. rQ)rOmake_rev_optionsrQ)rIr*r&r&r'make_newszRevOptions.make_newNN)rArBrC__doc__r r rLrrHrUpropertyrWrZr^rar&r&r&r'rNws&   rNcseZdZUiZeedfed<gdZdfdd Zde efdd Z e de dfd d Z e de efd d Ze de efddZdedddfddZdeddfddZdededfddZdededfddZdededfddZZS) VcsSupportrP _registry)sshgithgbzrsftpsvnrNcstjj|jtdSrF)urllibparse uses_netlocextendschemesrGrHrTrJr&r'rHszVcsSupport.__init__cCs |jSrF)rf__iter__rTr&r&r'rrs zVcsSupport.__iter__cCst|jSrF)listrfvaluesrTr&r&r'backendsszVcsSupport.backendscCsdd|jDS)NcSsg|]}|jqSr&)r8).0backendr&r&r' sz'VcsSupport.dirnames..)rurTr&r&r'dirnamesszVcsSupport.dirnamescCs g}|jD]}||jq|SrF)rurprq)rIrqrwr&r&r'r$s zVcsSupport.all_schemesclscCsLt|dstd|jdS|j|jvr$||j|j<td|jdSdS)NrzCannot register VCS %szRegistered VCS backend: %s)hasattrr9r:rArrfdebug)rIrzr&r&r'registers  zVcsSupport.registerrcCs||jvr |j|=dSdSrF)rfrIrr&r&r' unregisters  zVcsSupport.unregisterr4cCsXi}|jD]}||}|sqtd||j|||<q|s"dSt|td}||S)zv Return a VersionControl object if a repository of that type is found at the given directory. zDetermine that %s uses VCS: %sN)key)rfrtget_repository_rootr9r|rmaxlen)rIr4 vcs_backends vcs_backend repo_pathinner_most_repo_pathr&r&r'get_backend_for_dirs   zVcsSupport.get_backend_for_dirr%cCs&|jD] }||jvr|SqdS)9 Return a VersionControl object or None. N)rfrtrq)rIr%rr&r&r'get_backend_for_schemes  z!VcsSupport.get_backend_for_schemecCs|}|j|S)r)lowerrfgetr~r&r&r' get_backends zVcsSupport.get_backend)rN)rArBrCrfrrL__annotations__rqrHrrrrdrruryr$r r}rr rrrrMr&r&rJr'res  rec@sNeZdZUdZdZdZdZeedfe d<dZ eedfe d<dZ e ee d<e ded efd d Ze d ed e efd dZe ded efddZe deded efddZeded eefddZdeded efddZe d[de ede ed efddZe ded efd d!Ze d"ed#ed eeee ee efffd$d%Ze ded eee eeffd&d'Zed(e ed)e ed efd*d+Zded eeeffd,d-Z eded efd.d/Z!e d0ed1ed efd2d3Z"deded4ed dfd5d6Z#deded4ed dfd7d8Z$deded4ed dfd9d:Z%e ded;e ed efdd?Z'd eded dfd@dAZ(e d ed efdBdCZ)e d ed efdDdEZ*e F  G     F Hd\dIe+eeefdJedKe edLdMdNe e,e-dOe edPe e.ee/fdQe e0dRedSed efdTdUZ1e dVed efdWdXZ2e d ed e efdYdZZ3dS)]rPr[r&.rq unset_environNrV remote_urlrcCs||jd S)z Return whether the vcs prefix (e.g. "git+") should be added to a repository's remote url when used in a requirement. :)r startswithr)rzrr&r&r'should_add_vcs_url_prefixsz(VersionControl.should_add_vcs_url_prefixr4cCdS)z Return the path to Python project root, relative to the repo root. Return None if the project root is in the repo root. Nr&rzr4r&r&r'get_subdirectoryszVersionControl.get_subdirectoryrepo_dircCs ||S)zR Return the revision string that should be used in a requirement. ) get_revision)rzrr&r&r'get_requirement_revision's z'VersionControl.get_requirement_revisionr+cCsL||}||r|jd|}||}||}t||||d}|S)aC Return the requirement string to use to redownload the files currently at the given repository directory. Args: project_name: the (unescaped) project name. The return value has a form similar to the following: {repository_url}@{revision}#egg={project_name} +)r,)get_remote_urlrrrrr3)rzrr+r)revisionr,r2r&r&r'get_src_requirement.s   z"VersionControl.get_src_requirementr*cCt)z Return the base revision arguments for a vcs command. Args: rev: the name of a revision to install. Cannot be None. NotImplementedErrorr]r&r&r'rXFz VersionControl.get_base_rev_argsrEdestcCr)aZ Return true if the commit hash checked out at dest matches the revision in url. Always return False, if the VCS does not support immutable commit hashes. This method does not check if there are local uncommitted changes in dest after checkout, as pip currently has no use case for that. Fr&)rIrErr&r&r'is_immutable_rev_checkoutPs z(VersionControl.is_immutable_rev_checkoutrQcCst|||dS)z Return a RevOptions object. Args: rev: the name of a revision to install. extra_args: a list of extra options. r_)rN)rzr*rQr&r&r'r`]s zVersionControl.make_rev_optionsrepocCs&tj|\}}|tjjpt|S)zs posix absolute paths start with os.path.sep, win32 ones start with drive (like c:\folder) )r6r7 splitdriversepbool)rzrdrivetailr&r&r'_is_local_repositoryjsz#VersionControl._is_local_repositorynetlocr%cCs|dfS)aZ Parse the repository URL's netloc, and return the new netloc to use along with auth information. Args: netloc: the original repository URL netloc. scheme: the repository URL's scheme without the vcs prefix. This is mainly for the Subversion class to override, so that auth information can be provided via the --username and --password options instead of through the URL. For other subclasses like Git without such an option, auth information must stay in the URL. Returns: (netloc, (username, password)). rbr&)rzrr%r&r&r'get_netloc_and_authssz"VersionControl.get_netloc_and_authc Cstj|\}}}}}d|vrtd||ddd}|||\}}d}d|vr=|dd\}}|s=td|tj ||||df}|||fS)z Parse the repository URL to use, and return the URL, revision, and auth info to use. Returns: (url, rev, (username, password)). rzvSorry, {!r} is a malformed VCS url. The format is +://, e.g. svn+http://myrepo/svn/MyApp#egg=MyAppNr/zyThe URL {!r} has an empty revision (after @) which is not supported. Include a revision after @ or remove @ from the URL.r[) rmrnurlsplit ValueErrorformatsplitrrsplitr urlunsplit) rzrEr%rr7queryfrag user_passr*r&r&r'get_url_rev_and_auths$ z#VersionControl.get_url_rev_and_authusernamepasswordcCsgS)zM Return the RevOptions "extra arguments" to use in obtain(). r&)rrr&r&r' make_rev_argszVersionControl.make_rev_argsc CsT||j\}}}|\}}d}|durt|}|||}|j||d} t|| fS)zq Return the URL and RevOptions object to use in obtain(), as a tuple (url, rev_options). Nr_)rsecretrrr`r) rIrE secret_urlr*rrsecret_passwordrrQ rev_optionsr&r&r'get_url_rev_optionss  z"VersionControl.get_url_rev_optionscCstj|dS)zi Normalize a URL for comparison by unquoting it and removing any trailing slash. /)rmrnunquoterstriprEr&r&r' normalize_urlszVersionControl.normalize_urlurl1url2cCs||||kS)zV Compare two repo URLs for identity, ignoring incidental differences. )r)rzrrr&r&r' compare_urlsszVersionControl.compare_urlsrcCr)z Fetch a revision from a repository, in the case that this is the first fetch from the repository. Args: dest: the directory to fetch the repository to. rev_options: a RevOptions object. rrIrrErr&r&r' fetch_new zVersionControl.fetch_newcCr)z} Switch the repo at ``dest`` to point to ``URL``. Args: rev_options: a RevOptions object. rrr&r&r'switchrzVersionControl.switchcCr)z Update an already-existing repo to the given ``rev_options``. Args: rev_options: a RevOptions object. rrr&r&r'updaterzVersionControl.updatercCr)z Return whether the id of the current commit equals the given name. Args: dest: the repository directory. name: a string name. r)rzrrr&r&r'is_commit_id_equalrz!VersionControl.is_commit_id_equalc Cs||\}}tj|s||||dS|}||rj||}|||j rZt d|j t|||||jsSt dt||j |||||dSt ddSt d|j|j t||d}n t d||j|j d}t d |j|td |d |d }|d krtd|dkrt dt|t|||||dS|dkrt|}t dt||t||||||dS|dkrt d|j t|||||||dSdS)a Install or update in editable mode the package represented by this VersionControl object. :param dest: the repository directory in which to install or update. :param url: the repository URL starting with a vcs prefix. Nz)%s in %s exists, and has correct URL (%s)zUpdating %s %s%sz$Skipping because already up-to-date.z%s %s in %s exists with URL %s)z%(s)witch, (i)gnore, (w)ipe, (b)ackup )siwbz0Directory %s already exists, and is not a %s %s.)z(i)gnore, (w)ipe, (b)ackup )rrrz+The plan is to install the %s repository %szWhat to do? {}rrarz Deleting %srzBacking up %s to %srzSwitching %s %s to %s%s)rr6r7existsrr^is_repository_directoryrrrr9r| repo_nametitlerrr*inforr:rrrsysexitrrshutilmover) rIrrEr rev_display existing_urlpromptresponsedest_dirr&r&r'obtains      zVersionControl.obtaincCs&tj|r t||j||ddS)z Clean up current location and download the url repository (and vcs infos) into location :param url: the repository URL starting with a vcs prefix. rN)r6r7rrr)rIr4rEr&r&r'unpackMs zVersionControl.unpackcCr)z Return the url used at location Raises RemoteNotFoundError if the repository does not have a remote url configured. rrr&r&r'rXrzVersionControl.get_remote_urlcCr)zR Return the current commit id of the files at the given location. rrr&r&r'rbszVersionControl.get_revisionTraiseFcmd show_stdoutcwd on_returncodez"Literal["raise", "warn", "ignore"]extra_ok_returncodes command_desc extra_environspinnerlog_failed_cmd stdout_onlyc Cs|t|jg|R}zt||||||||j|| | d WSty.td|jd|jdty=td|jdw)z Run a VCS subcommand This is simply a wrapper around call_subprocess that adds the VCS command name, and checks that the VCS is available )rrrrrrrrzCannot find command z - do you have z installed and in your PATH?zNo permission to execute z - install it locally, globally (ask admin), or check your PATH. See possible solutions at https://pip.pypa.io/en/latest/reference/pip_freeze/#fixing-permission-denied.)rrrrFileNotFoundErrorrPermissionError) rzrrrrrrrrrrr&r&r' run_commandis4    zVersionControl.run_commandr7cCs,td||j|jtjtj||jS)zL Return whether a directory path is a repository directory. zChecking in %s for %s (%s)...)r9r|r8rr6r7rjoin)rzr7r&r&r'rsz&VersionControl.is_repository_directorycCs||r|SdS)ay Return the "root" (top-level) directory controlled by the vcs, or `None` if the directory is not in any. It is meant to be overridden to implement smarter detection mechanisms for specific vcs. This can do more than is_repository_directory() alone. For example, the Git override checks that Git is actually available. N)rrr&r&r'rs z"VersionControl.get_repository_rootrb) TNrNNNNTF)4rArBrCrr8rrqr rLrrrVr classmethodrrrrr staticmethodrrXrrrNr`rrAuthInforrrrrrrrrrrrrrr rintrrr rrrr&r&r&r'rP s      "     X       5rPrF)9rcloggingr6rr urllib.parsermtypingrrrrrrrr r r r pip._internal.cli.spinnersr pip._internal.exceptionsrrpip._internal.utils.miscrrrrrrrrpip._internal.utils.subprocessrrrpip._internal.utils.urlsrr__all__ getLoggerrAr9rLrrr(r3r? Exceptionr@rDrNrerrPr&r&r&r'sV4 (      CPPKH]uFh''Ppython3.10/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-310.pycnu[o aiQ@sddlZddlZddlZddlmZmZddlmZmZddl m Z m Z ddl m Z ddlmZddlmZmZmZmZeeZGdd d eZeedS) N)ListOptional) BadCommandInstallationError) HiddenText display_path) make_command) path_to_url) RevOptionsVersionControl(find_path_to_project_root_from_repo_rootvcscs eZdZdZdZdZdZedede efddZ d ed e d e dd fd dZ d ed e d e dd fddZd ed e d e dd fddZededefddZededefddZededefddZed edeedefddZededeefddZededeeffdd ZZS)! Mercurialhgz.hgclone)zhg+filezhg+httpzhg+httpszhg+sshzhg+static-httprevreturncCs|gS)N)rrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/vcs/mercurial.pyget_base_rev_args szMercurial.get_base_rev_argsdesturl rev_optionsNcCsP|}td||t||tddd|||jtdd||ddS)NzCloning hg %s%s to %srz --noupdate-qupdatecwd) to_displayloggerinfor run_commandrto_args)selfrrr rev_displayrrr fetch_new$s zMercurial.fetch_newc Cstj||jd}t}z)|||dd|jt |d }| |Wdn1s0wYWnt tj fyS}zt d||WYd}~dSd}~wwtdd|}|j||ddS) Nhgrcpathsdefaultwz/Could not switch Mercurial repository to %s: %srrr)ospathjoindirname configparserRawConfigParserreadsetsecretopenwriteOSErrorNoSectionErrorrwarningrr!r ) r"rrr repo_configconfig config_fileexccmd_argsrrrswitch2s   zMercurial.switchcCs4|jddg|dtdd|}|j||ddS)Npullrrr)r rr!)r"rrrr;rrrr@szMercurial.updatelocationcCs4|jddgdd|d}||rt|}|S)N showconfigz paths.defaultFT show_stdout stdout_onlyr)r strip_is_local_repositoryr )clsr>rrrrget_remote_urlEs zMercurial.get_remote_urlcC|jddgdd|d}|S)zW Return the repository-local changeset revision number, as an integer. parentsz--template={rev}FTr@r rC)rEr>current_revisionrrr get_revisionQszMercurial.get_revisioncCrG)zh Return the changeset identification hash, as a 40-character hexadecimal string rHz--template={node}FTr@rI)rEr>current_rev_hashrrrget_requirement_revision^sz"Mercurial.get_requirement_revisionnamecCsdS)z&Always assume the versions don't matchFr)rErrNrrris_commit_id_equallszMercurial.is_commit_id_equalcCsD|jdgdd|d}tj|stjtj||}t||S)z Return the path to Python project root, relative to the repo root. Return None if the project root is in the repo root. rootFTr@)r rCr)r*isabsabspathr+r )rEr> repo_rootrrrget_subdirectoryqs   zMercurial.get_subdirectorycsvt|}|r |Sz|jdg|ddddd}Wnty(td|YdSty1YdSwtj | dS)NrPFTraise)rrArB on_returncodelog_failed_cmdzIcould not determine if %s is under hg control because hg is not availablez ) superget_repository_rootr rrdebugrr)r*normpathrstrip)rEr>locr __class__rrrYs,   zMercurial.get_repository_root)__name__ __module__ __qualname__rNr, repo_nameschemes staticmethodstrrrrr r$r<r classmethodrFrKrMrboolrOrTrY __classcell__rrr_rrs,    $r)r-loggingr)typingrrpip._internal.exceptionsrrpip._internal.utils.miscrrpip._internal.utils.subprocessrpip._internal.utils.urlsr pip._internal.vcs.versioncontrolr r r r getLoggerrarrregisterrrrrs   PKH]i6..Opython3.10/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-310.pycnu[o aiT@s@ddlZddlZddlZddlZddlmZmZmZm Z m Z dS)N)RemoteNotFoundErrorRemoteNotValidErroris_urlmake_vcs_requirement_urlvcs) pip._internal.vcs.bazaarpippip._internal.vcs.gitpip._internal.vcs.mercurialpip._internal.vcs.subversion pip._internal.vcs.versioncontrolrrrrrr r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/vcs/__init__.pys  PKH]փ Qpython3.10/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-310.pycnu[o aiL-@sddlZddlZddlZddlmZmZmZddlmZm Z m Z m Z m Z ddl mZmZddlmZmZmZmZmZeeZedZedZedZed ZGd d d eZeedS) N)ListOptionalTuple) HiddenText display_pathis_console_interactiveis_installable_dirsplit_auth_from_netloc) CommandArgs make_command)AuthInfoRemoteNotFoundError RevOptionsVersionControlvcsz url="([^"]+)"zcommitted-rev="(\d+)"z\s*revision="(\d+)"z(.*)c seZdZdZdZdZdZedede fddZ e d ede efd d Z ed edefd dZedededeeeeeeeffffdd Zededeeeeefffdd Ze deedeedefddZed edefddZed edeeeeffddZededeede fd d!Zd4d#e dd"ffd$d% Zdeed&ffd'd(Zdeed&ffd)d*Zdefd+d,Zdeded-edd"fd.d/Z deded-edd"fd0d1Z!deded-edd"fd2d3Z"Z#S)5 Subversionsvnz.svncheckout)zsvn+sshzsvn+httpz svn+httpszsvn+svnzsvn+file remote_urlreturncCdS)NT)clsrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/vcs/subversion.pyshould_add_vcs_url_prefix$sz$Subversion.should_add_vcs_url_prefixrevcCsd|gS)Nz-rr)rrrrget_base_rev_args(szSubversion.get_base_rev_argslocationc Csd}t|D]P\}}}|j|vrg|dd<q||jtj||jd}tj|s.q||\}}||krD|dus?J|d}n|rK||sRg|dd<qt ||}qt |S)zR Return the maximum revision for all files under a given location rNentries/) oswalkdirnameremovepathjoinexists_get_svn_url_rev startswithmaxstr) rrrevisionbasedirs_ entries_fndirurllocalrevrrr get_revision,s$        zSubversion.get_revisionnetlocschemecs|dkr t||St|S)z This override allows the auth information to be passed to svn via the --username and --password options instead of via the URL. ssh)superget_netloc_and_authr )rr3r4 __class__rrr7IszSubversion.get_netloc_and_authurlcs.t|\}}}|drd|}|||fS)Nzssh://zsvn+)r6get_url_rev_and_authr()rr:r user_passr8rrr;Xs  zSubversion.get_url_rev_and_authusernamepasswordcCs(g}|r |d|g7}|r|d|g7}|S)Nz --usernamez --passwordr)r=r> extra_argsrrr make_rev_args`s   zSubversion.make_rev_argscCsZ|}t|s|}tj|}||krtd|tt|r||\}}|dur+t|S)NzMCould not find Python project for directory %s (tried all parent directories))rr r$r"loggerwarningr r')rr orig_location last_locationr:_revrrrget_remote_urlls  zSubversion.get_remote_urlc Csddlm}tj||jd}tj|r.t| }|}Wdn1s(wYnd}d}| dsA| dsA| drbt t t j |d}|dd=|dd }d d |Ddg}n\| d rt|} | sutd || d}dd t|Ddg}n6z'|jdd|gddd} t| } | dusJ| d}dd t| D}Wn|ydg}}Ynw|rt|} || fSd} || fS)Nr)InstallationErrorr8910z cSs,g|]}t|dkr|drt|dqS) )lenint).0drrr s,z/Subversion._get_svn_url_rev..zs      "PKH]-ɼ Mpython3.10/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-310.pycnu[o ai) @sddlZddlmZmZmZddlmZmZddlm Z ddl m Z ddl m Z mZmZmZmZeeZGdddeZeedS) N)ListOptionalTuple) HiddenText display_path) make_command) path_to_url)AuthInfoRemoteNotFoundError RevOptionsVersionControlvcscseZdZdZdZdZdZedede efddZ d ed e d e dd fd dZ d ed e d e dd fddZd ed e d e dd fddZed edeeeeefffdd ZededefddZededefddZed edeedefddZZS)Bazaarbzrz.bzrbranch)zbzr+httpz bzr+httpszbzr+sshzbzr+sftpzbzr+ftpzbzr+lpzbzr+filerevreturncCsd|gS)Nz-r)rrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/vcs/bazaar.pyget_base_rev_args szBazaar.get_base_rev_argsdesturl rev_optionsNcCs>|}td||t|tdd|||}||dS)NzChecking out %s%s to %sr-q) to_displayloggerinforrto_args run_command)selfrrr rev_displaycmd_argsrrr fetch_new$szBazaar.fetch_newcCs|jtd||ddS)Nswitchcwd)rr)rrrrrrrr#/sz Bazaar.switchcCs"tdd|}|j||ddS)Npullrr$)rrr)rrrrr!rrrupdate2sz Bazaar.updatecs.t|\}}}|drd|}|||fS)Nzssh://zbzr+)superget_url_rev_and_auth startswith)clsrr user_pass __class__rrr)6s  zBazaar.get_url_rev_and_authlocationcCsv|jdgdd|d}|D]*}|}dD]!}||r7||d}||r1t|S|Sqqt)NrFT show_stdout stdout_onlyr%)zcheckout of branch: zparent branch: )r splitlinesstripr*split_is_local_repositoryrr )r+r/urlslinexreporrrget_remote_url>s     zBazaar.get_remote_urlcCs |jdgdd|d}|dS)NrevnoFTr0)rr4)r+r/revisionrrr get_revisionMs zBazaar.get_revisionnamecCsdS)z&Always assume the versions don't matchFr)r+rrArrris_commit_id_equalWszBazaar.is_commit_id_equal)__name__ __module__ __qualname__rAdirname repo_nameschemes staticmethodstrrrrr r"r#r' classmethodrrr r)r<r@boolrB __classcell__rrr-rrs$  & $r)loggingtypingrrrpip._internal.utils.miscrrpip._internal.utils.subprocessrpip._internal.utils.urlsr pip._internal.vcs.versioncontrolr r r r r getLoggerrCrrregisterrrrrs   KPKH]oɩQQ7python3.10/site-packages/pip/_internal/vcs/mercurial.pynu[import configparser import logging import os from typing import List, Optional from pip._internal.exceptions import BadCommand, InstallationError from pip._internal.utils.misc import HiddenText, display_path from pip._internal.utils.subprocess import make_command from pip._internal.utils.urls import path_to_url from pip._internal.vcs.versioncontrol import ( RevOptions, VersionControl, find_path_to_project_root_from_repo_root, vcs, ) logger = logging.getLogger(__name__) class Mercurial(VersionControl): name = "hg" dirname = ".hg" repo_name = "clone" schemes = ( "hg+file", "hg+http", "hg+https", "hg+ssh", "hg+static-http", ) @staticmethod def get_base_rev_args(rev: str) -> List[str]: return [rev] def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: rev_display = rev_options.to_display() logger.info( "Cloning hg %s%s to %s", url, rev_display, display_path(dest), ) self.run_command(make_command("clone", "--noupdate", "-q", url, dest)) self.run_command( make_command("update", "-q", rev_options.to_args()), cwd=dest, ) def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: repo_config = os.path.join(dest, self.dirname, "hgrc") config = configparser.RawConfigParser() try: config.read(repo_config) config.set("paths", "default", url.secret) with open(repo_config, "w") as config_file: config.write(config_file) except (OSError, configparser.NoSectionError) as exc: logger.warning("Could not switch Mercurial repository to %s: %s", url, exc) else: cmd_args = make_command("update", "-q", rev_options.to_args()) self.run_command(cmd_args, cwd=dest) def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: self.run_command(["pull", "-q"], cwd=dest) cmd_args = make_command("update", "-q", rev_options.to_args()) self.run_command(cmd_args, cwd=dest) @classmethod def get_remote_url(cls, location: str) -> str: url = cls.run_command( ["showconfig", "paths.default"], show_stdout=False, stdout_only=True, cwd=location, ).strip() if cls._is_local_repository(url): url = path_to_url(url) return url.strip() @classmethod def get_revision(cls, location: str) -> str: """ Return the repository-local changeset revision number, as an integer. """ current_revision = cls.run_command( ["parents", "--template={rev}"], show_stdout=False, stdout_only=True, cwd=location, ).strip() return current_revision @classmethod def get_requirement_revision(cls, location: str) -> str: """ Return the changeset identification hash, as a 40-character hexadecimal string """ current_rev_hash = cls.run_command( ["parents", "--template={node}"], show_stdout=False, stdout_only=True, cwd=location, ).strip() return current_rev_hash @classmethod def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool: """Always assume the versions don't match""" return False @classmethod def get_subdirectory(cls, location: str) -> Optional[str]: """ Return the path to Python project root, relative to the repo root. Return None if the project root is in the repo root. """ # find the repo root repo_root = cls.run_command( ["root"], show_stdout=False, stdout_only=True, cwd=location ).strip() if not os.path.isabs(repo_root): repo_root = os.path.abspath(os.path.join(location, repo_root)) return find_path_to_project_root_from_repo_root(location, repo_root) @classmethod def get_repository_root(cls, location: str) -> Optional[str]: loc = super().get_repository_root(location) if loc: return loc try: r = cls.run_command( ["root"], cwd=location, show_stdout=False, stdout_only=True, on_returncode="raise", log_failed_cmd=False, ) except BadCommand: logger.debug( "could not determine if %s is under hg control " "because hg is not available", location, ) return None except InstallationError: return None return os.path.normpath(r.rstrip("\r\n")) vcs.register(Mercurial) PKH]s1!WW<python3.10/site-packages/pip/_internal/vcs/versioncontrol.pynu["""Handles all VCS (version control) support""" import logging import os import shutil import sys import urllib.parse from typing import ( TYPE_CHECKING, Any, Dict, Iterable, Iterator, List, Mapping, Optional, Tuple, Type, Union, ) from pip._internal.cli.spinners import SpinnerInterface from pip._internal.exceptions import BadCommand, InstallationError from pip._internal.utils.misc import ( HiddenText, ask_path_exists, backup_dir, display_path, hide_url, hide_value, is_installable_dir, rmtree, ) from pip._internal.utils.subprocess import CommandArgs, call_subprocess, make_command from pip._internal.utils.urls import get_url_scheme if TYPE_CHECKING: # Literal was introduced in Python 3.8. # # TODO: Remove `if TYPE_CHECKING` when dropping support for Python 3.7. from typing import Literal __all__ = ["vcs"] logger = logging.getLogger(__name__) AuthInfo = Tuple[Optional[str], Optional[str]] def is_url(name: str) -> bool: """ Return true if the name looks like a URL. """ scheme = get_url_scheme(name) if scheme is None: return False return scheme in ["http", "https", "file", "ftp"] + vcs.all_schemes def make_vcs_requirement_url( repo_url: str, rev: str, project_name: str, subdir: Optional[str] = None ) -> str: """ Return the URL for a VCS requirement. Args: repo_url: the remote VCS url, with any needed VCS prefix (e.g. "git+"). project_name: the (unescaped) project name. """ egg_project_name = project_name.replace("-", "_") req = f"{repo_url}@{rev}#egg={egg_project_name}" if subdir: req += f"&subdirectory={subdir}" return req def find_path_to_project_root_from_repo_root( location: str, repo_root: str ) -> Optional[str]: """ Find the the Python project's root by searching up the filesystem from `location`. Return the path to project root relative to `repo_root`. Return None if the project root is `repo_root`, or cannot be found. """ # find project root. orig_location = location while not is_installable_dir(location): last_location = location location = os.path.dirname(location) if location == last_location: # We've traversed up to the root of the filesystem without # finding a Python project. logger.warning( "Could not find a Python project for directory %s (tried all " "parent directories)", orig_location, ) return None if os.path.samefile(repo_root, location): return None return os.path.relpath(location, repo_root) class RemoteNotFoundError(Exception): pass class RemoteNotValidError(Exception): def __init__(self, url: str): super().__init__(url) self.url = url class RevOptions: """ Encapsulates a VCS-specific revision to install, along with any VCS install options. Instances of this class should be treated as if immutable. """ def __init__( self, vc_class: Type["VersionControl"], rev: Optional[str] = None, extra_args: Optional[CommandArgs] = None, ) -> None: """ Args: vc_class: a VersionControl subclass. rev: the name of the revision to install. extra_args: a list of extra options. """ if extra_args is None: extra_args = [] self.extra_args = extra_args self.rev = rev self.vc_class = vc_class self.branch_name: Optional[str] = None def __repr__(self) -> str: return f"" @property def arg_rev(self) -> Optional[str]: if self.rev is None: return self.vc_class.default_arg_rev return self.rev def to_args(self) -> CommandArgs: """ Return the VCS-specific command arguments. """ args: CommandArgs = [] rev = self.arg_rev if rev is not None: args += self.vc_class.get_base_rev_args(rev) args += self.extra_args return args def to_display(self) -> str: if not self.rev: return "" return f" (to revision {self.rev})" def make_new(self, rev: str) -> "RevOptions": """ Make a copy of the current instance, but with a new rev. Args: rev: the name of the revision for the new object. """ return self.vc_class.make_rev_options(rev, extra_args=self.extra_args) class VcsSupport: _registry: Dict[str, "VersionControl"] = {} schemes = ["ssh", "git", "hg", "bzr", "sftp", "svn"] def __init__(self) -> None: # Register more schemes with urlparse for various version control # systems urllib.parse.uses_netloc.extend(self.schemes) super().__init__() def __iter__(self) -> Iterator[str]: return self._registry.__iter__() @property def backends(self) -> List["VersionControl"]: return list(self._registry.values()) @property def dirnames(self) -> List[str]: return [backend.dirname for backend in self.backends] @property def all_schemes(self) -> List[str]: schemes: List[str] = [] for backend in self.backends: schemes.extend(backend.schemes) return schemes def register(self, cls: Type["VersionControl"]) -> None: if not hasattr(cls, "name"): logger.warning("Cannot register VCS %s", cls.__name__) return if cls.name not in self._registry: self._registry[cls.name] = cls() logger.debug("Registered VCS backend: %s", cls.name) def unregister(self, name: str) -> None: if name in self._registry: del self._registry[name] def get_backend_for_dir(self, location: str) -> Optional["VersionControl"]: """ Return a VersionControl object if a repository of that type is found at the given directory. """ vcs_backends = {} for vcs_backend in self._registry.values(): repo_path = vcs_backend.get_repository_root(location) if not repo_path: continue logger.debug("Determine that %s uses VCS: %s", location, vcs_backend.name) vcs_backends[repo_path] = vcs_backend if not vcs_backends: return None # Choose the VCS in the inner-most directory. Since all repository # roots found here would be either `location` or one of its # parents, the longest path should have the most path components, # i.e. the backend representing the inner-most repository. inner_most_repo_path = max(vcs_backends, key=len) return vcs_backends[inner_most_repo_path] def get_backend_for_scheme(self, scheme: str) -> Optional["VersionControl"]: """ Return a VersionControl object or None. """ for vcs_backend in self._registry.values(): if scheme in vcs_backend.schemes: return vcs_backend return None def get_backend(self, name: str) -> Optional["VersionControl"]: """ Return a VersionControl object or None. """ name = name.lower() return self._registry.get(name) vcs = VcsSupport() class VersionControl: name = "" dirname = "" repo_name = "" # List of supported schemes for this Version Control schemes: Tuple[str, ...] = () # Iterable of environment variable names to pass to call_subprocess(). unset_environ: Tuple[str, ...] = () default_arg_rev: Optional[str] = None @classmethod def should_add_vcs_url_prefix(cls, remote_url: str) -> bool: """ Return whether the vcs prefix (e.g. "git+") should be added to a repository's remote url when used in a requirement. """ return not remote_url.lower().startswith(f"{cls.name}:") @classmethod def get_subdirectory(cls, location: str) -> Optional[str]: """ Return the path to Python project root, relative to the repo root. Return None if the project root is in the repo root. """ return None @classmethod def get_requirement_revision(cls, repo_dir: str) -> str: """ Return the revision string that should be used in a requirement. """ return cls.get_revision(repo_dir) @classmethod def get_src_requirement(cls, repo_dir: str, project_name: str) -> str: """ Return the requirement string to use to redownload the files currently at the given repository directory. Args: project_name: the (unescaped) project name. The return value has a form similar to the following: {repository_url}@{revision}#egg={project_name} """ repo_url = cls.get_remote_url(repo_dir) if cls.should_add_vcs_url_prefix(repo_url): repo_url = f"{cls.name}+{repo_url}" revision = cls.get_requirement_revision(repo_dir) subdir = cls.get_subdirectory(repo_dir) req = make_vcs_requirement_url(repo_url, revision, project_name, subdir=subdir) return req @staticmethod def get_base_rev_args(rev: str) -> List[str]: """ Return the base revision arguments for a vcs command. Args: rev: the name of a revision to install. Cannot be None. """ raise NotImplementedError def is_immutable_rev_checkout(self, url: str, dest: str) -> bool: """ Return true if the commit hash checked out at dest matches the revision in url. Always return False, if the VCS does not support immutable commit hashes. This method does not check if there are local uncommitted changes in dest after checkout, as pip currently has no use case for that. """ return False @classmethod def make_rev_options( cls, rev: Optional[str] = None, extra_args: Optional[CommandArgs] = None ) -> RevOptions: """ Return a RevOptions object. Args: rev: the name of a revision to install. extra_args: a list of extra options. """ return RevOptions(cls, rev, extra_args=extra_args) @classmethod def _is_local_repository(cls, repo: str) -> bool: """ posix absolute paths start with os.path.sep, win32 ones start with drive (like c:\\folder) """ drive, tail = os.path.splitdrive(repo) return repo.startswith(os.path.sep) or bool(drive) @classmethod def get_netloc_and_auth( cls, netloc: str, scheme: str ) -> Tuple[str, Tuple[Optional[str], Optional[str]]]: """ Parse the repository URL's netloc, and return the new netloc to use along with auth information. Args: netloc: the original repository URL netloc. scheme: the repository URL's scheme without the vcs prefix. This is mainly for the Subversion class to override, so that auth information can be provided via the --username and --password options instead of through the URL. For other subclasses like Git without such an option, auth information must stay in the URL. Returns: (netloc, (username, password)). """ return netloc, (None, None) @classmethod def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]: """ Parse the repository URL to use, and return the URL, revision, and auth info to use. Returns: (url, rev, (username, password)). """ scheme, netloc, path, query, frag = urllib.parse.urlsplit(url) if "+" not in scheme: raise ValueError( "Sorry, {!r} is a malformed VCS url. " "The format is +://, " "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp".format(url) ) # Remove the vcs prefix. scheme = scheme.split("+", 1)[1] netloc, user_pass = cls.get_netloc_and_auth(netloc, scheme) rev = None if "@" in path: path, rev = path.rsplit("@", 1) if not rev: raise InstallationError( "The URL {!r} has an empty revision (after @) " "which is not supported. Include a revision after @ " "or remove @ from the URL.".format(url) ) url = urllib.parse.urlunsplit((scheme, netloc, path, query, "")) return url, rev, user_pass @staticmethod def make_rev_args( username: Optional[str], password: Optional[HiddenText] ) -> CommandArgs: """ Return the RevOptions "extra arguments" to use in obtain(). """ return [] def get_url_rev_options(self, url: HiddenText) -> Tuple[HiddenText, RevOptions]: """ Return the URL and RevOptions object to use in obtain(), as a tuple (url, rev_options). """ secret_url, rev, user_pass = self.get_url_rev_and_auth(url.secret) username, secret_password = user_pass password: Optional[HiddenText] = None if secret_password is not None: password = hide_value(secret_password) extra_args = self.make_rev_args(username, password) rev_options = self.make_rev_options(rev, extra_args=extra_args) return hide_url(secret_url), rev_options @staticmethod def normalize_url(url: str) -> str: """ Normalize a URL for comparison by unquoting it and removing any trailing slash. """ return urllib.parse.unquote(url).rstrip("/") @classmethod def compare_urls(cls, url1: str, url2: str) -> bool: """ Compare two repo URLs for identity, ignoring incidental differences. """ return cls.normalize_url(url1) == cls.normalize_url(url2) def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: """ Fetch a revision from a repository, in the case that this is the first fetch from the repository. Args: dest: the directory to fetch the repository to. rev_options: a RevOptions object. """ raise NotImplementedError def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: """ Switch the repo at ``dest`` to point to ``URL``. Args: rev_options: a RevOptions object. """ raise NotImplementedError def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: """ Update an already-existing repo to the given ``rev_options``. Args: rev_options: a RevOptions object. """ raise NotImplementedError @classmethod def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool: """ Return whether the id of the current commit equals the given name. Args: dest: the repository directory. name: a string name. """ raise NotImplementedError def obtain(self, dest: str, url: HiddenText) -> None: """ Install or update in editable mode the package represented by this VersionControl object. :param dest: the repository directory in which to install or update. :param url: the repository URL starting with a vcs prefix. """ url, rev_options = self.get_url_rev_options(url) if not os.path.exists(dest): self.fetch_new(dest, url, rev_options) return rev_display = rev_options.to_display() if self.is_repository_directory(dest): existing_url = self.get_remote_url(dest) if self.compare_urls(existing_url, url.secret): logger.debug( "%s in %s exists, and has correct URL (%s)", self.repo_name.title(), display_path(dest), url, ) if not self.is_commit_id_equal(dest, rev_options.rev): logger.info( "Updating %s %s%s", display_path(dest), self.repo_name, rev_display, ) self.update(dest, url, rev_options) else: logger.info("Skipping because already up-to-date.") return logger.warning( "%s %s in %s exists with URL %s", self.name, self.repo_name, display_path(dest), existing_url, ) prompt = ("(s)witch, (i)gnore, (w)ipe, (b)ackup ", ("s", "i", "w", "b")) else: logger.warning( "Directory %s already exists, and is not a %s %s.", dest, self.name, self.repo_name, ) # https://github.com/python/mypy/issues/1174 prompt = ("(i)gnore, (w)ipe, (b)ackup ", ("i", "w", "b")) # type: ignore logger.warning( "The plan is to install the %s repository %s", self.name, url, ) response = ask_path_exists("What to do? {}".format(prompt[0]), prompt[1]) if response == "a": sys.exit(-1) if response == "w": logger.warning("Deleting %s", display_path(dest)) rmtree(dest) self.fetch_new(dest, url, rev_options) return if response == "b": dest_dir = backup_dir(dest) logger.warning("Backing up %s to %s", display_path(dest), dest_dir) shutil.move(dest, dest_dir) self.fetch_new(dest, url, rev_options) return # Do nothing if the response is "i". if response == "s": logger.info( "Switching %s %s to %s%s", self.repo_name, display_path(dest), url, rev_display, ) self.switch(dest, url, rev_options) def unpack(self, location: str, url: HiddenText) -> None: """ Clean up current location and download the url repository (and vcs infos) into location :param url: the repository URL starting with a vcs prefix. """ if os.path.exists(location): rmtree(location) self.obtain(location, url=url) @classmethod def get_remote_url(cls, location: str) -> str: """ Return the url used at location Raises RemoteNotFoundError if the repository does not have a remote url configured. """ raise NotImplementedError @classmethod def get_revision(cls, location: str) -> str: """ Return the current commit id of the files at the given location. """ raise NotImplementedError @classmethod def run_command( cls, cmd: Union[List[str], CommandArgs], show_stdout: bool = True, cwd: Optional[str] = None, on_returncode: 'Literal["raise", "warn", "ignore"]' = "raise", extra_ok_returncodes: Optional[Iterable[int]] = None, command_desc: Optional[str] = None, extra_environ: Optional[Mapping[str, Any]] = None, spinner: Optional[SpinnerInterface] = None, log_failed_cmd: bool = True, stdout_only: bool = False, ) -> str: """ Run a VCS subcommand This is simply a wrapper around call_subprocess that adds the VCS command name, and checks that the VCS is available """ cmd = make_command(cls.name, *cmd) try: return call_subprocess( cmd, show_stdout, cwd, on_returncode=on_returncode, extra_ok_returncodes=extra_ok_returncodes, command_desc=command_desc, extra_environ=extra_environ, unset_environ=cls.unset_environ, spinner=spinner, log_failed_cmd=log_failed_cmd, stdout_only=stdout_only, ) except FileNotFoundError: # errno.ENOENT = no such file or directory # In other words, the VCS executable isn't available raise BadCommand( f"Cannot find command {cls.name!r} - do you have " f"{cls.name!r} installed and in your PATH?" ) except PermissionError: # errno.EACCES = Permission denied # This error occurs, for instance, when the command is installed # only for another user. So, the current user don't have # permission to call the other user command. raise BadCommand( f"No permission to execute {cls.name!r} - install it " f"locally, globally (ask admin), or check your PATH. " f"See possible solutions at " f"https://pip.pypa.io/en/latest/reference/pip_freeze/" f"#fixing-permission-denied." ) @classmethod def is_repository_directory(cls, path: str) -> bool: """ Return whether a directory path is a repository directory. """ logger.debug("Checking in %s for %s (%s)...", path, cls.dirname, cls.name) return os.path.exists(os.path.join(path, cls.dirname)) @classmethod def get_repository_root(cls, location: str) -> Optional[str]: """ Return the "root" (top-level) directory controlled by the vcs, or `None` if the directory is not in any. It is meant to be overridden to implement smarter detection mechanisms for specific vcs. This can do more than is_repository_directory() alone. For example, the Git override checks that Git is actually available. """ if cls.is_repository_directory(location): return location return None PKH]A@\) ) 4python3.10/site-packages/pip/_internal/vcs/bazaar.pynu[import logging from typing import List, Optional, Tuple from pip._internal.utils.misc import HiddenText, display_path from pip._internal.utils.subprocess import make_command from pip._internal.utils.urls import path_to_url from pip._internal.vcs.versioncontrol import ( AuthInfo, RemoteNotFoundError, RevOptions, VersionControl, vcs, ) logger = logging.getLogger(__name__) class Bazaar(VersionControl): name = "bzr" dirname = ".bzr" repo_name = "branch" schemes = ( "bzr+http", "bzr+https", "bzr+ssh", "bzr+sftp", "bzr+ftp", "bzr+lp", "bzr+file", ) @staticmethod def get_base_rev_args(rev: str) -> List[str]: return ["-r", rev] def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: rev_display = rev_options.to_display() logger.info( "Checking out %s%s to %s", url, rev_display, display_path(dest), ) cmd_args = make_command("branch", "-q", rev_options.to_args(), url, dest) self.run_command(cmd_args) def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: self.run_command(make_command("switch", url), cwd=dest) def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: cmd_args = make_command("pull", "-q", rev_options.to_args()) self.run_command(cmd_args, cwd=dest) @classmethod def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]: # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it url, rev, user_pass = super().get_url_rev_and_auth(url) if url.startswith("ssh://"): url = "bzr+" + url return url, rev, user_pass @classmethod def get_remote_url(cls, location: str) -> str: urls = cls.run_command( ["info"], show_stdout=False, stdout_only=True, cwd=location ) for line in urls.splitlines(): line = line.strip() for x in ("checkout of branch: ", "parent branch: "): if line.startswith(x): repo = line.split(x)[1] if cls._is_local_repository(repo): return path_to_url(repo) return repo raise RemoteNotFoundError @classmethod def get_revision(cls, location: str) -> str: revision = cls.run_command( ["revno"], show_stdout=False, stdout_only=True, cwd=location, ) return revision.splitlines()[-1] @classmethod def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool: """Always assume the versions don't match""" return False vcs.register(Bazaar) PKH]jbL-L-8python3.10/site-packages/pip/_internal/vcs/subversion.pynu[import logging import os import re from typing import List, Optional, Tuple from pip._internal.utils.misc import ( HiddenText, display_path, is_console_interactive, is_installable_dir, split_auth_from_netloc, ) from pip._internal.utils.subprocess import CommandArgs, make_command from pip._internal.vcs.versioncontrol import ( AuthInfo, RemoteNotFoundError, RevOptions, VersionControl, vcs, ) logger = logging.getLogger(__name__) _svn_xml_url_re = re.compile('url="([^"]+)"') _svn_rev_re = re.compile(r'committed-rev="(\d+)"') _svn_info_xml_rev_re = re.compile(r'\s*revision="(\d+)"') _svn_info_xml_url_re = re.compile(r"(.*)") class Subversion(VersionControl): name = "svn" dirname = ".svn" repo_name = "checkout" schemes = ("svn+ssh", "svn+http", "svn+https", "svn+svn", "svn+file") @classmethod def should_add_vcs_url_prefix(cls, remote_url: str) -> bool: return True @staticmethod def get_base_rev_args(rev: str) -> List[str]: return ["-r", rev] @classmethod def get_revision(cls, location: str) -> str: """ Return the maximum revision for all files under a given location """ # Note: taken from setuptools.command.egg_info revision = 0 for base, dirs, _ in os.walk(location): if cls.dirname not in dirs: dirs[:] = [] continue # no sense walking uncontrolled subdirs dirs.remove(cls.dirname) entries_fn = os.path.join(base, cls.dirname, "entries") if not os.path.exists(entries_fn): # FIXME: should we warn? continue dirurl, localrev = cls._get_svn_url_rev(base) if base == location: assert dirurl is not None base = dirurl + "/" # save the root url elif not dirurl or not dirurl.startswith(base): dirs[:] = [] continue # not part of the same svn tree, skip it revision = max(revision, localrev) return str(revision) @classmethod def get_netloc_and_auth( cls, netloc: str, scheme: str ) -> Tuple[str, Tuple[Optional[str], Optional[str]]]: """ This override allows the auth information to be passed to svn via the --username and --password options instead of via the URL. """ if scheme == "ssh": # The --username and --password options can't be used for # svn+ssh URLs, so keep the auth information in the URL. return super().get_netloc_and_auth(netloc, scheme) return split_auth_from_netloc(netloc) @classmethod def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]: # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it url, rev, user_pass = super().get_url_rev_and_auth(url) if url.startswith("ssh://"): url = "svn+" + url return url, rev, user_pass @staticmethod def make_rev_args( username: Optional[str], password: Optional[HiddenText] ) -> CommandArgs: extra_args: CommandArgs = [] if username: extra_args += ["--username", username] if password: extra_args += ["--password", password] return extra_args @classmethod def get_remote_url(cls, location: str) -> str: # In cases where the source is in a subdirectory, we have to look up in # the location until we find a valid project root. orig_location = location while not is_installable_dir(location): last_location = location location = os.path.dirname(location) if location == last_location: # We've traversed up to the root of the filesystem without # finding a Python project. logger.warning( "Could not find Python project for directory %s (tried all " "parent directories)", orig_location, ) raise RemoteNotFoundError url, _rev = cls._get_svn_url_rev(location) if url is None: raise RemoteNotFoundError return url @classmethod def _get_svn_url_rev(cls, location: str) -> Tuple[Optional[str], int]: from pip._internal.exceptions import InstallationError entries_path = os.path.join(location, cls.dirname, "entries") if os.path.exists(entries_path): with open(entries_path) as f: data = f.read() else: # subversion >= 1.7 does not have the 'entries' file data = "" url = None if data.startswith("8") or data.startswith("9") or data.startswith("10"): entries = list(map(str.splitlines, data.split("\n\x0c\n"))) del entries[0][0] # get rid of the '8' url = entries[0][3] revs = [int(d[9]) for d in entries if len(d) > 9 and d[9]] + [0] elif data.startswith("= 1.7 # Note that using get_remote_call_options is not necessary here # because `svn info` is being run against a local directory. # We don't need to worry about making sure interactive mode # is being used to prompt for passwords, because passwords # are only potentially needed for remote server requests. xml = cls.run_command( ["info", "--xml", location], show_stdout=False, stdout_only=True, ) match = _svn_info_xml_url_re.search(xml) assert match is not None url = match.group(1) revs = [int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml)] except InstallationError: url, revs = None, [] if revs: rev = max(revs) else: rev = 0 return url, rev @classmethod def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool: """Always assume the versions don't match""" return False def __init__(self, use_interactive: bool = None) -> None: if use_interactive is None: use_interactive = is_console_interactive() self.use_interactive = use_interactive # This member is used to cache the fetched version of the current # ``svn`` client. # Special value definitions: # None: Not evaluated yet. # Empty tuple: Could not parse version. self._vcs_version: Optional[Tuple[int, ...]] = None super().__init__() def call_vcs_version(self) -> Tuple[int, ...]: """Query the version of the currently installed Subversion client. :return: A tuple containing the parts of the version information or ``()`` if the version returned from ``svn`` could not be parsed. :raises: BadCommand: If ``svn`` is not installed. """ # Example versions: # svn, version 1.10.3 (r1842928) # compiled Feb 25 2019, 14:20:39 on x86_64-apple-darwin17.0.0 # svn, version 1.7.14 (r1542130) # compiled Mar 28 2018, 08:49:13 on x86_64-pc-linux-gnu # svn, version 1.12.0-SlikSvn (SlikSvn/1.12.0) # compiled May 28 2019, 13:44:56 on x86_64-microsoft-windows6.2 version_prefix = "svn, version " version = self.run_command(["--version"], show_stdout=False, stdout_only=True) if not version.startswith(version_prefix): return () version = version[len(version_prefix) :].split()[0] version_list = version.partition("-")[0].split(".") try: parsed_version = tuple(map(int, version_list)) except ValueError: return () return parsed_version def get_vcs_version(self) -> Tuple[int, ...]: """Return the version of the currently installed Subversion client. If the version of the Subversion client has already been queried, a cached value will be used. :return: A tuple containing the parts of the version information or ``()`` if the version returned from ``svn`` could not be parsed. :raises: BadCommand: If ``svn`` is not installed. """ if self._vcs_version is not None: # Use cached version, if available. # If parsing the version failed previously (empty tuple), # do not attempt to parse it again. return self._vcs_version vcs_version = self.call_vcs_version() self._vcs_version = vcs_version return vcs_version def get_remote_call_options(self) -> CommandArgs: """Return options to be used on calls to Subversion that contact the server. These options are applicable for the following ``svn`` subcommands used in this class. - checkout - switch - update :return: A list of command line arguments to pass to ``svn``. """ if not self.use_interactive: # --non-interactive switch is available since Subversion 0.14.4. # Subversion < 1.8 runs in interactive mode by default. return ["--non-interactive"] svn_version = self.get_vcs_version() # By default, Subversion >= 1.8 runs in non-interactive mode if # stdin is not a TTY. Since that is how pip invokes SVN, in # call_subprocess(), pip must pass --force-interactive to ensure # the user can be prompted for a password, if required. # SVN added the --force-interactive option in SVN 1.8. Since # e.g. RHEL/CentOS 7, which is supported until 2024, ships with # SVN 1.7, pip should continue to support SVN 1.7. Therefore, pip # can't safely add the option if the SVN version is < 1.8 (or unknown). if svn_version >= (1, 8): return ["--force-interactive"] return [] def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: rev_display = rev_options.to_display() logger.info( "Checking out %s%s to %s", url, rev_display, display_path(dest), ) cmd_args = make_command( "checkout", "-q", self.get_remote_call_options(), rev_options.to_args(), url, dest, ) self.run_command(cmd_args) def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: cmd_args = make_command( "switch", self.get_remote_call_options(), rev_options.to_args(), url, dest, ) self.run_command(cmd_args) def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: cmd_args = make_command( "update", self.get_remote_call_options(), rev_options.to_args(), dest, ) self.run_command(cmd_args) vcs.register(Subversion) PKH]_EE1python3.10/site-packages/pip/_internal/vcs/git.pynu[import logging import os.path import pathlib import re import urllib.parse import urllib.request from typing import List, Optional, Tuple from pip._internal.exceptions import BadCommand, InstallationError from pip._internal.utils.misc import HiddenText, display_path, hide_url from pip._internal.utils.subprocess import make_command from pip._internal.vcs.versioncontrol import ( AuthInfo, RemoteNotFoundError, RemoteNotValidError, RevOptions, VersionControl, find_path_to_project_root_from_repo_root, vcs, ) urlsplit = urllib.parse.urlsplit urlunsplit = urllib.parse.urlunsplit logger = logging.getLogger(__name__) GIT_VERSION_REGEX = re.compile( r"^git version " # Prefix. r"(\d+)" # Major. r"\.(\d+)" # Dot, minor. r"(?:\.(\d+))?" # Optional dot, patch. r".*$" # Suffix, including any pre- and post-release segments we don't care about. ) HASH_REGEX = re.compile("^[a-fA-F0-9]{40}$") # SCP (Secure copy protocol) shorthand. e.g. 'git@example.com:foo/bar.git' SCP_REGEX = re.compile( r"""^ # Optional user, e.g. 'git@' (\w+@)? # Server, e.g. 'github.com'. ([^/:]+): # The server-side path. e.g. 'user/project.git'. Must start with an # alphanumeric character so as not to be confusable with a Windows paths # like 'C:/foo/bar' or 'C:\foo\bar'. (\w[^:]*) $""", re.VERBOSE, ) def looks_like_hash(sha: str) -> bool: return bool(HASH_REGEX.match(sha)) class Git(VersionControl): name = "git" dirname = ".git" repo_name = "clone" schemes = ( "git+http", "git+https", "git+ssh", "git+git", "git+file", ) # Prevent the user's environment variables from interfering with pip: # https://github.com/pypa/pip/issues/1130 unset_environ = ("GIT_DIR", "GIT_WORK_TREE") default_arg_rev = "HEAD" @staticmethod def get_base_rev_args(rev: str) -> List[str]: return [rev] def is_immutable_rev_checkout(self, url: str, dest: str) -> bool: _, rev_options = self.get_url_rev_options(hide_url(url)) if not rev_options.rev: return False if not self.is_commit_id_equal(dest, rev_options.rev): # the current commit is different from rev, # which means rev was something else than a commit hash return False # return False in the rare case rev is both a commit hash # and a tag or a branch; we don't want to cache in that case # because that branch/tag could point to something else in the future is_tag_or_branch = bool(self.get_revision_sha(dest, rev_options.rev)[0]) return not is_tag_or_branch def get_git_version(self) -> Tuple[int, ...]: version = self.run_command(["version"], show_stdout=False, stdout_only=True) match = GIT_VERSION_REGEX.match(version) if not match: logger.warning("Can't parse git version: %s", version) return () return tuple(int(c) for c in match.groups()) @classmethod def get_current_branch(cls, location: str) -> Optional[str]: """ Return the current branch, or None if HEAD isn't at a branch (e.g. detached HEAD). """ # git-symbolic-ref exits with empty stdout if "HEAD" is a detached # HEAD rather than a symbolic ref. In addition, the -q causes the # command to exit with status code 1 instead of 128 in this case # and to suppress the message to stderr. args = ["symbolic-ref", "-q", "HEAD"] output = cls.run_command( args, extra_ok_returncodes=(1,), show_stdout=False, stdout_only=True, cwd=location, ) ref = output.strip() if ref.startswith("refs/heads/"): return ref[len("refs/heads/") :] return None @classmethod def get_revision_sha(cls, dest: str, rev: str) -> Tuple[Optional[str], bool]: """ Return (sha_or_none, is_branch), where sha_or_none is a commit hash if the revision names a remote branch or tag, otherwise None. Args: dest: the repository directory. rev: the revision name. """ # Pass rev to pre-filter the list. output = cls.run_command( ["show-ref", rev], cwd=dest, show_stdout=False, stdout_only=True, on_returncode="ignore", ) refs = {} # NOTE: We do not use splitlines here since that would split on other # unicode separators, which can be maliciously used to install a # different revision. for line in output.strip().split("\n"): line = line.rstrip("\r") if not line: continue try: ref_sha, ref_name = line.split(" ", maxsplit=2) except ValueError: # Include the offending line to simplify troubleshooting if # this error ever occurs. raise ValueError(f"unexpected show-ref line: {line!r}") refs[ref_name] = ref_sha branch_ref = f"refs/remotes/origin/{rev}" tag_ref = f"refs/tags/{rev}" sha = refs.get(branch_ref) if sha is not None: return (sha, True) sha = refs.get(tag_ref) return (sha, False) @classmethod def _should_fetch(cls, dest: str, rev: str) -> bool: """ Return true if rev is a ref or is a commit that we don't have locally. Branches and tags are not considered in this method because they are assumed to be always available locally (which is a normal outcome of ``git clone`` and ``git fetch --tags``). """ if rev.startswith("refs/"): # Always fetch remote refs. return True if not looks_like_hash(rev): # Git fetch would fail with abbreviated commits. return False if cls.has_commit(dest, rev): # Don't fetch if we have the commit locally. return False return True @classmethod def resolve_revision( cls, dest: str, url: HiddenText, rev_options: RevOptions ) -> RevOptions: """ Resolve a revision to a new RevOptions object with the SHA1 of the branch, tag, or ref if found. Args: rev_options: a RevOptions object. """ rev = rev_options.arg_rev # The arg_rev property's implementation for Git ensures that the # rev return value is always non-None. assert rev is not None sha, is_branch = cls.get_revision_sha(dest, rev) if sha is not None: rev_options = rev_options.make_new(sha) rev_options.branch_name = rev if is_branch else None return rev_options # Do not show a warning for the common case of something that has # the form of a Git commit hash. if not looks_like_hash(rev): logger.warning( "Did not find branch or tag '%s', assuming revision or ref.", rev, ) if not cls._should_fetch(dest, rev): return rev_options # fetch the requested revision cls.run_command( make_command("fetch", "-q", url, rev_options.to_args()), cwd=dest, ) # Change the revision to the SHA of the ref we fetched sha = cls.get_revision(dest, rev="FETCH_HEAD") rev_options = rev_options.make_new(sha) return rev_options @classmethod def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool: """ Return whether the current commit hash equals the given name. Args: dest: the repository directory. name: a string name. """ if not name: # Then avoid an unnecessary subprocess call. return False return cls.get_revision(dest) == name def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: rev_display = rev_options.to_display() logger.info("Cloning %s%s to %s", url, rev_display, display_path(dest)) if self.get_git_version() >= (2, 17): # Git added support for partial clone in 2.17 # https://git-scm.com/docs/partial-clone # Speeds up cloning by functioning without a complete copy of repository self.run_command( make_command( "clone", "--filter=blob:none", "-q", url, dest, ) ) else: self.run_command(make_command("clone", "-q", url, dest)) if rev_options.rev: # Then a specific revision was requested. rev_options = self.resolve_revision(dest, url, rev_options) branch_name = getattr(rev_options, "branch_name", None) logger.debug("Rev options %s, branch_name %s", rev_options, branch_name) if branch_name is None: # Only do a checkout if the current commit id doesn't match # the requested revision. if not self.is_commit_id_equal(dest, rev_options.rev): cmd_args = make_command( "checkout", "-q", rev_options.to_args(), ) self.run_command(cmd_args, cwd=dest) elif self.get_current_branch(dest) != branch_name: # Then a specific branch was requested, and that branch # is not yet checked out. track_branch = f"origin/{branch_name}" cmd_args = [ "checkout", "-b", branch_name, "--track", track_branch, ] self.run_command(cmd_args, cwd=dest) else: sha = self.get_revision(dest) rev_options = rev_options.make_new(sha) logger.info("Resolved %s to commit %s", url, rev_options.rev) #: repo may contain submodules self.update_submodules(dest) def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: self.run_command( make_command("config", "remote.origin.url", url), cwd=dest, ) cmd_args = make_command("checkout", "-q", rev_options.to_args()) self.run_command(cmd_args, cwd=dest) self.update_submodules(dest) def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: # First fetch changes from the default remote if self.get_git_version() >= (1, 9): # fetch tags in addition to everything else self.run_command(["fetch", "-q", "--tags"], cwd=dest) else: self.run_command(["fetch", "-q"], cwd=dest) # Then reset to wanted revision (maybe even origin/master) rev_options = self.resolve_revision(dest, url, rev_options) cmd_args = make_command("reset", "--hard", "-q", rev_options.to_args()) self.run_command(cmd_args, cwd=dest) #: update submodules self.update_submodules(dest) @classmethod def get_remote_url(cls, location: str) -> str: """ Return URL of the first remote encountered. Raises RemoteNotFoundError if the repository does not have a remote url configured. """ # We need to pass 1 for extra_ok_returncodes since the command # exits with return code 1 if there are no matching lines. stdout = cls.run_command( ["config", "--get-regexp", r"remote\..*\.url"], extra_ok_returncodes=(1,), show_stdout=False, stdout_only=True, cwd=location, ) remotes = stdout.splitlines() try: found_remote = remotes[0] except IndexError: raise RemoteNotFoundError for remote in remotes: if remote.startswith("remote.origin.url "): found_remote = remote break url = found_remote.split(" ")[1] return cls._git_remote_to_pip_url(url.strip()) @staticmethod def _git_remote_to_pip_url(url: str) -> str: """ Convert a remote url from what git uses to what pip accepts. There are 3 legal forms **url** may take: 1. A fully qualified url: ssh://git@example.com/foo/bar.git 2. A local project.git folder: /path/to/bare/repository.git 3. SCP shorthand for form 1: git@example.com:foo/bar.git Form 1 is output as-is. Form 2 must be converted to URI and form 3 must be converted to form 1. See the corresponding test test_git_remote_url_to_pip() for examples of sample inputs/outputs. """ if re.match(r"\w+://", url): # This is already valid. Pass it though as-is. return url if os.path.exists(url): # A local bare remote (git clone --mirror). # Needs a file:// prefix. return pathlib.PurePath(url).as_uri() scp_match = SCP_REGEX.match(url) if scp_match: # Add an ssh:// prefix and replace the ':' with a '/'. return scp_match.expand(r"ssh://\1\2/\3") # Otherwise, bail out. raise RemoteNotValidError(url) @classmethod def has_commit(cls, location: str, rev: str) -> bool: """ Check if rev is a commit that is available in the local repository. """ try: cls.run_command( ["rev-parse", "-q", "--verify", "sha^" + rev], cwd=location, log_failed_cmd=False, ) except InstallationError: return False else: return True @classmethod def get_revision(cls, location: str, rev: Optional[str] = None) -> str: if rev is None: rev = "HEAD" current_rev = cls.run_command( ["rev-parse", rev], show_stdout=False, stdout_only=True, cwd=location, ) return current_rev.strip() @classmethod def get_subdirectory(cls, location: str) -> Optional[str]: """ Return the path to Python project root, relative to the repo root. Return None if the project root is in the repo root. """ # find the repo root git_dir = cls.run_command( ["rev-parse", "--git-dir"], show_stdout=False, stdout_only=True, cwd=location, ).strip() if not os.path.isabs(git_dir): git_dir = os.path.join(location, git_dir) repo_root = os.path.abspath(os.path.join(git_dir, "..")) return find_path_to_project_root_from_repo_root(location, repo_root) @classmethod def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]: """ Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. That's required because although they use SSH they sometimes don't work with a ssh:// scheme (e.g. GitHub). But we need a scheme for parsing. Hence we remove it again afterwards and return it as a stub. """ # Works around an apparent Git bug # (see https://article.gmane.org/gmane.comp.version-control.git/146500) scheme, netloc, path, query, fragment = urlsplit(url) if scheme.endswith("file"): initial_slashes = path[: -len(path.lstrip("/"))] newpath = initial_slashes + urllib.request.url2pathname(path).replace( "\\", "/" ).lstrip("/") after_plus = scheme.find("+") + 1 url = scheme[:after_plus] + urlunsplit( (scheme[after_plus:], netloc, newpath, query, fragment), ) if "://" not in url: assert "file:" not in url url = url.replace("git+", "git+ssh://") url, rev, user_pass = super().get_url_rev_and_auth(url) url = url.replace("ssh://", "") else: url, rev, user_pass = super().get_url_rev_and_auth(url) return url, rev, user_pass @classmethod def update_submodules(cls, location: str) -> None: if not os.path.exists(os.path.join(location, ".gitmodules")): return cls.run_command( ["submodule", "update", "--init", "--recursive", "-q"], cwd=location, ) @classmethod def get_repository_root(cls, location: str) -> Optional[str]: loc = super().get_repository_root(location) if loc: return loc try: r = cls.run_command( ["rev-parse", "--show-toplevel"], cwd=location, show_stdout=False, stdout_only=True, on_returncode="raise", log_failed_cmd=False, ) except BadCommand: logger.debug( "could not determine if %s is under git control " "because git is not available", location, ) return None except InstallationError: return None return os.path.normpath(r.rstrip("\r\n")) @staticmethod def should_add_vcs_url_prefix(repo_url: str) -> bool: """In either https or ssh form, requirements must be prefixed with git+.""" return True vcs.register(Git) PKH]/TT6python3.10/site-packages/pip/_internal/vcs/__init__.pynu[# Expose a limited set of classes and functions so callers outside of # the vcs package don't need to import deeper than `pip._internal.vcs`. # (The test directory may still need to import from a vcs sub-package.) # Import all vcs modules to register each VCS in the VcsSupport object. import pip._internal.vcs.bazaar import pip._internal.vcs.git import pip._internal.vcs.mercurial import pip._internal.vcs.subversion # noqa: F401 from pip._internal.vcs.versioncontrol import ( # noqa: F401 RemoteNotFoundError, RemoteNotValidError, is_url, make_vcs_requirement_url, vcs, ) PKH]Za3a37python3.10/site-packages/pip/_internal/configuration.pynu["""Configuration management setup Some terminology: - name As written in config files. - value Value associated with a name - key Name combined with it's section (section.name) - variant A single word describing where the configuration key-value pair came from """ import configparser import locale import os import sys from typing import Any, Dict, Iterable, List, NewType, Optional, Tuple from pip._internal.exceptions import ( ConfigurationError, ConfigurationFileCouldNotBeLoaded, ) from pip._internal.utils import appdirs from pip._internal.utils.compat import WINDOWS from pip._internal.utils.logging import getLogger from pip._internal.utils.misc import ensure_dir, enum RawConfigParser = configparser.RawConfigParser # Shorthand Kind = NewType("Kind", str) CONFIG_BASENAME = "pip.ini" if WINDOWS else "pip.conf" ENV_NAMES_IGNORED = "version", "help" # The kinds of configurations there are. kinds = enum( USER="user", # User Specific GLOBAL="global", # System Wide SITE="site", # [Virtual] Environment Specific ENV="env", # from PIP_CONFIG_FILE ENV_VAR="env-var", # from Environment Variables ) OVERRIDE_ORDER = kinds.GLOBAL, kinds.USER, kinds.SITE, kinds.ENV, kinds.ENV_VAR VALID_LOAD_ONLY = kinds.USER, kinds.GLOBAL, kinds.SITE logger = getLogger(__name__) # NOTE: Maybe use the optionx attribute to normalize keynames. def _normalize_name(name: str) -> str: """Make a name consistent regardless of source (environment or file)""" name = name.lower().replace("_", "-") if name.startswith("--"): name = name[2:] # only prefer long opts return name def _disassemble_key(name: str) -> List[str]: if "." not in name: error_message = ( "Key does not contain dot separated section and key. " "Perhaps you wanted to use 'global.{}' instead?" ).format(name) raise ConfigurationError(error_message) return name.split(".", 1) def get_configuration_files() -> Dict[Kind, List[str]]: global_config_files = [ os.path.join(path, CONFIG_BASENAME) for path in appdirs.site_config_dirs("pip") ] site_config_file = os.path.join(sys.prefix, CONFIG_BASENAME) legacy_config_file = os.path.join( os.path.expanduser("~"), "pip" if WINDOWS else ".pip", CONFIG_BASENAME, ) new_config_file = os.path.join(appdirs.user_config_dir("pip"), CONFIG_BASENAME) return { kinds.GLOBAL: global_config_files, kinds.SITE: [site_config_file], kinds.USER: [legacy_config_file, new_config_file], } class Configuration: """Handles management of configuration. Provides an interface to accessing and managing configuration files. This class converts provides an API that takes "section.key-name" style keys and stores the value associated with it as "key-name" under the section "section". This allows for a clean interface wherein the both the section and the key-name are preserved in an easy to manage form in the configuration files and the data stored is also nice. """ def __init__(self, isolated: bool, load_only: Optional[Kind] = None) -> None: super().__init__() if load_only is not None and load_only not in VALID_LOAD_ONLY: raise ConfigurationError( "Got invalid value for load_only - should be one of {}".format( ", ".join(map(repr, VALID_LOAD_ONLY)) ) ) self.isolated = isolated self.load_only = load_only # Because we keep track of where we got the data from self._parsers: Dict[Kind, List[Tuple[str, RawConfigParser]]] = { variant: [] for variant in OVERRIDE_ORDER } self._config: Dict[Kind, Dict[str, Any]] = { variant: {} for variant in OVERRIDE_ORDER } self._modified_parsers: List[Tuple[str, RawConfigParser]] = [] def load(self) -> None: """Loads configuration from configuration files and environment""" self._load_config_files() if not self.isolated: self._load_environment_vars() def get_file_to_edit(self) -> Optional[str]: """Returns the file with highest priority in configuration""" assert self.load_only is not None, "Need to be specified a file to be editing" try: return self._get_parser_to_modify()[0] except IndexError: return None def items(self) -> Iterable[Tuple[str, Any]]: """Returns key-value pairs like dict.items() representing the loaded configuration """ return self._dictionary.items() def get_value(self, key: str) -> Any: """Get a value from the configuration.""" try: return self._dictionary[key] except KeyError: raise ConfigurationError(f"No such key - {key}") def set_value(self, key: str, value: Any) -> None: """Modify a value in the configuration.""" self._ensure_have_load_only() assert self.load_only fname, parser = self._get_parser_to_modify() if parser is not None: section, name = _disassemble_key(key) # Modify the parser and the configuration if not parser.has_section(section): parser.add_section(section) parser.set(section, name, value) self._config[self.load_only][key] = value self._mark_as_modified(fname, parser) def unset_value(self, key: str) -> None: """Unset a value in the configuration.""" self._ensure_have_load_only() assert self.load_only if key not in self._config[self.load_only]: raise ConfigurationError(f"No such key - {key}") fname, parser = self._get_parser_to_modify() if parser is not None: section, name = _disassemble_key(key) if not ( parser.has_section(section) and parser.remove_option(section, name) ): # The option was not removed. raise ConfigurationError( "Fatal Internal error [id=1]. Please report as a bug." ) # The section may be empty after the option was removed. if not parser.items(section): parser.remove_section(section) self._mark_as_modified(fname, parser) del self._config[self.load_only][key] def save(self) -> None: """Save the current in-memory state.""" self._ensure_have_load_only() for fname, parser in self._modified_parsers: logger.info("Writing to %s", fname) # Ensure directory exists. ensure_dir(os.path.dirname(fname)) with open(fname, "w") as f: parser.write(f) # # Private routines # def _ensure_have_load_only(self) -> None: if self.load_only is None: raise ConfigurationError("Needed a specific file to be modifying.") logger.debug("Will be working with %s variant only", self.load_only) @property def _dictionary(self) -> Dict[str, Any]: """A dictionary representing the loaded configuration.""" # NOTE: Dictionaries are not populated if not loaded. So, conditionals # are not needed here. retval = {} for variant in OVERRIDE_ORDER: retval.update(self._config[variant]) return retval def _load_config_files(self) -> None: """Loads configuration from configuration files""" config_files = dict(self.iter_config_files()) if config_files[kinds.ENV][0:1] == [os.devnull]: logger.debug( "Skipping loading configuration files due to " "environment's PIP_CONFIG_FILE being os.devnull" ) return for variant, files in config_files.items(): for fname in files: # If there's specific variant set in `load_only`, load only # that variant, not the others. if self.load_only is not None and variant != self.load_only: logger.debug("Skipping file '%s' (variant: %s)", fname, variant) continue parser = self._load_file(variant, fname) # Keeping track of the parsers used self._parsers[variant].append((fname, parser)) def _load_file(self, variant: Kind, fname: str) -> RawConfigParser: logger.verbose("For variant '%s', will try loading '%s'", variant, fname) parser = self._construct_parser(fname) for section in parser.sections(): items = parser.items(section) self._config[variant].update(self._normalized_keys(section, items)) return parser def _construct_parser(self, fname: str) -> RawConfigParser: parser = configparser.RawConfigParser() # If there is no such file, don't bother reading it but create the # parser anyway, to hold the data. # Doing this is useful when modifying and saving files, where we don't # need to construct a parser. if os.path.exists(fname): try: parser.read(fname) except UnicodeDecodeError: # See https://github.com/pypa/pip/issues/4963 raise ConfigurationFileCouldNotBeLoaded( reason="contains invalid {} characters".format( locale.getpreferredencoding(False) ), fname=fname, ) except configparser.Error as error: # See https://github.com/pypa/pip/issues/4893 raise ConfigurationFileCouldNotBeLoaded(error=error) return parser def _load_environment_vars(self) -> None: """Loads configuration from environment variables""" self._config[kinds.ENV_VAR].update( self._normalized_keys(":env:", self.get_environ_vars()) ) def _normalized_keys( self, section: str, items: Iterable[Tuple[str, Any]] ) -> Dict[str, Any]: """Normalizes items to construct a dictionary with normalized keys. This routine is where the names become keys and are made the same regardless of source - configuration files or environment. """ normalized = {} for name, val in items: key = section + "." + _normalize_name(name) normalized[key] = val return normalized def get_environ_vars(self) -> Iterable[Tuple[str, str]]: """Returns a generator with all environmental vars with prefix PIP_""" for key, val in os.environ.items(): if key.startswith("PIP_"): name = key[4:].lower() if name not in ENV_NAMES_IGNORED: yield name, val # XXX: This is patched in the tests. def iter_config_files(self) -> Iterable[Tuple[Kind, List[str]]]: """Yields variant and configuration files associated with it. This should be treated like items of a dictionary. """ # SMELL: Move the conditions out of this function # environment variables have the lowest priority config_file = os.environ.get("PIP_CONFIG_FILE", None) if config_file is not None: yield kinds.ENV, [config_file] else: yield kinds.ENV, [] config_files = get_configuration_files() # at the base we have any global configuration yield kinds.GLOBAL, config_files[kinds.GLOBAL] # per-user configuration next should_load_user_config = not self.isolated and not ( config_file and os.path.exists(config_file) ) if should_load_user_config: # The legacy config file is overridden by the new config file yield kinds.USER, config_files[kinds.USER] # finally virtualenv configuration first trumping others yield kinds.SITE, config_files[kinds.SITE] def get_values_in_config(self, variant: Kind) -> Dict[str, Any]: """Get values present in a config file""" return self._config[variant] def _get_parser_to_modify(self) -> Tuple[str, RawConfigParser]: # Determine which parser to modify assert self.load_only parsers = self._parsers[self.load_only] if not parsers: # This should not happen if everything works correctly. raise ConfigurationError( "Fatal Internal error [id=2]. Please report as a bug." ) # Use the highest priority parser. return parsers[-1] # XXX: This is patched in the tests. def _mark_as_modified(self, fname: str, parser: RawConfigParser) -> None: file_parser_tuple = (fname, parser) if file_parser_tuple not in self._modified_parsers: self._modified_parsers.append(file_parser_tuple) def __repr__(self) -> str: return f"{self.__class__.__name__}({self._dictionary!r})" PKH]ɓ - -7python3.10/site-packages/pip/_internal/utils/logging.pynu[import contextlib import errno import logging import logging.handlers import os import sys from logging import Filter from typing import IO, Any, Callable, Iterator, Optional, TextIO, Type, cast from pip._internal.utils._log import VERBOSE, getLogger from pip._internal.utils.compat import WINDOWS from pip._internal.utils.deprecation import DEPRECATION_MSG_PREFIX from pip._internal.utils.misc import ensure_dir try: import threading except ImportError: import dummy_threading as threading # type: ignore try: from pip._vendor import colorama # Lots of different errors can come from this, including SystemError and # ImportError. except Exception: colorama = None _log_state = threading.local() subprocess_logger = getLogger("pip.subprocessor") class BrokenStdoutLoggingError(Exception): """ Raised if BrokenPipeError occurs for the stdout stream while logging. """ def _is_broken_pipe_error(exc_class: Type[BaseException], exc: BaseException) -> bool: if exc_class is BrokenPipeError: return True # On Windows, a broken pipe can show up as EINVAL rather than EPIPE: # https://bugs.python.org/issue19612 # https://bugs.python.org/issue30418 if not WINDOWS: return False return isinstance(exc, OSError) and exc.errno in (errno.EINVAL, errno.EPIPE) @contextlib.contextmanager def indent_log(num: int = 2) -> Iterator[None]: """ A context manager which will cause the log output to be indented for any log messages emitted inside it. """ # For thread-safety _log_state.indentation = get_indentation() _log_state.indentation += num try: yield finally: _log_state.indentation -= num def get_indentation() -> int: return getattr(_log_state, "indentation", 0) class IndentingFormatter(logging.Formatter): default_time_format = "%Y-%m-%dT%H:%M:%S" def __init__( self, *args: Any, add_timestamp: bool = False, **kwargs: Any, ) -> None: """ A logging.Formatter that obeys the indent_log() context manager. :param add_timestamp: A bool indicating output lines should be prefixed with their record's timestamp. """ self.add_timestamp = add_timestamp super().__init__(*args, **kwargs) def get_message_start(self, formatted: str, levelno: int) -> str: """ Return the start of the formatted log message (not counting the prefix to add to each line). """ if levelno < logging.WARNING: return "" if formatted.startswith(DEPRECATION_MSG_PREFIX): # Then the message already has a prefix. We don't want it to # look like "WARNING: DEPRECATION: ...." return "" if levelno < logging.ERROR: return "WARNING: " return "ERROR: " def format(self, record: logging.LogRecord) -> str: """ Calls the standard formatter, but will indent all of the log message lines by our current indentation level. """ formatted = super().format(record) message_start = self.get_message_start(formatted, record.levelno) formatted = message_start + formatted prefix = "" if self.add_timestamp: prefix = f"{self.formatTime(record)} " prefix += " " * get_indentation() formatted = "".join([prefix + line for line in formatted.splitlines(True)]) return formatted def _color_wrap(*colors: str) -> Callable[[str], str]: def wrapped(inp: str) -> str: return "".join(list(colors) + [inp, colorama.Style.RESET_ALL]) return wrapped class ColorizedStreamHandler(logging.StreamHandler): # Don't build up a list of colors if we don't have colorama if colorama: COLORS = [ # This needs to be in order from highest logging level to lowest. (logging.ERROR, _color_wrap(colorama.Fore.RED)), (logging.WARNING, _color_wrap(colorama.Fore.YELLOW)), ] else: COLORS = [] def __init__(self, stream: Optional[TextIO] = None, no_color: bool = None) -> None: super().__init__(stream) self._no_color = no_color if WINDOWS and colorama: self.stream = colorama.AnsiToWin32(self.stream) def _using_stdout(self) -> bool: """ Return whether the handler is using sys.stdout. """ if WINDOWS and colorama: # Then self.stream is an AnsiToWin32 object. stream = cast(colorama.AnsiToWin32, self.stream) return stream.wrapped is sys.stdout return self.stream is sys.stdout def should_color(self) -> bool: # Don't colorize things if we do not have colorama or if told not to if not colorama or self._no_color: return False real_stream = ( self.stream if not isinstance(self.stream, colorama.AnsiToWin32) else self.stream.wrapped ) # If the stream is a tty we should color it if hasattr(real_stream, "isatty") and real_stream.isatty(): return True # If we have an ANSI term we should color it if os.environ.get("TERM") == "ANSI": return True # If anything else we should not color it return False def format(self, record: logging.LogRecord) -> str: msg = super().format(record) if self.should_color(): for level, color in self.COLORS: if record.levelno >= level: msg = color(msg) break return msg # The logging module says handleError() can be customized. def handleError(self, record: logging.LogRecord) -> None: exc_class, exc = sys.exc_info()[:2] # If a broken pipe occurred while calling write() or flush() on the # stdout stream in logging's Handler.emit(), then raise our special # exception so we can handle it in main() instead of logging the # broken pipe error and continuing. if ( exc_class and exc and self._using_stdout() and _is_broken_pipe_error(exc_class, exc) ): raise BrokenStdoutLoggingError() return super().handleError(record) class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler): def _open(self) -> IO[Any]: ensure_dir(os.path.dirname(self.baseFilename)) return super()._open() class MaxLevelFilter(Filter): def __init__(self, level: int) -> None: self.level = level def filter(self, record: logging.LogRecord) -> bool: return record.levelno < self.level class ExcludeLoggerFilter(Filter): """ A logging Filter that excludes records from a logger (or its children). """ def filter(self, record: logging.LogRecord) -> bool: # The base Filter class allows only records from a logger (or its # children). return not super().filter(record) def setup_logging(verbosity: int, no_color: bool, user_log_file: Optional[str]) -> int: """Configures and sets up all of the logging Returns the requested logging level, as its integer value. """ # Determine the level to be logging at. if verbosity >= 2: level_number = logging.DEBUG elif verbosity == 1: level_number = VERBOSE elif verbosity == -1: level_number = logging.WARNING elif verbosity == -2: level_number = logging.ERROR elif verbosity <= -3: level_number = logging.CRITICAL else: level_number = logging.INFO level = logging.getLevelName(level_number) # The "root" logger should match the "console" level *unless* we also need # to log to a user log file. include_user_log = user_log_file is not None if include_user_log: additional_log_file = user_log_file root_level = "DEBUG" else: additional_log_file = "/dev/null" root_level = level # Disable any logging besides WARNING unless we have DEBUG level logging # enabled for vendored libraries. vendored_log_level = "WARNING" if level in ["INFO", "ERROR"] else "DEBUG" # Shorthands for clarity log_streams = { "stdout": "ext://sys.stdout", "stderr": "ext://sys.stderr", } handler_classes = { "stream": "pip._internal.utils.logging.ColorizedStreamHandler", "file": "pip._internal.utils.logging.BetterRotatingFileHandler", } handlers = ["console", "console_errors", "console_subprocess"] + ( ["user_log"] if include_user_log else [] ) logging.config.dictConfig( { "version": 1, "disable_existing_loggers": False, "filters": { "exclude_warnings": { "()": "pip._internal.utils.logging.MaxLevelFilter", "level": logging.WARNING, }, "restrict_to_subprocess": { "()": "logging.Filter", "name": subprocess_logger.name, }, "exclude_subprocess": { "()": "pip._internal.utils.logging.ExcludeLoggerFilter", "name": subprocess_logger.name, }, }, "formatters": { "indent": { "()": IndentingFormatter, "format": "%(message)s", }, "indent_with_timestamp": { "()": IndentingFormatter, "format": "%(message)s", "add_timestamp": True, }, }, "handlers": { "console": { "level": level, "class": handler_classes["stream"], "no_color": no_color, "stream": log_streams["stdout"], "filters": ["exclude_subprocess", "exclude_warnings"], "formatter": "indent", }, "console_errors": { "level": "WARNING", "class": handler_classes["stream"], "no_color": no_color, "stream": log_streams["stderr"], "filters": ["exclude_subprocess"], "formatter": "indent", }, # A handler responsible for logging to the console messages # from the "subprocessor" logger. "console_subprocess": { "level": level, "class": handler_classes["stream"], "no_color": no_color, "stream": log_streams["stderr"], "filters": ["restrict_to_subprocess"], "formatter": "indent", }, "user_log": { "level": "DEBUG", "class": handler_classes["file"], "filename": additional_log_file, "encoding": "utf-8", "delay": True, "formatter": "indent_with_timestamp", }, }, "root": { "level": root_level, "handlers": handlers, }, "loggers": {"pip._vendor": {"level": vendored_log_level}}, } ) return level_number PKH]#0hhVpython3.10/site-packages/pip/_internal/utils/__pycache__/pkg_resources.cpython-310.pycnu[o ai@s2ddlmZmZmZddlmZGdddZdS))DictIterableList) yield_linesc@seZdZdZdeeefddfddZdedefdd Z dedefd d Z dede efd d Z dedefddZ dedeefddZdededdfddZdS) DictMetadataz>IMetadataProvider that reads metadata files from a dictionary.metadatareturnNcCs ||_dSN _metadata)selfrr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/pkg_resources.py__init__  zDictMetadata.__init__namecCs ||jvSr r r rr r r has_metadata rzDictMetadata.has_metadatac CsBz|j|WSty }z |jd|d7_d}~ww)Nz in z file)r decodeUnicodeDecodeErrorreason)r rer r r get_metadataszDictMetadata.get_metadatacCst||Sr )rrrr r rget_metadata_linesszDictMetadata.get_metadata_linescCsdS)NFr rr r rmetadata_isdirzDictMetadata.metadata_isdircCsgSr r rr r rmetadata_listdirrzDictMetadata.metadata_listdir script_name namespacecCsdSr r )r rrr r r run_script rzDictMetadata.run_script)__name__ __module__ __qualname____doc__rstrbytesrboolrrrrrrrrr r r rrsrN)typingrrrpip._vendor.pkg_resourcesrrr r r rs PKH]nI Ypython3.10/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-310.pycnu[o aiY@sPddlZddlmZmZmZdZ   d!dedeededed eef d d Zdedeed eed ed eef ddZ dedeed eefddZ dedeedeededeedeeded eefddZ dedeeded eefddZ dedeedeededeedeedeedeedededed eefdd Z dS)"N)ListOptionalSequencea'import io, os, sys, setuptools, tokenize; sys.argv[0] = {0!r}; __file__={0!r};f = getattr(tokenize, 'open', open)(__file__) if os.path.exists(__file__) else io.StringIO('from setuptools import setup; setup()');code = f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))F setup_py_pathglobal_optionsno_user_configunbuffered_outputreturncCsFtjg}|r |dg7}|dt|g7}|r||7}|r!|dg7}|S)ao Get setuptools command arguments with shim wrapped setup file invocation. :param setup_py_path: The path to setup.py to be wrapped. :param global_options: Additional global options. :param no_user_config: If True, disables personal user configuration. :param unbuffered_output: If True, adds the unbuffered switch to the argument list. z-uz-cz --no-user-cfg)sys executable_SETUPTOOLS_SHIMformat)rrrrargsr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/setuptools_build.pymake_setuptools_shim_argss  r build_optionsdestination_dircCs(t||dd}|dd|g7}||7}|S)NTrr bdist_wheelz-dr)rrrrrrrr make_setuptools_bdist_wheel_args/s  rcCst||dd}|ddg7}|S)NTrcleanz--allr)rrrrrrmake_setuptools_clean_argsAs  rinstall_optionsprefixhome use_user_sitecCsf|r|rJt|||d}|ddg7}||7}|r|d|g7}|dur)|d|g7}|r1|ddg7}|S)N)rrdevelopz --no-deps--prefixz --install-dir--user --prefix=r)rrrrrrrrrrrmake_setuptools_develop_argsLs     r" egg_info_dircCs*t||d}|dg7}|r|d|g7}|S)N)regg_infoz --egg-baser)rr#rrrrrmake_setuptools_egg_info_argsls   r%record_filenameroot header_dir pycompilec Cs|r|rJ|r |r Jt||| dd} | dd|g7} | dg7} |dur*| d|g7} |dur4| d|g7} |dur>| d|g7} |rF| d d g7} | rN| d g7} n| d g7} |r[| d |g7} | |7} | S)NT)rrrinstallz--recordz#--single-version-externally-managedz--rootrz--homer r!z --compilez --no-compilez--install-headersr) rrrr&r'rr(rrrr)rrrrmake_setuptools_install_args{s2         r+)NFF)r typingrrrr strboolrrrr"r%r+rrrrs             PKH]*Qpython3.10/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-310.pycnu[o ai@sddlZddlZddlZddlmZddlmZmZddlm Z m Z ddgZ de de fd d Z de dee fd dZde dee fd dZdS) N)Optional) site_packages user_site)running_under_virtualenvvirtualenv_no_globalegg_link_path_from_sys_pathegg_link_path_from_locationraw_namereturncCstdd|dS)z Convert a Name metadata value to a .egg-link name, by applying the same substitution as pkg_resources's safe_name function. Note: we cannot use canonicalize_name because it has a different logic. z[^A-Za-z0-9.]+-z .egg-link)resub)r r/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/egg_link.py_egg_link_namesrcCs:t|}tjD]}tj||}tj|r|SqdS)zJ Look for a .egg-link file for project name, by walking sys.path. N)rsyspathosjoinisfile)r egg_link_name path_itemegg_linkrrrrs  cCszg}tr|ttstr|tn tr|t|tt|}|D]}tj||}tj |r:|Sq'dS)a Return the path for the .egg-link file if it exists, otherwise, None. There's 3 scenarios: 1) not in a virtualenv try to find in site.USER_SITE, then site_packages 2) in a no-global virtualenv try to find in site_packages 3) in a yes-global virtualenv try to find in site_packages, then site.USER_SITE (don't look in global location) For #1 and #3, there could be odd cases, where there's an egg-link in 2 locations. This method will just return the first one found. N) rappendrrrrrrrr)r sitesrsiteegglinkrrrr*s       )rr rtypingrpip._internal.locationsrrpip._internal.utils.virtualenvrr__all__strrrrrrrrs   PKH]E..Qpython3.10/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-310.pycnu[o ai@s*dZddlZdedededefddZdS) z.For when pip wants to check the date or time. NyearmonthdayreturncCs tj}t|||}||kS)N)datetimedatetoday)rrrrgivenr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/datetime.pytoday_is_later_thans r )__doc__rintboolr r r r r sPKH]"2 Qpython3.10/site-packages/pip/_internal/utils/__pycache__/parallel.cpython-310.pycnu[o ai| @svdZddgZddlmZddlmZddlmZddlmZ ddl m Z m Z m Z mZmZddlmZeejej fZed Zed Zzdd lZWn eySd ZYnwd ZdZedede efddZ dde egefde edede efddZ dde egefde edede efddZ dde egefde edede efddZereZZd SeZeZd S)abConvenient parallelization of higher order functions. This module provides two helper functions, with appropriate fallbacks on Python 2 and on systems lacking support for synchronization mechanisms: - map_multiprocess - map_multithread These helpers work like Python 3's map, with two differences: - They don't guarantee the order of processing of the elements of the iterable. - The underlying process/thread pools chop the iterable into a number of chunks, so that for very long iterables using a large value for chunksize can make the job complete much faster than using the default value of 1. map_multiprocessmap_multithread)contextmanager)Poolpool)CallableIterableIteratorTypeVarUnion)DEFAULT_POOLSIZESTNTFirreturnccsBz|VW|||dS|||w)z>Return a context manager making sure the pool closes properly.N)closejoin terminaterr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/parallel.pyclosing.s  rfunciterable chunksizecCs t||S)zMake an iterator applying func to each element in iterable. This function is the sequential fallback either on Python 2 where Pool.imap* doesn't react to KeyboardInterrupt or when sem_open is unavailable. )map)rrrrrr _map_fallback;s rcCs<tt}||||WdS1swYdS)zChop iterable into chunks and submit them to a process pool. For very long iterables using a large value for chunksize can make the job complete much faster than using the default value of 1. Return an unordered iterator of the results. N)r ProcessPoolimap_unorderedrrrrrrr_map_multiprocessGs $r cCs>ttt}||||WdS1swYdS)zChop iterable into chunks and submit them to a thread pool. For very long iterables using a large value for chunksize can make the job complete much faster than using the default value of 1. Return an unordered iterator of the results. N)r ThreadPoolr rrrrr_map_multithreadUs $r")r)__doc____all__ contextlibrmultiprocessingrrrZmultiprocessing.dummyr!typingrr r r r Zpip._vendor.requests.adaptersr rrZmultiprocessing.synchronize ImportErrorZ LACK_SEM_OPENTIMEOUTrintrr r"rrrrrrsl                PKH]ϛ vvWpython3.10/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-310.pycnu[o ai@sZddlmZddlmZddlmZmZgdZeeZdee dee e ffddZ d S) )DistutilsArgError) FancyGetopt)DictList) )z exec-prefix=N)zhome=Nr)z install-base=Nr)z install-data=Nr)zinstall-headers=Nr)z install-lib=Nr)zinstall-platlib=Nr)zinstall-purelib=Nr)zinstall-scripts=Nr)zprefix=Nr)zroot=Nr)userNrargsreturnc CsHi}|D]}z tj|gd\}}Wn tyYqw||jq|S)z~Parse provided arguments, returning an object that has the matched arguments. Any unknown arguments are ignored. )r)_distutils_getoptgetoptrupdate__dict__)rresultarg_matchr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/distutils_args.pyparse_distutils_argss rN) distutils.errorsrdistutils.fancy_getoptrtypingrr_optionsr strrrrrrs "PKH]ަQSpython3.10/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-310.pycnu[o aiJ'@sddlZddlZddlZddlZddlmZmZmZmZm Z m Z m Z m Z ddl mZmZddlmZddlmZmZddlmZerHddlmZe e eefZdZd e eeefd efd d Zd e e eefd efd dZd e e eefd e efddZde e eefde ede eded ef ddZ          d+de e eefde de eddde eede ed e e eefd!e eed"e ed#e e d$e e d efd%d&Z!d'ed ed(fd)d*Z"dS),N) TYPE_CHECKINGAnyCallableIterableListMappingOptionalUnion)SpinnerInterface open_spinner)InstallationSubprocessError)VERBOSEsubprocess_logger) HiddenText)Literalz(----------------------------------------argsreturncGs2g}|D]}t|tr||q||q|S)z& Create a CommandArgs object. ) isinstancelistextendappend)r command_argsargr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/subprocess.py make_command!s    rcCsddd|DS)z/ Format command arguments for display.  css2|]}t|trtt|nt|VqdS)N)rrshlexquotestr.0rrrr ;s  z&format_command_args..)joinrrrrformat_command_args2s r%cCsdd|DS)z= Return the arguments in their raw, unredacted form. cSs g|] }t|tr |jn|qSr)rrsecretr rrr Es z'reveal_command_args..rr$rrrreveal_command_argsAsr(cmd_argscwdlines exit_statuscCs0t|}d|}dj|||t||td}|S)z Create and return the error message to use to log a subprocess error with command output. :param lines: A list of lines, each ending with a newline. zCommand errored out with exit status {exit_status}: command: {command_display} cwd: {cwd_display} Complete output ({line_count} lines): {output}{divider})r,command_display cwd_display line_countoutputdivider)r%r#formatlen LOG_DIVIDER)r)r*r+r,commandr1msgrrrmake_subprocess_output_errorHs r8FraiseTcmd show_stdout on_returncodez"Literal["raise", "warn", "ignore"]extra_ok_returncodes command_desc extra_environ unset_environspinnerlog_failed_cmd stdout_onlyc  Cs|durg}|dur g}|rtj} tj} ntj} t} t| k} | o&|du}|dur/t|}| d|tj }|r@| ||D]}| |dqBzt jt|t jt j| sZt jnt j||dd}Wntyy}z | rttd||d}~wwg}| s|jsJ|jsJ|j |j}|sn|}||d| ||r|sJ|qz|W|jr|jn |jr|jwwd|}n(|\}}|D]}| |q|||D]}| |q|||}|jo|j|v}|r|sJ|r| d n| d |rV|d kr7| s1| r1t!||||jd }t"|t#|j||d krGt$d||j||S|dkrO |St%d||S)a Args: show_stdout: if true, use INFO to log the subprocess's stderr and stdout streams. Otherwise, use DEBUG. Defaults to False. extra_ok_returncodes: an iterable of integer return codes that are acceptable, in addition to 0. Defaults to None, which means []. unset_environ: an iterable of environment variable names to unset prior to calling subprocess.Popen(). log_failed_cmd: if false, failed commands are not logged, only raised. stdout_only: if true, return only stdout, else return both. When true, logging of both stdout and stderr occurs when the subprocess has terminated, else logging occurs as subprocess output is produced. NzRunning command %sbackslashreplace)stdinstdoutstderrr*enverrorsz#Error %s while executing command %sT r-errordoner9)r)r*r+r,warnz$Command "%s" had error code %s in %signorezInvalid value: on_returncode=)&rinfologgingINFOverboser getEffectiveLevelr%osenvironcopyupdatepop subprocessPopenr(PIPESTDOUT ExceptioncriticalrFrEclosereadlinerstriprspinwaitr# communicate splitlines returncodefinishr8rKr warning ValueError)r:r;r*r<r=r>r?r@rArBrClog_subprocess used_levelshowing_subprocess use_spinnerrHnameprocexc all_outputliner1outerrout_lineerr_lineproc_had_errorr7rrrcall_subprocessks                              rxmessage).Nc s<  ddttdttdttttfddffdd }|S) zProvide a subprocess_runner that shows a spinner message. Intended for use with for pep517's Pep517HookCaller. Thus, the runner has an API that matches what's expected by Pep517HookCaller.subprocess_runner. Nr:r*r?rcs>t}t||||dWddS1swYdS)N)r*r?rA)r rx)r:r*r?rAryrrrunners "z+runner_with_spinner_message..runner)NN)rrrrr)ryr{rrzrrunner_with_spinner_message s  r|) FNr9NNNNNTF)#rPrTrrYtypingrrrrrrrr pip._internal.cli.spinnersr r pip._internal.exceptionsr pip._internal.utils.loggingr rpip._internal.utils.miscrrr CommandArgsr5rr%r(intr8boolrxr|rrrrs(   " %      #PKH]JCײNpython3.10/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-310.pycnu[o ai& @spddlZddlZddlmZmZdeefddZdeefddZdeefdd Zdeeeffd d Z dS) N)OptionalTuplereturncCs tptS)z9Returns glibc version string, or None if not using glibc.)glibc_version_string_confstrglibc_version_string_ctypesrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/glibc.pyglibc_version_string s r c CsBtjdkrdSz td\}}W|Stttfy YdSw)z@Primary implementation of glibc_version_string using os.confstr.win32NCS_GNU_LIBC_VERSION)sysplatformosconfstrsplitAttributeErrorOSError ValueError)_versionrrrrs rcCsrzddl}Wn tyYdSw|d}z|j}Wn ty%YdSw|j|_|}t|ts7| d}|S)z=Fallback implementation of glibc_version_string using ctypes.rNascii) ctypes ImportErrorCDLLgnu_get_libc_versionrc_char_prestype isinstancestrdecode)rprocess_namespacer version_strrrrrs        rcCst}|dur dSd|fS)zTry to determine the glibc version Returns a tuple of strings (lib, version) which default to empty strings in case the lookup fails. N)r"glibc)r ) glibc_versionrrrlibc_verNsr%) rr typingrrrr rrr%rrrrs/PKH]R2SSSpython3.10/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-310.pycnu[o ai@sddlZddlZddlZddlZddlZddlZddlZddlmZddl m Z ddl m Z m Z mZmZmZmZddlmZmZmZddlmZddlmZded efd d Zd ed ed dfddZded efddZedede d ee fddZedededdZ e ej!Z!ded efddZ"ded efddZ#deded eefddZ$ded ee%e&ffd d!Z'ded efd"d#Z(ded ee%e&ffd$d%Z)ded efd&d'Z*dS)(N)contextmanager)NamedTemporaryFile)AnyBinaryIOIteratorListUnioncast)retrystop_after_delay wait_fixed) get_path_uid) format_sizepathreturncCstjdks ttds dStj|sJd}||krNtj|rAtdkr:z t|}W|dkSt y9YdSwt |tj S|tj |}}||ksdS)Nwin32geteuidTrF) sysplatformhasattrosrisabslexistsrr OSErroraccessW_OKdirname)rpreviouspath_uidr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/filesystem.pycheck_path_owners"    r!srcdestc Cshz t||WdSty3||fD]}zt|}Wn ty%Yqw|r1td|dqw)zWrap shutil.copy2() but map errors copying socket files to SpecialFileError as expected. See also https://bugs.python.org/issue37700. `z ` is a socketN)shutilcopy2r is_socketSpecialFileError)r"r#fis_socket_filerrr copy2_fixed-s    r+cCstt|jSN)statS_ISSOCKrlstatst_moderrrr r'Dsr'kwargsc kstddtj|tj|dd|+}tt|}z|VW|t| n |t| wWddS1sCwYdS)a%Return a file-like object pointing to a tmp file next to path. The file is created securely and is ensured to be written to disk after the context reaches its end. kwargs will be passed to tempfile.NamedTemporaryFile to control the way the temporary file will be opened. Fz.tmp)deletedirprefixsuffixNr) rrrrbasenamer rflushfsyncfileno)rr2r)resultrrr adjacent_tmp_fileHs$    "r<Tg?)reraisestopwaitcCsRtj|stj|}||krn|}tj|rtjdkr%t|tjSt|S)zgCheck if a directory is writable. Uses os.access() on POSIX, tries creating files on Windows. posix)rrisdirrnamerr_test_writable_dir_win)rparentrrr test_writable_diris   rFc sd}dtdD]H}|dfddtdD}tj||}zt|tjtjBtjB}Wnty9Yqt yCYdSwt |t |d St d ) N(accesstest_deleteme_fishfingers_custard_$abcdefghijklmnopqrstuvwxyz0123456789 c3s|]}tVqdSr,)randomchoice).0_alphabetrr sz)_test_writable_dir_win..FTz3Unexpected condition testing for writable directory) rangejoinrropenO_RDWRO_CREATO_EXCLFileExistsErrorPermissionErrorcloseunlinkr)rr7rNrCfilefdrrOr rD{s       rDpatterncsBg}t|D]\}}t||}|fdd|Dq|S)zReturns a list of absolute paths of files beneath path, recursively, with filenames which match the UNIX-style shell glob pattern.c3s|] }tj|VqdSr,)rrrT)rMr)rootrr rQszfind_files..)rwalkfnmatchfilterextend)rr_r;rNfilesmatchesrr`r find_filess  rhcCstj|rdStj|S)Nr)rrislinkgetsizer1rrr file_sizes  rkcC tt|Sr,)rrkr1rrr format_file_size rmcCsBd}t|D]\}}}|D]}tj||}|t|7}qq|S)Ng)rrbrrTrk)rsizera_dirsrffilename file_pathrrr directory_sizesrscCrlr,)rrsr1rrr format_directory_sizernrt)+rcros.pathrKr%r-r contextlibrtempfilertypingrrrrrr pip._vendor.tenacityr r r pip._internal.utils.compatr pip._internal.utils.miscrstrboolr!r+r'r<_replace_retryreplacerFrDrhintfloatrkrmrsrtrrrr s6        PKH]}}Ppython3.10/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-310.pycnu[o ai@sdZddlZddlZddlmZddlmZdedefddZ dded e defd d Z dded e defd dZ dedeefddZ dS)z This code wraps the vendored appdirs module to so the return values are compatible for the current pip code base. The intention is to rewrite current usages gradually, keeping the tests pass, and eventually drop this after all usages are changed. N)List) platformdirsappnamereturncCstj|ddS)NF) appauthor)_appdirsuser_cache_dir)rr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/appdirs.pyrsrTroamingcCsBtj|d|d}tj|r|Sd}|rtj||}tj|S)NFrr z ~/.config/)r user_data_dirospathisdirjoin expanduser)rr rlinux_like_pathr r r _macos_user_config_dirs  rcCs$tjdkr t||Stj|d|dS)NdarwinFr )sysplatformrruser_config_dir)rr r r r r"s  rcCsNtjdkrtj|dddgStj|ddd}tjdkr|gS|tjdgS)NrFT)r multipathwin32z/etc)rrr site_data_dirsite_config_dirsplitrpathsep)rdirvalr r r site_config_dirs+s  r )T)__doc__rrtypingr pip._vendorrrstrrboolrrr r r r r s   PKH]bMpython3.10/site-packages/pip/_internal/utils/__pycache__/_log.cpython-310.pycnu[o ai@sRdZddlZddlmZmZdZGdddejZdedefd d Z d d d Z dS)zCustomize logging Defines custom logger class for the `logger.verbose(...)` method. init_logging() must be called before any other modules that call logging.getLogger. N)Anycastc@s*eZdZdZdedededdfddZdS) VerboseLoggerzXCustom Logger, defining a verbose log-level VERBOSE is between INFO and DEBUG. msgargskwargsreturnNcOs|jt|g|Ri|S)N)logVERBOSE)selfrrrr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/_log.pyverboseszVerboseLogger.verbose)__name__ __module__ __qualname____doc__strrrr r r rrsrnamer cCsttt|S)zBlogging.getLogger, but ensures our VerboseLogger class is returned)rrlogging getLogger)rr r rrsrcCsttttddS)zRegister our VerboseLogger and VERBOSE log level. Should be called before any calls to getLogger(), i.e. in pip._internal.__init__ r N)rsetLoggerClassr addLevelNamer r r r r init_loggings r)r N) rrtypingrrr Loggerrrrrr r r rs PKH]DDQpython3.10/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-310.pycnu[o ai@sUddlZddlZddlZddlZddlmZmZejdfejdfej dfej dfej dfej dfej d fgZeeeefed <ed Zd ed efddZdS)N)ListTuplezutf-8zutf-16z utf-16-bez utf-16-lezutf-32z utf-32-bez utf-32-leBOMSscoding[:=]\s*([-\w.]+)datareturncCstD]\}}||r|t|d|Sq|dddD]*}|dddkrLt|rLt|}|duss  PKH]S {Opython3.10/site-packages/pip/_internal/utils/__pycache__/models.cpython-310.pycnu[o ai@s2dZddlZddlmZmZmZGdddZdS)zUtilities for defining models N)AnyCallableTypec@seZdZdZddgZdededddfdd Zdefd d Z d ede fd dZ d ede fddZ d ede fddZ d ede fddZd ede fddZd edeeege fde fddZdS)KeyBasedCompareMixinz7Provides comparison capabilities that is based on a key _compare_key_defining_classkeydefining_classreturnNcCs||_||_dSN)rr)selfrr r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/models.py__init__ s zKeyBasedCompareMixin.__init__cCs t|jSr )hashr)r r r r__hash__s zKeyBasedCompareMixin.__hash__othercC||tjSr )_compareoperator__lt__r rr r rrzKeyBasedCompareMixin.__lt__cCrr )rr__le__rr r rrrzKeyBasedCompareMixin.__le__cCrr )rr__gt__rr r rrrzKeyBasedCompareMixin.__gt__cCrr )rr__ge__rr r rrrzKeyBasedCompareMixin.__ge__cCrr )rr__eq__rr r rr rzKeyBasedCompareMixin.__eq__methodcCst||jstS||j|jSr ) isinstancerNotImplementedr)r rrr r rr#s zKeyBasedCompareMixin._compare)__name__ __module__ __qualname____doc__ __slots__rrrintrboolrrrrrrrr r r rrs&r)r#rtypingrrrrr r r rsPKH]>V;  Tpython3.10/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-310.pycnu[o ai+@sUdZddlZddlZddlmZmZmZmZmZddl m Z ddl m Z dZGdddeZdaeed <  dd eeefd eed ed edeedeeddfddZdddZddddedeedeedeedeeddf ddZdS)zN A module that implements tooling to enable easy warnings about deprecations. N)AnyOptionalTextIOTypeUnion)parse) __version__z DEPRECATION: c@s eZdZdS)PipDeprecationWarningN)__name__ __module__ __qualname__r r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/deprecation.pyr sr _original_showwarningmessagecategoryfilenamelinenofilelinereturncCsb|durtdurt||||||dSdSt|tr&td}||dSt||||||dS)Nzpip._internal.deprecations)r issubclassr logging getLoggerwarning)rrrrrrloggerr r r _showwarnings  rcCs,tjdtddtdurtjatt_dSdS)NdefaultT)append)warnings simplefilterr r showwarningrr r r rinstall_warning_logger,s  r") feature_flagissuereason replacementgone_inr#r$cCs|duo ttt|k}|tdf||sdndf|df||s!dndf|dfg}dd d |D}|r8t|tj|td d dS) aHelper to deprecate existing functionality. reason: Textual reason shown to the user about why this functionality has been deprecated. Should be a complete sentence. replacement: Textual suggestion shown to the user about what alternative functionality they can use. gone_in: The version of pip does this functionality should get removed in. Raises an error if pip's current version is greater than or equal to this. feature_flag: Command-line flag of the form --use-feature={feature_flag} for testing upcoming functionality. issue: Issue number on the tracker that would serve as a useful place for users to find related discussion and provide feedback. Nz{}z*pip {} will enforce this behaviour change.z*Since pip {}, this is no longer supported.zA possible replacement is {}.zEYou can use the flag --use-feature={} to test the upcoming behaviour.z@Discussion can be found at https://github.com/pypa/pip/issues/{} css.|]\}}|dur|dur||VqdS)N)format).0value format_strr r r nszdeprecated..)r stacklevel)rcurrent_versionDEPRECATION_MSG_PREFIXjoinr rwarn)r%r&r'r#r$is_gone message_partsrr r r deprecated7s2  r6)NN)rN)__doc__rrtypingrrrrrZpip._vendor.packaging.versionrpiprr0r1Warningr r__annotations__strintrr"r6r r r rsT      PKH]=3lQpython3.10/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-310.pycnu[o ai@sdS)Nrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/__init__.pysPKH]vsz-IndentingFormatter.format..T) r.formatr:r4r+ formatTimer$join splitlines)r0r;r3 message_startr1r?rrBis zIndentingFormatter.format)rrrdefault_time_formatrboolr/strintr:r6 LogRecordrB __classcell__rrr1rr*Gs r*colorscsdtdtffdd }|S)Ninprcsdt|tjjgS)Nr5)rDlistrStyle RESET_ALL)rNrMrrwrapped{sz_color_wrap..wrapped)rI)rMrSrrRr _color_wrapzsrTcseZdZerejeejjfej eejj fgZ ngZ dde e deddffdd ZdefddZdefd d Zd ejdeffd d Zd ejddffdd ZZS)ColorizedStreamHandlerNstreamno_colorrcs4t|||_trtrt|j|_dSdSdSN)r.r/ _no_colorr r AnsiToWin32rV)r0rVrWr1rrr/s zColorizedStreamHandler.__init__cCs.trtrttj|j}|jtjuS|jtjuS)zA Return whether the handler is using sys.stdout. )r rr rZrVrSsysstdout)r0rVrrr _using_stdouts  z$ColorizedStreamHandler._using_stdoutcCsXtr|jrdSt|jtjs|jn|jj}t|dr |r dStj ddkr*dSdS)NFisattyTTERMANSI) rrYrrVrZrShasattrr^osenvironget)r0 real_streamrrr should_colors  z#ColorizedStreamHandler.should_colorr;cs@t|}|r|jD]\}}|j|kr||}|Sq |SrX)r.rBrfCOLORSr4)r0r;msglevelcolorr1rrrBs  zColorizedStreamHandler.formatcs@tdd\}}|r|r|rt||rtt|S)Nr")r[exc_infor]r!rr. handleError)r0r;rrr1rrrls z"ColorizedStreamHandler.handleError)NN)rrrrr6r9rTForeREDr7YELLOWrgrrrHr/r]rfrKrIrBrlrLrrr1rrUs   rUcs&eZdZdeeffdd ZZS)BetterRotatingFileHandlerrcsttj|jtSrX)rrbpathdirname baseFilenamer._open)r0r1rrrts zBetterRotatingFileHandler._open)rrrrrrtrLrrr1rrpsrpc@s2eZdZdeddfddZdejdefddZdS) MaxLevelFilterrirNcCs ||_dSrX)ri)r0rirrrr/s zMaxLevelFilter.__init__r;cCs |j|jkSrX)r4rir0r;rrrfilterr)zMaxLevelFilter.filter) rrrrJr/r6rKrHrwrrrrrusrucs,eZdZdZdejdeffdd ZZS)ExcludeLoggerFilterzQ A logging Filter that excludes records from a logger (or its children). r;rcst| SrX)r.rwrvr1rrrwszExcludeLoggerFilter.filter) rrrrr6rKrHrwrLrrr1rrxs rx verbosityrW user_log_filec Cs~|dkrtj}n"|dkrt}n|dkrtj}n|dkrtj}n |dkr'tj}ntj}t|}|du}|r:|}d}nd}|}|d vrDd nd}d d d } ddd} gd|rXdgng} tj dddtjddt j ddt j ddt ddt dddd|| d|| d d!d"gd#d$d | d|| d%d!gd#d$|| d|| d%d&gd#d$d| d'|d(dd)d*d+|| d,d-d.|iid/|S)0znConfigures and sets up all of the logging Returns the requested logging level, as its integer value. r"NDEBUGz /dev/null)INFOr9r7zext://sys.stdoutzext://sys.stderr)r\stderrz2pip._internal.utils.logging.ColorizedStreamHandlerz5pip._internal.utils.logging.BetterRotatingFileHandler)rVfile)consoleconsole_errorsconsole_subprocessuser_logFz*pip._internal.utils.logging.MaxLevelFilter)()rizlogging.Filter)rnamez/pip._internal.utils.logging.ExcludeLoggerFilter)exclude_warningsrestrict_to_subprocessexclude_subprocessz %(message)s)rrBT)rrBr+)indentindent_with_timestamprVr\rrr)riclassrWrVfilters formatterrrrzutf-8r)rirfilenameencodingdelayr)rrrr)rihandlersz pip._vendorri)versiondisable_existing_loggersr formattersrrootloggers) r6rr r7r9CRITICALr getLevelNameconfig dictConfigsubprocess_loggerrr*) ryrWrz level_numberriinclude_user_logadditional_log_file root_levelvendored_log_level log_streamshandler_classesrrrr setup_loggings      % Ir)r")6 contextlibrr6logging.handlersrbr[rtypingrrrrrrr r Zpip._internal.utils._logr r pip._internal.utils.compatr pip._internal.utils.deprecationrpip._internal.utils.miscr threading ImportErrorZdummy_threading pip._vendorr Exceptionlocalr%rr BaseExceptionrHr!contextmanagerrJr'r$ Formatterr*rIrT StreamHandlerrUrRotatingFileHandlerrprurxrrrrrsH (        3Q" PKH]Qpython3.10/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-310.pycnu[o ai@sUddlZddlZddlZddlZddlZddlmZmZddl m Z m Z m Z m Z mZmZddlmZmZeeZedddZedd d d Zdae eed <ed e dfddZGdddZdae eed<ed e efddZGdddZeZGdddZ Gddde Z!dS)N) ExitStackcontextmanager)AnyDictIteratorOptionalTypeVarUnion)enumrmtree_T TempDirectory)boundz build-envzephem-wheel-cachez req-build) BUILD_ENVEPHEM_WHEEL_CACHE REQ_BUILD_tempdir_managerreturnccsNt}t|}azdVW|an|awWddS1s wYdSN)rr)stackold_tempdir_managerr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/temp_dir.pyglobal_tempdir_managers "rc@sBeZdZdZd ddZdededdfdd Zdedefd d ZdS) TempDirectoryTypeRegistryzManages temp directory behaviorrNcCs i|_dSr_should_deleteselfrrr__init__*s z"TempDirectoryTypeRegistry.__init__kindvaluecCs||j|<dS)z[Indicate whether a TempDirectory of the given kind should be auto-deleted. Nr)rr r!rrr set_delete-z$TempDirectoryTypeRegistry.set_deletecCs|j|dS)z^Get configured auto-delete flag for a given TempDirectory type, default True. T)rget)rr rrr get_delete3r#z$TempDirectoryTypeRegistry.get_deleterN) __name__ __module__ __qualname____doc__rstrboolr"r%rrrrr's  r_tempdir_registryccs$t}taztVW|adS|aw)zuProvides a scoped global tempdir registry that can be used to dictate whether directories should be deleted. N)r-r)old_tempdir_registryrrrtempdir_registry=s r/c@s eZdZdS)_DefaultN)r'r(r)rrrrr0Ksr0c seZdZdZdeddfdeedeede fdedeffd d Z e d efd d Z d efddZ ded efddZdededed dfddZded efddZdddZZS)r aMHelper class that owns and cleans up a temporary directory. This class can be used as a context manager or as an OO representation of a temporary directory. Attributes: path Location to the created temporary directory delete Whether the directory should be deleted when exiting (when used as a contextmanager) Methods: cleanup() Deletes the temporary directory When used as a context manager, if the delete attribute is True, on exiting the context the temporary directory is deleted. NtempFpathdeleter globally_managedcspt|tur|durd}nd}|dur||}||_d|_||_||_|r6tdus/Jt |dSdS)NF) superr_default_create_path_deletedr3r r enter_context)rr2r3r r4 __class__rrrgs   zTempDirectory.__init__rcCs|jr Jd|j|jS)Nz"Attempted to access deleted path: )r9r8rrrrr2szTempDirectory.pathcCsd|jjd|jdS)N< >)r<r'r2rrrr__repr__szTempDirectory.__repr__rcCs|Srrrrrr __enter__szTempDirectory.__enter__excr!tbcCs<|jdur |j}n trt|j}nd}|r|dSdS)NT)r3r-r%r cleanup)rrBr!rCr3rrr__exit__s  zTempDirectory.__exit__cCs,tjtjd|dd}td||S)zs4      ^PKH];sjRRMpython3.10/site-packages/pip/_internal/utils/__pycache__/misc.cpython-310.pycnu[o ai*Q @s~ddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddlm Z ddlmZmZmZddlmZddlmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!ddl"m#Z#ddl$m%Z%m&Z&m'Z'ddl(m)Z)dd l*m+Z+dd l,m-Z-m.Z.m/Z/dd l,m0Z0dd l1m2Z2dd l3m4Z4ddl5m6Z6gdZ7e8e9Z:e dZ;eee<ee>e>fZ?ee@eee@ee@ffZAde@fddZBdee>dfdee>e>e>ffddZCde@ddfddZDde@fddZEe%de&de'dd dd"e@d#eFddfd$d%ZGd&edefde@d'e=ddfd(d)ZHde@de@fd*d+ZIdd"e@d-e@de@fd.d/ZJd0e@d1ee@de@fd2d3ZKd0e@ddfd4d5ZLd0e@d1ee@de@fd6d7ZMd0e@de@fd8d9ZNd0e@de@fd:d;ZOdfd=d>ZPd?eQde@fd@dAZRdBeeedeee@ee>ffdCdDZSde@deFfdEdFZTejUfdGedHe>deeVfdIdJZWdde@dKeFde@fdLdMZXde@dee@e@ffdNdOZYdPe@dQe@ddfdRdSZZde@deFfdTdUZ[dVe#deFfdWdXZ\dVe#deFfdYdZZ]dVe#deFfd[d\Z^d]d^Z_d_e@dee#fd`daZ`dVe#de@fdbdcZaddedeeddfdfdgZbGdhdidie Zcejddje@deecfdkdlZedeecfdmdnZfdeecfdodpZgdqedredeefdsdtZhdue@dvee>de@fdwdxZiddze@d{e@de@fd|d}Zjdze@dee@ee>ffd~dZkdze@deAfddZldze@de@fddZmde@dee@geedffdee@eAffddZndze@deAfddZodze@dee@fddZpde@dee@e@ee@e@fffddZqde@de@fddZrde@de@fddZsGdddZtde@detfddZude@detfddZvdeFddfddZwdeFfddZxdde@de>deee>ffddZydeFfddZzdeedeeeeffddZ{dee;geFfdee;deee;ee;ffddZ|dS)N)StringIO) filterfalsetee zip_longest) TracebackType) AnyBinaryIOCallableContextManagerIterableIteratorListOptionalTextIOTupleTypeTypeVarcast Distribution)retrystop_after_delay wait_fixed) __version__) CommandError)get_major_minor_version site_packages user_site) get_scheme)WINDOWS)egg_link_path_from_location)running_under_virtualenv) rmtree display_path backup_dirasksplitext format_sizeis_installable_dirnormalize_pathrenamesget_progcaptured_stdout ensure_dirremove_auth_from_urlTreturncCs4tjtjtdd}tj|}dt|tS)Nz..zpip {} from {} (python {})) ospathjoindirname__file__abspathformatrr) pip_pkg_dirr9/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/misc.pyget_pip_versionGs r;py_version_info.cCsDt|dkr|dt|d7}n t|dkr|dd}td|S)ax Convert a tuple of ints representing a Python version to one of length three. :param py_version_info: a tuple of ints representing a Python version, or None to specify no version. The tuple can have any length. :return: a tuple of length three if `py_version_info` is non-None. Otherwise, return `py_version_info` unchanged (i.e. None). )rN VersionInfo)lenr)r<r9r9r:normalize_version_infoRs    r@r2c Cs`zt|WdSty/}z|jtjkr|jtjkr$WYd}~dSWYd}~dSd}~ww)z os.path.makedirs without EEXIST.N)r1makedirsOSErrorerrnoEEXIST ENOTEMPTY)r2er9r9r:r-esr-c CsJztjtjd}|dvrtjdWS|WStttfy$YdSw)Nr)z __main__.pyz-cz -m pippip) r1r2basenamesysargv executableAttributeError TypeError IndexError)progr9r9r:r+osr+Tr=g?)reraisestopwaitFdir ignore_errorscCstj||tddS)N)rTonerror)shutilr"rmtree_errorhandler)rSrTr9r9r:r"}r"funcexc_infocCsNz t|jtj@ }Wn tyYdSw|r&t|tj||dS)zOn Windows, the files in .svn are read-only, so when rmtree() tries to remove them, an exception is thrown. We catch that here, remove the read-only attribute, and hopefully continue without problems.N)r1statst_modeS_IWRITErBchmod)rYr2rZhas_attr_readonlyr9r9r:rWs rWcCsFtjtj|}|ttjjr!d|ttd}|S)zTGives the display value for a given path, making it relative to cwd if possible..N)r1r2normcaser6 startswithgetcwdsepr?r2r9r9r:r#sr#.bakextcCsDd}|}tj||r|d7}|t|}tj||s ||S)z\Figure out the name of a directory to back up the given dir to (adding .bak, .bak2, etc))r1r2existsstr)rSrgn extensionr9r9r:r$s r$messageoptionscCs2tjddD] }||vr|Sq t||S)NPIP_EXISTS_ACTION)r1environgetsplitr%)rmrnactionr9r9r:ask_path_existss  rucCstjdr td|dS)z&Raise an error if no input is allowed. PIP_NO_INPUTz5No input was expected ($PIP_NO_INPUT set); question: N)r1rqrr Exceptionrmr9r9r:_check_no_inputs rycCsD t|t|}|}||vrtd|d|n|Sq)z@Ask the message interactively, with the given possible responsesrhz>Your response ({!r}) was not one of the expected responses: {}z, )ryinputstriplowerprintr7r3)rmrnresponser9r9r:r%s r%cCst|t|S)zAsk for input interactively.)ryrzrxr9r9r: ask_inputsrcCst|t|S)z!Ask for a password interactively.)rygetpassrxr9r9r: ask_passwords rvalcCs.|}|dvr dS|dvrdStd|)zConvert a string representation of truth to true (1) or false (0). True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if 'val' is anything else. )yyesttrueon1rh)rknoffalseoff0rzinvalid truth value )r| ValueError)rr9r9r: strtobools rbytescCsX|dkr d|ddS|dkrdt|dS|dkr%d|dSdt|S) Ni@Bz {:.1f} MBg@@ii'z{} kBz {:.1f} kBz{} bytes)r7int)rr9r9r:r'sr'rowscs@dd|D}ddt|ddiDfdd|D}|fS)zReturn a list of formatted rows and a list of column sizes. For example:: >>> tabulate([['foobar', 2000], [0xdeadbeef]]) (['foobar 2000', '3735928559'], [10, 4]) cSg|] }ttt|qSr9)tuplemaprj.0rowr9r9r: ztabulate..cSrr9)maxrr?)rcolr9r9r:rr fillvaluerpcs$g|]}dttj|qS) )r3rrjljustrstriprsizesr9r:rs$)r)rtabler9rr:tabulatesrcCsHtj|sdStjtj|drdStjtj|dr"dSdS)atIs path is a directory containing pyproject.toml or setup.py? If pyproject.toml exists, this is a PEP 517 project. Otherwise we look for a legacy setuptools layout by identifying setup.py. We don't check for the setup.cfg because using it without setup.py is only available for PEP 517 projects, which are already covered by the pyproject.toml check. Fzpyproject.tomlTzsetup.py)r1r2isdirisfiler3rer9r9r:r(s r(filesizeccs ||}|s dS|Vq)z7Yield pieces of data from a file-like object until EOF.TN)read)rrchunkr9r9r: read_chunkss rresolve_symlinkscCs6tj|}|rtj|}ntj|}tj|S)zN Convert a path to its canonical, case-normalized, absolute version. )r1r2 expanduserrealpathr6ra)r2rr9r9r:r)s   r)cCs@t|\}}|dr|dd|}|dd}||fS)z,Like os.path.splitext, but take off .tar tooz.tarN) posixpathr&r|endswith)r2basergr9r9r:r&$s  r&oldnewcCstj|\}}|r|rtj|st|t||tj|\}}|r<|r>zt|WdSty;YdSwdSdS)z7Like os.renames(), but handles renaming across devices.N) r1r2rsrirArVmove removedirsrB)rrheadtailr9r9r:r*-s   r*cCstsdS|ttjS)z Return True if path is within sys.prefix, if we're running in a virtualenv. If we're not in a virtualenv, all paths are considered "local." Caution: this function assumes the head of path has been normalized with normalize_path. T)r!rbr)rIprefixrer9r9r:is_local>s rdistcCs tt|S)z Return True if given Distribution object is installed locally (i.e. within current virtualenv). Always True if we're not in a virtualenv. )r dist_locationrr9r9r: dist_is_localLs rcCt|ttS)zF Return True if given Distribution is installed in user site. )rrbr)rrr9r9r:dist_in_usersiteWsrcCr)z[ Return True if given Distribution is installed in sysconfig.get_python_lib(). )rrbr)rrr9r9r:dist_in_site_packages^srcCs*tt|}|ttdjddS)zf Return True if given Distribution is installed in path matching distutils_scheme layout. rppythonr)r)rrbrpurelibrs)r norm_pathr9r9r:dist_in_install_pathfs rreq_namecCs<ddlm}ddlm}||}|durdSt||jS)a%Given a requirement name, return the installed Distribution object. This searches from *all* distributions available in the environment, to match the behavior of ``pkg_resources.get_distribution()``. Left for compatibility until direct pkg_resources uses are refactored out. r)get_default_environmentrN)pip._internal.metadatar$pip._internal.metadata.pkg_resourcesrget_distributionr_dist)rr_Distrr9r9r:rps    rcCs t|j}|r t|St|jS)aO Get the site-packages location of this distribution. Generally this is dist.location, except in the case of develop-installed packages, where dist.location is the source code location, and we want to know where the egg-link file is. The returned location is normalized (in particular, with symlinks removed). )r project_namer)location)regg_linkr9r9r:rs  rmsgargscGstj|g|RdSN)loggerinfo)rrr9r9r: write_outputsrc@s<eZdZUdZeed<ededdfddZeddZ dS) StreamWrapperN orig_streamr0cCs ||_|Sr)r)clsrr9r9r: from_streamszStreamWrapper.from_streamcCs|jjSr)rencodingselfr9r9r:rszStreamWrapper.encoding) __name__ __module__ __qualname__rr__annotations__ classmethodrpropertyrr9r9r9r:rs r stream_namec csLtt|}tt|t|ztt|VWtt||dStt||w)zReturn a context manager used by captured_stdout/stdin/stderr that temporarily replaces the sys stream *stream_name* with a StringIO. Taken from Lib/support/__init__.py in the CPython repo. N)getattrrIsetattrrr)r orig_stdoutr9r9r:captured_outputs  rcCtdS)zCapture the output of sys.stdout: with captured_stdout() as stdout: print('hello') self.assertEqual(stdout.getvalue(), 'hello ') Taken from Lib/support/__init__.py in the CPython repo. stdoutrr9r9r9r:r,s r,cCr)z See captured_stdout(). stderrrr9r9r9r:captured_stderrsr sequentialnamedcOsDtt|tt|fi|}dd|D}||d<tdd|S)NcSsi|]\}}||qSr9r9)rkeyvaluer9r9r: szenum..reverse_mappingEnumr9)dictzipranger?itemstype)rrenumsreverser9r9r:enums rhostportcCs.|dur|Sd|vrd|d}|d|S)z. Build a netloc from a host-port pair N:[]r9)rrr9r9r: build_netlocs  rhttpsnetlocschemecCs8|ddkrd|vrd|vrd|d}|d|S)z) Build a full URL from a netloc. r@rrz://)count)rrr9r9r:build_url_from_netlocs rcCs t|}tj|}|j|jfS)z2 Return the host-port pair from a netloc. )rurllibparseurlparsehostnamer)rurlparsedr9r9r: parse_netlocs  rcCstd|vr|dfS|dd\}}d}d|vr|dd\}}n|d}}tj|}|dur4tj|}|||ffS)zp Parse out and remove the auth information from a netloc. Returns: (netloc, (username, password)). r)NNrhNr)rsplitrsr r unquote)rauthpwuserr9r9r:split_auth_from_netlocs    rcCsNt|\}\}}|dur|S|durd}d}ntj|}d}dj|||dS)z Replace the sensitive data in a netloc with "****", if it exists. For example: - "user:pass@example.com" returns "user:****@example.com" - "accesstoken@example.com" returns "****@example.com" N****rpz:****z{user}{password}@{netloc})rpasswordr)rr r quoter7)rrrr9r9r: redact_netloc s rr transform_netloccCsJtj|}||j}|j|d|j|j|jf}tj|}|t d|fS)aRTransform and replace netloc in a url. transform_netloc is a function taking the netloc and returning a tuple. The first element of this tuple is the new netloc. The entire tuple is returned. Returns a tuple containing the transformed url as item 0 and the original tuple returned by transform_netloc as item 1. r NetlocTuple) r r urlsplitrrr2queryfragment urlunsplitr)r rpurl netloc_tuple url_piecessurlr9r9r:_transform_urls  r$cCst|Sr)rrr9r9r: _get_netloc3sr&cCs t|fSr)rr%r9r9r:_redact_netloc7s r'cCst|t\}\}}|||fS)z Parse a url into separate netloc, auth, and url with no auth. Returns: (url_without_auth, netloc, (username, password)) r$r&)r url_without_authrrr9r9r:split_auth_netloc_from_url;s r*cCt|tdS)z7Return a copy of url with 'username:password@' removed.rr(r r9r9r:r.Esr.cCr+)z.Replace the password in a given url with ****.r)r$r'r,r9r9r:redact_auth_from_urlLsr-c@sPeZdZdededdfddZdefddZdefd d Zd edefd d Z dS) HiddenTextsecretredactedr0NcCs||_||_dSr)r/r0)rr/r0r9r9r:__init__Rs zHiddenText.__init__cCsdt|S)Nz)r7rjrr9r9r:__repr__VszHiddenText.__repr__cCs|jSrr0rr9r9r:__str__YszHiddenText.__str__othercCs t|t|kr dS|j|jkS)NF)rr/)rr5r9r9r:__eq__]s zHiddenText.__eq__) rrrrjr1r2r4rboolr6r9r9r9r:r.Qs r.rcCs t|ddS)Nrr3)r.)rr9r9r: hide_valuefs r8cCst|}t||dS)Nr3)r-r.)r r0r9r9r:hide_urljs r9 modifying_pipcCszddtjddjtjddg}|o!to!tjtjd|v}|r;tjddgtjd d}t d d |dS) zProtection of pip.exe from modification on Windows On Windows, any operation modifying pip should be run as: python -m pip ... zpip.exez pip{}.exerz pip{}.{}.exeNrz-mrGrhz3To modify pip, please run the following command: {}r) r7rI version_inforr1r2rHrJrKrr3)r: pip_namesshould_show_use_python_msg new_commandr9r9r:(protect_pip_from_modification_on_windowsosr?cCstjduo tjS)zIs this console interactive?N)rIstdinisattyr9r9r9r:is_console_interactiverXrB blocksizecCslt}d}t|d}t||dD] }|t|7}||qWd||fS1s-wY||fS)z5Return (hash, length) for path using hashlib.sha256()rrb)rN)hashlibsha256openrr?update)r2rDhlengthrblockr9r9r: hash_files    rMcCs$zddl}WdStyYdSw)z8 Return whether the wheel package is installed. rNFT)wheel ImportError)rNr9r9r:is_wheel_installeds   rPiterablecCst|}t||S)zb Return paired elements. For example: s -> (s0, s1), (s2, s3), (s4, s5), ... )iterr)rQr9r9r:pairwises rSpredcCs t|\}}t||t||fS)z Use a predicate to partition entries into false entries and true entries, like partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 )rrfilter)rTrQt1t2r9r9r: partitions rX)F)rf)T)r)rC)} contextlibrCrrFiologgingr1rrVr[rI urllib.parser r itertoolsrrrtypesrtypingrrr r r r r rrrrrrpip._vendor.pkg_resourcesrpip._vendor.tenacityrrrrGrpip._internal.exceptionsrpip._internal.locationsrrrrpip._internal.utils.compatrpip._internal.utils.egg_linkr pip._internal.utils.virtualenvr!__all__ getLoggerrrr/ BaseExceptionExcInforr>rjrr;r@r-r+r7r"rWr#r$ruryr%rrrfloatr'rr(DEFAULT_BUFFER_SIZErrr)r&r*rrrrrrrrrcontextmanagerrr,rrrrrrrr$r&r'r*r.r-r.r8r9r?rBrMrPrSrXr9r9r9r:s  <        $  "  *             $   "  PKH]X_python3.10/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-310.pycnu[o ai@s dZddlZdddZedS)a-A helper module that injects SecureTransport, on import. The import should be done as early as possible, to ensure all requests and sessions (or whatever) are created after injecting SecureTransport. Note that we only do the injection on macOS, when the linked OpenSSL is too old to handle TLSv1.2. Nreturnc CsttjdkrdSzddl}Wn tyYdSw|jdkrdSzddlm}Wn ttfy3YdSw|dS)Ndarwinri)securetransport) sysplatformssl ImportErrorOPENSSL_VERSION_NUMBERpip._vendor.urllib3.contribrOSErrorinject_into_urllib3)rrr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/inject_securetransport.pyinject_securetransport s     r)rN)__doc__rrr r r rs  PKH]_m''Rpython3.10/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-310.pycnu[o ai" @sdZddlZddlZddlZddlZddlZddlZddlmZm Z m Z ddlm Z ddl m Z ddlmZmZmZmZddlmZeeZeeZz ddlZee7ZWneycedYnwz ddlZee7ZWney|ed Ynwd efd d Zd ed e efddZ deed e!fddZ"deded e!fddZ#d ed dfddZ$de d e!fddZ%d'dedede!d dfd d!Z&deded dfd"d#Z' d(deded$e ed dfd%d&Z(dS))zUtilities related archives. N)IterableListOptional)ZipInfo)InstallationError)BZ2_EXTENSIONSTAR_EXTENSIONS XZ_EXTENSIONSZIP_EXTENSIONS) ensure_dirzbz2 module is not availablezlzma module is not availablereturncCstd}t||S)zBGet the current umask which involves having to set it temporarily.r)osumask)maskr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/unpacking.py current_umask+s  rpathcCsd|dd}d|vr$d|vr|d|dksd|vr$|ddSd|vr.|ddS|dgS)N/\)lstripfindsplitrrrrsplit_leading_dir2s$  rpathscCsDd}|D]}t|\}}|sdS|dur|}q||krdSqdS)zyReturns true if all the paths have the same leading path name (i.e., everything is in one subdirectory in an archive)NFT)r)r common_prefixrprefixrestrrrhas_leading_dir>s r! directorytargetcCs0tj|}tj|}tj||g}||kS)zL Return true if the absolute path of target is within the directory )r rabspath commonprefix)r"r# abs_directory abs_targetrrrris_within_directoryMs  r(cCst|dt@dBdS)zx Make file present at path have execute for user/group/world (chmod +x) is no-op on windows per python docs iIN)r chmodrrrrr2set_extracted_file_to_default_mode_plus_executableXsr+infocCs$|jd?}t|ot|o|d@S)Nr)) external_attrboolstatS_ISREG)r,moderrrzip_item_is_executable`s r3Tfilenamelocationflattenc CsJt|t|d}ztj|dd}t|o|}|D]{}|j}|}|r,t|d}t j ||}t j |} t ||sId} t| ||||dsS|drXt|qt| ||} z)t|d} t| | Wd n1sxwYW| t|rt|q| t|rt|wwW|d S|w) a Unzip the file (with path `filename`) to the destination `location`. All files are written based on system defaults and umask (i.e. permissions are not preserved), except that regular file members with any execute permissions (user, group, or world) have "chmod +x" applied after being written. Note that for windows, any execute changes using os.chmod are no-ops per the python docs. rbT) allowZip64rzQThe zip file ({}) has a file ({}) trying to install outside target directory ({})rrwbN)r openzipfileZipFiler!namelistinfolistr4rr rjoindirnamer(rformatendswithshutil copyfileobjcloser3r+) r4r5r6zipfpzipleadingr,namefndirmessagefpdestfprrr unzip_filegsF         rOc Cs.t||ds|drd}n&|trd}n|tr)d}n|dr3d}ntd|d }tj||d d }zt d d | D}| D]}|j }|r`t |d}t j||}t||swd}t|||||rt|qS|rz|||WqSty} ztd||j | WYd} ~ qSd} ~ wwz||} Wnttfy} ztd||j | WYd} ~ qSd} ~ wwtt j|| dusJt|d} t| | Wdn1swY| ||||jd@r t |qSW|dS|w)a Untar the file (with path `filename`) to the destination `location`. All files are written based on system defaults and umask (i.e. permissions are not preserved), except that regular file members with any execute permissions (user, group, or world) have "chmod +x" applied after being written. Note that for windows, any execute changes using os.chmod are no-ops per the python docs. z.gzz.tgzzr:gzzr:bz2zr:xzz.tarrz-Cannot determine compression type for file %szr:*zutf-8)encodingcSsg|]}|jqSr)rI).0memberrrr szuntar_file..rzQThe tar file ({}) has a file ({}) trying to install outside target directory ({})z/In the tar file %s the member %s is invalid: %sNr9r))!r lowerrBrr loggerwarningtarfiler:r! getmembersrIrr rr?r(rrAisdirissym_extract_member Exception extractfileKeyErrorAttributeErrorr@rCrDrEutimer2r+) r4r5r2tarrHrSrJrrLexcrMrNrrr untar_files            3rd content_typecCstj|}|dks|tst|r#t|||d ddS|dks7t |s7|t t t r>t||dStd|||td|)Nzapplication/zipz.whl)r6zapplication/x-gzipzZCannot unpack file %s (downloaded from %s, content-type: %s); cannot detect archive formatz#Cannot determine archive format of )r rrealpathrUrBr r; is_zipfilerOrX is_tarfilerrr rdrVcriticalr)r4r5rerrr unpack_files(  rj)T)N))__doc__loggingr rCr0rXr;typingrrrrpip._internal.exceptionsrpip._internal.utils.filetypesrrr r pip._internal.utils.miscr getLogger__name__rVSUPPORTED_EXTENSIONSbz2 ImportErrordebuglzmaintrstrrr/r!r(r+r3rOrdrjrrrrsX          .TPKH]{CNN[python3.10/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-310.pycnu[o ai @sddlmZddlmZmZmZmZddlmZddl m Z ddl m Z dede de fd d Zd e defd d Z dded ee dedefddZdS))Optional) ArchiveInfo DirectUrlDirInfoVcsInfo)Link) path_to_url)vcs direct_urlnamereturncCs||d}g}t|jtr|d|jj|j|jj7}n$t|jtr6||j7}|jj r5| |jj n t|jt s>J||j7}|j rN| d|j |rY|dd |7}|S)z0Convert a DirectUrl to a pip requirement string.z @ z{}+{}@{}z subdirectory=#&)validate isinstanceinforformatr url commit_idrhashappendr subdirectoryjoin)r r requirement fragmentsr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/direct_url_helpers.py%direct_url_as_pep440_direct_reference s&    r source_dircCstt|tdddS)NT)editable)rr)rrr)rrrrdirect_url_for_editable sr NFlinklink_is_in_wheel_cachec Cs|jr6t|j}|s J||j\}}}|r|sJ|}n |s#J||}t|t|j ||d|j dS| rDt|jt |j dSd}|j } | rS| d|j}t|jt|d|j dS)N)r rrequested_revision)rrr=)r)is_vcsr get_backend_for_schemeschemeget_url_rev_and_authurl_without_fragment get_revisionrrr subdirectory_fragmentis_existing_dirr hash_namerr) r!rr" vcs_backendrr#_rrr-rrrdirect_url_from_link'sF    r0)NF)typingrpip._internal.models.direct_urlrrrrpip._internal.models.linkrpip._internal.utils.urlsrpip._internal.vcsr strrr boolr0rrrrs"    PKH] Ο[python3.10/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-310.pycnu[o ai @sLdZddlZddlmZmZmZddlmZmZm Z m Z m Z m Z m Z mZedZdeedfdefd d Zd edeefd d Zd edeefddZd edeefddZdeeedeeefddZdedefddZ ddeedeedefddZ    d deedeeedeedeeedeef ddZdS)!z3Generate and work with PEP 425 Compatibility Tags. N)ListOptionalTuple) PythonVersionTagcompatible_tags cpython_tags generic_tagsinterpreter_nameinterpreter_version mac_platformsz(.+)_(\d+)_(\d+)_(.+) version_info.returncCsdtt|ddS)N)joinmapstr)r r/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/compatibility_tags.pyversion_info_to_nodotsrarchcsTt|}|r%|\}}}t|t|f}fddt||D}|S|g}|S)Ncs$g|]}d|tddqS)z{}_{}macosx_N)formatlen).0rnamerr sz"_mac_platforms..) _osx_arch_patmatchgroupsintr )rr majorminor actual_arch mac_versionarchesrrr_mac_platformss   r(cCsl|g}|d\}}}|dkr'|dvr%|d|||d|||S|dkr4|d|||S)N_ manylinux2014>x86_64i686 manylinux2010 manylinux1) partitionappend)rr' arch_prefixarch_sep arch_suffixrrr_custom_manylinux_platforms.sr4cCsD|d\}}}|drt|}|S|dvrt|}|S|g}|S)Nr)macosx)r*r-)r/ startswithr(r4)rr1r2r3r'rrr_get_custom_platformsCs r7 platformscsT|sdStg}|D]}|vrq fddt|D}|||q |S)Ncsg|]}|vr|qSrr)rcseenrrrXsz-_expand_allowed_platforms..)setr7updateextend)r8resultp additionsrr:r_expand_allowed_platformsNs  rBversioncCs6t|dkrt|dt|ddfSt|dfS)Nr)rr")rCrrr_get_python_version_s rEimplementationcCs(|durt}|durt}||S)N)r r )rFrCrrr_get_custom_interpreterfs  rGimplabiscCs~g}d}|dur t|}t||}t|}|ptdk}|r)|t|||dn |t|||d|t|||d|S)aVReturn a list of supported tags for each version specified in `versions`. :param version: a string version, of the form "33" or "32", or None. The version will be assumed to support our ABI. :param platform: specify a list of platforms you want valid tags for, or None. If None, use the local system platform. :param impl: specify the exact implementation you want valid tags for, or None. If None, use the local interpreter impl. :param abis: specify a list of abis you want valid tags for, or None. If None, use the local interpreter abi. Ncp)python_versionrIr8) interpreterrIr8)rKrLr8)rErGrBr r>rr r)rCr8rHrI supportedrKrL is_cpythonrrr get_supportedps< rO)NN)NNNN)__doc__retypingrrrZpip._vendor.packaging.tagsrrrrr r r r compilerr"rrr(r4r7rBrErGrOrrrrsD( "     PKH]b]{ { Rpython3.10/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-310.pycnu[o ai @sddlZddlZddlmZddlmZddlmZmZddl m Z ddl m Z m Z ddlmZddlmZdd lmZdd lmZeeZd eed eed fdefddZdedefddZdedefddZejdddedefddZ dS)N)Message) FeedParser)OptionalTuple) pkg_resources) specifiersversion Requirement) Distribution)NoneMetadataError) display_pathrequires_python version_info.returncCs4|durdSt|}tdtt|}||vS)a Check if the given Python version matches a "Requires-Python" specifier. :param version_info: A 3-tuple of ints representing a Python major-minor-micro version to check (e.g. `sys.version_info[:3]`). :return: `True` if the given Python version satisfies the requirement. Otherwise, return `False`. :raises InvalidSpecifier: If `requires_python` has an invalid format. NT.)r SpecifierSetrparsejoinmapstr)rrrequires_python_specifierpython_versionr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/packaging.pycheck_requires_pythons  rdistcCsd}t|tjr||r||}n|dr d}||}n tdt|jd}|dur4t ||t }| || S)z :raises NoneMetadataError: if the distribution reports `has_metadata()` True but `get_metadata()` returns None. METADATAzPKG-INFOzNo metadata found in %sN) isinstancerDistInfoDistribution has_metadata get_metadataloggerwarningr locationr rfeedclose)r metadata_namemetadata feed_parserrrrr")s     r"cCs2|dr|dD] }|r|Sq dS)N INSTALLERr)r!get_metadata_linesstrip)rlinerrr get_installerDs  r/i)maxsize req_stringcCst|S)z5Construct a packaging.Requirement object with cachingr )r1rrrget_requirementLsr2)! functoolslogging email.messager email.parserrtypingrr pip._vendorrZpip._vendor.packagingrrZ"pip._vendor.packaging.requirementsr pip._vendor.pkg_resourcesr pip._internal.exceptionsr pip._internal.utils.miscr getLogger__name__r#rintboolrr"r/ lru_cacher2rrrrs.           PKH]8$aaTpython3.10/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-310.pycnu[o aij@sHddlZddlmZmZddlmZd deeededefdd Z dS) N)ListOptional)mainFargs_nowarnreturncCs|stjdt|S)aCentral wrapper for all old entrypoints. Historically pip has had several entrypoints defined. Because of issues arising from PATH, sys.path, multiple Pythons, their interactions, and most of them having a pip installed, users suffer every time an entrypoint gets moved. To alleviate this pain, and provide a mechanism for warning users and directing them to an appropriate place for help, we now define all of our old entrypoints as wrappers for the current one. aWARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip. Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue. To avoid this problem you can invoke Python with '-m pip' instead of running pip directly. )sysstderrwriter)rrr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/entrypoints.py_wrappers  r )NF) rtypingrrpip._internal.cli.mainrstrboolintr r r r r s $PKH]f1Rpython3.10/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-310.pycnu[o ai@sUdZddlmZddlmZdZdZeedfed<dZ eedfed <d efZ eedfed <d Z eedfed <e ee e Z dede fddZdS)zFiletype information. )Tuple)splitextz.whl)z.tar.bz2z.tbz.BZ2_EXTENSIONS)z.tar.xzz.txzz.tlzz.tar.lzz .tar.lzma XZ_EXTENSIONSz.zipZIP_EXTENSIONS)z.tar.gzz.tgzz.tarTAR_EXTENSIONSnamereturncCs t|d}|tvrdSdS)z9Return True if `name` is a considered as an archive file.TF)rlowerARCHIVE_EXTENSIONS)rextr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/filetypes.pyis_archive_filesrN)__doc__typingrpip._internal.utils.miscrWHEEL_EXTENSIONrstr__annotations__rrrr boolrrrrrs  PKH]ѐ[[Npython3.10/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-310.pycnu[o ai@sLdZddlZddlmZddlmZddlmZmZddl m Z m Z ddl m Z ddlmZmZdd lmZdd lmZd ZeeZGd d d eZde dededefddZde dedeeeffddZde dedefddZde dedefddZde dedefddZ dedee!d ffd!d"Z"d#ee!d fdeddfd$d%Z#dS)&z0Support functions for working with wheel files. N)Message)Parser)DictTuple) BadZipFileZipFile)canonicalize_name)DistInfoDistribution Distribution)UnsupportedWheel) DictMetadata)rcsLeZdZdZdeeefdeddffdd Zdedeffd d ZZ S) WheelMetadatazaMetadata provider that maps metadata decoding exceptions to our internal exception type. metadata wheel_namereturnNcst|||_dS)N)super__init__ _wheel_name)selfrr __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/wheel.pyrs  zWheelMetadata.__init__namec s>zt|WSty}z td|jd|d}~ww)NzError decoding metadata for : )r get_metadataUnicodeDecodeErrorr r)rrerrrrszWheelMetadata.get_metadata) __name__ __module__ __qualname____doc__rstrbytesrr __classcell__rrrrrs"r wheel_ziprlocationrc st||\}fdd|D}i}|D])}|dd\}}z t||||<Wqty?}z td|t|d}~wwt||} t|| |dS)zaGet a pkg_resources distribution given a wheel. :raises UnsupportedWheel: on any errors cs g|] }|dr|qS)/) startswith.0pinfo_dirrr 2s z8pkg_resources_distribution_for_wheel..r(r {} has an invalid wheel, {}N)r'r project_name) parse_wheelnamelistsplitread_wheel_metadata_filer formatr#rr ) r&rr'_metadata_files metadata_textpath metadata_namerrrr-r$pkg_resources_distribution_for_wheel)s r<c Cs`zt||}t||}t|}Wnty&}z td|t|d}~wwt||||fS)zExtract information from the provided wheel, ensuring it meets basic standards. Returns the name of the .dist-info directory and the parsed WHEEL metadata. r0N)wheel_dist_info_dirwheel_metadata wheel_versionr r6r#check_compatibility)r&rr.rversionrrrrr2Bs    r2sourcecCsdd|D}dd|D}|stdt|dkr&tdd||d }t|}t|}||s?td |||S) zReturns the name of the contained .dist-info directory. Raises AssertionError or UnsupportedWheel if not found, >1 found, or it doesn't match the provided name. cSsh|] }|dddqS)r(r r)r4r*rrr [sz&wheel_dist_info_dir..cSsg|] }|dr|qS)z .dist-info)endswith)r+srrrr/]sz'wheel_dist_info_dir..z.dist-info directory not foundr z)multiple .dist-info directories found: {}z, rz2.dist-info directory {!r} does not start with {!r})r3r lenr6joinrr))rBrsubdirs info_dirsr. info_dir_namecanonical_namerrrr=Ts$  r=r:c Cs@z||WStttfy}z td|d|d}~ww)Nzcould not read z file: )readrKeyError RuntimeErrorr )rBr:rrrrr5us  r5 dist_info_dirc CsZ|d}t||}z|}Wnty&}z td|d|d}~wwt|S)ziReturn the WHEEL metadata of an extracted wheel, if possible. Otherwise, raise UnsupportedWheel. z/WHEELzerror decoding rN)r5decoderr rparsestr)rBrOr:wheel_contents wheel_textrrrrr>~s    r> wheel_data.cCsT|d}|dur td|}z ttt|dWSty)td|w)zbGiven WHEEL metadata, return the parsed Wheel-Version. Otherwise, raise UnsupportedWheel. z Wheel-VersionNzWHEEL is missing Wheel-Version.zinvalid Wheel-Version: )r striptuplemapintr4 ValueError)rT version_textrArrrr?s r?rAc CsT|dtdkrtd|dtt||tkr(tddtt|dSdS)aRaises errors or warns if called with an incompatible Wheel-Version. pip should refuse to install a Wheel-Version that's a major series ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when installing a version only minor version ahead (e.g 1.2 > 1.1). version: a 2-tuple representing a Wheel-Version (Major, Minor) name: name of wheel or package to raise exception about :raises UnsupportedWheel: when an incompatible Wheel-Version is given rzB{}'s Wheel-Version ({}) is not compatible with this version of piprUz*Installing from a newer Wheel-Version (%s)N)VERSION_COMPATIBLEr r6rGrXr#loggerwarning)rArrrrr@s r@)$r"logging email.messager email.parserrtypingrrzipfilerrpip._vendor.packaging.utilsrpip._vendor.pkg_resourcesr r pip._internal.exceptionsr !pip._internal.utils.pkg_resourcesr r\ getLoggerrr]rr#r<r2r=r$r5r>rYr?r@rrrrs8       ! "PKH]Opython3.10/site-packages/pip/_internal/utils/__pycache__/compat.cpython-310.pycnu[o ai\@szdZddlZddlZddlZgdZeeZdefddZ de de fdd Z hd Z ejd p:ejd ko:ejd kZdS)zKStuff that differs in different Python versions and platform distributions.N) get_path_uid stdlib_pkgsWINDOWSreturncCs2zddl}WdStyYnwddlm}|S)NrT) IS_PYOPENSSL)_ssl ImportErrorpip._vendor.urllib3.utilr)rrr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/compat.pyhas_tlss  r pathcCsbttdrt|tjtjB}t|j}t||Stj |s*t |j}|St |d)a) Return path's uid. Does not follow symlinks: https://github.com/pypa/pip/pull/935#discussion_r5307003 Placed this function in compat due to differences on AIX and Jython, that should eventually go away. :raises OSError: When path is a symlink or can't be read. O_NOFOLLOWz/ is a symlink; Will not return uid for symlinks) hasattrosopenO_RDONLYrfstatst_uidcloser islinkstatOSError)r fdfile_uidr r r rs    r>wsgirefpythonargparsewinclint)__doc__loggingrsys__all__ getLogger__name__loggerboolr strintrrplatform startswithnamerr r r r s   $PKH]uuOpython3.10/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-310.pycnu[o ai@sddlZddlmZmZmZmZmZddlmZm Z m Z ddl m Z er0ddlm Z ddlmZdZgdZGd d d ZGd d d eZdS) N) TYPE_CHECKINGBinaryIODictIteratorList) HashMismatch HashMissingInstallationError) read_chunks)_Hash)NoReturnsha256)r sha384sha512c@seZdZdZd$deeeefddfddZd%dd Ze de fd d Z d ed ede fddZ deeddfddZdeedfddfddZdeddfddZdeddfddZde fddZdede fd d!Zde fd"d#ZdS)&HasheszaA wrapper that builds multiple hashes at once and checks them against known-good values NhashesreturncCs4i}|dur|D] \}}t|||<q ||_dS)zo :param hashes: A dict of algorithm names pointing to lists of allowed hex digests N)itemssorted_allowed)selfrallowedalgkeysr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/hashes.py__init__s  zHashes.__init__othercsbt|tstS|s Ss|Si}|jD]\}jvr qfdd|D|<qt|S)Ncsg|] }|jvr|qSr)r).0vrrrr ;sz"Hashes.__and__..) isinstancerNotImplementedrr)rrnewvaluesrr r__and__+s  zHashes.__and__cCstdd|jDS)Ncss|]}t|VqdSN)len)rdigestsrrr @sz&Hashes.digest_count..)sumrr%rrrr digest_count>szHashes.digest_count hash_name hex_digestcCs||j|gvS)z/Return whether the given hex digest is allowed.)rget)rr.r/rrris_hash_allowedBszHashes.is_hash_allowedchunksc Csi}|jD]}z t|||<Wqttfy"td|w|D]}|D]}||q+q%| D]\}}| |j|vrHdSq8| |dS)zCheck good hashes against ones built from iterable of chunks of data. Raise HashMismatch if none match. zUnknown hash name: N) rrhashlibr$ ValueError TypeErrorr r%updater hexdigest_raise)rr2gotsr.chunkhashgotrrrcheck_against_chunksFs   zHashes.check_against_chunksr9r r cCs t|j|r')rrrr9rrrr8]s z Hashes._raisefilecCs|t|S)zaCheck good hashes against a file-like object Raise HashMismatch if none match. )r=r )rr?rrrcheck_against_file`szHashes.check_against_filepathcCs8t|d }||WdS1swYdS)Nrb)openr@)rrAr?rrrcheck_against_pathhs $zHashes.check_against_pathcCs t|jS)z,Return whether I know any known-good hashes.)boolrr,rrr__bool__ls zHashes.__bool__cCst|tstS|j|jkSr')r"rr#r)rrrrr__eq__ps  z Hashes.__eq__cCs"tdtdd|jDS)N,css,|]\}}|D] }d||fVqqdS):N)join)rr digest_listdigestrrrr*xs z"Hashes.__hash__..)r;rJrrrr,rrr__hash__uszHashes.__hash__r')rrrr)__name__ __module__ __qualname____doc__rstrrrr&propertyintr-rEr1rbytesr=r8rr@rDrFobjectrGrMrrrrrs  rcs<eZdZdZd fdd Zdeedfddfd d ZZS) MissingHasheszA workalike for Hashes used when we're missing a hash for a requirement It computes the actual hash of the requirement and raises a HashMissing exception showing it to the user. rNcstjtgiddS)z!Don't offer the ``hashes`` kwarg.)rN)superr FAVORITE_HASHr, __class__rrrszMissingHashes.__init__r9r r cCst|tr')rrYr7r>rrrr8szMissingHashes._raise)rN) rNrOrPrQrrrRr8 __classcell__rrrZrrWs"rW)r3typingrrrrrpip._internal.exceptionsrrr pip._internal.utils.miscr r r rY STRONG_HASHESrrWrrrrs   hPKH]-\\Mpython3.10/site-packages/pip/_internal/utils/__pycache__/urls.cpython-310.pycnu[o ai@svddlZddlZddlZddlZddlmZddlmZde dee fddZ d e de fd d Z de de fd d Z dS)N)Optional)WINDOWSurlreturncCs d|vrdS|dddS)N:rr)splitlower)rr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/urls.pyget_url_scheme sr pathcCs.tjtj|}tjdtj|}|S)zh Convert a path to a file: URL. The path will be made absolute and have quoted path parts. file:) osr normpathabspathurllibparseurljoinrequest pathname2url)r rr r r path_to_urlsrcCs|ds Jd|dtj|\}}}}}|r|dkr!d}ntr(d|}ntd|tj||}tr\|s\t|dkr\|d d kr\|d t j vr\|d d dvr\|d d}|S)z( Convert a file: URL to a path. rz1You can only turn file: urls into filenames (not ) localhostz\\z8non-local file URIs are not supported on this platform: r/r)rz:/N) startswithrrurlsplitr ValueErrorr url2pathnamelenstring ascii_letters)r_netlocr r r r url_to_paths0      r() rr$ urllib.parserurllib.requesttypingrcompatrstrr rr(r r r r s   PKH](/  Spython3.10/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-310.pycnu[o ai @sddlZddlZddlZddlZddlZddlmZmZee Z e dZ de fddZde fddZde fd d Zdeeefd d Zde fd dZde fddZde fddZdS)N)ListOptionalz8include-system-site-packages\s*=\s*(?Ptrue|false)returncCstjttdtjkS)znChecks if sys.base_prefix and sys.prefix match. This handles PEP 405 compliant virtual environments. base_prefix)sysprefixgetattrr r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_internal/utils/virtualenv.py_running_under_venvsr cCs ttdS)zmChecks if sys.real_prefix is set. This handles virtual environments created with pypa's virtualenv. real_prefix)hasattrrr r r r !_running_under_regular_virtualenvs rcCs tptS)zBReturn True if we're running inside a virtualenv, False otherwise.)r rr r r r running_under_virtualenvs rcCsftjtjd}z t|dd}|WdWS1s!wYWdSty2YdSw)zReads {sys.prefix}/pyvenv.cfg and returns its contents as list of lines Returns None, if it could not read/access the file. z pyvenv.cfgzutf-8)encodingN) ospathjoinrropenread splitlinesOSError)pyvenv_cfg_filefr r r _get_pyvenv_cfg_lines$s ( rcCsPt}|durtddS|D]}t|}|dur%|ddkr%dSqdS)aZCheck `{sys.prefix}/pyvenv.cfg` for system site-packages inclusion PEP 405 specifies that when system site-packages are not supposed to be visible from a virtual environment, `pyvenv.cfg` must contain the following line: include-system-site-packages = false Additionally, log a warning if accessing the file fails. NzCould not access 'pyvenv.cfg' despite a virtual environment being active. Assuming global site-packages is not accessible in this environment.TvaluefalseF)rloggerwarning#_INCLUDE_SYSTEM_SITE_PACKAGES_REGEXmatchgroup) cfg_linesliner r r r _no_global_under_venv3s  r$cCs0tjtjtj}tj|d}tj|S)zCheck if "no-global-site-packages.txt" exists beside site.py This mirrors logic in pypa/virtualenv for determining whether system site-packages are visible in the virtual environment. zno-global-site-packages.txt)rrdirnameabspathsite__file__rexists) site_mod_dirno_global_site_packages_filer r r #_no_global_under_regular_virtualenvPs  r,cCstrtStr tSdS)zHReturns a boolean, whether running in venv with no system site-packages.F)r r$rr,r r r r virtualenv_no_global^s r-)loggingrrer'rtypingrr getLogger__name__rcompilerboolr rrstrrr$r,r-r r r r s"  PKH]Bpython3.10/site-packages/pip/_internal/utils/compatibility_tags.pynu["""Generate and work with PEP 425 Compatibility Tags. """ import re from typing import List, Optional, Tuple from pip._vendor.packaging.tags import ( PythonVersion, Tag, compatible_tags, cpython_tags, generic_tags, interpreter_name, interpreter_version, mac_platforms, ) _osx_arch_pat = re.compile(r"(.+)_(\d+)_(\d+)_(.+)") def version_info_to_nodot(version_info: Tuple[int, ...]) -> str: # Only use up to the first two numbers. return "".join(map(str, version_info[:2])) def _mac_platforms(arch: str) -> List[str]: match = _osx_arch_pat.match(arch) if match: name, major, minor, actual_arch = match.groups() mac_version = (int(major), int(minor)) arches = [ # Since we have always only checked that the platform starts # with "macosx", for backwards-compatibility we extract the # actual prefix provided by the user in case they provided # something like "macosxcustom_". It may be good to remove # this as undocumented or deprecate it in the future. "{}_{}".format(name, arch[len("macosx_") :]) for arch in mac_platforms(mac_version, actual_arch) ] else: # arch pattern didn't match (?!) arches = [arch] return arches def _custom_manylinux_platforms(arch: str) -> List[str]: arches = [arch] arch_prefix, arch_sep, arch_suffix = arch.partition("_") if arch_prefix == "manylinux2014": # manylinux1/manylinux2010 wheels run on most manylinux2014 systems # with the exception of wheels depending on ncurses. PEP 599 states # manylinux1/manylinux2010 wheels should be considered # manylinux2014 wheels: # https://www.python.org/dev/peps/pep-0599/#backwards-compatibility-with-manylinux2010-wheels if arch_suffix in {"i686", "x86_64"}: arches.append("manylinux2010" + arch_sep + arch_suffix) arches.append("manylinux1" + arch_sep + arch_suffix) elif arch_prefix == "manylinux2010": # manylinux1 wheels run on most manylinux2010 systems with the # exception of wheels depending on ncurses. PEP 571 states # manylinux1 wheels should be considered manylinux2010 wheels: # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels arches.append("manylinux1" + arch_sep + arch_suffix) return arches def _get_custom_platforms(arch: str) -> List[str]: arch_prefix, arch_sep, arch_suffix = arch.partition("_") if arch.startswith("macosx"): arches = _mac_platforms(arch) elif arch_prefix in ["manylinux2014", "manylinux2010"]: arches = _custom_manylinux_platforms(arch) else: arches = [arch] return arches def _expand_allowed_platforms(platforms: Optional[List[str]]) -> Optional[List[str]]: if not platforms: return None seen = set() result = [] for p in platforms: if p in seen: continue additions = [c for c in _get_custom_platforms(p) if c not in seen] seen.update(additions) result.extend(additions) return result def _get_python_version(version: str) -> PythonVersion: if len(version) > 1: return int(version[0]), int(version[1:]) else: return (int(version[0]),) def _get_custom_interpreter( implementation: Optional[str] = None, version: Optional[str] = None ) -> str: if implementation is None: implementation = interpreter_name() if version is None: version = interpreter_version() return f"{implementation}{version}" def get_supported( version: Optional[str] = None, platforms: Optional[List[str]] = None, impl: Optional[str] = None, abis: Optional[List[str]] = None, ) -> List[Tag]: """Return a list of supported tags for each version specified in `versions`. :param version: a string version, of the form "33" or "32", or None. The version will be assumed to support our ABI. :param platform: specify a list of platforms you want valid tags for, or None. If None, use the local system platform. :param impl: specify the exact implementation you want valid tags for, or None. If None, use the local interpreter impl. :param abis: specify a list of abis you want valid tags for, or None. If None, use the local interpreter abi. """ supported: List[Tag] = [] python_version: Optional[PythonVersion] = None if version is not None: python_version = _get_python_version(version) interpreter = _get_custom_interpreter(impl, version) platforms = _expand_allowed_platforms(platforms) is_cpython = (impl or interpreter_name()) == "cp" if is_cpython: supported.extend( cpython_tags( python_version=python_version, abis=abis, platforms=platforms, ) ) else: supported.extend( generic_tags( interpreter=interpreter, abis=abis, platforms=platforms, ) ) supported.extend( compatible_tags( python_version=python_version, interpreter=interpreter, platforms=platforms, ) ) return supported PKH]_jj;python3.10/site-packages/pip/_internal/utils/entrypoints.pynu[import sys from typing import List, Optional from pip._internal.cli.main import main def _wrapper(args: Optional[List[str]] = None, _nowarn: bool = False) -> int: """Central wrapper for all old entrypoints. Historically pip has had several entrypoints defined. Because of issues arising from PATH, sys.path, multiple Pythons, their interactions, and most of them having a pip installed, users suffer every time an entrypoint gets moved. To alleviate this pain, and provide a mechanism for warning users and directing them to an appropriate place for help, we now define all of our old entrypoints as wrappers for the current one. """ if not _nowarn: sys.stderr.write( "WARNING: pip is being invoked by an old script wrapper. This will " "fail in a future version of pip.\n" "Please see https://github.com/pypa/pip/issues/5599 for advice on " "fixing the underlying issue.\n" "To avoid this problem you can invoke Python with '-m pip' instead of " "running pip directly.\n" ) return main(args) PKH];[:python3.10/site-packages/pip/_internal/utils/filesystem.pynu[import fnmatch import os import os.path import random import shutil import stat import sys from contextlib import contextmanager from tempfile import NamedTemporaryFile from typing import Any, BinaryIO, Iterator, List, Union, cast from pip._vendor.tenacity import retry, stop_after_delay, wait_fixed from pip._internal.utils.compat import get_path_uid from pip._internal.utils.misc import format_size def check_path_owner(path: str) -> bool: # If we don't have a way to check the effective uid of this process, then # we'll just assume that we own the directory. if sys.platform == "win32" or not hasattr(os, "geteuid"): return True assert os.path.isabs(path) previous = None while path != previous: if os.path.lexists(path): # Check if path is writable by current user. if os.geteuid() == 0: # Special handling for root user in order to handle properly # cases where users use sudo without -H flag. try: path_uid = get_path_uid(path) except OSError: return False return path_uid == 0 else: return os.access(path, os.W_OK) else: previous, path = path, os.path.dirname(path) return False # assume we don't own the path def copy2_fixed(src: str, dest: str) -> None: """Wrap shutil.copy2() but map errors copying socket files to SpecialFileError as expected. See also https://bugs.python.org/issue37700. """ try: shutil.copy2(src, dest) except OSError: for f in [src, dest]: try: is_socket_file = is_socket(f) except OSError: # An error has already occurred. Another error here is not # a problem and we can ignore it. pass else: if is_socket_file: raise shutil.SpecialFileError(f"`{f}` is a socket") raise def is_socket(path: str) -> bool: return stat.S_ISSOCK(os.lstat(path).st_mode) @contextmanager def adjacent_tmp_file(path: str, **kwargs: Any) -> Iterator[BinaryIO]: """Return a file-like object pointing to a tmp file next to path. The file is created securely and is ensured to be written to disk after the context reaches its end. kwargs will be passed to tempfile.NamedTemporaryFile to control the way the temporary file will be opened. """ with NamedTemporaryFile( delete=False, dir=os.path.dirname(path), prefix=os.path.basename(path), suffix=".tmp", **kwargs, ) as f: result = cast(BinaryIO, f) try: yield result finally: result.flush() os.fsync(result.fileno()) # Tenacity raises RetryError by default, explicitly raise the original exception _replace_retry = retry(reraise=True, stop=stop_after_delay(1), wait=wait_fixed(0.25)) replace = _replace_retry(os.replace) # test_writable_dir and _test_writable_dir_win are copied from Flit, # with the author's agreement to also place them under pip's license. def test_writable_dir(path: str) -> bool: """Check if a directory is writable. Uses os.access() on POSIX, tries creating files on Windows. """ # If the directory doesn't exist, find the closest parent that does. while not os.path.isdir(path): parent = os.path.dirname(path) if parent == path: break # Should never get here, but infinite loops are bad path = parent if os.name == "posix": return os.access(path, os.W_OK) return _test_writable_dir_win(path) def _test_writable_dir_win(path: str) -> bool: # os.access doesn't work on Windows: http://bugs.python.org/issue2528 # and we can't use tempfile: http://bugs.python.org/issue22107 basename = "accesstest_deleteme_fishfingers_custard_" alphabet = "abcdefghijklmnopqrstuvwxyz0123456789" for _ in range(10): name = basename + "".join(random.choice(alphabet) for _ in range(6)) file = os.path.join(path, name) try: fd = os.open(file, os.O_RDWR | os.O_CREAT | os.O_EXCL) except FileExistsError: pass except PermissionError: # This could be because there's a directory with the same name. # But it's highly unlikely there's a directory called that, # so we'll assume it's because the parent dir is not writable. # This could as well be because the parent dir is not readable, # due to non-privileged user access. return False else: os.close(fd) os.unlink(file) return True # This should never be reached raise OSError("Unexpected condition testing for writable directory") def find_files(path: str, pattern: str) -> List[str]: """Returns a list of absolute paths of files beneath path, recursively, with filenames which match the UNIX-style shell glob pattern.""" result: List[str] = [] for root, _, files in os.walk(path): matches = fnmatch.filter(files, pattern) result.extend(os.path.join(root, f) for f in matches) return result def file_size(path: str) -> Union[int, float]: # If it's a symlink, return 0. if os.path.islink(path): return 0 return os.path.getsize(path) def format_file_size(path: str) -> str: return format_size(file_size(path)) def directory_size(path: str) -> Union[int, float]: size = 0.0 for root, _dirs, files in os.walk(path): for filename in files: file_path = os.path.join(root, filename) size += file_size(file_path) return size def format_directory_size(path: str) -> str: return format_size(directory_size(path)) PKH]R=U& & 5python3.10/site-packages/pip/_internal/utils/glibc.pynu[# The following comment should be removed at some point in the future. # mypy: strict-optional=False import os import sys from typing import Optional, Tuple def glibc_version_string() -> Optional[str]: "Returns glibc version string, or None if not using glibc." return glibc_version_string_confstr() or glibc_version_string_ctypes() def glibc_version_string_confstr() -> Optional[str]: "Primary implementation of glibc_version_string using os.confstr." # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely # to be broken or missing. This strategy is used in the standard library # platform module: # https://github.com/python/cpython/blob/fcf1d003bf4f0100c9d0921ff3d70e1127ca1b71/Lib/platform.py#L175-L183 if sys.platform == "win32": return None try: # os.confstr("CS_GNU_LIBC_VERSION") returns a string like "glibc 2.17": _, version = os.confstr("CS_GNU_LIBC_VERSION").split() except (AttributeError, OSError, ValueError): # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)... return None return version def glibc_version_string_ctypes() -> Optional[str]: "Fallback implementation of glibc_version_string using ctypes." try: import ctypes except ImportError: return None # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen # manpage says, "If filename is NULL, then the returned handle is for the # main program". This way we can let the linker do the work to figure out # which libc our process is actually using. process_namespace = ctypes.CDLL(None) try: gnu_get_libc_version = process_namespace.gnu_get_libc_version except AttributeError: # Symbol doesn't exist -> therefore, we are not linked to # glibc. return None # Call gnu_get_libc_version, which returns a string like "2.5" gnu_get_libc_version.restype = ctypes.c_char_p version_str = gnu_get_libc_version() # py2 / py3 compatibility: if not isinstance(version_str, str): version_str = version_str.decode("ascii") return version_str # platform.libc_ver regularly returns completely nonsensical glibc # versions. E.g. on my computer, platform says: # # ~$ python2.7 -c 'import platform; print(platform.libc_ver())' # ('glibc', '2.7') # ~$ python3.5 -c 'import platform; print(platform.libc_ver())' # ('glibc', '2.9') # # But the truth is: # # ~$ ldd --version # ldd (Debian GLIBC 2.22-11) 2.22 # # This is unfortunate, because it means that the linehaul data on libc # versions that was generated by pip 8.1.2 and earlier is useless and # misleading. Solution: instead of using platform, use our code that actually # works. def libc_ver() -> Tuple[str, str]: """Try to determine the glibc version Returns a tuple of strings (lib, version) which default to empty strings in case the lookup fails. """ glibc_version = glibc_version_string() if glibc_version is None: return ("", "") else: return ("glibc", glibc_version) PKH]жŎ++;python3.10/site-packages/pip/_internal/utils/deprecation.pynu[""" A module that implements tooling to enable easy warnings about deprecations. """ import logging import warnings from typing import Any, Optional, TextIO, Type, Union from pip._vendor.packaging.version import parse from pip import __version__ as current_version # NOTE: tests patch this name. DEPRECATION_MSG_PREFIX = "DEPRECATION: " class PipDeprecationWarning(Warning): pass _original_showwarning: Any = None # Warnings <-> Logging Integration def _showwarning( message: Union[Warning, str], category: Type[Warning], filename: str, lineno: int, file: Optional[TextIO] = None, line: Optional[str] = None, ) -> None: if file is not None: if _original_showwarning is not None: _original_showwarning(message, category, filename, lineno, file, line) elif issubclass(category, PipDeprecationWarning): # We use a specially named logger which will handle all of the # deprecation messages for pip. logger = logging.getLogger("pip._internal.deprecations") logger.warning(message) else: _original_showwarning(message, category, filename, lineno, file, line) def install_warning_logger() -> None: # Enable our Deprecation Warnings warnings.simplefilter("default", PipDeprecationWarning, append=True) global _original_showwarning if _original_showwarning is None: _original_showwarning = warnings.showwarning warnings.showwarning = _showwarning def deprecated( *, reason: str, replacement: Optional[str], gone_in: Optional[str], feature_flag: Optional[str] = None, issue: Optional[int] = None, ) -> None: """Helper to deprecate existing functionality. reason: Textual reason shown to the user about why this functionality has been deprecated. Should be a complete sentence. replacement: Textual suggestion shown to the user about what alternative functionality they can use. gone_in: The version of pip does this functionality should get removed in. Raises an error if pip's current version is greater than or equal to this. feature_flag: Command-line flag of the form --use-feature={feature_flag} for testing upcoming functionality. issue: Issue number on the tracker that would serve as a useful place for users to find related discussion and provide feedback. """ # Determine whether or not the feature is already gone in this version. is_gone = gone_in is not None and parse(current_version) >= parse(gone_in) message_parts = [ (reason, f"{DEPRECATION_MSG_PREFIX}{{}}"), ( gone_in, "pip {} will enforce this behaviour change." if not is_gone else "Since pip {}, this is no longer supported.", ), ( replacement, "A possible replacement is {}.", ), ( feature_flag, "You can use the flag --use-feature={} to test the upcoming behaviour." if not is_gone else None, ), ( issue, "Discussion can be found at https://github.com/pypa/pip/issues/{}", ), ] message = " ".join( format_str.format(value) for value, format_str in message_parts if format_str is not None and value is not None ) # Raise as an error if this behaviour is deprecated. if is_gone: raise PipDeprecationWarning(message) warnings.warn(message, category=PipDeprecationWarning, stacklevel=2) PKH]7#*Q*Q4python3.10/site-packages/pip/_internal/utils/misc.pynu[# The following comment should be removed at some point in the future. # mypy: strict-optional=False import contextlib import errno import getpass import hashlib import io import logging import os import posixpath import shutil import stat import sys import urllib.parse from io import StringIO from itertools import filterfalse, tee, zip_longest from types import TracebackType from typing import ( Any, BinaryIO, Callable, ContextManager, Iterable, Iterator, List, Optional, TextIO, Tuple, Type, TypeVar, cast, ) from pip._vendor.pkg_resources import Distribution from pip._vendor.tenacity import retry, stop_after_delay, wait_fixed from pip import __version__ from pip._internal.exceptions import CommandError from pip._internal.locations import get_major_minor_version, site_packages, user_site from pip._internal.locations import get_scheme from pip._internal.utils.compat import WINDOWS from pip._internal.utils.egg_link import egg_link_path_from_location from pip._internal.utils.virtualenv import running_under_virtualenv __all__ = [ "rmtree", "display_path", "backup_dir", "ask", "splitext", "format_size", "is_installable_dir", "normalize_path", "renames", "get_prog", "captured_stdout", "ensure_dir", "remove_auth_from_url", ] logger = logging.getLogger(__name__) T = TypeVar("T") ExcInfo = Tuple[Type[BaseException], BaseException, TracebackType] VersionInfo = Tuple[int, int, int] NetlocTuple = Tuple[str, Tuple[Optional[str], Optional[str]]] def get_pip_version() -> str: pip_pkg_dir = os.path.join(os.path.dirname(__file__), "..", "..") pip_pkg_dir = os.path.abspath(pip_pkg_dir) return "pip {} from {} (python {})".format( __version__, pip_pkg_dir, get_major_minor_version(), ) def normalize_version_info(py_version_info: Tuple[int, ...]) -> Tuple[int, int, int]: """ Convert a tuple of ints representing a Python version to one of length three. :param py_version_info: a tuple of ints representing a Python version, or None to specify no version. The tuple can have any length. :return: a tuple of length three if `py_version_info` is non-None. Otherwise, return `py_version_info` unchanged (i.e. None). """ if len(py_version_info) < 3: py_version_info += (3 - len(py_version_info)) * (0,) elif len(py_version_info) > 3: py_version_info = py_version_info[:3] return cast("VersionInfo", py_version_info) def ensure_dir(path: str) -> None: """os.path.makedirs without EEXIST.""" try: os.makedirs(path) except OSError as e: # Windows can raise spurious ENOTEMPTY errors. See #6426. if e.errno != errno.EEXIST and e.errno != errno.ENOTEMPTY: raise def get_prog() -> str: try: prog = os.path.basename(sys.argv[0]) if prog in ("__main__.py", "-c"): return f"{sys.executable} -m pip" else: return prog except (AttributeError, TypeError, IndexError): pass return "pip" # Retry every half second for up to 3 seconds # Tenacity raises RetryError by default, explicitly raise the original exception @retry(reraise=True, stop=stop_after_delay(3), wait=wait_fixed(0.5)) def rmtree(dir: str, ignore_errors: bool = False) -> None: shutil.rmtree(dir, ignore_errors=ignore_errors, onerror=rmtree_errorhandler) def rmtree_errorhandler(func: Callable[..., Any], path: str, exc_info: ExcInfo) -> None: """On Windows, the files in .svn are read-only, so when rmtree() tries to remove them, an exception is thrown. We catch that here, remove the read-only attribute, and hopefully continue without problems.""" try: has_attr_readonly = not (os.stat(path).st_mode & stat.S_IWRITE) except OSError: # it's equivalent to os.path.exists return if has_attr_readonly: # convert to read/write os.chmod(path, stat.S_IWRITE) # use the original function to repeat the operation func(path) return else: raise def display_path(path: str) -> str: """Gives the display value for a given path, making it relative to cwd if possible.""" path = os.path.normcase(os.path.abspath(path)) if path.startswith(os.getcwd() + os.path.sep): path = "." + path[len(os.getcwd()) :] return path def backup_dir(dir: str, ext: str = ".bak") -> str: """Figure out the name of a directory to back up the given dir to (adding .bak, .bak2, etc)""" n = 1 extension = ext while os.path.exists(dir + extension): n += 1 extension = ext + str(n) return dir + extension def ask_path_exists(message: str, options: Iterable[str]) -> str: for action in os.environ.get("PIP_EXISTS_ACTION", "").split(): if action in options: return action return ask(message, options) def _check_no_input(message: str) -> None: """Raise an error if no input is allowed.""" if os.environ.get("PIP_NO_INPUT"): raise Exception( f"No input was expected ($PIP_NO_INPUT set); question: {message}" ) def ask(message: str, options: Iterable[str]) -> str: """Ask the message interactively, with the given possible responses""" while 1: _check_no_input(message) response = input(message) response = response.strip().lower() if response not in options: print( "Your response ({!r}) was not one of the expected responses: " "{}".format(response, ", ".join(options)) ) else: return response def ask_input(message: str) -> str: """Ask for input interactively.""" _check_no_input(message) return input(message) def ask_password(message: str) -> str: """Ask for a password interactively.""" _check_no_input(message) return getpass.getpass(message) def strtobool(val: str) -> int: """Convert a string representation of truth to true (1) or false (0). True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if 'val' is anything else. """ val = val.lower() if val in ("y", "yes", "t", "true", "on", "1"): return 1 elif val in ("n", "no", "f", "false", "off", "0"): return 0 else: raise ValueError(f"invalid truth value {val!r}") def format_size(bytes: float) -> str: if bytes > 1000 * 1000: return "{:.1f} MB".format(bytes / 1000.0 / 1000) elif bytes > 10 * 1000: return "{} kB".format(int(bytes / 1000)) elif bytes > 1000: return "{:.1f} kB".format(bytes / 1000.0) else: return "{} bytes".format(int(bytes)) def tabulate(rows: Iterable[Iterable[Any]]) -> Tuple[List[str], List[int]]: """Return a list of formatted rows and a list of column sizes. For example:: >>> tabulate([['foobar', 2000], [0xdeadbeef]]) (['foobar 2000', '3735928559'], [10, 4]) """ rows = [tuple(map(str, row)) for row in rows] sizes = [max(map(len, col)) for col in zip_longest(*rows, fillvalue="")] table = [" ".join(map(str.ljust, row, sizes)).rstrip() for row in rows] return table, sizes def is_installable_dir(path: str) -> bool: """Is path is a directory containing pyproject.toml or setup.py? If pyproject.toml exists, this is a PEP 517 project. Otherwise we look for a legacy setuptools layout by identifying setup.py. We don't check for the setup.cfg because using it without setup.py is only available for PEP 517 projects, which are already covered by the pyproject.toml check. """ if not os.path.isdir(path): return False if os.path.isfile(os.path.join(path, "pyproject.toml")): return True if os.path.isfile(os.path.join(path, "setup.py")): return True return False def read_chunks(file: BinaryIO, size: int = io.DEFAULT_BUFFER_SIZE) -> Iterator[bytes]: """Yield pieces of data from a file-like object until EOF.""" while True: chunk = file.read(size) if not chunk: break yield chunk def normalize_path(path: str, resolve_symlinks: bool = True) -> str: """ Convert a path to its canonical, case-normalized, absolute version. """ path = os.path.expanduser(path) if resolve_symlinks: path = os.path.realpath(path) else: path = os.path.abspath(path) return os.path.normcase(path) def splitext(path: str) -> Tuple[str, str]: """Like os.path.splitext, but take off .tar too""" base, ext = posixpath.splitext(path) if base.lower().endswith(".tar"): ext = base[-4:] + ext base = base[:-4] return base, ext def renames(old: str, new: str) -> None: """Like os.renames(), but handles renaming across devices.""" # Implementation borrowed from os.renames(). head, tail = os.path.split(new) if head and tail and not os.path.exists(head): os.makedirs(head) shutil.move(old, new) head, tail = os.path.split(old) if head and tail: try: os.removedirs(head) except OSError: pass def is_local(path: str) -> bool: """ Return True if path is within sys.prefix, if we're running in a virtualenv. If we're not in a virtualenv, all paths are considered "local." Caution: this function assumes the head of path has been normalized with normalize_path. """ if not running_under_virtualenv(): return True return path.startswith(normalize_path(sys.prefix)) def dist_is_local(dist: Distribution) -> bool: """ Return True if given Distribution object is installed locally (i.e. within current virtualenv). Always True if we're not in a virtualenv. """ return is_local(dist_location(dist)) def dist_in_usersite(dist: Distribution) -> bool: """ Return True if given Distribution is installed in user site. """ return dist_location(dist).startswith(normalize_path(user_site)) def dist_in_site_packages(dist: Distribution) -> bool: """ Return True if given Distribution is installed in sysconfig.get_python_lib(). """ return dist_location(dist).startswith(normalize_path(site_packages)) def dist_in_install_path(dist): """ Return True if given Distribution is installed in path matching distutils_scheme layout. """ norm_path = normalize_path(dist_location(dist)) return norm_path.startswith(normalize_path( get_scheme("").purelib.split('python')[0])) def get_distribution(req_name: str) -> Optional[Distribution]: """Given a requirement name, return the installed Distribution object. This searches from *all* distributions available in the environment, to match the behavior of ``pkg_resources.get_distribution()``. Left for compatibility until direct pkg_resources uses are refactored out. """ from pip._internal.metadata import get_default_environment from pip._internal.metadata.pkg_resources import Distribution as _Dist dist = get_default_environment().get_distribution(req_name) if dist is None: return None return cast(_Dist, dist)._dist def dist_location(dist: Distribution) -> str: """ Get the site-packages location of this distribution. Generally this is dist.location, except in the case of develop-installed packages, where dist.location is the source code location, and we want to know where the egg-link file is. The returned location is normalized (in particular, with symlinks removed). """ egg_link = egg_link_path_from_location(dist.project_name) if egg_link: return normalize_path(egg_link) return normalize_path(dist.location) def write_output(msg: Any, *args: Any) -> None: logger.info(msg, *args) class StreamWrapper(StringIO): orig_stream: TextIO = None @classmethod def from_stream(cls, orig_stream: TextIO) -> "StreamWrapper": cls.orig_stream = orig_stream return cls() # compileall.compile_dir() needs stdout.encoding to print to stdout # https://github.com/python/mypy/issues/4125 @property def encoding(self): # type: ignore return self.orig_stream.encoding @contextlib.contextmanager def captured_output(stream_name: str) -> Iterator[StreamWrapper]: """Return a context manager used by captured_stdout/stdin/stderr that temporarily replaces the sys stream *stream_name* with a StringIO. Taken from Lib/support/__init__.py in the CPython repo. """ orig_stdout = getattr(sys, stream_name) setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout)) try: yield getattr(sys, stream_name) finally: setattr(sys, stream_name, orig_stdout) def captured_stdout() -> ContextManager[StreamWrapper]: """Capture the output of sys.stdout: with captured_stdout() as stdout: print('hello') self.assertEqual(stdout.getvalue(), 'hello\n') Taken from Lib/support/__init__.py in the CPython repo. """ return captured_output("stdout") def captured_stderr() -> ContextManager[StreamWrapper]: """ See captured_stdout(). """ return captured_output("stderr") # Simulates an enum def enum(*sequential: Any, **named: Any) -> Type[Any]: enums = dict(zip(sequential, range(len(sequential))), **named) reverse = {value: key for key, value in enums.items()} enums["reverse_mapping"] = reverse return type("Enum", (), enums) def build_netloc(host: str, port: Optional[int]) -> str: """ Build a netloc from a host-port pair """ if port is None: return host if ":" in host: # Only wrap host with square brackets when it is IPv6 host = f"[{host}]" return f"{host}:{port}" def build_url_from_netloc(netloc: str, scheme: str = "https") -> str: """ Build a full URL from a netloc. """ if netloc.count(":") >= 2 and "@" not in netloc and "[" not in netloc: # It must be a bare IPv6 address, so wrap it with brackets. netloc = f"[{netloc}]" return f"{scheme}://{netloc}" def parse_netloc(netloc: str) -> Tuple[str, Optional[int]]: """ Return the host-port pair from a netloc. """ url = build_url_from_netloc(netloc) parsed = urllib.parse.urlparse(url) return parsed.hostname, parsed.port def split_auth_from_netloc(netloc: str) -> NetlocTuple: """ Parse out and remove the auth information from a netloc. Returns: (netloc, (username, password)). """ if "@" not in netloc: return netloc, (None, None) # Split from the right because that's how urllib.parse.urlsplit() # behaves if more than one @ is present (which can be checked using # the password attribute of urlsplit()'s return value). auth, netloc = netloc.rsplit("@", 1) pw: Optional[str] = None if ":" in auth: # Split from the left because that's how urllib.parse.urlsplit() # behaves if more than one : is present (which again can be checked # using the password attribute of the return value) user, pw = auth.split(":", 1) else: user, pw = auth, None user = urllib.parse.unquote(user) if pw is not None: pw = urllib.parse.unquote(pw) return netloc, (user, pw) def redact_netloc(netloc: str) -> str: """ Replace the sensitive data in a netloc with "****", if it exists. For example: - "user:pass@example.com" returns "user:****@example.com" - "accesstoken@example.com" returns "****@example.com" """ netloc, (user, password) = split_auth_from_netloc(netloc) if user is None: return netloc if password is None: user = "****" password = "" else: user = urllib.parse.quote(user) password = ":****" return "{user}{password}@{netloc}".format( user=user, password=password, netloc=netloc ) def _transform_url( url: str, transform_netloc: Callable[[str], Tuple[Any, ...]] ) -> Tuple[str, NetlocTuple]: """Transform and replace netloc in a url. transform_netloc is a function taking the netloc and returning a tuple. The first element of this tuple is the new netloc. The entire tuple is returned. Returns a tuple containing the transformed url as item 0 and the original tuple returned by transform_netloc as item 1. """ purl = urllib.parse.urlsplit(url) netloc_tuple = transform_netloc(purl.netloc) # stripped url url_pieces = (purl.scheme, netloc_tuple[0], purl.path, purl.query, purl.fragment) surl = urllib.parse.urlunsplit(url_pieces) return surl, cast("NetlocTuple", netloc_tuple) def _get_netloc(netloc: str) -> NetlocTuple: return split_auth_from_netloc(netloc) def _redact_netloc(netloc: str) -> Tuple[str]: return (redact_netloc(netloc),) def split_auth_netloc_from_url(url: str) -> Tuple[str, str, Tuple[str, str]]: """ Parse a url into separate netloc, auth, and url with no auth. Returns: (url_without_auth, netloc, (username, password)) """ url_without_auth, (netloc, auth) = _transform_url(url, _get_netloc) return url_without_auth, netloc, auth def remove_auth_from_url(url: str) -> str: """Return a copy of url with 'username:password@' removed.""" # username/pass params are passed to subversion through flags # and are not recognized in the url. return _transform_url(url, _get_netloc)[0] def redact_auth_from_url(url: str) -> str: """Replace the password in a given url with ****.""" return _transform_url(url, _redact_netloc)[0] class HiddenText: def __init__(self, secret: str, redacted: str) -> None: self.secret = secret self.redacted = redacted def __repr__(self) -> str: return "".format(str(self)) def __str__(self) -> str: return self.redacted # This is useful for testing. def __eq__(self, other: Any) -> bool: if type(self) != type(other): return False # The string being used for redaction doesn't also have to match, # just the raw, original string. return self.secret == other.secret def hide_value(value: str) -> HiddenText: return HiddenText(value, redacted="****") def hide_url(url: str) -> HiddenText: redacted = redact_auth_from_url(url) return HiddenText(url, redacted=redacted) def protect_pip_from_modification_on_windows(modifying_pip: bool) -> None: """Protection of pip.exe from modification on Windows On Windows, any operation modifying pip should be run as: python -m pip ... """ pip_names = [ "pip.exe", "pip{}.exe".format(sys.version_info[0]), "pip{}.{}.exe".format(*sys.version_info[:2]), ] # See https://github.com/pypa/pip/issues/1299 for more discussion should_show_use_python_msg = ( modifying_pip and WINDOWS and os.path.basename(sys.argv[0]) in pip_names ) if should_show_use_python_msg: new_command = [sys.executable, "-m", "pip"] + sys.argv[1:] raise CommandError( "To modify pip, please run the following command:\n{}".format( " ".join(new_command) ) ) def is_console_interactive() -> bool: """Is this console interactive?""" return sys.stdin is not None and sys.stdin.isatty() def hash_file(path: str, blocksize: int = 1 << 20) -> Tuple[Any, int]: """Return (hash, length) for path using hashlib.sha256()""" h = hashlib.sha256() length = 0 with open(path, "rb") as f: for block in read_chunks(f, size=blocksize): length += len(block) h.update(block) return h, length def is_wheel_installed() -> bool: """ Return whether the wheel package is installed. """ try: import wheel # noqa: F401 except ImportError: return False return True def pairwise(iterable: Iterable[Any]) -> Iterator[Tuple[Any, Any]]: """ Return paired elements. For example: s -> (s0, s1), (s2, s3), (s4, s5), ... """ iterable = iter(iterable) return zip_longest(iterable, iterable) def partition( pred: Callable[[T], bool], iterable: Iterable[T], ) -> Tuple[Iterable[T], Iterable[T]]: """ Use a predicate to partition entries into false entries and true entries, like partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 """ t1, t2 = tee(iterable) return filterfalse(pred, t1), filter(pred, t2) PKH]l=8python3.10/site-packages/pip/_internal/utils/datetime.pynu["""For when pip wants to check the date or time. """ import datetime def today_is_later_than(year: int, month: int, day: int) -> bool: today = datetime.date.today() given = datetime.date(year, month, day) return today > given PKH]; 6python3.10/site-packages/pip/_internal/utils/models.pynu["""Utilities for defining models """ import operator from typing import Any, Callable, Type class KeyBasedCompareMixin: """Provides comparison capabilities that is based on a key""" __slots__ = ["_compare_key", "_defining_class"] def __init__(self, key: Any, defining_class: Type["KeyBasedCompareMixin"]) -> None: self._compare_key = key self._defining_class = defining_class def __hash__(self) -> int: return hash(self._compare_key) def __lt__(self, other: Any) -> bool: return self._compare(other, operator.__lt__) def __le__(self, other: Any) -> bool: return self._compare(other, operator.__le__) def __gt__(self, other: Any) -> bool: return self._compare(other, operator.__gt__) def __ge__(self, other: Any) -> bool: return self._compare(other, operator.__ge__) def __eq__(self, other: Any) -> bool: return self._compare(other, operator.__eq__) def _compare(self, other: Any, method: Callable[[Any, Any], bool]) -> bool: if not isinstance(other, self._defining_class): return NotImplemented return method(self._compare_key, other._compare_key) PKH]Pg6python3.10/site-packages/pip/_internal/utils/hashes.pynu[import hashlib from typing import TYPE_CHECKING, BinaryIO, Dict, Iterator, List from pip._internal.exceptions import HashMismatch, HashMissing, InstallationError from pip._internal.utils.misc import read_chunks if TYPE_CHECKING: from hashlib import _Hash # NoReturn introduced in 3.6.2; imported only for type checking to maintain # pip compatibility with older patch versions of Python 3.6 from typing import NoReturn # The recommended hash algo of the moment. Change this whenever the state of # the art changes; it won't hurt backward compatibility. FAVORITE_HASH = "sha256" # Names of hashlib algorithms allowed by the --hash option and ``pip hash`` # Currently, those are the ones at least as collision-resistant as sha256. STRONG_HASHES = ["sha256", "sha384", "sha512"] class Hashes: """A wrapper that builds multiple hashes at once and checks them against known-good values """ def __init__(self, hashes: Dict[str, List[str]] = None) -> None: """ :param hashes: A dict of algorithm names pointing to lists of allowed hex digests """ allowed = {} if hashes is not None: for alg, keys in hashes.items(): # Make sure values are always sorted (to ease equality checks) allowed[alg] = sorted(keys) self._allowed = allowed def __and__(self, other: "Hashes") -> "Hashes": if not isinstance(other, Hashes): return NotImplemented # If either of the Hashes object is entirely empty (i.e. no hash # specified at all), all hashes from the other object are allowed. if not other: return self if not self: return other # Otherwise only hashes that present in both objects are allowed. new = {} for alg, values in other._allowed.items(): if alg not in self._allowed: continue new[alg] = [v for v in values if v in self._allowed[alg]] return Hashes(new) @property def digest_count(self) -> int: return sum(len(digests) for digests in self._allowed.values()) def is_hash_allowed(self, hash_name: str, hex_digest: str) -> bool: """Return whether the given hex digest is allowed.""" return hex_digest in self._allowed.get(hash_name, []) def check_against_chunks(self, chunks: Iterator[bytes]) -> None: """Check good hashes against ones built from iterable of chunks of data. Raise HashMismatch if none match. """ gots = {} for hash_name in self._allowed.keys(): try: gots[hash_name] = hashlib.new(hash_name) except (ValueError, TypeError): raise InstallationError(f"Unknown hash name: {hash_name}") for chunk in chunks: for hash in gots.values(): hash.update(chunk) for hash_name, got in gots.items(): if got.hexdigest() in self._allowed[hash_name]: return self._raise(gots) def _raise(self, gots: Dict[str, "_Hash"]) -> "NoReturn": raise HashMismatch(self._allowed, gots) def check_against_file(self, file: BinaryIO) -> None: """Check good hashes against a file-like object Raise HashMismatch if none match. """ return self.check_against_chunks(read_chunks(file)) def check_against_path(self, path: str) -> None: with open(path, "rb") as file: return self.check_against_file(file) def __bool__(self) -> bool: """Return whether I know any known-good hashes.""" return bool(self._allowed) def __eq__(self, other: object) -> bool: if not isinstance(other, Hashes): return NotImplemented return self._allowed == other._allowed def __hash__(self) -> int: return hash( ",".join( sorted( ":".join((alg, digest)) for alg, digest_list in self._allowed.items() for digest in digest_list ) ) ) class MissingHashes(Hashes): """A workalike for Hashes used when we're missing a hash for a requirement It computes the actual hash of the requirement and raises a HashMissing exception showing it to the user. """ def __init__(self) -> None: """Don't offer the ``hashes`` kwarg.""" # Pass our favorite hash in to generate a "gotten hash". With the # empty list, it will never match, so an error will always raise. super().__init__(hashes={FAVORITE_HASH: []}) def _raise(self, gots: Dict[str, "_Hash"]) -> "NoReturn": raise HashMissing(gots[FAVORITE_HASH].hexdigest()) PKH]~4python3.10/site-packages/pip/_internal/utils/urls.pynu[import os import string import urllib.parse import urllib.request from typing import Optional from .compat import WINDOWS def get_url_scheme(url: str) -> Optional[str]: if ":" not in url: return None return url.split(":", 1)[0].lower() def path_to_url(path: str) -> str: """ Convert a path to a file: URL. The path will be made absolute and have quoted path parts. """ path = os.path.normpath(os.path.abspath(path)) url = urllib.parse.urljoin("file:", urllib.request.pathname2url(path)) return url def url_to_path(url: str) -> str: """ Convert a file: URL to a path. """ assert url.startswith( "file:" ), f"You can only turn file: urls into filenames (not {url!r})" _, netloc, path, _, _ = urllib.parse.urlsplit(url) if not netloc or netloc == "localhost": # According to RFC 8089, same as empty authority. netloc = "" elif WINDOWS: # If we have a UNC path, prepend UNC share notation. netloc = "\\\\" + netloc else: raise ValueError( f"non-local file URIs are not supported on this platform: {url!r}" ) path = urllib.request.url2pathname(netloc + path) # On Windows, urlsplit parses the path as something like "/C:/Users/foo". # This creates issues for path-related functions like io.open(), so we try # to detect and strip the leading slash. if ( WINDOWS and not netloc # Not UNC. and len(path) >= 3 and path[0] == "/" # Leading slash to strip. and path[1] in string.ascii_letters # Drive letter. and path[2:4] in (":", ":/") # Colon + end of string, or colon + absolute path. ): path = path[1:] return path PKH]ɘJ'J':python3.10/site-packages/pip/_internal/utils/subprocess.pynu[import logging import os import shlex import subprocess from typing import ( TYPE_CHECKING, Any, Callable, Iterable, List, Mapping, Optional, Union, ) from pip._internal.cli.spinners import SpinnerInterface, open_spinner from pip._internal.exceptions import InstallationSubprocessError from pip._internal.utils.logging import VERBOSE, subprocess_logger from pip._internal.utils.misc import HiddenText if TYPE_CHECKING: # Literal was introduced in Python 3.8. # # TODO: Remove `if TYPE_CHECKING` when dropping support for Python 3.7. from typing import Literal CommandArgs = List[Union[str, HiddenText]] LOG_DIVIDER = "----------------------------------------" def make_command(*args: Union[str, HiddenText, CommandArgs]) -> CommandArgs: """ Create a CommandArgs object. """ command_args: CommandArgs = [] for arg in args: # Check for list instead of CommandArgs since CommandArgs is # only known during type-checking. if isinstance(arg, list): command_args.extend(arg) else: # Otherwise, arg is str or HiddenText. command_args.append(arg) return command_args def format_command_args(args: Union[List[str], CommandArgs]) -> str: """ Format command arguments for display. """ # For HiddenText arguments, display the redacted form by calling str(). # Also, we don't apply str() to arguments that aren't HiddenText since # this can trigger a UnicodeDecodeError in Python 2 if the argument # has type unicode and includes a non-ascii character. (The type # checker doesn't ensure the annotations are correct in all cases.) return " ".join( shlex.quote(str(arg)) if isinstance(arg, HiddenText) else shlex.quote(arg) for arg in args ) def reveal_command_args(args: Union[List[str], CommandArgs]) -> List[str]: """ Return the arguments in their raw, unredacted form. """ return [arg.secret if isinstance(arg, HiddenText) else arg for arg in args] def make_subprocess_output_error( cmd_args: Union[List[str], CommandArgs], cwd: Optional[str], lines: List[str], exit_status: int, ) -> str: """ Create and return the error message to use to log a subprocess error with command output. :param lines: A list of lines, each ending with a newline. """ command = format_command_args(cmd_args) # We know the joined output value ends in a newline. output = "".join(lines) msg = ( # Use a unicode string to avoid "UnicodeEncodeError: 'ascii' # codec can't encode character ..." in Python 2 when a format # argument (e.g. `output`) has a non-ascii character. "Command errored out with exit status {exit_status}:\n" " command: {command_display}\n" " cwd: {cwd_display}\n" "Complete output ({line_count} lines):\n{output}{divider}" ).format( exit_status=exit_status, command_display=command, cwd_display=cwd, line_count=len(lines), output=output, divider=LOG_DIVIDER, ) return msg def call_subprocess( cmd: Union[List[str], CommandArgs], show_stdout: bool = False, cwd: Optional[str] = None, on_returncode: 'Literal["raise", "warn", "ignore"]' = "raise", extra_ok_returncodes: Optional[Iterable[int]] = None, command_desc: Optional[str] = None, extra_environ: Optional[Mapping[str, Any]] = None, unset_environ: Optional[Iterable[str]] = None, spinner: Optional[SpinnerInterface] = None, log_failed_cmd: Optional[bool] = True, stdout_only: Optional[bool] = False, ) -> str: """ Args: show_stdout: if true, use INFO to log the subprocess's stderr and stdout streams. Otherwise, use DEBUG. Defaults to False. extra_ok_returncodes: an iterable of integer return codes that are acceptable, in addition to 0. Defaults to None, which means []. unset_environ: an iterable of environment variable names to unset prior to calling subprocess.Popen(). log_failed_cmd: if false, failed commands are not logged, only raised. stdout_only: if true, return only stdout, else return both. When true, logging of both stdout and stderr occurs when the subprocess has terminated, else logging occurs as subprocess output is produced. """ if extra_ok_returncodes is None: extra_ok_returncodes = [] if unset_environ is None: unset_environ = [] # Most places in pip use show_stdout=False. What this means is-- # # - We connect the child's output (combined stderr and stdout) to a # single pipe, which we read. # - We log this output to stderr at DEBUG level as it is received. # - If DEBUG logging isn't enabled (e.g. if --verbose logging wasn't # requested), then we show a spinner so the user can still see the # subprocess is in progress. # - If the subprocess exits with an error, we log the output to stderr # at ERROR level if it hasn't already been displayed to the console # (e.g. if --verbose logging wasn't enabled). This way we don't log # the output to the console twice. # # If show_stdout=True, then the above is still done, but with DEBUG # replaced by INFO. if show_stdout: # Then log the subprocess output at INFO level. log_subprocess = subprocess_logger.info used_level = logging.INFO else: # Then log the subprocess output using VERBOSE. This also ensures # it will be logged to the log file (aka user_log), if enabled. log_subprocess = subprocess_logger.verbose used_level = VERBOSE # Whether the subprocess will be visible in the console. showing_subprocess = subprocess_logger.getEffectiveLevel() <= used_level # Only use the spinner if we're not showing the subprocess output # and we have a spinner. use_spinner = not showing_subprocess and spinner is not None if command_desc is None: command_desc = format_command_args(cmd) log_subprocess("Running command %s", command_desc) env = os.environ.copy() if extra_environ: env.update(extra_environ) for name in unset_environ: env.pop(name, None) try: proc = subprocess.Popen( # Convert HiddenText objects to the underlying str. reveal_command_args(cmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT if not stdout_only else subprocess.PIPE, cwd=cwd, env=env, errors="backslashreplace", ) except Exception as exc: if log_failed_cmd: subprocess_logger.critical( "Error %s while executing command %s", exc, command_desc, ) raise all_output = [] if not stdout_only: assert proc.stdout assert proc.stdin proc.stdin.close() # In this mode, stdout and stderr are in the same pipe. while True: line: str = proc.stdout.readline() if not line: break line = line.rstrip() all_output.append(line + "\n") # Show the line immediately. log_subprocess(line) # Update the spinner. if use_spinner: assert spinner spinner.spin() try: proc.wait() finally: if proc.stdout: proc.stdout.close() output = "".join(all_output) else: # In this mode, stdout and stderr are in different pipes. # We must use communicate() which is the only safe way to read both. out, err = proc.communicate() # log line by line to preserve pip log indenting for out_line in out.splitlines(): log_subprocess(out_line) all_output.append(out) for err_line in err.splitlines(): log_subprocess(err_line) all_output.append(err) output = out proc_had_error = proc.returncode and proc.returncode not in extra_ok_returncodes if use_spinner: assert spinner if proc_had_error: spinner.finish("error") else: spinner.finish("done") if proc_had_error: if on_returncode == "raise": if not showing_subprocess and log_failed_cmd: # Then the subprocess streams haven't been logged to the # console yet. msg = make_subprocess_output_error( cmd_args=cmd, cwd=cwd, lines=all_output, exit_status=proc.returncode, ) subprocess_logger.error(msg) raise InstallationSubprocessError(proc.returncode, command_desc) elif on_returncode == "warn": subprocess_logger.warning( 'Command "%s" had error code %s in %s', command_desc, proc.returncode, cwd, ) elif on_returncode == "ignore": pass else: raise ValueError(f"Invalid value: on_returncode={on_returncode!r}") return output def runner_with_spinner_message(message: str) -> Callable[..., None]: """Provide a subprocess_runner that shows a spinner message. Intended for use with for pep517's Pep517HookCaller. Thus, the runner has an API that matches what's expected by Pep517HookCaller.subprocess_runner. """ def runner( cmd: List[str], cwd: Optional[str] = None, extra_environ: Optional[Mapping[str, Any]] = None, ) -> None: with open_spinner(message) as spinner: call_subprocess( cmd, cwd=cwd, extra_environ=extra_environ, spinner=spinner, ) return runner PKH] int: """Get the current umask which involves having to set it temporarily.""" mask = os.umask(0) os.umask(mask) return mask def split_leading_dir(path: str) -> List[str]: path = path.lstrip("/").lstrip("\\") if "/" in path and ( ("\\" in path and path.find("/") < path.find("\\")) or "\\" not in path ): return path.split("/", 1) elif "\\" in path: return path.split("\\", 1) else: return [path, ""] def has_leading_dir(paths: Iterable[str]) -> bool: """Returns true if all the paths have the same leading path name (i.e., everything is in one subdirectory in an archive)""" common_prefix = None for path in paths: prefix, rest = split_leading_dir(path) if not prefix: return False elif common_prefix is None: common_prefix = prefix elif prefix != common_prefix: return False return True def is_within_directory(directory: str, target: str) -> bool: """ Return true if the absolute path of target is within the directory """ abs_directory = os.path.abspath(directory) abs_target = os.path.abspath(target) prefix = os.path.commonprefix([abs_directory, abs_target]) return prefix == abs_directory def set_extracted_file_to_default_mode_plus_executable(path: str) -> None: """ Make file present at path have execute for user/group/world (chmod +x) is no-op on windows per python docs """ os.chmod(path, (0o777 & ~current_umask() | 0o111)) def zip_item_is_executable(info: ZipInfo) -> bool: mode = info.external_attr >> 16 # if mode and regular file and any execute permissions for # user/group/world? return bool(mode and stat.S_ISREG(mode) and mode & 0o111) def unzip_file(filename: str, location: str, flatten: bool = True) -> None: """ Unzip the file (with path `filename`) to the destination `location`. All files are written based on system defaults and umask (i.e. permissions are not preserved), except that regular file members with any execute permissions (user, group, or world) have "chmod +x" applied after being written. Note that for windows, any execute changes using os.chmod are no-ops per the python docs. """ ensure_dir(location) zipfp = open(filename, "rb") try: zip = zipfile.ZipFile(zipfp, allowZip64=True) leading = has_leading_dir(zip.namelist()) and flatten for info in zip.infolist(): name = info.filename fn = name if leading: fn = split_leading_dir(name)[1] fn = os.path.join(location, fn) dir = os.path.dirname(fn) if not is_within_directory(location, fn): message = ( "The zip file ({}) has a file ({}) trying to install " "outside target directory ({})" ) raise InstallationError(message.format(filename, fn, location)) if fn.endswith("/") or fn.endswith("\\"): # A directory ensure_dir(fn) else: ensure_dir(dir) # Don't use read() to avoid allocating an arbitrarily large # chunk of memory for the file's content fp = zip.open(name) try: with open(fn, "wb") as destfp: shutil.copyfileobj(fp, destfp) finally: fp.close() if zip_item_is_executable(info): set_extracted_file_to_default_mode_plus_executable(fn) finally: zipfp.close() def untar_file(filename: str, location: str) -> None: """ Untar the file (with path `filename`) to the destination `location`. All files are written based on system defaults and umask (i.e. permissions are not preserved), except that regular file members with any execute permissions (user, group, or world) have "chmod +x" applied after being written. Note that for windows, any execute changes using os.chmod are no-ops per the python docs. """ ensure_dir(location) if filename.lower().endswith(".gz") or filename.lower().endswith(".tgz"): mode = "r:gz" elif filename.lower().endswith(BZ2_EXTENSIONS): mode = "r:bz2" elif filename.lower().endswith(XZ_EXTENSIONS): mode = "r:xz" elif filename.lower().endswith(".tar"): mode = "r" else: logger.warning( "Cannot determine compression type for file %s", filename, ) mode = "r:*" tar = tarfile.open(filename, mode, encoding="utf-8") try: leading = has_leading_dir([member.name for member in tar.getmembers()]) for member in tar.getmembers(): fn = member.name if leading: fn = split_leading_dir(fn)[1] path = os.path.join(location, fn) if not is_within_directory(location, path): message = ( "The tar file ({}) has a file ({}) trying to install " "outside target directory ({})" ) raise InstallationError(message.format(filename, path, location)) if member.isdir(): ensure_dir(path) elif member.issym(): try: # https://github.com/python/typeshed/issues/2673 tar._extract_member(member, path) # type: ignore except Exception as exc: # Some corrupt tar files seem to produce this # (specifically bad symlinks) logger.warning( "In the tar file %s the member %s is invalid: %s", filename, member.name, exc, ) continue else: try: fp = tar.extractfile(member) except (KeyError, AttributeError) as exc: # Some corrupt tar files seem to produce this # (specifically bad symlinks) logger.warning( "In the tar file %s the member %s is invalid: %s", filename, member.name, exc, ) continue ensure_dir(os.path.dirname(path)) assert fp is not None with open(path, "wb") as destfp: shutil.copyfileobj(fp, destfp) fp.close() # Update the timestamp (useful for cython compiled files) tar.utime(member, path) # member have any execute permissions for user/group/world? if member.mode & 0o111: set_extracted_file_to_default_mode_plus_executable(path) finally: tar.close() def unpack_file( filename: str, location: str, content_type: Optional[str] = None, ) -> None: filename = os.path.realpath(filename) if ( content_type == "application/zip" or filename.lower().endswith(ZIP_EXTENSIONS) or zipfile.is_zipfile(filename) ): unzip_file(filename, location, flatten=not filename.endswith(".whl")) elif ( content_type == "application/x-gzip" or tarfile.is_tarfile(filename) or filename.lower().endswith(TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS) ): untar_file(filename, location) else: # FIXME: handle? # FIXME: magic signatures? logger.critical( "Cannot unpack file %s (downloaded from %s, content-type: %s); " "cannot detect archive format", filename, location, content_type, ) raise InstallationError(f"Cannot determine archive format of {location}") PKH]>9=python3.10/site-packages/pip/_internal/utils/pkg_resources.pynu[from typing import Dict, Iterable, List from pip._vendor.pkg_resources import yield_lines class DictMetadata: """IMetadataProvider that reads metadata files from a dictionary.""" def __init__(self, metadata: Dict[str, bytes]) -> None: self._metadata = metadata def has_metadata(self, name: str) -> bool: return name in self._metadata def get_metadata(self, name: str) -> str: try: return self._metadata[name].decode() except UnicodeDecodeError as e: # Mirrors handling done in pkg_resources.NullProvider. e.reason += f" in {name} file" raise def get_metadata_lines(self, name: str) -> Iterable[str]: return yield_lines(self.get_metadata(name)) def metadata_isdir(self, name: str) -> bool: return False def metadata_listdir(self, name: str) -> List[str]: return [] def run_script(self, script_name: str, namespace: str) -> None: pass PKH]rB7python3.10/site-packages/pip/_internal/utils/appdirs.pynu[""" This code wraps the vendored appdirs module to so the return values are compatible for the current pip code base. The intention is to rewrite current usages gradually, keeping the tests pass, and eventually drop this after all usages are changed. """ import os import sys from typing import List from pip._vendor import platformdirs as _appdirs def user_cache_dir(appname: str) -> str: return _appdirs.user_cache_dir(appname, appauthor=False) def _macos_user_config_dir(appname: str, roaming: bool = True) -> str: # Use ~/Application Support/pip, if the directory exists. path = _appdirs.user_data_dir(appname, appauthor=False, roaming=roaming) if os.path.isdir(path): return path # Use a Linux-like ~/.config/pip, by default. linux_like_path = "~/.config/" if appname: linux_like_path = os.path.join(linux_like_path, appname) return os.path.expanduser(linux_like_path) def user_config_dir(appname: str, roaming: bool = True) -> str: if sys.platform == "darwin": return _macos_user_config_dir(appname, roaming) return _appdirs.user_config_dir(appname, appauthor=False, roaming=roaming) # for the discussion regarding site_config_dir locations # see def site_config_dirs(appname: str) -> List[str]: if sys.platform == "darwin": return [_appdirs.site_data_dir(appname, appauthor=False, multipath=True)] dirval = _appdirs.site_config_dir(appname, appauthor=False, multipath=True) if sys.platform == "win32": return [dirval] # Unix-y system. Look in /etc as well. return dirval.split(os.pathsep) + ["/etc"] PKH]9YY@python3.10/site-packages/pip/_internal/utils/setuptools_build.pynu[import sys from typing import List, Optional, Sequence # Shim to wrap setup.py invocation with setuptools # # We set sys.argv[0] to the path to the underlying setup.py file so # setuptools / distutils don't take the path to the setup.py to be "-c" when # invoking via the shim. This avoids e.g. the following manifest_maker # warning: "warning: manifest_maker: standard file '-c' not found". _SETUPTOOLS_SHIM = ( "import io, os, sys, setuptools, tokenize; sys.argv[0] = {0!r}; __file__={0!r};" "f = getattr(tokenize, 'open', open)(__file__) " "if os.path.exists(__file__) " "else io.StringIO('from setuptools import setup; setup()');" "code = f.read().replace('\\r\\n', '\\n');" "f.close();" "exec(compile(code, __file__, 'exec'))" ) def make_setuptools_shim_args( setup_py_path: str, global_options: Sequence[str] = None, no_user_config: bool = False, unbuffered_output: bool = False, ) -> List[str]: """ Get setuptools command arguments with shim wrapped setup file invocation. :param setup_py_path: The path to setup.py to be wrapped. :param global_options: Additional global options. :param no_user_config: If True, disables personal user configuration. :param unbuffered_output: If True, adds the unbuffered switch to the argument list. """ args = [sys.executable] if unbuffered_output: args += ["-u"] args += ["-c", _SETUPTOOLS_SHIM.format(setup_py_path)] if global_options: args += global_options if no_user_config: args += ["--no-user-cfg"] return args def make_setuptools_bdist_wheel_args( setup_py_path: str, global_options: Sequence[str], build_options: Sequence[str], destination_dir: str, ) -> List[str]: # NOTE: Eventually, we'd want to also -S to the flags here, when we're # isolating. Currently, it breaks Python in virtualenvs, because it # relies on site.py to find parts of the standard library outside the # virtualenv. args = make_setuptools_shim_args( setup_py_path, global_options=global_options, unbuffered_output=True ) args += ["bdist_wheel", "-d", destination_dir] args += build_options return args def make_setuptools_clean_args( setup_py_path: str, global_options: Sequence[str], ) -> List[str]: args = make_setuptools_shim_args( setup_py_path, global_options=global_options, unbuffered_output=True ) args += ["clean", "--all"] return args def make_setuptools_develop_args( setup_py_path: str, global_options: Sequence[str], install_options: Sequence[str], no_user_config: bool, prefix: Optional[str], home: Optional[str], use_user_site: bool, ) -> List[str]: assert not (use_user_site and prefix) args = make_setuptools_shim_args( setup_py_path, global_options=global_options, no_user_config=no_user_config, ) args += ["develop", "--no-deps"] args += install_options if prefix: args += ["--prefix", prefix] if home is not None: args += ["--install-dir", home] if use_user_site: args += ["--user", "--prefix="] return args def make_setuptools_egg_info_args( setup_py_path: str, egg_info_dir: Optional[str], no_user_config: bool, ) -> List[str]: args = make_setuptools_shim_args(setup_py_path, no_user_config=no_user_config) args += ["egg_info"] if egg_info_dir: args += ["--egg-base", egg_info_dir] return args def make_setuptools_install_args( setup_py_path: str, global_options: Sequence[str], install_options: Sequence[str], record_filename: str, root: Optional[str], prefix: Optional[str], header_dir: Optional[str], home: Optional[str], use_user_site: bool, no_user_config: bool, pycompile: bool, ) -> List[str]: assert not (use_user_site and prefix) assert not (use_user_site and root) args = make_setuptools_shim_args( setup_py_path, global_options=global_options, no_user_config=no_user_config, unbuffered_output=True, ) args += ["install", "--record", record_filename] args += ["--single-version-externally-managed"] if root is not None: args += ["--root", root] if prefix is not None: args += ["--prefix", prefix] if home is not None: args += ["--home", home] if use_user_site: args += ["--user", "--prefix="] if pycompile: args += ["--compile"] else: args += ["--no-compile"] if header_dir: args += ["--install-headers", header_dir] args += install_options return args PKH]f=O 9python3.10/site-packages/pip/_internal/utils/packaging.pynu[import functools import logging from email.message import Message from email.parser import FeedParser from typing import Optional, Tuple from pip._vendor import pkg_resources from pip._vendor.packaging import specifiers, version from pip._vendor.packaging.requirements import Requirement from pip._vendor.pkg_resources import Distribution from pip._internal.exceptions import NoneMetadataError from pip._internal.utils.misc import display_path logger = logging.getLogger(__name__) def check_requires_python( requires_python: Optional[str], version_info: Tuple[int, ...] ) -> bool: """ Check if the given Python version matches a "Requires-Python" specifier. :param version_info: A 3-tuple of ints representing a Python major-minor-micro version to check (e.g. `sys.version_info[:3]`). :return: `True` if the given Python version satisfies the requirement. Otherwise, return `False`. :raises InvalidSpecifier: If `requires_python` has an invalid format. """ if requires_python is None: # The package provides no information return True requires_python_specifier = specifiers.SpecifierSet(requires_python) python_version = version.parse(".".join(map(str, version_info))) return python_version in requires_python_specifier def get_metadata(dist: Distribution) -> Message: """ :raises NoneMetadataError: if the distribution reports `has_metadata()` True but `get_metadata()` returns None. """ metadata_name = "METADATA" if isinstance(dist, pkg_resources.DistInfoDistribution) and dist.has_metadata( metadata_name ): metadata = dist.get_metadata(metadata_name) elif dist.has_metadata("PKG-INFO"): metadata_name = "PKG-INFO" metadata = dist.get_metadata(metadata_name) else: logger.warning("No metadata found in %s", display_path(dist.location)) metadata = "" if metadata is None: raise NoneMetadataError(dist, metadata_name) feed_parser = FeedParser() # The following line errors out if with a "NoneType" TypeError if # passed metadata=None. feed_parser.feed(metadata) return feed_parser.close() def get_installer(dist: Distribution) -> str: if dist.has_metadata("INSTALLER"): for line in dist.get_metadata_lines("INSTALLER"): if line.strip(): return line.strip() return "" @functools.lru_cache(maxsize=512) def get_requirement(req_string: str) -> Requirement: """Construct a packaging.Requirement object with caching""" # Parsing requirement strings is expensive, and is also expected to happen # with a low diversity of different arguments (at least relative the number # constructed). This method adds a cache to requirement object creation to # minimize repeated parsing of the same string to construct equivalent # Requirement objects. return Requirement(req_string) PKH]95python3.10/site-packages/pip/_internal/utils/wheel.pynu["""Support functions for working with wheel files. """ import logging from email.message import Message from email.parser import Parser from typing import Dict, Tuple from zipfile import BadZipFile, ZipFile from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.pkg_resources import DistInfoDistribution, Distribution from pip._internal.exceptions import UnsupportedWheel from pip._internal.utils.pkg_resources import DictMetadata VERSION_COMPATIBLE = (1, 0) logger = logging.getLogger(__name__) class WheelMetadata(DictMetadata): """Metadata provider that maps metadata decoding exceptions to our internal exception type. """ def __init__(self, metadata: Dict[str, bytes], wheel_name: str) -> None: super().__init__(metadata) self._wheel_name = wheel_name def get_metadata(self, name: str) -> str: try: return super().get_metadata(name) except UnicodeDecodeError as e: # Augment the default error with the origin of the file. raise UnsupportedWheel( f"Error decoding metadata for {self._wheel_name}: {e}" ) def pkg_resources_distribution_for_wheel( wheel_zip: ZipFile, name: str, location: str ) -> Distribution: """Get a pkg_resources distribution given a wheel. :raises UnsupportedWheel: on any errors """ info_dir, _ = parse_wheel(wheel_zip, name) metadata_files = [p for p in wheel_zip.namelist() if p.startswith(f"{info_dir}/")] metadata_text: Dict[str, bytes] = {} for path in metadata_files: _, metadata_name = path.split("/", 1) try: metadata_text[metadata_name] = read_wheel_metadata_file(wheel_zip, path) except UnsupportedWheel as e: raise UnsupportedWheel("{} has an invalid wheel, {}".format(name, str(e))) metadata = WheelMetadata(metadata_text, location) return DistInfoDistribution(location=location, metadata=metadata, project_name=name) def parse_wheel(wheel_zip: ZipFile, name: str) -> Tuple[str, Message]: """Extract information from the provided wheel, ensuring it meets basic standards. Returns the name of the .dist-info directory and the parsed WHEEL metadata. """ try: info_dir = wheel_dist_info_dir(wheel_zip, name) metadata = wheel_metadata(wheel_zip, info_dir) version = wheel_version(metadata) except UnsupportedWheel as e: raise UnsupportedWheel("{} has an invalid wheel, {}".format(name, str(e))) check_compatibility(version, name) return info_dir, metadata def wheel_dist_info_dir(source: ZipFile, name: str) -> str: """Returns the name of the contained .dist-info directory. Raises AssertionError or UnsupportedWheel if not found, >1 found, or it doesn't match the provided name. """ # Zip file path separators must be / subdirs = {p.split("/", 1)[0] for p in source.namelist()} info_dirs = [s for s in subdirs if s.endswith(".dist-info")] if not info_dirs: raise UnsupportedWheel(".dist-info directory not found") if len(info_dirs) > 1: raise UnsupportedWheel( "multiple .dist-info directories found: {}".format(", ".join(info_dirs)) ) info_dir = info_dirs[0] info_dir_name = canonicalize_name(info_dir) canonical_name = canonicalize_name(name) if not info_dir_name.startswith(canonical_name): raise UnsupportedWheel( ".dist-info directory {!r} does not start with {!r}".format( info_dir, canonical_name ) ) return info_dir def read_wheel_metadata_file(source: ZipFile, path: str) -> bytes: try: return source.read(path) # BadZipFile for general corruption, KeyError for missing entry, # and RuntimeError for password-protected files except (BadZipFile, KeyError, RuntimeError) as e: raise UnsupportedWheel(f"could not read {path!r} file: {e!r}") def wheel_metadata(source: ZipFile, dist_info_dir: str) -> Message: """Return the WHEEL metadata of an extracted wheel, if possible. Otherwise, raise UnsupportedWheel. """ path = f"{dist_info_dir}/WHEEL" # Zip file path separators must be / wheel_contents = read_wheel_metadata_file(source, path) try: wheel_text = wheel_contents.decode() except UnicodeDecodeError as e: raise UnsupportedWheel(f"error decoding {path!r}: {e!r}") # FeedParser (used by Parser) does not raise any exceptions. The returned # message may have .defects populated, but for backwards-compatibility we # currently ignore them. return Parser().parsestr(wheel_text) def wheel_version(wheel_data: Message) -> Tuple[int, ...]: """Given WHEEL metadata, return the parsed Wheel-Version. Otherwise, raise UnsupportedWheel. """ version_text = wheel_data["Wheel-Version"] if version_text is None: raise UnsupportedWheel("WHEEL is missing Wheel-Version") version = version_text.strip() try: return tuple(map(int, version.split("."))) except ValueError: raise UnsupportedWheel(f"invalid Wheel-Version: {version!r}") def check_compatibility(version: Tuple[int, ...], name: str) -> None: """Raises errors or warns if called with an incompatible Wheel-Version. pip should refuse to install a Wheel-Version that's a major series ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when installing a version only minor version ahead (e.g 1.2 > 1.1). version: a 2-tuple representing a Wheel-Version (Major, Minor) name: name of wheel or package to raise exception about :raises UnsupportedWheel: when an incompatible Wheel-Version is given """ if version[0] > VERSION_COMPATIBLE[0]: raise UnsupportedWheel( "{}'s Wheel-Version ({}) is not compatible with this version " "of pip".format(name, ".".join(map(str, version))) ) elif version > VERSION_COMPATIBLE: logger.warning( "Installing from a newer Wheel-Version (%s)", ".".join(map(str, version)), ) PKH]#/>python3.10/site-packages/pip/_internal/utils/distutils_args.pynu[from distutils.errors import DistutilsArgError from distutils.fancy_getopt import FancyGetopt from typing import Dict, List _options = [ ("exec-prefix=", None, ""), ("home=", None, ""), ("install-base=", None, ""), ("install-data=", None, ""), ("install-headers=", None, ""), ("install-lib=", None, ""), ("install-platlib=", None, ""), ("install-purelib=", None, ""), ("install-scripts=", None, ""), ("prefix=", None, ""), ("root=", None, ""), ("user", None, ""), ] # typeshed doesn't permit Tuple[str, None, str], see python/typeshed#3469. _distutils_getopt = FancyGetopt(_options) # type: ignore def parse_distutils_args(args: List[str]) -> Dict[str, str]: """Parse provided arguments, returning an object that has the matched arguments. Any unknown arguments are ignored. """ result = {} for arg in args: try: _, match = _distutils_getopt.getopt(args=[arg]) except DistutilsArgError: # We don't care about any other options, which here may be # considered unrecognized since our option list is not # exhaustive. pass else: result.update(match.__dict__) return result PKH]>S| | 8python3.10/site-packages/pip/_internal/utils/parallel.pynu["""Convenient parallelization of higher order functions. This module provides two helper functions, with appropriate fallbacks on Python 2 and on systems lacking support for synchronization mechanisms: - map_multiprocess - map_multithread These helpers work like Python 3's map, with two differences: - They don't guarantee the order of processing of the elements of the iterable. - The underlying process/thread pools chop the iterable into a number of chunks, so that for very long iterables using a large value for chunksize can make the job complete much faster than using the default value of 1. """ __all__ = ["map_multiprocess", "map_multithread"] from contextlib import contextmanager from multiprocessing import Pool as ProcessPool from multiprocessing import pool from multiprocessing.dummy import Pool as ThreadPool from typing import Callable, Iterable, Iterator, TypeVar, Union from pip._vendor.requests.adapters import DEFAULT_POOLSIZE Pool = Union[pool.Pool, pool.ThreadPool] S = TypeVar("S") T = TypeVar("T") # On platforms without sem_open, multiprocessing[.dummy] Pool # cannot be created. try: import multiprocessing.synchronize # noqa except ImportError: LACK_SEM_OPEN = True else: LACK_SEM_OPEN = False # Incredibly large timeout to work around bpo-8296 on Python 2. TIMEOUT = 2000000 @contextmanager def closing(pool: Pool) -> Iterator[Pool]: """Return a context manager making sure the pool closes properly.""" try: yield pool finally: # For Pool.imap*, close and join are needed # for the returned iterator to begin yielding. pool.close() pool.join() pool.terminate() def _map_fallback( func: Callable[[S], T], iterable: Iterable[S], chunksize: int = 1 ) -> Iterator[T]: """Make an iterator applying func to each element in iterable. This function is the sequential fallback either on Python 2 where Pool.imap* doesn't react to KeyboardInterrupt or when sem_open is unavailable. """ return map(func, iterable) def _map_multiprocess( func: Callable[[S], T], iterable: Iterable[S], chunksize: int = 1 ) -> Iterator[T]: """Chop iterable into chunks and submit them to a process pool. For very long iterables using a large value for chunksize can make the job complete much faster than using the default value of 1. Return an unordered iterator of the results. """ with closing(ProcessPool()) as pool: return pool.imap_unordered(func, iterable, chunksize) def _map_multithread( func: Callable[[S], T], iterable: Iterable[S], chunksize: int = 1 ) -> Iterator[T]: """Chop iterable into chunks and submit them to a thread pool. For very long iterables using a large value for chunksize can make the job complete much faster than using the default value of 1. Return an unordered iterator of the results. """ with closing(ThreadPool(DEFAULT_POOLSIZE)) as pool: return pool.imap_unordered(func, iterable, chunksize) if LACK_SEM_OPEN: map_multiprocess = map_multithread = _map_fallback else: map_multiprocess = _map_multiprocess map_multithread = _map_multithread PKH]ck\\6python3.10/site-packages/pip/_internal/utils/compat.pynu["""Stuff that differs in different Python versions and platform distributions.""" import logging import os import sys __all__ = ["get_path_uid", "stdlib_pkgs", "WINDOWS"] logger = logging.getLogger(__name__) def has_tls() -> bool: try: import _ssl # noqa: F401 # ignore unused return True except ImportError: pass from pip._vendor.urllib3.util import IS_PYOPENSSL return IS_PYOPENSSL def get_path_uid(path: str) -> int: """ Return path's uid. Does not follow symlinks: https://github.com/pypa/pip/pull/935#discussion_r5307003 Placed this function in compat due to differences on AIX and Jython, that should eventually go away. :raises OSError: When path is a symlink or can't be read. """ if hasattr(os, "O_NOFOLLOW"): fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) file_uid = os.fstat(fd).st_uid os.close(fd) else: # AIX and Jython # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW if not os.path.islink(path): # older versions of Jython don't have `os.fstat` file_uid = os.stat(path).st_uid else: # raise OSError for parity with os.O_NOFOLLOW above raise OSError(f"{path} is a symlink; Will not return uid for symlinks") return file_uid # packages in the stdlib that may have installation metadata, but should not be # considered 'installed'. this theoretically could be determined based on # dist.location (py27:`sysconfig.get_paths()['stdlib']`, # py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may # make this ineffective, so hard-coding stdlib_pkgs = {"python", "wsgiref", "argparse"} # windows detection, covers cpython and ironpython WINDOWS = sys.platform.startswith("win") or (sys.platform == "cli" and os.name == "nt") PKH]Z' :python3.10/site-packages/pip/_internal/utils/virtualenv.pynu[import logging import os import re import site import sys from typing import List, Optional logger = logging.getLogger(__name__) _INCLUDE_SYSTEM_SITE_PACKAGES_REGEX = re.compile( r"include-system-site-packages\s*=\s*(?Ptrue|false)" ) def _running_under_venv() -> bool: """Checks if sys.base_prefix and sys.prefix match. This handles PEP 405 compliant virtual environments. """ return sys.prefix != getattr(sys, "base_prefix", sys.prefix) def _running_under_regular_virtualenv() -> bool: """Checks if sys.real_prefix is set. This handles virtual environments created with pypa's virtualenv. """ # pypa/virtualenv case return hasattr(sys, "real_prefix") def running_under_virtualenv() -> bool: """Return True if we're running inside a virtualenv, False otherwise.""" return _running_under_venv() or _running_under_regular_virtualenv() def _get_pyvenv_cfg_lines() -> Optional[List[str]]: """Reads {sys.prefix}/pyvenv.cfg and returns its contents as list of lines Returns None, if it could not read/access the file. """ pyvenv_cfg_file = os.path.join(sys.prefix, "pyvenv.cfg") try: # Although PEP 405 does not specify, the built-in venv module always # writes with UTF-8. (pypa/pip#8717) with open(pyvenv_cfg_file, encoding="utf-8") as f: return f.read().splitlines() # avoids trailing newlines except OSError: return None def _no_global_under_venv() -> bool: """Check `{sys.prefix}/pyvenv.cfg` for system site-packages inclusion PEP 405 specifies that when system site-packages are not supposed to be visible from a virtual environment, `pyvenv.cfg` must contain the following line: include-system-site-packages = false Additionally, log a warning if accessing the file fails. """ cfg_lines = _get_pyvenv_cfg_lines() if cfg_lines is None: # We're not in a "sane" venv, so assume there is no system # site-packages access (since that's PEP 405's default state). logger.warning( "Could not access 'pyvenv.cfg' despite a virtual environment " "being active. Assuming global site-packages is not accessible " "in this environment." ) return True for line in cfg_lines: match = _INCLUDE_SYSTEM_SITE_PACKAGES_REGEX.match(line) if match is not None and match.group("value") == "false": return True return False def _no_global_under_regular_virtualenv() -> bool: """Check if "no-global-site-packages.txt" exists beside site.py This mirrors logic in pypa/virtualenv for determining whether system site-packages are visible in the virtual environment. """ site_mod_dir = os.path.dirname(os.path.abspath(site.__file__)) no_global_site_packages_file = os.path.join( site_mod_dir, "no-global-site-packages.txt", ) return os.path.exists(no_global_site_packages_file) def virtualenv_no_global() -> bool: """Returns a boolean, whether running in venv with no system site-packages.""" # PEP 405 compliance needs to be checked first since virtualenv >=20 would # return True for both checks, but is only able to use the PEP 405 config. if _running_under_venv(): return _no_global_under_venv() if _running_under_regular_virtualenv(): return _no_global_under_regular_virtualenv() return False PKH]E8python3.10/site-packages/pip/_internal/utils/temp_dir.pynu[import errno import itertools import logging import os.path import tempfile from contextlib import ExitStack, contextmanager from typing import Any, Dict, Iterator, Optional, TypeVar, Union from pip._internal.utils.misc import enum, rmtree logger = logging.getLogger(__name__) _T = TypeVar("_T", bound="TempDirectory") # Kinds of temporary directories. Only needed for ones that are # globally-managed. tempdir_kinds = enum( BUILD_ENV="build-env", EPHEM_WHEEL_CACHE="ephem-wheel-cache", REQ_BUILD="req-build", ) _tempdir_manager: Optional[ExitStack] = None @contextmanager def global_tempdir_manager() -> Iterator[None]: global _tempdir_manager with ExitStack() as stack: old_tempdir_manager, _tempdir_manager = _tempdir_manager, stack try: yield finally: _tempdir_manager = old_tempdir_manager class TempDirectoryTypeRegistry: """Manages temp directory behavior""" def __init__(self) -> None: self._should_delete: Dict[str, bool] = {} def set_delete(self, kind: str, value: bool) -> None: """Indicate whether a TempDirectory of the given kind should be auto-deleted. """ self._should_delete[kind] = value def get_delete(self, kind: str) -> bool: """Get configured auto-delete flag for a given TempDirectory type, default True. """ return self._should_delete.get(kind, True) _tempdir_registry: Optional[TempDirectoryTypeRegistry] = None @contextmanager def tempdir_registry() -> Iterator[TempDirectoryTypeRegistry]: """Provides a scoped global tempdir registry that can be used to dictate whether directories should be deleted. """ global _tempdir_registry old_tempdir_registry = _tempdir_registry _tempdir_registry = TempDirectoryTypeRegistry() try: yield _tempdir_registry finally: _tempdir_registry = old_tempdir_registry class _Default: pass _default = _Default() class TempDirectory: """Helper class that owns and cleans up a temporary directory. This class can be used as a context manager or as an OO representation of a temporary directory. Attributes: path Location to the created temporary directory delete Whether the directory should be deleted when exiting (when used as a contextmanager) Methods: cleanup() Deletes the temporary directory When used as a context manager, if the delete attribute is True, on exiting the context the temporary directory is deleted. """ def __init__( self, path: Optional[str] = None, delete: Union[bool, None, _Default] = _default, kind: str = "temp", globally_managed: bool = False, ): super().__init__() if delete is _default: if path is not None: # If we were given an explicit directory, resolve delete option # now. delete = False else: # Otherwise, we wait until cleanup and see what # tempdir_registry says. delete = None # The only time we specify path is in for editables where it # is the value of the --src option. if path is None: path = self._create(kind) self._path = path self._deleted = False self.delete = delete self.kind = kind if globally_managed: assert _tempdir_manager is not None _tempdir_manager.enter_context(self) @property def path(self) -> str: assert not self._deleted, f"Attempted to access deleted path: {self._path}" return self._path def __repr__(self) -> str: return f"<{self.__class__.__name__} {self.path!r}>" def __enter__(self: _T) -> _T: return self def __exit__(self, exc: Any, value: Any, tb: Any) -> None: if self.delete is not None: delete = self.delete elif _tempdir_registry: delete = _tempdir_registry.get_delete(self.kind) else: delete = True if delete: self.cleanup() def _create(self, kind: str) -> str: """Create a temporary directory and store its path in self.path""" # We realpath here because some systems have their default tmpdir # symlinked to another directory. This tends to confuse build # scripts, so we canonicalize the path by traversing potential # symlinks here. path = os.path.realpath(tempfile.mkdtemp(prefix=f"pip-{kind}-")) logger.debug("Created temporary directory: %s", path) return path def cleanup(self) -> None: """Remove the temporary directory created and reset state""" self._deleted = True if not os.path.exists(self._path): return rmtree(self._path) class AdjacentTempDirectory(TempDirectory): """Helper class that creates a temporary directory adjacent to a real one. Attributes: original The original directory to create a temp directory for. path After calling create() or entering, contains the full path to the temporary directory. delete Whether the directory should be deleted when exiting (when used as a contextmanager) """ # The characters that may be used to name the temp directory # We always prepend a ~ and then rotate through these until # a usable name is found. # pkg_resources raises a different error for .dist-info folder # with leading '-' and invalid metadata LEADING_CHARS = "-~.=%0123456789" def __init__(self, original: str, delete: Optional[bool] = None) -> None: self.original = original.rstrip("/\\") super().__init__(delete=delete) @classmethod def _generate_names(cls, name: str) -> Iterator[str]: """Generates a series of temporary names. The algorithm replaces the leading characters in the name with ones that are valid filesystem characters, but are not valid package names (for both Python and pip definitions of package). """ for i in range(1, len(name)): for candidate in itertools.combinations_with_replacement( cls.LEADING_CHARS, i - 1 ): new_name = "~" + "".join(candidate) + name[i:] if new_name != name: yield new_name # If we make it this far, we will have to make a longer name for i in range(len(cls.LEADING_CHARS)): for candidate in itertools.combinations_with_replacement( cls.LEADING_CHARS, i ): new_name = "~" + "".join(candidate) + name if new_name != name: yield new_name def _create(self, kind: str) -> str: root, name = os.path.split(self.original) for candidate in self._generate_names(name): path = os.path.join(root, candidate) try: os.mkdir(path) except OSError as ex: # Continue if the name exists already if ex.errno != errno.EEXIST: raise else: path = os.path.realpath(path) break else: # Final fallback on the default behavior. path = os.path.realpath(tempfile.mkdtemp(prefix=f"pip-{kind}-")) logger.debug("Created temporary directory: %s", path) return path PKH]Jx9?4python3.10/site-packages/pip/_internal/utils/_log.pynu["""Customize logging Defines custom logger class for the `logger.verbose(...)` method. init_logging() must be called before any other modules that call logging.getLogger. """ import logging from typing import Any, cast # custom log level for `--verbose` output # between DEBUG and INFO VERBOSE = 15 class VerboseLogger(logging.Logger): """Custom Logger, defining a verbose log-level VERBOSE is between INFO and DEBUG. """ def verbose(self, msg: str, *args: Any, **kwargs: Any) -> None: return self.log(VERBOSE, msg, *args, **kwargs) def getLogger(name: str) -> VerboseLogger: """logging.getLogger, but ensures our VerboseLogger class is returned""" return cast(VerboseLogger, logging.getLogger(name)) def init_logging() -> None: """Register our VerboseLogger and VERBOSE log level. Should be called before any calls to getLogger(), i.e. in pip._internal.__init__ """ logging.setLoggerClass(VerboseLogger) logging.addLevelName(VERBOSE, "VERBOSE") PKH]O-9python3.10/site-packages/pip/_internal/utils/filetypes.pynu["""Filetype information. """ from typing import Tuple from pip._internal.utils.misc import splitext WHEEL_EXTENSION = ".whl" BZ2_EXTENSIONS: Tuple[str, ...] = (".tar.bz2", ".tbz") XZ_EXTENSIONS: Tuple[str, ...] = ( ".tar.xz", ".txz", ".tlz", ".tar.lz", ".tar.lzma", ) ZIP_EXTENSIONS: Tuple[str, ...] = (".zip", WHEEL_EXTENSION) TAR_EXTENSIONS: Tuple[str, ...] = (".tar.gz", ".tgz", ".tar") ARCHIVE_EXTENSIONS = ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS def is_archive_file(name: str) -> bool: """Return True if `name` is a considered as an archive file.""" ext = splitext(name)[1].lower() if ext in ARCHIVE_EXTENSIONS: return True return False PKH]&] Bpython3.10/site-packages/pip/_internal/utils/direct_url_helpers.pynu[from typing import Optional from pip._internal.models.direct_url import ArchiveInfo, DirectUrl, DirInfo, VcsInfo from pip._internal.models.link import Link from pip._internal.utils.urls import path_to_url from pip._internal.vcs import vcs def direct_url_as_pep440_direct_reference(direct_url: DirectUrl, name: str) -> str: """Convert a DirectUrl to a pip requirement string.""" direct_url.validate() # if invalid, this is a pip bug requirement = name + " @ " fragments = [] if isinstance(direct_url.info, VcsInfo): requirement += "{}+{}@{}".format( direct_url.info.vcs, direct_url.url, direct_url.info.commit_id ) elif isinstance(direct_url.info, ArchiveInfo): requirement += direct_url.url if direct_url.info.hash: fragments.append(direct_url.info.hash) else: assert isinstance(direct_url.info, DirInfo) requirement += direct_url.url if direct_url.subdirectory: fragments.append("subdirectory=" + direct_url.subdirectory) if fragments: requirement += "#" + "&".join(fragments) return requirement def direct_url_for_editable(source_dir: str) -> DirectUrl: return DirectUrl( url=path_to_url(source_dir), info=DirInfo(editable=True), ) def direct_url_from_link( link: Link, source_dir: Optional[str] = None, link_is_in_wheel_cache: bool = False ) -> DirectUrl: if link.is_vcs: vcs_backend = vcs.get_backend_for_scheme(link.scheme) assert vcs_backend url, requested_revision, _ = vcs_backend.get_url_rev_and_auth( link.url_without_fragment ) # For VCS links, we need to find out and add commit_id. if link_is_in_wheel_cache: # If the requested VCS link corresponds to a cached # wheel, it means the requested revision was an # immutable commit hash, otherwise it would not have # been cached. In that case we don't have a source_dir # with the VCS checkout. assert requested_revision commit_id = requested_revision else: # If the wheel was not in cache, it means we have # had to checkout from VCS to build and we have a source_dir # which we can inspect to find out the commit id. assert source_dir commit_id = vcs_backend.get_revision(source_dir) return DirectUrl( url=url, info=VcsInfo( vcs=vcs_backend.name, commit_id=commit_id, requested_revision=requested_revision, ), subdirectory=link.subdirectory_fragment, ) elif link.is_existing_dir(): return DirectUrl( url=link.url_without_fragment, info=DirInfo(), subdirectory=link.subdirectory_fragment, ) else: hash = None hash_name = link.hash_name if hash_name: hash = f"{hash_name}={link.hash}" return DirectUrl( url=link.url_without_fragment, info=ArchiveInfo(hash=hash), subdirectory=link.subdirectory_fragment, ) PKH]8python3.10/site-packages/pip/_internal/utils/__init__.pynu[PKH]a8python3.10/site-packages/pip/_internal/utils/encoding.pynu[import codecs import locale import re import sys from typing import List, Tuple BOMS: List[Tuple[bytes, str]] = [ (codecs.BOM_UTF8, "utf-8"), (codecs.BOM_UTF16, "utf-16"), (codecs.BOM_UTF16_BE, "utf-16-be"), (codecs.BOM_UTF16_LE, "utf-16-le"), (codecs.BOM_UTF32, "utf-32"), (codecs.BOM_UTF32_BE, "utf-32-be"), (codecs.BOM_UTF32_LE, "utf-32-le"), ] ENCODING_RE = re.compile(br"coding[:=]\s*([-\w.]+)") def auto_decode(data: bytes) -> str: """Check a bytes string for a BOM to correctly detect the encoding Fallback to locale.getpreferredencoding(False) like open() on Python3""" for bom, encoding in BOMS: if data.startswith(bom): return data[len(bom) :].decode(encoding) # Lets check the first two lines as in PEP263 for line in data.split(b"\n")[:2]: if line[0:1] == b"#" and ENCODING_RE.search(line): result = ENCODING_RE.search(line) assert result is not None encoding = result.groups()[0].decode("ascii") return data.decode(encoding) return data.decode( locale.getpreferredencoding(False) or sys.getdefaultencoding(), ) PKH][w]8python3.10/site-packages/pip/_internal/utils/egg_link.pynu[# The following comment should be removed at some point in the future. # mypy: strict-optional=False import os import re import sys from typing import Optional from pip._internal.locations import site_packages, user_site from pip._internal.utils.virtualenv import ( running_under_virtualenv, virtualenv_no_global, ) __all__ = [ "egg_link_path_from_sys_path", "egg_link_path_from_location", ] def _egg_link_name(raw_name: str) -> str: """ Convert a Name metadata value to a .egg-link name, by applying the same substitution as pkg_resources's safe_name function. Note: we cannot use canonicalize_name because it has a different logic. """ return re.sub("[^A-Za-z0-9.]+", "-", raw_name) + ".egg-link" def egg_link_path_from_sys_path(raw_name: str) -> Optional[str]: """ Look for a .egg-link file for project name, by walking sys.path. """ egg_link_name = _egg_link_name(raw_name) for path_item in sys.path: egg_link = os.path.join(path_item, egg_link_name) if os.path.isfile(egg_link): return egg_link return None def egg_link_path_from_location(raw_name: str) -> Optional[str]: """ Return the path for the .egg-link file if it exists, otherwise, None. There's 3 scenarios: 1) not in a virtualenv try to find in site.USER_SITE, then site_packages 2) in a no-global virtualenv try to find in site_packages 3) in a yes-global virtualenv try to find in site_packages, then site.USER_SITE (don't look in global location) For #1 and #3, there could be odd cases, where there's an egg-link in 2 locations. This method will just return the first one found. """ sites = [] if running_under_virtualenv(): sites.append(site_packages) if not virtualenv_no_global() and user_site: sites.append(user_site) else: if user_site: sites.append(user_site) sites.append(site_packages) egg_link_name = _egg_link_name(raw_name) for site in sites: egglink = os.path.join(site, egg_link_name) if os.path.isfile(egglink): return egglink return None PKH]Fpython3.10/site-packages/pip/_internal/utils/inject_securetransport.pynu["""A helper module that injects SecureTransport, on import. The import should be done as early as possible, to ensure all requests and sessions (or whatever) are created after injecting SecureTransport. Note that we only do the injection on macOS, when the linked OpenSSL is too old to handle TLSv1.2. """ import sys def inject_securetransport() -> None: # Only relevant on macOS if sys.platform != "darwin": return try: import ssl except ImportError: return # Checks for OpenSSL 1.0.1 if ssl.OPENSSL_VERSION_NUMBER >= 0x1000100F: return try: from pip._vendor.urllib3.contrib import securetransport except (ImportError, OSError): return securetransport.inject_into_urllib3() inject_securetransport() PKH]_4 &&3python3.10/site-packages/pip/_internal/build_env.pynu["""Build Environment used for isolation during sdist building """ import contextlib import logging import os import pathlib import sys import textwrap import zipfile from collections import OrderedDict from sysconfig import get_paths from types import TracebackType from typing import TYPE_CHECKING, Iterable, Iterator, List, Optional, Set, Tuple, Type from pip._vendor.certifi import where from pip._vendor.packaging.requirements import Requirement from pip._vendor.packaging.version import Version from pip import __file__ as pip_location from pip._internal.cli.spinners import open_spinner from pip._internal.locations import get_platlib, get_prefixed_libs, get_purelib from pip._internal.metadata import get_environment from pip._internal.utils.subprocess import call_subprocess from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds if TYPE_CHECKING: from pip._internal.index.package_finder import PackageFinder logger = logging.getLogger(__name__) class _Prefix: def __init__(self, path: str) -> None: self.path = path self.setup = False self.bin_dir = get_paths( "nt" if os.name == "nt" else "posix_prefix", vars={"base": path, "platbase": path}, )["scripts"] self.lib_dirs = get_prefixed_libs(path) @contextlib.contextmanager def _create_standalone_pip() -> Iterator[str]: """Create a "standalone pip" zip file. The zip file's content is identical to the currently-running pip. It will be used to install requirements into the build environment. """ source = pathlib.Path(pip_location).resolve().parent # Return the current instance if `source` is not a directory. We can't build # a zip from this, and it likely means the instance is already standalone. if not source.is_dir(): yield str(source) return with TempDirectory(kind="standalone-pip") as tmp_dir: pip_zip = os.path.join(tmp_dir.path, "__env_pip__.zip") kwargs = {} if sys.version_info >= (3, 8): kwargs["strict_timestamps"] = False with zipfile.ZipFile(pip_zip, "w", **kwargs) as zf: for child in source.rglob("*"): zf.write(child, child.relative_to(source.parent).as_posix()) yield os.path.join(pip_zip, "pip") class BuildEnvironment: """Creates and manages an isolated environment to install build deps""" def __init__(self) -> None: temp_dir = TempDirectory(kind=tempdir_kinds.BUILD_ENV, globally_managed=True) self._prefixes = OrderedDict( (name, _Prefix(os.path.join(temp_dir.path, name))) for name in ("normal", "overlay") ) self._bin_dirs: List[str] = [] self._lib_dirs: List[str] = [] for prefix in reversed(list(self._prefixes.values())): self._bin_dirs.append(prefix.bin_dir) self._lib_dirs.extend(prefix.lib_dirs) # Customize site to: # - ensure .pth files are honored # - prevent access to system site packages system_sites = { os.path.normcase(site) for site in (get_purelib(), get_platlib()) } self._site_dir = os.path.join(temp_dir.path, "site") if not os.path.exists(self._site_dir): os.mkdir(self._site_dir) with open(os.path.join(self._site_dir, "sitecustomize.py"), "w") as fp: fp.write( textwrap.dedent( """ import os, site, sys # First, drop system-sites related paths. original_sys_path = sys.path[:] known_paths = set() for path in {system_sites!r}: site.addsitedir(path, known_paths=known_paths) system_paths = set( os.path.normcase(path) for path in sys.path[len(original_sys_path):] ) original_sys_path = [ path for path in original_sys_path if os.path.normcase(path) not in system_paths ] sys.path = original_sys_path # Second, add lib directories. # ensuring .pth file are processed. for path in {lib_dirs!r}: assert not path in sys.path site.addsitedir(path) """ ).format(system_sites=system_sites, lib_dirs=self._lib_dirs) ) def __enter__(self) -> None: self._save_env = { name: os.environ.get(name, None) for name in ("PATH", "PYTHONNOUSERSITE", "PYTHONPATH") } path = self._bin_dirs[:] old_path = self._save_env["PATH"] if old_path: path.extend(old_path.split(os.pathsep)) pythonpath = [self._site_dir] os.environ.update( { "PATH": os.pathsep.join(path), "PYTHONNOUSERSITE": "1", "PYTHONPATH": os.pathsep.join(pythonpath), } ) def __exit__( self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType], ) -> None: for varname, old_value in self._save_env.items(): if old_value is None: os.environ.pop(varname, None) else: os.environ[varname] = old_value def check_requirements( self, reqs: Iterable[str] ) -> Tuple[Set[Tuple[str, str]], Set[str]]: """Return 2 sets: - conflicting requirements: set of (installed, wanted) reqs tuples - missing requirements: set of reqs """ missing = set() conflicting = set() if reqs: env = get_environment(self._lib_dirs) for req_str in reqs: req = Requirement(req_str) dist = env.get_distribution(req.name) if not dist: missing.add(req_str) continue if isinstance(dist.version, Version): installed_req_str = f"{req.name}=={dist.version}" else: installed_req_str = f"{req.name}==={dist.version}" if dist.version not in req.specifier: conflicting.add((installed_req_str, req_str)) # FIXME: Consider direct URL? return conflicting, missing def install_requirements( self, finder: "PackageFinder", requirements: Iterable[str], prefix_as_string: str, message: str, ) -> None: prefix = self._prefixes[prefix_as_string] assert not prefix.setup prefix.setup = True if not requirements: return with contextlib.ExitStack() as ctx: # TODO: Remove this block when dropping 3.6 support. Python 3.6 # lacks importlib.resources and pep517 has issues loading files in # a zip, so we fallback to the "old" method by adding the current # pip directory to the child process's sys.path. if sys.version_info < (3, 7): pip_runnable = os.path.dirname(pip_location) else: pip_runnable = ctx.enter_context(_create_standalone_pip()) self._install_requirements( pip_runnable, finder, requirements, prefix, message, ) @staticmethod def _install_requirements( pip_runnable: str, finder: "PackageFinder", requirements: Iterable[str], prefix: _Prefix, message: str, ) -> None: args: List[str] = [ sys.executable, pip_runnable, "install", "--ignore-installed", "--no-user", "--prefix", prefix.path, "--no-warn-script-location", ] if logger.getEffectiveLevel() <= logging.DEBUG: args.append("-v") for format_control in ("no_binary", "only_binary"): formats = getattr(finder.format_control, format_control) args.extend( ( "--" + format_control.replace("_", "-"), ",".join(sorted(formats or {":none:"})), ) ) index_urls = finder.index_urls if index_urls: args.extend(["-i", index_urls[0]]) for extra_index in index_urls[1:]: args.extend(["--extra-index-url", extra_index]) else: args.append("--no-index") for link in finder.find_links: args.extend(["--find-links", link]) for host in finder.trusted_hosts: args.extend(["--trusted-host", host]) if finder.allow_all_prereleases: args.append("--pre") if finder.prefer_binary: args.append("--prefer-binary") args.append("--") args.extend(requirements) extra_environ = {"_PIP_STANDALONE_CERT": where()} with open_spinner(message) as spinner: call_subprocess(args, spinner=spinner, extra_environ=extra_environ) class NoOpBuildEnvironment(BuildEnvironment): """A no-op drop-in replacement for BuildEnvironment""" def __init__(self) -> None: pass def __enter__(self) -> None: pass def __exit__( self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType], ) -> None: pass def cleanup(self) -> None: pass def install_requirements( self, finder: "PackageFinder", requirements: Iterable[str], prefix_as_string: str, message: str, ) -> None: raise NotImplementedError() PKH]b=KK2python3.10/site-packages/pip/_internal/__init__.pynu[from typing import List, Optional import pip._internal.utils.inject_securetransport # noqa from pip._internal.utils import _log # init_logging() must be called before any call to logging.getLogger() # which happens at import of most modules. _log.init_logging() def main(args: (Optional[List[str]]) = None) -> int: """This is preserved for old console scripts that may still be referencing it. For additional details, see https://github.com/pypa/pip/issues/7498. """ from pip._internal.utils.entrypoints import _wrapper return _wrapper(args, _nowarn=True) PKH]g=python3.10/site-packages/pip/_internal/self_outdated_check.pynu[import datetime import hashlib import json import logging import optparse import os.path import sys from typing import Any, Dict from pip._vendor.packaging.version import parse as parse_version from pip._internal.index.collector import LinkCollector from pip._internal.index.package_finder import PackageFinder from pip._internal.metadata import get_default_environment from pip._internal.models.selection_prefs import SelectionPreferences from pip._internal.network.session import PipSession from pip._internal.utils.filesystem import adjacent_tmp_file, check_path_owner, replace from pip._internal.utils.misc import ensure_dir SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ" logger = logging.getLogger(__name__) def _get_statefile_name(key: str) -> str: key_bytes = key.encode() name = hashlib.sha224(key_bytes).hexdigest() return name class SelfCheckState: def __init__(self, cache_dir: str) -> None: self.state: Dict[str, Any] = {} self.statefile_path = None # Try to load the existing state if cache_dir: self.statefile_path = os.path.join( cache_dir, "selfcheck", _get_statefile_name(self.key) ) try: with open(self.statefile_path, encoding="utf-8") as statefile: self.state = json.load(statefile) except (OSError, ValueError, KeyError): # Explicitly suppressing exceptions, since we don't want to # error out if the cache file is invalid. pass @property def key(self) -> str: return sys.prefix def save(self, pypi_version: str, current_time: datetime.datetime) -> None: # If we do not have a path to cache in, don't bother saving. if not self.statefile_path: return # Check to make sure that we own the directory if not check_path_owner(os.path.dirname(self.statefile_path)): return # Now that we've ensured the directory is owned by this user, we'll go # ahead and make sure that all our directories are created. ensure_dir(os.path.dirname(self.statefile_path)) state = { # Include the key so it's easy to tell which pip wrote the # file. "key": self.key, "last_check": current_time.strftime(SELFCHECK_DATE_FMT), "pypi_version": pypi_version, } text = json.dumps(state, sort_keys=True, separators=(",", ":")) with adjacent_tmp_file(self.statefile_path) as f: f.write(text.encode()) try: # Since we have a prefix-specific state file, we can just # overwrite whatever is there, no need to check. replace(f.name, self.statefile_path) except OSError: # Best effort. pass def was_installed_by_pip(pkg: str) -> bool: """Checks whether pkg was installed by pip This is used not to display the upgrade message when pip is in fact installed by system package manager, such as dnf on Fedora. """ dist = get_default_environment().get_distribution(pkg) return dist is not None and "pip" == dist.installer def pip_self_version_check(session: PipSession, options: optparse.Values) -> None: """Check for an update for pip. Limit the frequency of checks to once per week. State is stored either in the active virtualenv or in the user's USER_CACHE_DIR keyed off the prefix of the pip script path. """ installed_dist = get_default_environment().get_distribution("pip") if not installed_dist: return pip_version = installed_dist.version pypi_version = None try: state = SelfCheckState(cache_dir=options.cache_dir) current_time = datetime.datetime.utcnow() # Determine if we need to refresh the state if "last_check" in state.state and "pypi_version" in state.state: last_check = datetime.datetime.strptime( state.state["last_check"], SELFCHECK_DATE_FMT ) if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60: pypi_version = state.state["pypi_version"] # Refresh the version if we need to or just see if we need to warn if pypi_version is None: # Lets use PackageFinder to see what the latest pip version is link_collector = LinkCollector.create( session, options=options, suppress_no_index=True, ) # Pass allow_yanked=False so we don't suggest upgrading to a # yanked version. selection_prefs = SelectionPreferences( allow_yanked=False, allow_all_prereleases=False, # Explicitly set to False ) finder = PackageFinder.create( link_collector=link_collector, selection_prefs=selection_prefs, ) best_candidate = finder.find_best_candidate("pip").best_candidate if best_candidate is None: return pypi_version = str(best_candidate.version) # save that we've performed a check state.save(pypi_version, current_time) remote_version = parse_version(pypi_version) local_version_is_older = ( pip_version < remote_version and pip_version.base_version != remote_version.base_version and was_installed_by_pip("pip") ) # Determine if our pypi_version is older if not local_version_is_older: return # We cannot tell how the current pip is available in the current # command context, so be pragmatic here and suggest the command # that's always available. This does not accommodate spaces in # `sys.executable`. pip_cmd = f"{sys.executable} -m pip" logger.warning( "You are using pip version %s; however, version %s is " "available.\nYou should consider upgrading via the " "'%s install --upgrade pip' command.", pip_version, pypi_version, pip_cmd, ) except Exception: logger.debug( "There was an error checking the latest version of pip", exc_info=True, ) PKH]5%python3.10/site-packages/pip/py.typednu[pip is a command line program. While it is implemented in Python, and so is available for import, you must not use pip's internal APIs in this way. Typing information is provided as a convenience only and is not a guarantee. Expect unannounced changes to the API and types in releases. PKH]:4@ee(python3.10/site-packages/pip/__init__.pynu[from typing import List, Optional __version__ = "21.3.1" def main(args: Optional[List[str]] = None) -> int: """This is an internal API only meant for use by pip's own console scripts. For additional details, see https://github.com/pypa/pip/issues/7498. """ from pip._internal.utils.entrypoints import _wrapper return _wrapper(args) PKH]M(Rpython3.10/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-310.pycnu[o ai@sdZdS)z3.2N) __version__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/idna/package_data.pysPKH]x޻m#m#Jpython3.10/site-packages/pip/_vendor/idna/__pycache__/core.cpython-310.pycnu[o ai2@s0ddlmZddlZddlZddlZddlmZmZddlm Z dZ dZ e dZ Gd d d eZGd d d eZGd ddeZGdddeZddZddZddZddZddZddZd7ddZd d!Zd"d#Zd$d%Zd&d'Zd7d(d)Zd*d+Zd,d-Z d.d/Z!d8d1d2Z"d9d3d4Z#d:d5d6Z$dS);)idnadataN)UnionOptional)intranges_contain sxn--u [.。.。]c@eZdZdZdS) IDNAErrorz7 Base exception for all IDNA-encoding related problems N__name__ __module__ __qualname____doc__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/idna/core.pyr r c@r) IDNABidiErrorz= Exception when bidirectional requirements are not satisfied Nr rrrrrrrc@r)InvalidCodepointz> Exception when a disallowed or unallocated codepoint is used Nr rrrrrrrc@r)InvalidCodepointContextzE Exception when the codepoint is not valid in the context it is used Nr rrrrrrrcCs0tt|}|dkrtt|std|S)Nrz Unknown character in unicodedata) unicodedata combiningchrname ValueError)cpvrrr_combining_class s rcCstt|tj|S)N)rordrscripts)rscriptrrr _is_script(sr cCs |dS)Npunycode)encodesrrr _punycode, r%cCs d|S)NzU+{:04X})formatr#rrr_unot0r&r(cCst|dkrdSdS)N?FTlenlabelrrrvalid_label_length5s r.cCst||rdndkr dSdS)NFTr*)r- trailing_dotrrrvalid_string_length<sr2Fc CsPd}t|dD]\}}t|}|dkrtdt|||dvr$d}q|s+|s+dSt|d}|dvr9d}n|d kr@d}n td t|d}d}t|dD]M\}}t|}|r|d vrhtd ||d vrod}n|dkrud}|dvr|s~|}qR||krtdqR|dvrtd||dvrd}qR|dkrd}qR|stddS)NFrz1Unknown directionality in label {} at position {})RALANTr)r4r5Lz=First codepoint in label {} must be directionality L, R or AL) r4r5r6ENESCSETONBNNSMzGInvalid direction for codepoint at position {} in a right-to-left label)r4r5r8r6r>)r6r8z2Can not mix numeral types in a right-to-left label)r7r8r9r:r;r<r=r>zGInvalid direction for codepoint at position {} in a left-to-right label)r7r8z0Label ends with illegal codepoint directionality) enumerater bidirectionalrr'repr) r- check_ltr bidi_labelidxr directionrtl valid_ending number_typerrr check_bidiCsV  rIcCs"t|dddkrtddS)NrMz0Label begins with an illegal combining characterT)rcategoryr r,rrrcheck_initial_combinersrLcCs<|dddkr td|ddks|ddkrtdd S) Nz--z4Label has disallowed hyphens in 3rd and 4th positionr-z)Label must not start or end with a hyphenT)r r,rrrcheck_hyphen_oks rQcCstd||kr tddS)NNFCz%Label must be in Normalization Form C)r normalizer r,rrr check_nfcsrTcCs,t||}|dkr||dkrtt||dtkrdSd}t|dddD]!}tjt||}|tdkr9q&|tdtd fvrGd}nq&|sLdSd}t|dt|D]"}tjt||}|tdkrjqW|td td fvryd}|SqW|S|d kr|dkrtt||dtkrdSdSdS) Ni rrTFrPTr7Dr4i )rr_virama_combining_classranger joining_typesgetr+)r-poscp_valueoki joining_typerrrvalid_contextjsB   r`cCst||}|dkr3d|krt|dkr1ndSt||ddkr1t||ddkr1dSdS|dkrP|t|dkrNt|dkrNt||ddSdS|d ksX|d krg|dkret||dd SdS|d kr|D]}|d krtqmt|dst|dst|drdSqmdSd|krdkrnn|D]}dt|krdkrdSqqdSd|krdkrndS|D]}dt|krdkrdSqqdSdS)NrrlTFiuGreekiiHebrewi0u・HiraganaKatakanaHani`iiii)rr+r )r-r[ exceptionr\rrrrvalid_contextosJ (ric Cs<t|ttfr |d}t|dkrtdt|t|t|t |D]q\}}t |}t |t j dr7q&t |t j drlzt||sTtdt||dt|Wq&tyktdt||dt|wt |t j d rt||std t||dt|q&td t||dt|t|dS) Nzutf-8rz Empty LabelPVALIDCONTEXTJz*Joiner {} not allowed at position {} in {}rz         rc Cst|ttfr |d}|rt|||}d}g}|r |d}nt|}|r,|dgkr0td|ddkr;|d=d}|D]}t|}|rK| |q=td|rV| d d |}t ||sdtd |S) NrtF.r3 Empty domainrPT Empty label.zDomain too long) rnrorprqrsplit_unicode_dots_rer r{appendjoinr2) r$strictuts46rrr1resultlabelsr-rrrr"as2         r"cCst|ttfr |d}|rt||d}d}g}|s t|}n|d}|r,|dgkr0td|ds9|d=d}|D]}t|}|rI| |q;td|rT| dd |S) NrtFrr3rrPTr) rnrorprqrrrr rurr)r$rrrr1rrr-rrrrqs,       rq)F)TF)FFFF)FFF)%r3rrrretypingrr intrangesrrWrxcompiler UnicodeErrorr rrrrr r%r(r.r2rIrLrQrTr`rirsr{rurr"rqrrrrs>    <  ,+   !PKH]ѐnnOpython3.10/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-310.pycnu[o ai@s@dZddlZddlmZmZddZddZdd Zd d ZdS) a  Given a list of integers, made up of (hopefully) a small number of long runs of consecutive integers, compute a representation of the form ((start1, end1), (start2, end2) ...). Then answer the question "was x present in the original list?" in time O(log(# runs)). N)ListTuplecCst|}g}d}tt|D]1}|dt|kr%||||ddkr%q||d|d}|t|d|dd|}qt|S)aRepresent a list of integers as a sequence of ranges: ((start_0, end_0), (start_1, end_1), ...), such that the original integers are exactly those x such that start_i <= x < end_i for some i. Ranges are encoded as single integers (start << 32 | end), not as tuples. r)sortedrangelenappend _encode_rangetuple)list_ sorted_listranges last_writei current_ranger/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/idna/intranges.pyintranges_from_list s rcCs |d>|BS)N r)startendrrrr !s r cCs|d?|d@fS)Nrlr)rrrr _decode_range%srcCsvt|d}t||}|dkr%t||d\}}||kr$|kr%dS|t|kr9t||\}}||kr9dSdS)z=Determine if `int_` falls into one of the ranges in `ranges`.rrTF)r bisect bisect_leftrr)int_rtuple_posleftright_rrrintranges_contain*s   r") __doc__rtypingrrrr rr"rrrrs PKH];_C{{Npython3.10/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-310.pycnu[o aiQ@stddlmZddlmZmZmZmZmZmZm Z m Z m Z m Z m Z mZmZmZmZmZmZmZddlmZgdZdS)) __version__) IDNABidiError IDNAErrorInvalidCodepointInvalidCodepointContextalabel check_bidicheck_hyphen_okcheck_initial_combiner check_label check_nfcdecodeencodeulabel uts46_remapvalid_contextjvalid_contextovalid_label_lengthvalid_string_length)intranges_contain)rrrrrrr r r r r rrrrrrrrN) package_datarcorerrrrrrr r r r r rrrrrrr intrangesr__all__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/idna/__init__.pys P  PKH]ny] ] Kpython3.10/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-310.pycnu[o ai} @sddlmZmZmZmZmZddlZddlZddlm Z m Z e dZ Gdddej Z Gdd d ejZGd d d ejZGd d d e ejZGddde ejZddZdS))encodedecodealabelulabel IDNAErrorN)TupleOptionalu [.。.。]c@s eZdZdddZdddZdS)CodecstrictcC.|dkr td||sdSt|t|fS)Nr Unsupported error handling "{}")r)rformatrlenselfdataerrorsr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/idna/codec.pyr z Codec.encodecCr )Nr r r)rrrrrrrrrrz Codec.decodeN)r )__name__ __module__ __qualname__rrrrrrr s  r c@eZdZddZdS)IncrementalEncoderc C|dkr td||sdSt|}d}|r+|ds"d}|d=n |s+|d=|r+d}g}d}|D]}|t||r@|d7}|t|7}q1d||} |t|7}| |fS Nr r rr.rr)rr_unicode_dots_resplitappendrrjoin rrrfinallabels trailing_dotresultsizelabelZ result_strrrr_buffer_encodes0  z!IncrementalEncoder._buffer_encodeN)rrrr.rrrrr rc@r)IncrementalDecoderc Crr )rrr#r$r%rrr&r'rrr_buffer_decodeAs0  z!IncrementalDecoder._buffer_decodeN)rrrr1rrrrr0@r/r0c@ eZdZdS) StreamWriterNrrrrrrrr3br3c@r2) StreamReaderNr4rrrrr6fr5r6c Cs tjdtjtjttttdS)Nidna)namerrincrementalencoderincrementaldecoder streamwriter streamreader) codecs CodecInfor rrrr0r3r6rrrr getregentryjsr?)corerrrrrr=retypingrr compiler#r BufferedIncrementalEncoderrBufferedIncrementalDecoderr0r3r6r?rrrrs "" PKH]8/Lpython3.10/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-310.pycnu[o aih@s<ddlTddlTddlmZmZddZddZdd Zd S) )*)AnyUnioncCt|SN)encodelabelr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/idna/compat.pyToASCIIr cCrr)decoder r r r ToUnicode rrcCstd)Nz,IDNA 2008 does not utilise nameprep protocol)NotImplementedError)sr r r nameprep rrN)corecodectypingrrr rrr r r r s  PKH]s̸Npython3.10/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-310.pycnu[o ain @sdZddddddZiddd dd dd dd dd dddddddddddddddddddddddiddddddddddd dd!dd"dd#dd$dd%dd&dd'dd(dd)dd*dd+did,dd-dd.dd/dd0dd1dd2d3d4dd5dd6dd7dd8dd9dd:dd;dddd?dd@ddAddBddCddDddEddFddGddHddIddJddKddLddMddNdidOddPddQddRddSddTddUddVddWddXddYddZdd[dd\dd]dd^dd_did`ddaddbddcdddddeddfddgddhddiddjddkddlddmddnddoddpdidqddrddsddtdduddvddwddxddyddzdd{dd|dd}dd~dddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddd dd did dd dd dddddddddddddddddddddddddddddiddddddddd d3d!dd"dd#dd$dd%dd&dd'dd(dd)dd*dd+dd,did-dd.dd/dd0dd1dd2dd3dd4dd5dd6dd7dd8dd9dd:dd;dddd?dd@ddAddBddCddDddEddFddGddHddIddJddKddLddMddNdidOddPddQddRddSddTddUddVddWddXddYddZdd[dd\dd]dd^dd_did`ddaddbddcdddddeddfddgddhddiddjddkddlddmddnddod3dpdidqddrddsddtdduddvddwddxddyddzdd{dd|dd}dd~dddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddidddddddddddddddddddddddddddd3ddddddiddddddddddddddddddddddddddddddddd did dd dd dd dddddddddddddddddddddddddddiddddddddddd dd!dd"dd#dd$dd%dd&dd'dd(dd)dd*dd+did,dd-d.d/dd0dd1dd2dd3dd4dd5dd6dd7dd8dd9dd:dd;dddd?dd@ddAddBddCddDddEddFddGd.dHddIddJddKddLddMddNdidOddPddQddRddSddTddUddVddWddXddYddZdd[dd\dd]dd^dd_did`ddaddbddcdddddeddfddgddhddiddjddkddlddmddnddoddpdidqddrddsd.dtdduddvddwddxddyddzdd{dd|dd}dd~dddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddd̐d.ddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddd dddddddddddd Zd d d dZdS(z13.0.0)$lt lx l~ l lll l0l8lll+tlbtulkulvl|l`|lF|lN }X@}lZd}l\l}l^t}l~|}l~l~llXltlll'!lf+-lllFRH)l.:l.l:l/<l0@l0@l*0@l<0@MP8lnzdlzio? &578]N`k:lz`K) lD@ll7{tll={ll?{llB{mlE{ mlP{m)0Al0tBl1@ S1@E lrH) 0Bl1C2Gl2@KlX3Llp}l}l0@ h1E )GreekHanHebrewHiraganaKatakanaiUiiiiiii i Di!i"Ri#i$i%i&i'i(i)i*i+i,i-i.i/i0i1i2i3i4i5i6i7i8i9i:i;i<i=i>i?i@CiAiBiCiDiEiFiGiHiIiJinioiqirisitiuiviwixiyizi{i|i}i~iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiTiiiiiiiiiiiiiiii i!i"i#i$i%i&i'i(i)i*i+i,i-i.i/iMiNiOiPiQiRiSiTiUiViWiXiYiZi[i\i]i^i_i`iaibicidieifigihiiijikiliminioipiqirisitiuiviwixiyizi{i|i}i~iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii@iAiBiCiDiEiFiGiHiIiJiKiLiMiNiOiPiQiRiSiTiUiViWiXi`iaibicidieifigihiiijiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii ii i!i"i#i$i%i&i'i(i)i*i+i,i-i.i/i0i1i2i3i4i5i6i7i8i9i:i;i<i=i>i?i@iAiBiCiDiEiFiGiHiIiJiKiLiMiNiOiPiQiRiSiTiUiViWiXiYiZi[i\i]i^i_i`iaibicidieifigihiiijikiliminioipiqirisitiuiviwixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii i i/ if ig ih ii i@iAiBiCiDiEiFiGiHiIiJiKiLiMiNiOiPiQiRiSiTiUiViWiXiYiZi[i\i]i^i_i`iaibicidieifigihiiijikiliminioipiqirLisi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i! i" i# i0i1i2i3i4i5i6i7i8i9i:i;i<i=i>i?i@iAiBiCiDiEiQiRiSiTiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii i i i i iiiiiiiiiiiiiiiiiii i!i"i#i$i%i&i'i(i)i*i+i,i-i.i/i0i1i2i3i4i5i6i7i8i9i:) i;i<i=i>i?i@iAiBiCiK(l.l:l{l|lll lll $l ,l4l<lDlLlTl\ldllltl |l"l$l&l(l*l,l.l0l2l6l9l;l=l?lClElGlI lL,lN4lP<lRDlTLlVTlX\lZdl\ll^tl`|lbldlflhljlllnlplrltlvlxl{l}lll ll l0lHlTldlxllllllllllll8l@lHlPlXl`lhlpl|lllllllllllllll lll $l ,l4l<lDlLlTl\ldllltl |l"l$l&l(l*l,l.l0l2l:l=lAlC lH lJ$ lL, lN4 l< l l l l l@ lC lO lp@ lr lt lx l~ l@ll\ldllltl|llllllllllll`lbldlflhljlllnlplrltlvlxlzl|l~lll l,l4l<lDlLlTl\ldllltl|llllllllllllllllllll l(l0l8lDlLlTl\ldllltl|llllllllllllllllll lll $l ,l4l<lDlLlTl\ldllltl |l"l$l&l(l*l,l.l0lZdll lDllllr ll@l@l`lullTl|lllK@l4lll. l\!lk!l"l"lL#lX #ld %lp %l %l &l <&l L&l &l &l &l &l 'l ,'l \'l 'l 'l 'l 'l (l (l <(l) L(l1 (l3 (l6 (l: (l= (lC (lI )lN ,)lR D)l] p)lv )l *l *l <*l L*l *l *l *l *l +l ,+l @+l +l +l +l ,l ,l <,l) L,l1 ,l4 ,l: ,lE ,lI -lN ,-lX T-ld |-lp -lr -l .l .l 8.l H.l d.l p.l x.l .l .l .l .l /l (/l @/l \/l /l 0l 80l) H0l: 0lE 0lI 1lN (1lW T1l[ `1ld 1lp 1l 2l 2l 82l H2l 2l 2l 2l 3l (3l T3l x3l 3l 3l 3l 4l 84lE H4lI 5lO (5lX P5ld |5lp 5l 5l 6l 6l h6l 6l 6l 7l (7l <7l X7l `7l 7l 7l38l;8lO9lZ@9l:l:l:l0:l:l:l:l;l;l ;l@;lx;ll>lP>ld>lx>l>l>l>l>l?lJ@l@Al@ClClIHlN(IlW@IlY`Il^hIlIl(Jl@JlJlJlKlKl Kl`KlHLl[`Ll`tMlNlNlmPlYlZlZl[l \l8\l5\lT]lm]lq]lt]l^l^l\_lp_l_l@`ly`lblbldl,dl<dlneluelflfl@glhl_hl}ilil@jljljljlLllZ@mltmlnl8plJql~4ql@slPsl,tl0tl<tlO8ulxululwlwlxl xlxlxl $xl ,xl4xlxl@xlBylD ylFylHylJ$ylL,ylN4ylP'l@'lB'lD' lF'lH'lJ'$lL',lN'4lP'<lR'DlT'LlV'TlX'\lZ'dl\'ll^'tl`'|lb'ld'lf'lh'lj'll'ln'lp'ly'l{'l}'l'l'l' l'l'l'0l'8l'Dl'Ll'\l'dl'll'tl'|l'l'l'l'l'l'l'l'l'l'l'l'l' l' l'(l'l((l-( lt(!l("l(@#l(#l(#l.)#lT)$l)&l)<'l)'l7*(lN*)lZ*@)lw*)l*)l*l+l*+l*+l+,l+$,l+D,l'+,l/+,l[+,lj+-l+/l+/l+/lW0lz8hlzDhlzLhl z|hl"zhl%zhl*zhl{xll0~xlt~yl l'4l;l>lNl^@lll l l l  lA lJ l{@ lll lll`l(ldl7lVlhl l  l6( l9 l= lV lw!l"l#l#l $l: $l &l &l (l (l 0(l T(l6 d(l; (l@ (l} )l *l +l $+l6 ,lV -ls -l .lI 0l 3l( 4l: 4l:l:l:l<l(<lQ<l>l?lG@lpAlAl@ClCl5Dl@DlHElt@ElwElFl$Gl8GlpGlHl8LHl?HlJl Jl(JltlHtlZ@ulfuliulul@vlLvlvl{l~l# lD% l/4@ lGF l9j l_j) ljj) lj@+ lj+ l7k, lDk- lZk@- lxk- lk- ln9 lKo< lo<= lo<> lo? lo? rl@ l  l 4 l1@ r rl2E lk<p l}<q l<r l<@r l<tr l7ZhlmZhlvZilZjlZljlZjl`l` l"`ll%`l+`l-al>alJalOa8lb lh lh@#lLi$lZi@%l{orrrrr r )l 0)llv lljll0C)PVALIDCONTEXTJCONTEXTON) __version__scripts joining_typescodepoint_classesr#r#/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/idna/idnadata.pysv*& Z      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ PKH]#KX88Opython3.10/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-310.pycnu[o aiy@sddlmZmZmZ dZddZddZddZd d Zd d Z d dZ ddZ ddZ ddZ ddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3d4Zd5d6Zd7d8Zd9d:Z d;d<Z!d=d>Z"d?d@Z#dAdBZ$dCdDZ%dEdFZ&dGdHZ'dIdJZ(dKdLZ)dMdNZ*dOdPZ+dQdRZ,dSdTZ-dUdVZ.dWdXZ/dYdZZ0d[d\Z1d]d^Z2d_d`Z3dadbZ4dcddZ5dedfZ6dgdhZ7didjZ8dkdlZ9dmdnZ:dodpZ;dqdrZdwdxZ?dydzZ@d{d|ZAd}d~ZBddZCddZDddZEddZFddZGddZHddZIddZJddZKddZLddZMddZNddZOddZPddZQddZRddZSddZTeUeeeee e e e e eeeeeeeeeeeeeeeeeee e!e"e#e$e%e&e'e(e)e*e+e,e-e.e/e0e1e2e3e4e5e6e7e8e9e:e;e<e=e>e?e@eAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTZVdS))ListTupleUnionz13.0.0cCgdS)N)d)r3)r)r)r)r)r)r)r)r) r) r) r) r) r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r) r)!r)"r)#r)$r)%r)&r)'r)(r))r)*r)+r),r)-V).r4)/r)0r4)1r4)2r4)3r4)4r4)5r4)6r4)7r4)8r4)9r4):r);r)<r)=r)>r)?r)@r)AMa)BrIb)CrIc)DrId)ErIe)FrIf)GrIg)HrIh)IrIi)JrIj)KrIk)LrIl)MrIm)NrIn)OrIo)PrIp)QrIq)RrIr)SrIs)TrIt)UrIu)VrIv)WrIw)XrIx)YrIy)ZrIz)[r)\r)]r)^r)_r)`r)ar4)br4)cr4rrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/idna/uts46data.py_seg_0 rcCr)N)d)dr4)er4)fr4)gr4)hr4)ir4)jr4)kr4)lr4)mr4)nr4)or4)pr4)qr4)rr4)sr4)tr4)ur4)vr4)wr4)xr4)yr4)zr4){r)|r)}r)~r)r)X)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r)r )r4)r4)r4)r4)r4)r4)r4)ru ̈)r4)rIrJ)r4)r4)I)r4)r ̄)r4)r4)rI2)rIr)r ́)rIμ)r4)r4)ru ̧)rI1)rIrf)r4)rIu1⁄4)rIu1⁄2)rIu3⁄4)r4)rIà)rIá)rIâ)rIã)rIä)rIå)rIæ)rIçrrrrr_seg_1rrrcCr)N)d)rIè)rIé)rIê)rIë)rIì)rIí)rIî)rIï)rIð)rIñ)rIò)rIó)rIô)rIõ)rIö)r4)rIø)rIù)rIú)rIû)rIü)rIý)rIþ)Dss)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)r4)rIuā)ir4)irIuă)ir4)irIuą)ir4)irIuć)ir4)irIuĉ)i r4)i rIuċ)i r4)i rIuč)i r4)irIuď)ir4)irIuđ)ir4)irIuē)ir4)irIuĕ)ir4)irIuė)ir4)irIuę)ir4)irIuě)ir4)irIuĝ)ir4)irIuğ)ir4)i rIuġ)i!r4)i"rIuģ)i#r4)i$rIuĥ)i%r4)i&rIħ)i'r4)i(rIuĩ)i)r4)i*rIuī)i+r4rrrrr_seg_2rrQcCr)N)d)i,rIuĭ)i-r4)i.rIuį)i/r4)i0rIui̇)i1r4)i2rIZij)i4rIuĵ)i5r4)i6rIuķ)i7r4)i9rIuĺ)i:r4)i;rIuļ)i<r4)i=rIuľ)i>r4)i?rIul·)iArIuł)iBr4)iCrIuń)iDr4)iErIuņ)iFr4)iGrIuň)iHr4)iIrIuʼn)iJrIŋ)iKr4)iLrIuō)iMr4)iNrIuŏ)iOr4)iPrIuő)iQr4)iRrIœ)iSr4)iTrIuŕ)iUr4)iVrIuŗ)iWr4)iXrIuř)iYr4)iZrIuś)i[r4)i\rIuŝ)i]r4)i^rIuş)i_r4)i`rIuš)iar4)ibrIuţ)icr4)idrIuť)ier4)ifrIuŧ)igr4)ihrIuũ)iir4)ijrIuū)ikr4)ilrIuŭ)imr4)inrIuů)ior4)iprIuű)iqr4)irrIuų)isr4)itrIuŵ)iur4)ivrIuŷ)iwr4)ixrIÿ)iyrIuź)izr4)i{rIuż)i|r4)i}rIuž)i~r4)irIrn)ir4)irIuɓ)irIuƃ)ir4)irIuƅ)ir4)irIɔ)irIuƈ)ir4)irIuɖ)irIuɗ)irIuƌ)ir4)irIǝ)irIə)irIɛ)irIuƒ)ir4)irIuɠrrrrr_seg_3DrrYcCr)N)d)irIɣ)ir4)irIɩ)irIɨ)irIuƙ)ir4)irIɯ)irIɲ)ir4)irIɵ)irIuơ)ir4)irIuƣ)ir4)irIuƥ)ir4)irIuʀ)irIuƨ)ir4)irIʃ)ir4)irIuƭ)ir4)irIuʈ)irIuư)ir4)irIʊ)irIʋ)irIuƴ)ir4)irIuƶ)ir4)irIʒ)irIuƹ)ir4)irIuƽ)ir4)irIudž)irIZlj)irIZnj)irIuǎ)ir4)irIuǐ)ir4)irIuǒ)ir4)irIuǔ)ir4)irIuǖ)ir4)irIuǘ)ir4)irIuǚ)ir4)irIuǜ)ir4)irIuǟ)ir4)irIuǡ)ir4)irIuǣ)ir4)irIuǥ)ir4)irIuǧ)ir4)irIuǩ)ir4)irIuǫ)ir4)irIuǭ)ir4)irIuǯ)ir4)irIZdz)irIuǵ)ir4)irIuƕ)irIuƿ)irIuǹ)ir4)irIuǻ)ir4)irIuǽ)ir4)irIuǿ)ir4)irIuȁ)ir4)irIuȃ)ir4)irIuȅ)ir4)irIuȇ)ir4)irIuȉ)i r4)i rIuȋ)i r4)i rIuȍrrrrr_seg_4rrdcCr)N)d)i r4)irIuȏ)ir4)irIuȑ)ir4)irIuȓ)ir4)irIuȕ)ir4)irIuȗ)ir4)irIuș)ir4)irIuț)ir4)irIuȝ)ir4)irIuȟ)ir4)i rIuƞ)i!r4)i"rIȣ)i#r4)i$rIuȥ)i%r4)i&rIuȧ)i'r4)i(rIuȩ)i)r4)i*rIuȫ)i+r4)i,rIuȭ)i-r4)i.rIuȯ)i/r4)i0rIuȱ)i1r4)i2rIuȳ)i3r4)i:rIuⱥ)i;rIuȼ)i<r4)i=rIuƚ)i>rIuⱦ)i?r4)iArIuɂ)iBr4)iCrIuƀ)iDrIʉ)iErIʌ)iFrIuɇ)iGr4)iHrIuɉ)iIr4)iJrIuɋ)iKr4)iLrIuɍ)iMr4)iNrIuɏ)iOr4)irIrX)irIɦ)irIr\)irIrl)irIuɹ)irIuɻ)irIuʁ)irIrv)irIrz)ir4)iru ̆)iru ̇)iru ̊)iru ̨)iru ̃)iru ̋)ir4)irIrZ)irIr`)irIrn)irIrx)irIuʕ)ir4)i@rIù)iArIú)iBr4)iCrIu̓)iDrIǘ)iErIι)iFr4)iOr)iPr4)iprIuͱ)iqr4)irrIuͳ)isr4)itrIuʹ)iur4)ivrIuͷ)iwr4rrrrr_seg_5rrjcCr)N)d)ixr)izru ι)i{r4)i~r;)irIuϳ)ir)irr)ir ̈́)irIά)irI·)irIέ)irIή)irIί)ir)irIό)ir)irIύ)irIώ)ir4)irIα)irIβ)irIγ)irIδ)irIε)irIζ)irIη)irIθ)irIri)irIκ)irIλ)irIr)irIν)irIξ)irIο)irIπ)irIρ)ir)irIσ)irIτ)irIυ)irIφ)irIχ)irIψ)irIω)irIuϊ)irIϋ)ir4)ir-r)ir4)irIuϗ)irIrv)irIr|)irIr)irIrs)irIr)irIr)irIr)ir4)irIuϙ)ir4)irIuϛ)ir4)irIϝ)ir4)irIuϟ)ir4)irIuϡ)ir4)irIuϣ)ir4)irIuϥ)ir4)irIuϧ)ir4)irIuϩ)ir4)irIuϫ)ir4)irIuϭ)ir4)irIuϯ)ir4)irIr})irIr)irIr)ir4)irIr|)irIry)ir4)irIuϸ)ir4)irIr)irIuϻ)ir4)irIuͻ)irIuͼ)irIuͽ)irIuѐ)irIuё)irIuђrrrrr_seg_6rrcCr)N)d)irIuѓ)irIuє)irIuѕ)irIuі)irIuї)irIuј)i rIuљ)i rIuњ)i rIuћ)i rIuќ)i rIuѝ)irIuў)irIuџ)irIuа)irIuб)irIв)irIuг)irIд)irIuе)irIuж)irIuз)irIuи)irIuй)irIuк)irIuл)irIuм)irIн)irIо)irIuп)i rIuр)i!rIс)i"rIт)i#rIuу)i$rIuф)i%rIuх)i&rIuц)i'rIuч)i(rIuш)i)rIuщ)i*rIъ)i+rIuы)i,rIь)i-rIuэ)i.rIuю)i/rIuя)i0r4)i`rIuѡ)iar4)ibrIѣ)icr4)idrIuѥ)ier4)ifrIuѧ)igr4)ihrIuѩ)iir4)ijrIuѫ)ikr4)ilrIuѭ)imr4)inrIuѯ)ior4)iprIuѱ)iqr4)irrIuѳ)isr4)itrIuѵ)iur4)ivrIuѷ)iwr4)ixrIuѹ)iyr4)izrIuѻ)i{r4)i|rIuѽ)i}r4)i~rIuѿ)ir4)irIuҁ)ir4)irIuҋ)ir4)irIuҍ)ir4)irIuҏ)ir4)irIuґ)ir4)irIuғ)ir4)irIuҕ)ir4)irIuҗ)ir4)irIuҙ)ir4)irIuқ)ir4)irIuҝ)ir4rrrrr_seg_7rrcCr)N)d)irIuҟ)ir4)irIuҡ)ir4)irIuң)ir4)irIuҥ)ir4)irIuҧ)ir4)irIuҩ)ir4)irIuҫ)ir4)irIuҭ)ir4)irIuү)ir4)irIuұ)ir4)irIuҳ)ir4)irIuҵ)ir4)irIuҷ)ir4)irIuҹ)ir4)irIuһ)ir4)irIuҽ)ir4)irIuҿ)ir4)ir)irIuӂ)ir4)irIuӄ)ir4)irIuӆ)ir4)irIuӈ)ir4)irIuӊ)ir4)irIuӌ)ir4)irIuӎ)ir4)irIuӑ)ir4)irIuӓ)ir4)irIuӕ)ir4)irIuӗ)ir4)irIuә)ir4)irIuӛ)ir4)irIuӝ)ir4)irIuӟ)ir4)irIuӡ)ir4)irIuӣ)ir4)irIuӥ)ir4)irIuӧ)ir4)irIuө)ir4)irIuӫ)ir4)irIuӭ)ir4)irIuӯ)ir4)irIuӱ)ir4)irIuӳ)ir4)irIuӵ)ir4)irIuӷ)ir4)irIuӹ)ir4)irIuӻ)ir4)irIuӽ)ir4)irIuӿ)ir4)irIuԁ)ir4)irIuԃrrrrr_seg_8QrrcCr)N)d)ir4)irIuԅ)ir4)irIuԇ)ir4)irIuԉ)i r4)i rIuԋ)i r4)i rIuԍ)i r4)irIuԏ)ir4)irIuԑ)ir4)irIuԓ)ir4)irIuԕ)ir4)irIuԗ)ir4)irIuԙ)ir4)irIuԛ)ir4)irIuԝ)ir4)irIuԟ)ir4)i rIuԡ)i!r4)i"rIuԣ)i#r4)i$rIuԥ)i%r4)i&rIuԧ)i'r4)i(rIuԩ)i)r4)i*rIuԫ)i+r4)i,rIuԭ)i-r4)i.rIuԯ)i/r4)i0r)i1rIuա)i2rIuբ)i3rIuգ)i4rIuդ)i5rIuե)i6rIuզ)i7rIuէ)i8rIuը)i9rIuթ)i:rIuժ)i;rIuի)i<rIuլ)i=rIuխ)i>rIuծ)i?rIuկ)i@rIuհ)iArIuձ)iBrIuղ)iCrIuճ)iDrIuմ)iErIuյ)iFrIuն)iGrIuշ)iHrIuո)iIrIuչ)iJrIuպ)iKrIuջ)iLrIuռ)iMrIuս)iNrIuվ)iOrIuտ)iPrIuր)iQrIuց)iRrIuւ)iSrIuփ)iTrIuք)iUrIuօ)iVrIuֆ)iWr)iYr4)irIuեւ)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4rrrrr_seg_9rrcCr)N)d)iurIuاٴ)ivrIuوٴ)iwrIۇٴ)ixrIuيٴ)iyr4)ir)ir4)ir)ir4)iKr)iMr4)ir)ir4)ir)ir4)i.r)i0r4)i?r)i@r4)i\r)i^r4)i_r)i`r4)ikr)ir4)ir)ir4)ir)ir4)ir)ir4)iX rIuक़)iY rIuख़)iZ rIuग़)i[ rIuज़)i\ rIuड़)i] rIuढ़)i^ rIuफ़)i_ rIuय़)i` r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i rIuড়)i rIuঢ়)i r)i rIuয়)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i) r)i* r4)i1 r)i2 r4)i3 rIuਲ਼)i4 r)i5 r4)i6 rIuਸ਼)i7 r)i8 r4)i: r)i< r4)i= r)i> r4)iC r)iG r4)iI r)iK r4)iN r)iQ r4)iR r)iY rIuਖ਼)iZ rIuਗ਼)i[ rIuਜ਼rrrrr_seg_10#rrcCr)N)d)i\ r4)i] r)i^ rIuਫ਼)i_ r)if r4)iw r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i) r)i* r4)i1 r)i2 r4)i4 r)i5 r4)i: r)i< r4)iE r)iG r4)iI r)iK r4)iN r)iU r4)iX r)i\ rIuଡ଼)i] rIuଢ଼)i^ r)i_ r4)id r)if r4)ix r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4rrrrr_seg_11rrcCr)N)d)i) r)i* r4)i: r)i= r4)iE r)iF r4)iI r)iJ r4)iN r)iU r4)iW r)iX r4)i[ r)i` r4)id r)if r4)ip r)iw r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)iE r)iF r4)iI r)iJ r4)iP r)iT r4)id r)if r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)ir4)i3rIuํา)i4r4)i;r)i?r4)i\r)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)irIuໍາ)ir4rrrrr_seg_12rrcCr)N)d)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)irIuຫນ)irIuຫມ)ir4)ir)ir4)i rIu་)i r4)iCrIuགྷ)iDr4)iHr)iIr4)iMrIuཌྷ)iNr4)iRrIuདྷ)iSr4)iWrIuབྷ)iXr4)i\rIuཛྷ)i]r4)iirIuཀྵ)ijr4)imr)iqr4)isrIuཱི)itr4)iurIuཱུ)ivrIuྲྀ)iwrIu ྲཱྀ)ixrIuླྀ)iyrIu ླཱྀ)izr4)irIuཱྀ)ir4)irIuྒྷ)ir4)ir)ir4)irIuྜྷ)ir4)irIuྡྷ)ir4)irIuྦྷ)ir4)irIuྫྷ)ir4)irIuྐྵ)ir4)ir)ir4)ir)ir4)ir)ir4)ir)irIuⴧ)ir)irIuⴭ)ir)ir4)irIნ)ir4)i_r)iar4)iIr)iJr4)iNr)iPr4)iWr)iXr4)iYr)iZr4)i^r)i`r4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4rrrrr_seg_13^rrcCr)N)d)ir)ir4)i[r)i]r4)i}r)ir4)ir)ir4)ir)irIuᏰ)irIuᏱ)irIuᏲ)irIuᏳ)irIuᏴ)irIuᏵ)ir)ir4)ir)ir4)ir)ir4)ir)ir4)i r)ir4)ir)i r4)i7r)i@r4)iTr)i`r4)imr)inr4)iqr)irr4)itr)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)i r)ir)ir4)ir)i r4)iyr)ir4)ir)ir4)ir)ir4)ir)i r4)i,r)i0r4)i<r)i@r4)iAr)iDr4)inr)ipr4)iur)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)i_r)i`r4)i}r)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)iLr)iPr4)i}r)ir4)ir)ir4)i8r)i;r4)iJr)iMr4rrrrr_seg_14rrcCr)N)d)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIꙋ)ir)irIuა)irIuბ)irIuგ)irIuდ)irIuე)irIuვ)irIuზ)irIuთ)irIuი)irIuკ)irIuლ)irIuმ)irIr)irIuო)irIuპ)irIuჟ)irIuრ)irIuს)irIuტ)irIuუ)irIuფ)irIuქ)irIuღ)irIuყ)irIuშ)irIuჩ)irIuც)irIuძ)irIuწ)irIuჭ)irIuხ)irIuჯ)irIuჰ)irIuჱ)irIuჲ)irIuჳ)irIuჴ)irIuჵ)irIuჶ)irIuჷ)irIuჸ)irIuჹ)irIuჺ)ir)irIuჽ)irIuჾ)irIuჿ)ir4)ir)ir4)ir)ir4)i,rIrJ)i-rIr)i.rIrL)i/r4)i0rIrP)i1rIrR)i2rIrV)i3rIrV)i4rIrX)i5rIrZ)i6rIr\)i7rIr^)i8rIr`)i9rIrb)i:rIrd)i;r4)i<rIrf)i=rIre)i>rIrh)i?rIrl)i@rIrp)iArIrr)iBrIrv)iCrIrJ)iDrIɐ)iErIɑ)iFrIuᴂ)iGrIrL)iHrIrP)iIrIrR)iJrIrW)iKrIrX)iLrIɜ)iMrIrV)iNr4)iOrIr^)iPrIrb)iQrIrR)iRrIrfrrrrr_seg_150rrcCr)N)d)iSrIrU)iTrIuᴖ)iUrIuᴗ)iVrIrh)iWrIrp)iXrIrr)iYrIuᴝ)iZrIr])i[rIrt)i\rIuᴥ)i]rIrv)i^rIrw)i_rIrx)i`rIr)iarIr)ibrIrZ)icrIrl)idrIrr)ierIrt)ifrIrv)igrIrw)ihrIr)iirIr)ijrIr)ikr4)ixrIr)iyr4)irIɒ)irIrN)irIuɕ)irIr)irIr)irIrT)irIuɟ)irIɡ)irIɥ)irIr\)irIr[)irIɪ)irIuᵻ)irIʝ)irIuɭ)irIuᶅ)irIuʟ)irIɱ)irIuɰ)irIr^)irIuɳ)irIuɴ)irIr_)irIuɸ)irIʂ)irIr`)irIuƫ)irIrf)irIra)irIuᴜ)irIrb)irIrg)irIr|)irIuʐ)irIuʑ)irIrc)irIr|)ir4)ir)ir4)irIuḁ)ir4)irIuḃ)ir4)irIuḅ)ir4)irIuḇ)ir4)irIuḉ)i r4)i rIuḋ)i r4)i rIuḍ)i r4)irIuḏ)ir4)irIuḑ)ir4)irIuḓ)ir4)irIuḕ)ir4)irIuḗ)ir4)irIuḙ)ir4)irIuḛ)ir4)irIuḝ)ir4)irIuḟ)ir4)i rIuḡrrrrr_seg_16rrcCr)N)d)i!r4)i"rIuḣ)i#r4)i$rIuḥ)i%r4)i&rIuḧ)i'r4)i(rIuḩ)i)r4)i*rIuḫ)i+r4)i,rIuḭ)i-r4)i.rIuḯ)i/r4)i0rIuḱ)i1r4)i2rIuḳ)i3r4)i4rIuḵ)i5r4)i6rIuḷ)i7r4)i8rIuḹ)i9r4)i:rIuḻ)i;r4)i<rIuḽ)i=r4)i>rIuḿ)i?r4)i@rIuṁ)iAr4)iBrIuṃ)iCr4)iDrIuṅ)iEr4)iFrIuṇ)iGr4)iHrIuṉ)iIr4)iJrIuṋ)iKr4)iLrIuṍ)iMr4)iNrIuṏ)iOr4)iPrIuṑ)iQr4)iRrIuṓ)iSr4)iTrIuṕ)iUr4)iVrIuṗ)iWr4)iXrIuṙ)iYr4)iZrIuṛ)i[r4)i\rIuṝ)i]r4)i^rIuṟ)i_r4)i`rIṡ)iar4)ibrIuṣ)icr4)idrIuṥ)ier4)ifrIuṧ)igr4)ihrIuṩ)iir4)ijrIuṫ)ikr4)ilrIuṭ)imr4)inrIuṯ)ior4)iprIuṱ)iqr4)irrIuṳ)isr4)itrIuṵ)iur4)ivrIuṷ)iwr4)ixrIuṹ)iyr4)izrIuṻ)i{r4)i|rIuṽ)i}r4)i~rIuṿ)ir4)irIuẁ)ir4)irIuẃ)ir4)irIuẅrrrrr_seg_17rrcCr)N)d)ir4)irIuẇ)ir4)irIuẉ)ir4)irIuẋ)ir4)irIuẍ)ir4)irIuẏ)ir4)irIuẑ)ir4)irIuẓ)ir4)irIuẕ)ir4)irIuaʾ)irIr)ir4)irIr.)ir4)irIuạ)ir4)irIuả)ir4)irIuấ)ir4)irIuầ)ir4)irIuẩ)ir4)irIuẫ)ir4)irIuậ)ir4)irIuắ)ir4)irIuằ)ir4)irIuẳ)ir4)irIuẵ)ir4)irIuặ)ir4)irIuẹ)ir4)irIuẻ)ir4)irIuẽ)ir4)irIuế)ir4)irIuề)ir4)irIuể)ir4)irIuễ)ir4)irIuệ)ir4)irIuỉ)ir4)irIuị)ir4)irIuọ)ir4)irIuỏ)ir4)irIuố)ir4)irIuồ)ir4)irIuổ)ir4)irIuỗ)ir4)irIuộ)ir4)irIuớ)ir4)irIuờ)ir4)irIuở)ir4)irIuỡ)ir4)irIuợ)ir4)irIuụ)ir4)irIuủ)ir4)irIuứ)ir4)irIuừ)ir4)irIuử)ir4rrrrr_seg_18krrcCr)N)d)irIuữ)ir4)irIuự)ir4)irIuỳ)ir4)irIuỵ)ir4)irIuỷ)ir4)irIuỹ)ir4)irIuỻ)ir4)irIuỽ)ir4)irIuỿ)ir4)irIuἀ)i rIuἁ)i rIuἂ)i rIuἃ)i rIuἄ)i rIuἅ)irIuἆ)irIuἇ)ir4)ir)irIuἐ)irIuἑ)irIuἒ)irIuἓ)irIuἔ)irIuἕ)ir)i r4)i(rIuἠ)i)rIuἡ)i*rIuἢ)i+rIuἣ)i,rIuἤ)i-rIuἥ)i.rIuἦ)i/rIuἧ)i0r4)i8rIuἰ)i9rIuἱ)i:rIuἲ)i;rIuἳ)i<rIuἴ)i=rIuἵ)i>rIuἶ)i?rIuἷ)i@r4)iFr)iHrIuὀ)iIrIuὁ)iJrIuὂ)iKrIuὃ)iLrIuὄ)iMrIuὅ)iNr)iPr4)iXr)iYrIuὑ)iZr)i[rIuὓ)i\r)i]rIuὕ)i^r)i_rIuὗ)i`r4)ihrIuὠ)iirIuὡ)ijrIuὢ)ikrIuὣ)ilrIuὤ)imrIuὥ)inrIuὦ)iorIuὧ)ipr4)iqrIrm)irr4)isrIro)itr4)iurIrp)ivr4)iwrIrq)ixr4)iyrIrr)izr4)i{rIrs)i|r4)i}rIrt)i~r)irIἀι)irIἁι)irIἂι)irIἃι)irIἄιrrrrr_seg_19rrcCr)N)d)irIἅι)irIἆι)irIἇι)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIἠι)irIἡι)irIἢι)irIἣι)irIἤι)irIἥι)irIἦι)irIἧι)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIὠι)irIὡι)irIὢι)irIὣι)irIὤι)irIὥι)irIὦι)irIὧι)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)ir4)irIuὰι)irIαι)irIuάι)ir)ir4)irIuᾶι)irIuᾰ)irIuᾱ)irIuὰ)irIrm)irIr)ir ̓)irIri)irr)iru ͂)iru ̈͂)irIuὴι)irIηι)irIuήι)ir)ir4)irIuῆι)irIuὲ)irIro)irIuὴ)irIrp)irIr)iru ̓̀)iru ̓́)iru ̓͂)ir4)irIuΐ)ir)ir4)irIuῐ)irIuῑ)irIuὶ)irIrq)ir)iru ̔̀)iru ̔́)iru ̔͂)ir4)irIuΰ)ir4)irIuῠ)irIuῡ)irIuὺ)irIrs)irIuῥ)iru ̈̀)irrl)ir`)ir)irIuὼι)irIωιrrrrr_seg_20=rrcCr)N)d)irIuώι)ir)ir4)irIuῶι)irIuὸ)irIrr)irIuὼ)irIrt)irIr)irr)iru ̔)ir)i rr)i r)i r-)i r)i r4)i rIu‐)i r4)i ru ̳)i r4)i$ r)i' r4)i( r)i/ rr)i0 r4)i3 rIu′′)i4 rIu ′′′)i5 r4)i6 rIu‵‵)i7 rIu ‵‵‵)i8 r4)i< rz!!)i= r4)i> r ̅)i? r4)iG rz??)iH rz?!)iI rz!?)iJ r4)iW rIu ′′′′)iX r4)i_ rr)i` r)ia r)id r)ie r)ip rI0)iq rIrZ)ir r)it rI4)iu rI5)iv rI6)iw rI7)ix rI8)iy rI9)iz r+)i{ rI−)i| r=)i} r()i~ r))i rIrd)i rIr)i rIr)i rIr)i rIr)i rIr)i rIr)i rIr)i rIr)i rIr)i rIr)i rr)i rIr)i rr)i rr)i rr)i r)i rIrJ)i rIrR)i rIrf)i rIrx)i rIrW)i rIrX)i rIr^)i rIr`)i rIrb)i rIrd)i rIrh)i rIrn)i rIrp)i r)i r4)i rIrs)i r4)i r)i r4)i r)i!rza/c)i!rza/srrrrr_seg_21rrcCr)N)d)i!rIrN)i!rIu°c)i!r4)i!rzc/o)i!rzc/u)i!rIrX)i!r4)i !rIu°f)i !rIrV)i !rIrX)i!rIrP)i!rIrZ)i!rIr`)i!r4)i!rIrd)i!rIno)i!r4)i!rIrh)i!rIrj)i!rIrl)i!r4)i !rIsm)i!!rItel)i"!rItm)i#!r4)i$!rIr|)i%!r4)i&!rIr)i'!r4)i(!rIr|)i)!r4)i*!rIr^)i+!rIr)i,!rIrL)i-!rIrN)i.!r4)i/!rIrR)i1!rIrT)i2!r)i3!rIrb)i4!rIrf)i5!rIא)i6!rIuב)i7!rIuג)i8!rIד)i9!rIrZ)i:!r4)i;!rIZfax)i/rIu戶)i?/rI手)i@/rIu支)iA/rIu攴)iB/rI文)iC/rIu斗)iD/rIu斤)iE/rIu方)iF/rIu无)iG/rI日)iH/rIu曰)iI/rI月)iJ/rI木)iK/rIu欠)iL/rIu止)iM/rI歹)iN/rIu殳)iO/rIu毋)iP/rIu比)iQ/rIu毛)iR/rIu氏)iS/rIu气)iT/rI水)iU/rI火)iV/rIu爪)iW/rIu父)iX/rIu爻)iY/rIu爿)iZ/rIu片)i[/rIu牙)i\/rIu牛)i]/rIu犬)i^/rIu玄)i_/rIu玉)i`/rIu瓜)ia/rIu瓦)ib/rIu甘)ic/rI生)id/rIu用)ie/rIu田)if/rIu疋)ig/rIu疒)ih/rIu癶)ii/rIu白)ij/rIu皮)ik/rIu皿)il/rIu目)im/rIu矛)in/rIu矢)io/rIu石)ip/rIu示)iq/rIu禸)ir/rIu禾)is/rIu穴)it/rI立)iu/rIu竹rrrrr_seg_27 rr)cCr)N)d)iv/rIu米)iw/rIu糸)ix/rIu缶)iy/rIu网)iz/rIu羊)i{/rI羽)i|/rI老)i}/rIu而)i~/rIu耒)i/rIu耳)i/rIu聿)i/rIu肉)i/rIu臣)i/rIu自)i/rIu至)i/rIu臼)i/rIu舌)i/rIu舛)i/rIu舟)i/rIu艮)i/rIu色)i/rIu艸)i/rIu虍)i/rIu虫)i/rIu血)i/rI行)i/rI衣)i/rIu襾)i/rI見)i/rIu角)i/rIu言)i/rIu谷)i/rIu豆)i/rI豕)i/rIu豸)i/rIu貝)i/rIu赤)i/rI走)i/rIu足)i/rIu身)i/rI車)i/rIu辛)i/rI辰)i/rIu辵)i/rIu邑)i/rIu酉)i/rIu釆)i/rI里)i/rI金)i/rIu長)i/rIu門)i/rIu阜)i/rIu隶)i/rIu隹)i/rIu雨)i/rIu靑)i/rIu非)i/rIu面)i/rIu革)i/rIu韋)i/rIu韭)i/rIu音)i/rIu頁)i/rIu風)i/rIu飛)i/rIu食)i/rIu首)i/rIu香)i/rIu馬)i/rIu骨)i/rIu高)i/rIu髟)i/rIu鬥)i/rIu鬯)i/rIu鬲)i/rIu鬼)i/rIu魚)i/rIu鳥)i/rIu鹵)i/rI鹿)i/rIu麥)i/rI麻)i/rIu黃)i/rIu黍)i/rIu黑)i/rI黹)i/rIu黽)i/rIu鼎)i/rIu鼓)i/rIu鼠)i/rI鼻)i/rIu齊)i/rIu齒)i/rI龍)i/rI龜)i/rIu龠)i/r)i0rr)i0r4)i0rI.rrrrr_seg_28 rr<cCr)N)d)i0r4)i60rIu〒)i70r4)i80rIr)i90rIu卄)i:0rIu卅)i;0r4)i@0r)iA0r4)i0r)i0r4)i0ru ゙)i0ru ゚)i0r4)i0rIuより)i0r4)i0rIuコト)i1r)i1r4)i01r)i11rIᄀ)i21rIᄁ)i31rIᆪ)i41rIᄂ)i51rIᆬ)i61rIᆭ)i71rIᄃ)i81rIᄄ)i91rIᄅ)i:1rIᆰ)i;1rIᆱ)i<1rIᆲ)i=1rIᆳ)i>1rIᆴ)i?1rIᆵ)i@1rIᄚ)iA1rIᄆ)iB1rIᄇ)iC1rIᄈ)iD1rIᄡ)iE1rIᄉ)iF1rIᄊ)iG1rIᄋ)iH1rIᄌ)iI1rIᄍ)iJ1rIᄎ)iK1rIᄏ)iL1rIᄐ)iM1rIᄑ)iN1rIᄒ)iO1rIᅡ)iP1rIᅢ)iQ1rIᅣ)iR1rIᅤ)iS1rIᅥ)iT1rIᅦ)iU1rIᅧ)iV1rIᅨ)iW1rIᅩ)iX1rIᅪ)iY1rIᅫ)iZ1rIᅬ)i[1rIᅭ)i\1rIᅮ)i]1rIᅯ)i^1rIᅰ)i_1rIᅱ)i`1rIᅲ)ia1rIᅳ)ib1rIᅴ)ic1rIᅵ)id1r)ie1rIuᄔ)if1rIuᄕ)ig1rIuᇇ)ih1rIuᇈ)ii1rIuᇌ)ij1rIuᇎ)ik1rIuᇓ)il1rIuᇗ)im1rIuᇙ)in1rIuᄜ)io1rIuᇝ)ip1rIuᇟ)iq1rIuᄝ)ir1rIuᄞ)is1rIuᄠ)it1rIuᄢ)iu1rIuᄣ)iv1rIuᄧ)iw1rIuᄩ)ix1rIuᄫ)iy1rIuᄬ)iz1rIuᄭ)i{1rIuᄮ)i|1rIuᄯ)i}1rIuᄲ)i~1rIuᄶ)i1rIuᅀ)i1rIuᅇrrrrr_seg_29 rrpcCr)N)d)i1rIuᅌ)i1rIuᇱ)i1rIuᇲ)i1rIuᅗ)i1rIuᅘ)i1rIuᅙ)i1rIuᆄ)i1rIuᆅ)i1rIuᆈ)i1rIuᆑ)i1rIuᆒ)i1rIuᆔ)i1rIuᆞ)i1rIuᆡ)i1r)i1r4)i1rIr)i1rIr)i1rI三)i1rI四)i1rI上)i1rI中)i1rI下)i1rIu甲)i1rIr)i1rIu丙)i1rIu丁)i1rI天)i1rIu地)i1rIr)i1r4)i1r)i1r4)i2ru(ᄀ))i2ru(ᄂ))i2ru(ᄃ))i2ru(ᄅ))i2ru(ᄆ))i2ru(ᄇ))i2ru(ᄉ))i2ru(ᄋ))i2ru(ᄌ))i 2ru(ᄎ))i 2ru(ᄏ))i 2ru(ᄐ))i 2ru(ᄑ))i 2ru(ᄒ))i2ru(가))i2ru(나))i2ru(다))i2ru(라))i2ru(마))i2ru(바))i2ru(사))i2ru(아))i2ru(자))i2ru(차))i2ru(카))i2ru(타))i2ru(파))i2ru(하))i2ru(주))i2ru(오전))i2ru(오후))i2r)i 2ru(一))i!2ru(二))i"2ru(三))i#2ru(四))i$2ru(五))i%2ru(六))i&2ru(七))i'2ru(八))i(2ru(九))i)2ru(十))i*2ru(月))i+2ru(火))i,2ru(水))i-2ru(木))i.2ru(金))i/2ru(土))i02ru(日))i12ru(株))i22ru(有))i32ru(社))i42ru(名))i52ru(特))i62ru(財))i72ru(祝))i82ru(労))i92ru(代))i:2ru(呼))i;2ru(学))i<2ru(監))i=2ru(企))i>2ru(資))i?2ru(協))i@2ru(祭))iA2ru(休))iB2ru(自)rrrrr_seg_30W rrwcCr)N)d)iC2ru(至))iD2rIu問)iE2rIu幼)iF2rIr )iG2rIu箏)iH2r4)iP2rIZpte)iQ2rIZ21)iR2rIZ22)iS2rIZ23)iT2rIZ24)iU2rIZ25)iV2rIZ26)iW2rI27)iX2rIZ28)iY2rIZ29)iZ2rIZ30)i[2rIZ31)i\2rIZ32)i]2rIZ33)i^2rIZ34)i_2rIZ35)i`2rIr=)ia2rIr@)ib2rIrC)ic2rIrE)id2rIrM)ie2rIrN)if2rIrQ)ig2rIrS)ih2rIrT)ii2rIrV)ij2rIrW)ik2rIrX)il2rIrY)im2rIrZ)in2rIu가)io2rIu나)ip2rIu다)iq2rIu라)ir2rIu마)is2rIu바)it2rIu사)iu2rIu아)iv2rIu자)iw2rIu차)ix2rIu카)iy2rIu타)iz2rIu파)i{2rIu하)i|2rIu참고)i}2rIu주의)i~2rIu우)i2r4)i2rIr)i2rIr)i2rIrq)i2rIrr)i2rIu五)i2rI六)i2rIu七)i2rIr)i2rIu九)i2rIr)i2rIr")i2rIr&)i2rIr%)i2rIr#)i2rIr4)i2rIr)i2rIr!)i2rIu株)i2rI有)i2rI社)i2rIu名)i2rIu特)i2rIu財)i2rI祝)i2rIu労)i2rIu秘)i2rIu男)i2rIr)i2rIu適)i2rIu優)i2rIu印)i2rIu注)i2rIu項)i2rIu休)i2rIu写)i2rIu正)i2rIrs)i2rIrt)i2rIru)i2rI左)i2rI右)i2rIu医)i2rIu宗)i2rIu学)i2rIu監)i2rIu企rrrrr_seg_31 rrcCr)N)d)i2rIu資)i2rIu協)i2rIu夜)i2rIZ36)i2rIZ37)i2rIZ38)i2rIZ39)i2rIZ40)i2rIZ41)i2rIZ42)i2rIZ43)i2rIZ44)i2rIZ45)i2rIZ46)i2rIZ47)i2rIZ48)i2rIZ49)i2rIZ50)i2rIu1月)i2rIu2月)i2rIu3月)i2rIu4月)i2rIu5月)i2rIu6月)i2rIu7月)i2rIu8月)i2rIu9月)i2rIu10月)i2rIu11月)i2rIu12月)i2rIhg)i2rIZerg)i2rIZev)i2rIZltd)i2rIア)i2rIイ)i2rIウ)i2rIエ)i2rIオ)i2rIカ)i2rIキ)i2rIク)i2rIケ)i2rIコ)i2rIサ)i2rIシ)i2rIス)i2rIセ)i2rIソ)i2rIタ)i2rIチ)i2rIツ)i2rIテ)i2rIト)i2rIナ)i2rIニ)i2rIヌ)i2rIネ)i2rIノ)i2rIハ)i2rIヒ)i2rIフ)i2rIヘ)i2rIホ)i2rIマ)i2rIミ)i2rIム)i2rIメ)i2rIモ)i2rIヤ)i2rIユ)i2rIヨ)i2rIラ)i2rIリ)i2rIル)i2rIレ)i2rIロ)i2rIワ)i2rIuヰ)i2rIuヱ)i2rIヲ)i2rIu令和)i3rIu アパート)i3rIu アルファ)i3rIu アンペア)i3rIu アール)i3rIu イニング)i3rIu インチ)i3rIu ウォン)i3rIuエスクード)i3rIu エーカー)i 3rIu オンス)i 3rIu オーム)i 3rIu カイリ)i 3rIu カラット)i 3rIu カロリー)i3rIu ガロン)i3rIu ガンマ)i3rIuギガ)i3rIu ギニーrrrrr_seg_32) rrcCr)N)d)i3rIu キュリー)i3rIu ギルダー)i3rIuキロ)i3rIuキログラム)i3rIuキロメートル)i3rIuキロワット)i3rIu グラム)i3rIuグラムトン)i3rIuクルゼイロ)i3rIu クローネ)i3rIu ケース)i3rIu コルナ)i3rIu コーポ)i3rIu サイクル)i 3rIuサンチーム)i!3rIu シリング)i"3rIu センチ)i#3rIu セント)i$3rIu ダース)i%3rIuデシ)i&3rIuドル)i'3rIuトン)i(3rIuナノ)i)3rIu ノット)i*3rIu ハイツ)i+3rIuパーセント)i,3rIu パーツ)i-3rIu バーレル)i.3rIuピアストル)i/3rIu ピクル)i03rIuピコ)i13rIuビル)i23rIuファラッド)i33rIu フィート)i43rIuブッシェル)i53rIu フラン)i63rIuヘクタール)i73rIuペソ)i83rIu ペニヒ)i93rIu ヘルツ)i:3rIu ペンス)i;3rIu ページ)i<3rIu ベータ)i=3rIu ポイント)i>3rIu ボルト)i?3rIuホン)i@3rIu ポンド)iA3rIu ホール)iB3rIu ホーン)iC3rIu マイクロ)iD3rIu マイル)iE3rIu マッハ)iF3rIu マルク)iG3rIuマンション)iH3rIu ミクロン)iI3rIuミリ)iJ3rIuミリバール)iK3rIuメガ)iL3rIu メガトン)iM3rIu メートル)iN3rIu ヤード)iO3rIu ヤール)iP3rIu ユアン)iQ3rIu リットル)iR3rIuリラ)iS3rIu ルピー)iT3rIu ルーブル)iU3rIuレム)iV3rIuレントゲン)iW3rIu ワット)iX3rIu0点)iY3rIu1点)iZ3rIu2点)i[3rIu3点)i\3rIu4点)i]3rIu5点)i^3rIu6点)i_3rIu7点)i`3rIu8点)ia3rIu9点)ib3rIu10点)ic3rIu11点)id3rIu12点)ie3rIu13点)if3rIu14点)ig3rIu15点)ih3rIu16点)ii3rIu17点)ij3rIu18点)ik3rIu19点)il3rIu20点)im3rIu21点)in3rIu22点)io3rIu23点)ip3rIu24点)iq3rIhpa)ir3rIda)is3rIau)it3rIbar)iu3rIovrrrrr_seg_33 rrcCr)N)d)iv3rIZpc)iw3rIdm)ix3rIZdm2)iy3rIZdm3)iz3rIiu)i{3rIu平成)i|3rIu昭和)i}3rIu大正)i~3rIu明治)i3rIu 株式会社)i3rIpa)i3rIna)i3rIuμa)i3rIma)i3rIka)i3rIkb)i3rImb)i3rIgb)i3rIcal)i3rIZkcal)i3rIpf)i3rInf)i3rIuμf)i3rIuμg)i3rIZmg)i3rIZkg)i3rIhz)i3rIkhz)i3rImhz)i3rIghz)i3rIthz)i3rIuμl)i3rIml)i3rIdl)i3rIkl)i3rIZfm)i3rInm)i3rIuμm)i3rImm)i3rIcm)i3rIkm)i3rIZmm2)i3rIZcm2)i3rIm2)i3rIZkm2)i3rIZmm3)i3rIZcm3)i3rIZm3)i3rIZkm3)i3rIum∕s)i3rIum∕s2)i3rIr)i3rIkpa)i3rImpa)i3rIgpa)i3rIZrad)i3rIurad∕s)i3rIurad∕s2)i3rIZps)i3rIns)i3rIuμs)i3rIms)i3rIpv)i3rInv)i3rIuμv)i3rImv)i3rIkv)i3rIr)i3rIpw)i3rInw)i3rIuμw)i3rImw)i3rIkw)i3rIr)i3rIukω)i3rIumω)i3r)i3rIbq)i3rIcc)i3rIcd)i3rIuc∕kg)i3r)i3rIdb)i3rIgy)i3rIZha)i3rIhp)i3rIin)i3rIkk)i3rIr)i3rIZkt)i3rIZlm)i3rIln)i3rIlog)i3rIZlx)i3rIr)i3rImil)i3rIZmol)i3rIph)i3r)i3rIppmrrrrr_seg_34 rrcCr)N)d)i3rIpr)i3rIsr)i3rIsv)i3rIwb)i3rIuv∕m)i3rIua∕m)i3rIu1日)i3rIu2日)i3rIu3日)i3rIu4日)i3rIu5日)i3rIu6日)i3rIu7日)i3rIu8日)i3rIu9日)i3rIu10日)i3rIu11日)i3rIu12日)i3rIu13日)i3rIu14日)i3rIu15日)i3rIu16日)i3rIu17日)i3rIu18日)i3rIu19日)i3rIu20日)i3rIu21日)i3rIu22日)i3rIu23日)i3rIu24日)i3rIu25日)i3rIu26日)i3rIu27日)i3rIu28日)i3rIu29日)i3rIu30日)i3rIu31日)i3rIZgal)i4r4)ir)ir4)ir)ir4)iǤr)iФr4)i,r)i@rIuꙁ)iAr4)iBrIuꙃ)iCr4)iDrIuꙅ)iEr4)iFrIuꙇ)iGr4)iHrIuꙉ)iIr4)iJrIr)iKr4)iLrIuꙍ)iMr4)iNrIuꙏ)iOr4)iPrIuꙑ)iQr4)iRrIuꙓ)iSr4)iTrIuꙕ)iUr4)iVrIuꙗ)iWr4)iXrIuꙙ)iYr4)iZrIuꙛ)i[r4)i\rIuꙝ)i]r4)i^rIuꙟ)i_r4)i`rIuꙡ)iar4)ibrIuꙣ)icr4)idrIuꙥ)ier4)ifrIuꙧ)igr4)ihrIuꙩ)iir4)ijrIuꙫ)ikr4)ilrIuꙭ)imr4)irIuꚁ)ir4)irIuꚃ)ir4)irIuꚅ)ir4)irIuꚇ)ir4rrrrr_seg_35drrcCr)N)d)irIuꚉ)ir4)irIuꚋ)ir4)irIuꚍ)ir4)irIuꚏ)ir4)irIuꚑ)ir4)irIuꚓ)ir4)irIuꚕ)ir4)irIuꚗ)ir4)irIuꚙ)ir4)irIuꚛ)ir4)irIr)irIr)ir4)ir)ir4)i"rIuꜣ)i#r4)i$rIuꜥ)i%r4)i&rIꜧ)i'r4)i(rIuꜩ)i)r4)i*rIuꜫ)i+r4)i,rIuꜭ)i-r4)i.rIuꜯ)i/r4)i2rIuꜳ)i3r4)i4rIuꜵ)i5r4)i6rIuꜷ)i7r4)i8rIuꜹ)i9r4)i:rIuꜻ)i;r4)i<rIuꜽ)i=r4)i>rIuꜿ)i?r4)i@rIuꝁ)iAr4)iBrIuꝃ)iCr4)iDrIuꝅ)iEr4)iFrIuꝇ)iGr4)iHrIuꝉ)iIr4)iJrIuꝋ)iKr4)iLrIuꝍ)iMr4)iNrIuꝏ)iOr4)iPrIuꝑ)iQr4)iRrIuꝓ)iSr4)iTrIuꝕ)iUr4)iVrIuꝗ)iWr4)iXrIuꝙ)iYr4)iZrIuꝛ)i[r4)i\rIuꝝ)i]r4)i^rIuꝟ)i_r4)i`rIuꝡ)iar4)ibrIuꝣ)icr4)idrIuꝥ)ier4)ifrIuꝧ)igr4)ihrIuꝩ)iir4)ijrIuꝫ)ikr4)ilrIuꝭ)imr4)inrIꝯrrrrr_seg_36rrcCr)N)d)ior4)iprIr)iqr4)iyrIuꝺ)izr4)i{rIuꝼ)i|r4)i}rIuᵹ)i~rIuꝿ)ir4)irIuꞁ)ir4)irIuꞃ)ir4)irIuꞅ)ir4)irIuꞇ)ir4)irIuꞌ)ir4)irIr)ir4)irIuꞑ)ir4)irIuꞓ)ir4)irIuꞗ)ir4)irIuꞙ)ir4)irIuꞛ)ir4)irIuꞝ)ir4)irIuꞟ)ir4)irIuꞡ)ir4)irIuꞣ)ir4)irIuꞥ)ir4)irIuꞧ)ir4)irIuꞩ)ir4)irIrh)irIr)irIr)irIuɬ)irIr)ir4)irIuʞ)irIuʇ)irIr)irIuꭓ)irIuꞵ)ir4)irIuꞷ)ir4)irIuꞹ)ir4)irIuꞻ)ir4)irIuꞽ)ir4)irIuꞿ)ir4)ir)i§rIuꟃ)içr4)iħrIuꞔ)iŧrIr)iƧrIuᶎ)iǧrIuꟈ)iȧr4)iɧrIuꟊ)iʧr4)i˧r)irIuꟶ)ir4)irIrP)irIrS)ir4)i-r)i0r4)i:r)i@r4)ixr)ir4)iƨr)iΨr4)iڨr)ir4)iTr)i_r4)i}r)ir4)iΩr)iϩr4rrrrr_seg_376rrcCr)N)d)iکr)iީr4)ir)ir4)i7r)i@r4)iNr)iPr4)iZr)i\r4)iêr)i۪r4)ir)ir4)ir)i r4)ir)ir4)ir)i r4)i'r)i(r4)i/r)i0r4)i\rIr)i]rIuꬷ)i^rIr)i_rIuꭒ)i`r4)iirIuʍ)ijr4)ilr)iprIuᎠ)iqrIuᎡ)irrIuᎢ)isrIuᎣ)itrIuᎤ)iurIuᎥ)ivrIuᎦ)iwrIuᎧ)ixrIuᎨ)iyrIuᎩ)izrIuᎪ)i{rIuᎫ)i|rIuᎬ)i}rIuᎭ)i~rIuᎮ)irIuᎯ)irIuᎰ)irIuᎱ)irIuᎲ)irIuᎳ)irIuᎴ)irIuᎵ)irIuᎶ)irIuᎷ)irIuᎸ)irIuᎹ)irIuᎺ)irIuᎻ)irIuᎼ)irIuᎽ)irIuᎾ)irIuᎿ)irIuᏀ)irIuᏁ)irIuᏂ)irIuᏃ)irIuᏄ)irIuᏅ)irIuᏆ)irIuᏇ)irIuᏈ)irIuᏉ)irIuᏊ)irIuᏋ)irIuᏌ)irIuᏍ)irIuᏎ)irIuᏏ)irIuᏐ)irIuᏑ)irIuᏒ)irIuᏓ)irIuᏔ)irIuᏕ)irIuᏖ)irIuᏗ)irIuᏘ)irIuᏙ)irIuᏚ)irIuᏛ)irIuᏜ)irIuᏝ)irIuᏞ)irIuᏟ)irIuᏠ)irIuᏡ)irIuᏢ)irIuᏣrrrrr_seg_38rrcCr)N)d)irIuᏤ)irIuᏥ)irIuᏦ)irIuᏧ)irIuᏨ)irIuᏩ)irIuᏪ)irIuᏫ)irIuᏬ)irIuᏭ)irIuᏮ)irIuᏯ)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)irIu豈)irIu更)irIr1)irIu賈)irIu滑)irIu串)irIu句)irIr:)i rIu契)i rIr4)i rIu喇)i rIu奈)i rI懶)irIu癩)irIu羅)irIu蘿)irIu螺)irIu裸)irIu邏)irI樂)irIu洛)irIu烙)irIu珞)irIu落)irIu酪)irIu駱)irIu亂)irIu卵)irIu欄)irIu爛)irIu蘭)i rIu鸞)i!rIu嵐)i"rIu濫)i#rIu藍)i$rIu襤)i%rIu拉)i&rIu臘)i'rIu蠟)i(rI廊)i)rI朗)i*rIu浪)i+rIu狼)i,rIu郎)i-rIu來)i.rIu冷)i/rIu勞)i0rIu擄)i1rIu櫓)i2rIu爐)i3rIu盧)i4rIr+)i5rIu蘆)i6rI虜)i7rIu路)i8rIu露)i9rIu魯)i:rIu鷺)i;rI碌)i<rIu祿)i=rIu綠)i>rIu菉)i?rIu錄)i@rIr5)iArIu論)iBrIu壟)iCrIu弄)iDrIu籠)iErIu聾)iFrIu牢)iGrIu磊)iHrIu賂)iIrIu雷)iJrIu壘)iKrIu屢)iLrIu樓)iMrIu淚)iNrIu漏rrrrr_seg_39rrcCr)N)d)iOrIu累)iPrIu縷)iQrIu陋)iRrIu勒)iSrIu肋)iTrIu凜)iUrIu凌)iVrIu稜)iWrIu綾)iXrIu菱)iYrIu陵)iZrIu讀)i[rIu拏)i\rIr)i]rI諾)i^rIu丹)i_rI寧)i`rIu怒)iarI率)ibrI異)icrI北)idrIu磻)ierIu便)ifrIu復)igrIu不)ihrIu泌)iirIu數)ijrIu索)ikrIu參)ilrIu塞)imrIu省)inrIu葉)iorI說)iprI殺)iqrIr2)irrIu沈)isrIu拾)itrI若)iurIu掠)ivrIu略)iwrIu亮)ixrIu兩)iyrIu凉)izrIu梁)i{rIu糧)i|rIu良)i}rIu諒)i~rIu量)irIu勵)irIu呂)irIr)irIu廬)irIu旅)irIu濾)irIu礪)irIu閭)irIu驪)irIu麗)irIu黎)irIr)irIu曆)irIu歷)irIu轢)irIu年)irIu憐)irIu戀)irIu撚)irIu漣)irIu煉)irIu璉)irIu秊)irI練)irIu聯)irIu輦)irIu蓮)irIu連)irIu鍊)irIu列)irIu劣)irIu咽)irIu烈)irIu裂)irIr)irIu廉)irIu念)irIu捻)irIu殮)irIu簾)irIu獵)irIu令)irIu囹)irIr)irIu嶺)irIu怜)irIu玲)irIu瑩)irIu羚)irIu聆)irIu鈴)irIu零rrrrr_seg_40qrrcCr)N)d)irIu靈)irIu領)irIu例)irIu禮)irIu醴)irIu隸)irIu惡)irIu了)irIu僚)irIu寮)irIu尿)irI料)irIr)irIu燎)irIu療)irIu蓼)irIu遼)irIr9)irIu暈)irIu阮)irIu劉)irIu杻)irIu柳)irI流)irIu溜)irIu琉)irIu留)irIu硫)irIu紐)irIu類)irIry)irIu戮)irIu陸)irIu倫)irIu崙)irIu淪)irIu輪)irIu律)irIu慄)irIu栗)irIr)irIu隆)irIu利)irIu吏)irIu履)irIu易)irIu李)irIu梨)irIu泥)irIu理)irIu痢)irIu罹)irIu裏)irIu裡)irIr3)irIu離)irIu匿)irIu溺)irIu吝)irIu燐)irIu璘)irIu藺)irIu隣)irIu鱗)irIu麟)irIu林)irIu淋)irIu臨)irIr()irIu笠)irIu粒)irIu狀)irIu炙)irIu識)irIu什)irIu茶)irIu刺)irI切)irIu度)irIu拓)irIu糖)irIu宅)irIu洞)irIu暴)irIu輻)irIr,)i rIu降)i rIr.)i rIu廓)i rIu兀)i rIu嗀)ir4)irI塚)ir4)irI晴)ir4)irIu凞)irI猪)irI益)irIu礼rrrrr_seg_41rr cCr)N)d)irIu神)irIu祥)irI福)irI靖)irIu精)irIr*)ir4)i rIu蘒)i!r4)i"rI諸)i#r4)i%rI逸)i&rIu都)i'r4)i*rIu飯)i+rIu飼)i,rIu館)i-rIu鶴)i.rIu郞)i/rIu隷)i0rI侮)i1rI僧)i2rI免)i3rI勉)i4rI勤)i5rI卑)i6rI喝)i7rI嘆)i8rIu器)i9rIu塀)i:rIu墨)i;rIu層)i<rIr)i=rI悔)i>rIu慨)i?rI憎)i@rI懲)iArI敏)iBrIu既)iCrI暑)iDrI梅)iErI海)iFrIu渚)iGrI漢)iHrI煮)iIrIu爫)iJrIu琢)iKrIu碑)iLrIr{)iMrIu祉)iNrIu祈)iOrIu祐)iPrI祖)iQrIr|)iRrIu禍)iSrIu禎)iTrI穀)iUrIu突)iVrI節)iWrIr)iXrIu縉)iYrIu繁)iZrIu署)i[rI者)i\rIu臭)i]rIu艹)i_rI著)i`rIu褐)iarI視)ibrI謁)icrI謹)idrIu賓)ierI贈)ifrIu辶)igrIr)ihrI難)iirI響)ijrI頻)ikrIu恵)ilrIu𤋮)imrIu舘)inr)iprIu並)iqrI况)irrIu全)isrIu侀)itrIu充)iurIu冀)ivrI勇)iwrI勺)ixrIr)iyrIu啕)izrI喙)i{rIu嗢)i|rIr)i}rIu墳)i~rIu奄)irIu奔)irIu婢)irIu嬨rrrrr_seg_42Crr1cCr)N)d)irIu廒)irIu廙)irIu彩)irIu徭)irIu惘)irI慎)irIu愈)irIr)irIu慠)irIr)irIu戴)irIu揄)irIu搜)irIu摒)irIu敖)irIr)irIr)irI望)irIu杖)irIr$)irIr)irIr)irIu滛)irI滋)irIr)irI瀞)irIr )irIu瞧)irI爵)irIu犯)irIr )irI瑱)irIu甆)irIu画)irIu瘝)irIu瘟)irIr )irIu盛)irI直)irI睊)irIu着)irI磌)irIu窱)irIr#)irIu类)irIu絛)irIr)irIu缾)irIr$)irIu荒)irIu華)irI蝹)irIu襁)irIu覆)irIr&)irIu調)irIr)irIu請)irIr')irIr)irI諭)irIr()irI變)irIr))irI輸)irIu遲)irIu醙)irIu鉶)irIu陼)irIr*)irIr )irIu韛)irIr+)irI頋)irIr,)irI鬒)irIr:)irIu𢡊)irIu𢡄)irIu𣏕)irI㮝)irIu䀘)irI䀹)irIu𥉉)irIu𥳐)irIu𧻓)irIu齃)irIu龎)ir)irIff)irIfi)irIfl)irIffi)irIffl)irIst)ir)irIuմն)irIuմե)irIuմի)irIuվնrrrrr_seg_43rrIcCr)N)d)irIuմխ)ir)irIuיִ)ir4)irIuײַ)i rIuע)i!rIr)i"rIr)i#rIuה)i$rIuכ)i%rIuל)i&rIuם)i'rIuר)i(rIuת)i)rr)i*rIuשׁ)i+rIuשׂ)i,rIuשּׁ)i-rIuשּׂ)i.rIuאַ)i/rIuאָ)i0rIuאּ)i1rIuבּ)i2rIuגּ)i3rIuדּ)i4rIuהּ)i5rIuוּ)i6rIuזּ)i7r)i8rIuטּ)i9rIuיּ)i:rIuךּ)i;rIuכּ)i<rIuלּ)i=r)i>rIuמּ)i?r)i@rIuנּ)iArIuסּ)iBr)iCrIuףּ)iDrIuפּ)iEr)iFrIuצּ)iGrIuקּ)iHrIuרּ)iIrIuשּ)iJrIuתּ)iKrIuוֹ)iLrIuבֿ)iMrIuכֿ)iNrIuפֿ)iOrIuאל)iPrIuٱ)iRrIuٻ)iVrIuپ)iZrIuڀ)i^rIuٺ)ibrIuٿ)ifrIuٹ)ijrIuڤ)inrIuڦ)irrIuڄ)ivrIuڃ)izrIuچ)i~rIuڇ)irIuڍ)irIuڌ)irIuڎ)irIuڈ)irIuژ)irIuڑ)irIuک)irIuگ)irIuڳ)irIuڱ)irIں)irIuڻ)irIuۀ)irIuہ)irIuھ)irIuے)irIuۓ)ir4)ir)irIuڭ)irIuۇ)irIuۆ)irIuۈ)irIr)irIuۋ)irIuۅ)irIuۉ)irIuې)irIى)irIuئا)irIuئە)irIuئو)irIuئۇ)irIuئۆrrrrr_seg_44rrLcCr)N)d)irIuئۈ)irIuئې)irIئى)irIuی)irIئج)irIئح)irIئم)irIrM)irIئي)irIبج)irIبح)irIبخ)irIبم)i rIبى)i rIبي)i rIتج)i rIتح)i rIتخ)irIتم)irIتى)irIتي)irIuثج)irIثم)irIثى)irIثي)irIجح)irIجم)irIحج)irIحم)irIخج)irIuخح)irIخم)irIسج)irIسح)irIسخ)irIسم)i rIصح)i!rIصم)i"rIضج)i#rIضح)i$rIضخ)i%rIضم)i&rIطح)i'rIطم)i(rIظم)i)rIعج)i*rIعم)i+rIغج)i,rIغم)i-rIفج)i.rIفح)i/rIفخ)i0rIفم)i1rIفى)i2rIفي)i3rIقح)i4rIقم)i5rIقى)i6rIقي)i7rIكا)i8rIكج)i9rIكح)i:rIكخ)i;rIكل)i<rIكم)i=rIكى)i>rIكي)i?rIلج)i@rIلح)iArIلخ)iBrIلم)iCrIلى)iDrIلي)iErIمج)iFrIمح)iGrIمخ)iHrIمم)iIrIuمى)iJrIuمي)iKrIنج)iLrIنح)iMrIنخ)iNrIنم)iOrIنى)iPrIني)iQrIهج)iRrIهم)iSrIuهى)iTrIuهي)iUrIيج)iVrIيح)iWrIيخ)iXrIيم)iYrIيى)iZrIيي)i[rIuذٰ)i\rIuرٰ)i]rIىٰ)i^ru ٌّ)i_ru ٍّrrrrr_seg_45~rrcCr)N)d)i`ru َّ)iaru ُّ)ibru ِّ)icru ّٰ)idrIuئر)ierIuئز)ifrIrP)igrIuئن)ihrIrM)iirIrQ)ijrIuبر)ikrIuبز)ilrIrU)imrIuبن)inrIrV)iorIrW)iprIuتر)iqrIuتز)irrIr[)isrIuتن)itrIr\)iurIr])ivrIuثر)iwrIuثز)ixrIr^)iyrIuثن)izrIr_)i{rIr`)i|rIr|)i}rIr})i~rIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIuما)irIr)irIuنر)irIuنز)irIr)irIuنن)irIr)irIr)irIr)irIuير)irIuيز)irIr)irIuين)irIr)irIr)irIrN)irIrO)irIuئخ)irIrP)irIئه)irIrR)irIrS)irIrT)irIrU)irIبه)irIrX)irIrY)irIrZ)irIr[)irIته)irIr^)irIra)irIrb)irIrc)irIrd)irIre)irIrf)irIrg)irIrh)irIri)irIrj)irIrk)irIuصخ)irIrl)irIrm)irIrn)irIro)irIrp)irIrq)irIrs)irIrt)irIru)irIrv)irIrw)irIrx)irIry)irIrz)irIr{)irIr~)irIrrrrrr_seg_46rrcCr)N)d)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIuله)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIنه)irIr)irIr)irIuهٰ)irIr)irIr)irIr)irIr)irIيه)irIrP)irIr)irIrU)irIr)irIr[)irIr)irIr^)irIuثه)irIrj)irIسه)irIشم)irIشه)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIuـَّ)irIuـُّ)irIuـِّ)irIطى)irIطي)irIعى)irIعي)irIغى)irIغي)irIسى)irIسي)irIشى)irIشي)irIحى)irIحي)irIجى)irIجي)irIخى)irIخي)irIصى)irIصي)irIضى)irIضي)i rIشج)i rIشح)i rIشخ)i rIr)i rIشر)irIسر)irIصر)irIضر)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)i rIr)i!rIr)i"rIr)i#rIr)i$rIr)i%rIr)i&rIr)i'rIrrrrrr_seg_47PrrcCr)N)d)i(rIr)i)rIr)i*rIr)i+rIr)i,rIr)i-rIr)i.rIr)i/rIr)i0rIr)i1rIr)i2rIr)i3rIrr)i4rIrg)i5rIrh)i6rIri)i7rIr)i8rIr)i9rIr)i:rIrr)i;rIrs)i<rIuاً)i>r4)i@r)iPrIuتجم)iQrIuتحج)iSrIuتحم)iTrIuتخم)iUrIuتمج)iVrIuتمح)iWrIuتمخ)iXrIuجمح)iZrIuحمي)i[rIuحمى)i\rIuسحج)i]rIuسجح)i^rIuسجى)i_rIuسمح)iarIuسمج)ibrIuسمم)idrIuصحح)ifrIصمم)igrIuشحم)iirIuشجي)ijrIuشمخ)ilrIuشمم)inrIuضحى)iorIuضخم)iqrIuطمح)isrIuطمم)itrIuطمي)iurIعجم)ivrIuعمم)ixrIuعمى)iyrIuغمم)izrIuغمي)i{rIuغمى)i|rIuفخم)i~rIقمح)irIuقمم)irIلحم)irIuلحي)irIuلحى)irIuلجج)irIuلخم)irIuلمح)irIuمحج)irIuمحم)irIuمحي)irIuمجح)irIuمجم)irIuمخج)irIuمخم)ir)irIuمجخ)irIuهمج)irIuهمم)irIuنحم)irIuنحى)irIuنجم)irIuنجى)irIuنمي)irIuنمى)irIuيمم)irIuبخي)irIuتجي)irIuتجى)irIuتخي)irIuتخى)irIuتمي)irIuتمى)irIuجمي)irIuجحى)irIuجمى)irIuسخى)irIuصحي)irIuشحي)irIuضحي)irIuلجي)irIuلمي)irIuيحيrrrrr_seg_48rrcCr)N)d)irIuيجي)irIuيمي)irIuممي)irIuقمي)irIuنحي)irIr)irIr)irIuعمي)irIuكمي)irIنجح)irIuمخي)irIلجم)irIكمم)irIr)irIr)irIuجحي)irIuحجي)irIuمجي)irIuفمي)irIuبحي)irIr)irIr)irIr)irIuسخي)irIuنجي)ir)irIuصلے)irIuقلے)irIuالله)irIuاكبر)irIuمحمد)irIuصلعم)irIuرسول)irIuعليه)irIuوسلم)irIuصلى)iru!صلى الله عليه وسلم)iruجل جلاله)irIuریال)ir4)ir)ir)ir,)irI、)ir)ir:)irrk)ir!)ir?)irIu〖)irIu〗)ir)i r4)i0r)i1rI—)i2rIu–)i3r_)i5rr)i6rr)i7r{)i8r})i9rI〔)i:rI〕)i;rIu【)i<rIu】)i=rIu《)i>rIu》)i?rIr)i@rIr)iArI「)iBrI」)iCrIu『)iDrIu』)iEr4)iGr[)iHr])iIrr)iMrr)iPrr)iQrIr)iRr)iTrrk)iUrr)iVrr)iWrr)iXrIr)iYrr)iZrr)i[rr)i\rr)i]rIr)i^rIr)i_r#)i`r&)iar*)ibrr)icrI-)idr<)ier>)ifrrrrrrr_seg_49"rrcCr)N)d)igr)ihr\)iir$)ijr%)ikr@)ilr)ipru ً)iqrIuـً)irru ٌ)isr4)itru ٍ)iur)ivru َ)iwrIuـَ)ixru ُ)iyrIuـُ)izru ِ)i{rIuـِ)i|ru ّ)i}rIuـّ)i~ru ْ)irIuـْ)irIuء)irIuآ)irIuأ)irIuؤ)irIuإ)irIuئ)irIا)irIب)irIuة)irIت)irIث)irIج)irIح)irIخ)irIد)irIذ)irIر)irIز)irIس)irIش)irIص)irIض)irIط)irIظ)irIع)irIغ)irIف)irIق)irIك)irIل)irIم)irIن)irIه)irIو)irIrK)irIي)irIuلآ)irIuلأ)irIuلإ)irIuلا)ir)ir)ir)irr)ir")irr)irr)irr)irr)ir')irr)i rr)i rr)i rr)i rr)i rIr)irIr;)ir/)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irr)irrk)irr)irr)irr)irr)i rr)i!rIrJ)i"rIrL)i#rIrNrrrrr_seg_50rr cCr)N)d)i$rIrP)i%rIrR)i&rIrT)i'rIrV)i(rIrX)i)rIrZ)i*rIr\)i+rIr^)i,rIr`)i-rIrb)i.rIrd)i/rIrf)i0rIrh)i1rIrj)i2rIrl)i3rIrn)i4rIrp)i5rIrr)i6rIrt)i7rIrv)i8rIrx)i9rIrz)i:rIr|)i;rr)i<rr)i=rr)i>r^)i?rr)i@rr)iArIrJ)iBrIrL)iCrIrN)iDrIrP)iErIrR)iFrIrT)iGrIrV)iHrIrX)iIrIrZ)iJrIr\)iKrIr^)iLrIr`)iMrIrb)iNrIrd)iOrIrf)iPrIrh)iQrIrj)iRrIrl)iSrIrn)iTrIrp)iUrIrr)iVrIrt)iWrIrv)iXrIrx)iYrIrz)iZrIr|)i[rr)i\r|)i]rr)i^r~)i_rIu⦅)i`rIu⦆)iarIr;)ibrIr)icrIr)idrIr)ierIu・)ifrIr)igrIuァ)ihrIuィ)iirIuゥ)ijrIuェ)ikrIuォ)ilrIuャ)imrIuュ)inrIuョ)iorIuッ)iprIuー)iqrIr)irrIr)isrIr)itrIr)iurIr)ivrIr)iwrIr)ixrIr)iyrIr)izrIr)i{rIr)i|rIr)i}rIr)i~rIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIrrrrrr_seg_51rrcCr)N)d)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIuン)irIu゙)irIu゚)ir)irIr=)irIr>)irIr?)irIr@)irIrA)irIrB)irIrC)irIrD)irIrE)irIrF)irIrG)irIrH)irIrI)irIrJ)irIrK)irIrL)irIrM)irIrN)irIrO)irIrP)irIrQ)irIrR)irIrS)irIrT)irIrU)irIrV)irIrW)irIrX)irIrY)irIrZ)ir)irIr[)irIr\)irIr])irIr^)irIr_)irIr`)ir)irIra)irIrb)irIrc)irIrd)irIre)irIrf)ir)irIrg)irIrh)irIri)irIrj)irIrk)irIrl)ir)irIrm)irIrn)irIro)ir)irI¢)irI£)irI¬)irr)irI¦)irI¥)irIu₩)ir)irIu│)irIu←)irIu↑)irIu→)irIu↓)irIu■)irIu○)ir)ir4)i r)i r4rrrrr_seg_52]rrcCr)N)d)i'r)i(r4)i;r)i<r4)i>r)i?r4)iNr)iPr4)i^r)ir4)ir)ir4)ir)ir4)i4r)i7r4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)i$r)i-r4)iKr)iPr4)i{r)ir4)ir)ir4)ir)ir4)ir)irIu𐐨)irIu𐐩)irIu𐐪)irIu𐐫)irIu𐐬)irIu𐐭)irIu𐐮)irIu𐐯)irIu𐐰)i rIu𐐱)i rIu𐐲)i rIu𐐳)i rIu𐐴)i rIu𐐵)irIu𐐶)irIu𐐷)irIu𐐸)irIu𐐹)irIu𐐺)irIu𐐻)irIu𐐼)irIu𐐽)irIu𐐾)irIu𐐿)irIu𐑀)irIu𐑁)irIu𐑂)irIu𐑃)irIu𐑄)irIu𐑅)irIu𐑆)irIu𐑇)i rIu𐑈)i!rIu𐑉)i"rIu𐑊)i#rIu𐑋)i$rIu𐑌)i%rIu𐑍)i&rIu𐑎)i'rIu𐑏)i(r4)ir)ir4)ir)irIu𐓘)irIu𐓙)irIu𐓚)irIu𐓛)irIu𐓜)irIu𐓝)irIu𐓞)irIu𐓟)irIu𐓠)irIu𐓡)irIu𐓢)irIu𐓣)irIu𐓤)irIu𐓥)irIu𐓦rrrrr_seg_53rrcCr)N)d)irIu𐓧)irIu𐓨)irIu𐓩)irIu𐓪)irIu𐓫)irIu𐓬)irIu𐓭)irIu𐓮)irIu𐓯)irIu𐓰)irIu𐓱)irIu𐓲)irIu𐓳)irIu𐓴)irIu𐓵)irIu𐓶)irIu𐓷)irIu𐓸)irIu𐓹)irIu𐓺)irIu𐓻)ir)ir4)ir)ir4)i(r)i0r4)idr)ior4)ipr)ir4)i7r)i@r4)iVr)i`r4)ihr)ir4)ir)ir4)i r)i r4)i6r)i7r4)i9r)i<r4)i=r)i?r4)iVr)iWr4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)i r)i r4)i: r)i? r4)i@ r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i r)i r4)i6 r)i8 r4)i; r)i? r4)iI r)iP r4)iY r)i` r4)i r)i r4)i r)i r4)i r)i r4)i6 r)i9 r4)iV r)iX r4)is r)ix r4)i r)i r4)i r)i r4)i rrrrrr_seg_54/rrcCr)N)d)i r4)iI r)i rIu𐳀)i rIu𐳁)i rIu𐳂)i rIu𐳃)i rIu𐳄)i rIu𐳅)i rIu𐳆)i rIu𐳇)i rIu𐳈)i rIu𐳉)i rIu𐳊)i rIu𐳋)i rIu𐳌)i rIu𐳍)i rIu𐳎)i rIu𐳏)i rIu𐳐)i rIu𐳑)i rIu𐳒)i rIu𐳓)i rIu𐳔)i rIu𐳕)i rIu𐳖)i rIu𐳗)i rIu𐳘)i rIu𐳙)i rIu𐳚)i rIu𐳛)i rIu𐳜)i rIu𐳝)i rIu𐳞)i rIu𐳟)i rIu𐳠)i rIu𐳡)i rIu𐳢)i rIu𐳣)i rIu𐳤)i rIu𐳥)i rIu𐳦)i rIu𐳧)i rIu𐳨)i rIu𐳩)i rIu𐳪)i rIu𐳫)i rIu𐳬)i rIu𐳭)i rIu𐳮)i rIu𐳯)i rIu𐳰)i rIu𐳱)i rIu𐳲)i r)i r4)i r)i r4)i( r)i0 r4)i: r)i`r4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)i(r)i0r4)iZr)ir4)ir)ir4)ir)ir4)iNr)iRr4)ipr)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)i5r)i6r4)iHr)iPr4)iwr)ir4)ir)ir4)ir)ir4)irrrrrr_seg_55rrcCr)N)d)ir4)i?r)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)i r)ir4)ir)ir4)i)r)i*r4)i1r)i2r4)i4r)i5r4)i:r)i;r4)iEr)iGr4)iIr)iKr4)iNr)iPr4)iQr)iWr4)iXr)i]r4)idr)ifr4)imr)ipr4)iur)ir4)i\r)i]r4)ibr)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)iEr)iPr4)iZr)i`r4)imr)ir4)ir)ir4)ir)ir4)ir)ir4)i,r)i0r4)i@r)ir4)i<r)irIu𑣀)irIu𑣁)irIu𑣂)irIu𑣃)irIu𑣄)irIu𑣅)irIu𑣆)irIu𑣇)irIu𑣈)irIu𑣉)irIu𑣊)irIu𑣋)irIu𑣌)irIu𑣍)irIu𑣎)irIu𑣏)irIu𑣐)irIu𑣑)irIu𑣒)irIu𑣓)irIu𑣔)irIu𑣕)irIu𑣖)irIu𑣗rrrrr_seg_56rrcCr)N)d)irIu𑣘)irIu𑣙)irIu𑣚)irIu𑣛)irIu𑣜)irIu𑣝)irIu𑣞)irIu𑣟)ir4)ir)ir4)ir)i r4)i r)i r4)ir)ir4)ir)ir4)i6r)i7r4)i9r)i;r4)iGr)iPr4)iZr)ir4)ir)ir4)ir)ir4)ir)ir4)iHr)iPr4)ir)ir4)ir)ir4)i r)i r4)i7r)i8r4)iFr)iPr4)imr)ipr4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)i r)i r4)i7r)i:r4)i;r)i<r4)i>r)i?r4)iHr)iPr4)iZr)i`r4)ifr)igr4)iir)ijr4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)i#r)i$r4)io$r)ip$r4)iu$r)i$r4)iD%r)i0r4)i/4r)iDr4)iGFr)ihr4)i9jr)i@jr4)i_jrrrrrr_seg_57jrrcCr)N)d)i`jr4)ijjr)injr4)ipjr)ijr4)ijr)ijr4)ijr)ikr4)iFkr)iPkr4)iZkr)i[kr4)ibkr)ickr4)ixkr)i}kr4)ikr)i@nrIu𖹠)iAnrIu𖹡)iBnrIu𖹢)iCnrIu𖹣)iDnrIu𖹤)iEnrIu𖹥)iFnrIu𖹦)iGnrIu𖹧)iHnrIu𖹨)iInrIu𖹩)iJnrIu𖹪)iKnrIu𖹫)iLnrIu𖹬)iMnrIu𖹭)iNnrIu𖹮)iOnrIu𖹯)iPnrIu𖹰)iQnrIu𖹱)iRnrIu𖹲)iSnrIu𖹳)iTnrIu𖹴)iUnrIu𖹵)iVnrIu𖹶)iWnrIu𖹷)iXnrIu𖹸)iYnrIu𖹹)iZnrIu𖹺)i[nrIu𖹻)i\nrIu𖹼)i]nrIu𖹽)i^nrIu𖹾)i_nrIu𖹿)i`nr4)inr)ior4)iKor)iOor4)ior)ior4)ior)ior4)ior)ior4)ior)ipr4)ir)ir4)i֌r)ir4)i r)ir4)ir)iPr4)iSr)idr4)ihr)ipr4)ir)ir4)ikr)ipr4)i}r)ir4)ir)ir4)ir)ir4)ir)ir)ir4)ir)ir4)i'r)i)r4)i^rIu𝅗𝅥)i_rIu𝅘𝅥)i`rIu 𝅘𝅥𝅮)iarIu 𝅘𝅥𝅯)ibrIu 𝅘𝅥𝅰)icrIu 𝅘𝅥𝅱)idrIu 𝅘𝅥𝅲)ier4rrrrr_seg_58rrcCr)N)d)isr)i{r4)irIu𝆹𝅥)irIu𝆺𝅥)irIu 𝆹𝅥𝅮)irIu 𝆺𝅥𝅮)irIu 𝆹𝅥𝅯)irIu 𝆺𝅥𝅯)ir4)ir)ir4)iFr)ir4)ir)ir4)iWr)i`r4)iyr)irIrJ)irIrL)irIrN)irIrP)irIrR)irIrT)irIrV)irIrX)irIrZ)i rIr\)i rIr^)i rIr`)i rIrb)i rIrd)irIrf)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)irIrL)irIrN)irIrP)irIrR)irIrT)i rIrV)i!rIrX)i"rIrZ)i#rIr\)i$rIr^)i%rIr`)i&rIrb)i'rIrd)i(rIrf)i)rIrh)i*rIrj)i+rIrl)i,rIrn)i-rIrp)i.rIrr)i/rIrt)i0rIrv)i1rIrx)i2rIrz)i3rIr|)i4rIrJ)i5rIrL)i6rIrN)i7rIrP)i8rIrR)i9rIrT)i:rIrV)i;rIrX)i<rIrZ)i=rIr\)i>rIr^)i?rIr`)i@rIrb)iArIrd)iBrIrf)iCrIrh)iDrIrj)iErIrl)iFrIrn)iGrIrp)iHrIrr)iIrIrt)iJrIrv)iKrIrx)iLrIrz)iMrIr|)iNrIrJ)iOrIrL)iPrIrN)iQrIrPrrrrr_seg_59<rrcCr)N)d)iRrIrR)iSrIrT)iTrIrV)iUr)iVrIrZ)iWrIr\)iXrIr^)iYrIr`)iZrIrb)i[rIrd)i\rIrf)i]rIrh)i^rIrj)i_rIrl)i`rIrn)iarIrp)ibrIrr)icrIrt)idrIrv)ierIrx)ifrIrz)igrIr|)ihrIrJ)iirIrL)ijrIrN)ikrIrP)ilrIrR)imrIrT)inrIrV)iorIrX)iprIrZ)iqrIr\)irrIr^)isrIr`)itrIrb)iurIrd)ivrIrf)iwrIrh)ixrIrj)iyrIrl)izrIrn)i{rIrp)i|rIrr)i}rIrt)i~rIrv)irIrx)irIrz)irIr|)irIrJ)irIrL)irIrN)irIrP)irIrR)irIrT)irIrV)irIrX)irIrZ)irIr\)irIr^)irIr`)irIrb)irIrd)irIrf)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)ir)irIrN)irIrP)ir)irIrV)ir)irIr\)irIr^)ir)irIrd)irIrf)irIrh)irIrj)ir)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)irIrL)irIrNrrrrr_seg_60rrcCr)N)d)irIrP)ir)irIrT)ir)irIrX)irIrZ)irIr\)irIr^)irIr`)irIrb)irIrd)ir)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)irIrL)irIrN)irIrP)irIrR)irIrT)irIrV)irIrX)irIrZ)irIr\)irIr^)irIr`)irIrb)irIrd)irIrf)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)irIrL)irIrN)irIrP)irIrR)irIrT)irIrV)irIrX)irIrZ)irIr\)irIr^)irIr`)irIrb)irIrd)irIrf)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)irIrL)ir)irIrP)irIrR)i rIrT)i rIrV)i r)i rIr\)irIr^)irIr`)irIrb)irIrd)irIrf)irIrh)irIrj)ir)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irrrrrr_seg_61rrcCr)N)d)irIrJ)irIrL)i rIrN)i!rIrP)i"rIrR)i#rIrT)i$rIrV)i%rIrX)i&rIrZ)i'rIr\)i(rIr^)i)rIr`)i*rIrb)i+rIrd)i,rIrf)i-rIrh)i.rIrj)i/rIrl)i0rIrn)i1rIrp)i2rIrr)i3rIrt)i4rIrv)i5rIrx)i6rIrz)i7rIr|)i8rIrJ)i9rIrL)i:r)i;rIrP)i<rIrR)i=rIrT)i>rIrV)i?r)i@rIrZ)iArIr\)iBrIr^)iCrIr`)iDrIrb)iEr)iFrIrf)iGr)iJrIrn)iKrIrp)iLrIrr)iMrIrt)iNrIrv)iOrIrx)iPrIrz)iQr)iRrIrJ)iSrIrL)iTrIrN)iUrIrP)iVrIrR)iWrIrT)iXrIrV)iYrIrX)iZrIrZ)i[rIr\)i\rIr^)i]rIr`)i^rIrb)i_rIrd)i`rIrf)iarIrh)ibrIrj)icrIrl)idrIrn)ierIrp)ifrIrr)igrIrt)ihrIrv)iirIrx)ijrIrz)ikrIr|)ilrIrJ)imrIrL)inrIrN)iorIrP)iprIrR)iqrIrT)irrIrV)isrIrX)itrIrZ)iurIr\)ivrIr^)iwrIr`)ixrIrb)iyrIrd)izrIrf)i{rIrh)i|rIrj)i}rIrl)i~rIrn)irIrp)irIrr)irIrt)irIrv)irIrxrrrrr_seg_62wrrcCr)N)d)irIrz)irIr|)irIrJ)irIrL)irIrN)irIrP)irIrR)irIrT)irIrV)irIrX)irIrZ)irIr\)irIr^)irIr`)irIrb)irIrd)irIrf)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)irIrL)irIrN)irIrP)irIrR)irIrT)irIrV)irIrX)irIrZ)irIr\)irIr^)irIr`)irIrb)irIrd)irIrf)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)irIrL)irIrN)irIrP)irIrR)irIrT)irIrV)irIrX)irIrZ)irIr\)irIr^)irIr`)irIrb)irIrd)irIrf)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)irIrL)irIrN)irIrP)irIrR)irIrT)irIrV)irIrX)irIrZ)irIr\)irIr^)irIr`)irIrb)irIrd)irIrf)irIrh)irIrj)irIrl)irIrn)irIrprrrrr_seg_63rrcCr)N)d)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)irIrL)irIrN)irIrP)irIrR)irIrT)irIrV)irIrX)irIrZ)irIr\)irIr^)irIr`)irIrb)irIrd)irIrf)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)i rIrL)i rIrN)i rIrP)i rIrR)i rIrT)irIrV)irIrX)irIrZ)irIr\)irIr^)irIr`)irIrb)irIrd)irIrf)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)i rIrz)i!rIr|)i"rIrJ)i#rIrL)i$rIrN)i%rIrP)i&rIrR)i'rIrT)i(rIrV)i)rIrX)i*rIrZ)i+rIr\)i,rIr^)i-rIr`)i.rIrb)i/rIrd)i0rIrf)i1rIrh)i2rIrj)i3rIrl)i4rIrn)i5rIrp)i6rIrr)i7rIrt)i8rIrv)i9rIrx)i:rIrz)i;rIr|)i<rIrJ)i=rIrL)i>rIrN)i?rIrP)i@rIrR)iArIrT)iBrIrV)iCrIrX)iDrIrZ)iErIr\)iFrIr^)iGrIr`)iHrIrb)iIrIrd)iJrIrf)iKrIrhrrrrr_seg_64Irr cCr)N)d)iLrIrj)iMrIrl)iNrIrn)iOrIrp)iPrIrr)iQrIrt)iRrIrv)iSrIrx)iTrIrz)iUrIr|)iVrIrJ)iWrIrL)iXrIrN)iYrIrP)iZrIrR)i[rIrT)i\rIrV)i]rIrX)i^rIrZ)i_rIr\)i`rIr^)iarIr`)ibrIrb)icrIrd)idrIrf)ierIrh)ifrIrj)igrIrl)ihrIrn)iirIrp)ijrIrr)ikrIrt)ilrIrv)imrIrx)inrIrz)iorIr|)iprIrJ)iqrIrL)irrIrN)isrIrP)itrIrR)iurIrT)ivrIrV)iwrIrX)ixrIrZ)iyrIr\)izrIr^)i{rIr`)i|rIrb)i}rIrd)i~rIrf)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIrJ)irIrL)irIrN)irIrP)irIrR)irIrT)irIrV)irIrX)irIrZ)irIr\)irIr^)irIr`)irIrb)irIrd)irIrf)irIrh)irIrj)irIrl)irIrn)irIrp)irIrr)irIrt)irIrv)irIrx)irIrz)irIr|)irIuı)irIuȷ)ir)irIru)irIrv)irIrw)irIrx)irIry)irIrz)irIr{)irIr|)irIrirrrrr_seg_65rr!cCr)N)d)irIr})irIr~)irIr)irIr)irIr)irIr)irIr)irIr)irIr|)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irI∇)irIru)irIrv)irIrw)irIrx)irIry)irIrz)irIr{)irIr|)irIri)irIr})irIr~)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irI∂)irIry)irIr|)irIr})irIr)irIr)irIr)irIru)irIrv)irIrw)irIrx)irIry)irIrz)irIr{)irIr|)irIri)irIr})irIr~)irIr)irIr)irIr)irIr)irIr)irIr)irIr|)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr")irIru)irIrv)irIrw)irIrx)irIry)irIrz)irIr{)irIr|)irIri)irIr})irIr~)irIr)irIr)i rIr)i rIr)i rIr)i rIr)i rIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr#)irIryrrrrr_seg_66rr$cCr)N)d)irIr|)irIr})irIr)irIr)irIr)irIru)irIrv)irIrw)irIrx)i rIry)i!rIrz)i"rIr{)i#rIr|)i$rIri)i%rIr})i&rIr~)i'rIr)i(rIr)i)rIr)i*rIr)i+rIr)i,rIr)i-rIr|)i.rIr)i/rIr)i0rIr)i1rIr)i2rIr)i3rIr)i4rIr)i5rIr")i6rIru)i7rIrv)i8rIrw)i9rIrx)i:rIry)i;rIrz)i<rIr{)i=rIr|)i>rIri)i?rIr})i@rIr~)iArIr)iBrIr)iCrIr)iDrIr)iErIr)iFrIr)iGrIr)iIrIr)iJrIr)iKrIr)iLrIr)iMrIr)iNrIr)iOrIr#)iPrIry)iQrIr|)iRrIr})iSrIr)iTrIr)iUrIr)iVrIru)iWrIrv)iXrIrw)iYrIrx)iZrIry)i[rIrz)i\rIr{)i]rIr|)i^rIri)i_rIr})i`rIr~)iarIr)ibrIr)icrIr)idrIr)ierIr)ifrIr)igrIr|)ihrIr)iirIr)ijrIr)ikrIr)ilrIr)imrIr)inrIr)iorIr")iprIru)iqrIrv)irrIrw)isrIrx)itrIry)iurIrz)ivrIr{)iwrIr|)ixrIri)iyrIr})izrIr~)i{rIrrrrrr_seg_67rr%cCr)N)d)i|rIr)i}rIr)i~rIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr#)irIry)irIr|)irIr})irIr)irIr)irIr)irIru)irIrv)irIrw)irIrx)irIry)irIrz)irIr{)irIr|)irIri)irIr})irIr~)irIr)irIr)irIr)irIr)irIr)irIr)irIr|)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr")irIru)irIrv)irIrw)irIrx)irIry)irIrz)irIr{)irIr|)irIri)irIr})irIr~)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr#)irIry)irIr|)irIr})irIr)irIr)irIr)irIr)ir)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIrrrrrr_seg_68rr&cCr)N)d)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)i"r)i#r4)i%r)i&r4)i+r)ir4)i-r)i0r4)i>r)i@r4)iJr)iNr4)iPr)ir4)ir)ir4)ir)ir4)ir)ir4)ir)irIu𞤢)irIu𞤣)irIu𞤤)irIu𞤥)irIu𞤦)irIu𞤧)irIu𞤨)irIu𞤩)irIu𞤪)i rIu𞤫)i rIu𞤬)i rIu𞤭)i rIu𞤮)i rIu𞤯)irIu𞤰)irIu𞤱)irIu𞤲)irIu𞤳)irIu𞤴)irIu𞤵)irIu𞤶)irIu𞤷)irIu𞤸)irIu𞤹)irIu𞤺)irIu𞤻)irIu𞤼)irIu𞤽)irIu𞤾)irIu𞤿)irIu𞥀)irIu𞥁)i rIu𞥂)i!rIu𞥃)i"r4)iLr)iPr4)iZr)i^r4)i`rrrrrr_seg_69Vrr'cCr)N)d)iqr4)ir)ir4)i>r)irIr)irIr)irIr)irIr)ir)irIr)irIr)irIr)irIr)i rIr)i rIr)i rIr)i rIr)i rIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIٮ)irIrJ)irIڡ)irIٯ)i r)i!rIr)i"rIr)i#r)i$rIr)i%r)i'rIr)i(r)i)rIr)i*rIr)i+rIr)i,rIr)i-rIr)i.rIr)i/rIr)i0rIr)i1rIr)i2rIr)i3r)i4rIr)i5rIr)i6rIr)i7rIr)i8r)i9rIr)i:r)i;rIr)i<r)iBrIr)iCr)iGrIr)iHr)iIrIr)iJr)iKrIr)iLr)iMrIr)iNrIr)iOrIr)iPr)iQrIr)iRrIr)iSr)iTrIr)iUr)iWrIr)iXr)iYrIr)iZr)i[rIr)i\r)i]rIrJ)i^r)i_rIr*)i`r)iarIr)ibrIr)icr)idrIr)ier)igrIr)ihrIr)iirIr)ijrIrrrrrr_seg_70rr+cCr)N)d)ikr)ilrIr)imrIr)inrIr)iorIr)iprIr)iqrIr)irrIr)isr)itrIr)iurIr)ivrIr)iwrIr)ixr)iyrIr)izrIr)i{rIr)i|rIr()i}r)i~rIr))ir)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)ir)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)ir)irIr)irIr)irIr)ir)irIr)irIr)irIr)irIr)irIr)ir)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)ir)ir4)ir)ir4)i,r)i0r4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)irz0,)irz1,)irz2,)irz3,)irz4,)irz5,)irz6,)irz7,rrrrr_seg_71(rr,cCr)N)d)i rz8,)i rz9,)i r4)irr)irr)irr)irr)irr)irr)irr)irr)irr)irr)irr)irr)irr)irr)irr)irr)i rr)i!rr)i"rr)i#rr)i$rr)i%rr)i&rr )i'rr )i(rr )i)rr )i*rIu〔s〕)i+rIrN)i,rIrl)i-rIr)i.rIZwz)i/r4)i0rIrJ)i1rIrL)i2rIrN)i3rIrP)i4rIrR)i5rIrT)i6rIrV)i7rIrX)i8rIrZ)i9rIr\)i:rIr^)i;rIr`)i<rIrb)i=rIrd)i>rIrf)i?rIrh)i@rIrj)iArIrl)iBrIrn)iCrIrp)iDrIrr)iErIrt)iFrIrv)iGrIrx)iHrIrz)iIrIr|)iJrIZhv)iKrIr)iLrIsd)iMrIr.)iNrIZppv)iOrIZwc)iPr4)ijrIZmc)ikrIZmd)ilrImr)imr4)irIZdj)ir4)ir)ir4)irIuほか)irIuココ)irIr)ir)irIr)irIu字)irIu双)irIuデ)irIr)irI多)irIu解)irIrv)irIu交)irIu映)irIu無)irIr)irIu前)irIu後)irI再)irIu新)i rIu初)i!rIu終)i"rIr')i#rIu販rrrrr_seg_72rr1cCr)N)d)i$rIu声)i%rIu吹)i&rIu演)i'rIu投)i(rIu捕)i)rIr)i*rIrq)i+rIu遊)i,rIr})i-rIrt)i.rIr~)i/rIu指)i0rIr0)i1rIu打)i2rIu禁)i3rIu空)i4rIu合)i5rIu満)i6rIrz)i7rIr")i8rIu申)i9rI割)i:rIu営)i;rIu配)i<r)i@rIu 〔本〕)iArIu 〔三〕)iBrIu 〔二〕)iCrIu 〔安〕)iDrIu 〔点〕)iErIu 〔打〕)iFrIu 〔盗〕)iGrIu 〔勝〕)iHrIu 〔敗〕)iIr)iPrIu得)iQrIu可)iRr)i`r4)ifr)ir4)ir)ir4)ir)ir4)ir)ir4)itr)ir4)ir)ir4)ir)ir4)i r)ir4)iHr)iPr4)iZr)i`r4)ir)ir4)ir)ir4)ir)ir4)iyr)izr4)ir)ir4)iTr)i`r4)inr)ipr4)iur)ixr4)i{r)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)ir4)ir)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIr)irIrrrrrr_seg_73rr3cCr)N)d)ir)ir4)iަr)ir4)i5r)i@r4)ir)i r4)ir)ir4)ir)irIu丽)irIu丸)irIu乁)irIu𠄢)irIu你)irIr)irIu侻)irIu倂)irIu偺)i rIu備)i rIr)i rIu像)i rIu㒞)i rIu𠘺)irIr)irIu兔)irIu兤)irIu具)irIu𠔜)irIu㒹)irIu內)irIr0)irIu𠕋)irIu冗)irIu冤)irIu仌)irIu冬)irIr-)irIu𩇟)irIr)irIu刃)irIu㓟)i rIu刻)i!rIu剆)i"rIr2)i#rIu剷)i$rIu㔕)i%rIr.)i&rIr)i'rIr)i(rIr/)i)rIu包)i*rIu匆)i+rIr)i,rIu卉)i-rIr)i.rIu博)i/rIu即)i0rIu卽)i1rIu卿)i4rIu𠨬)i5rIu灰)i6rIu及)i7rIu叟)i8rIu𠭣)i9rIu叫)i:rIu叱)i;rIu吆)i<rIu咞)i=rIu吸)i>rIu呈)i?rIu周)i@rIu咢)iArIu哶)iBrIu唐)iCrIu啓)iDrIu啣)iErIu善)iGrIr0)iHrIu喫)iIrIu喳)iJrIu嗂)iKrIu圖)iLrIr)iMrIu圗)iNrIu噑)iOrIu噴)iPrIr)iQrIu壮)iRrIu城)iSrIu埴)iTrIu堍)iUrIu型)iVrIu堲)iWrIu報)iXrIu墬)iYrIu𡓤)iZrIu売)i[rIu壷rrrrr_seg_74crr4cCr)N)d)i\rIu夆)i]rIr/)i^rIu夢)i_rIu奢)i`rIu𡚨)iarIu𡛪)ibrIu姬)icrIu娛)idrIu娧)ierIu姘)ifrIu婦)igrIu㛮)ihr)iirIu嬈)ijrIu嬾)ilrIu𡧈)imrIu寃)inrIu寘)iorIr)iprIu寳)iqrIu𡬘)irrIu寿)isrIu将)itr)iurIr)ivrIu㞁)iwrIu屠)ixrIr)iyrIu峀)izrIu岍)i{rIu𡷤)i|rIu嵃)i}rIu𡷦)i~rIu嵮)irIu嵫)irIu嵼)irIu巡)irIu巢)irIu㠯)irIu巽)irIu帨)irIu帽)irIu幩)irIu㡢)irIu𢆃)irIu㡼)irIu庰)irIu庳)irIu庶)irIr)irIu𪎒)irIr)irIu𢌱)irI舁)irIu弢)irIu㣇)irIu𣊸)irIu𦇚)irIu形)irIu彫)irIu㣣)irIu徚)irIu忍)irIu志)irIu忹)irIu悁)irIu㤺)irIu㤜)irIr)irIu𢛔)irIu惇)irIu慈)irI慌)irIr2)irIr6)irIu慺)irIr)irIu憲)irIu憤)irIu憯)irIu懞)irIr)irIr)irIu成)irIu戛)irIu扝)irIu抱)irIu拔)irIu捐)irIu𢬌)irIu挽)irIu拼)irIu捨)irIu掃)irIu揤)irIu𢯱)irIu搢)irIu揅)irIu掩)irIu㨮rrrrr_seg_75rr7cCr)N)d)irIu摩)irIu摾)irIu撝)irIu摷)irIu㩬)irIr)irIu敬)irIu𣀊)irIu旣)irIu書)irIu晉)irIu㬙)irIr)irIu㬈)irIu㫤)irIu冒)irIu冕)irIu最)irIu暜)irIu肭)irIu䏙)irIr)irIr3)irIu朡)irIu杞)irIu杓)irIu𣏃)irIu㭉)irIu柺)irIu枅)irIu桒)irIr)irIu𣑭)irIu梎)irIu栟)irIu椔)irIrA)irIu楂)irIu榣)irIu槪)irIu檨)irIu𣚣)irIu櫛)irIu㰘)irIu次)irIu𣢧)irIu歔)irIu㱎)irIu歲)irIu殟)irIr)irIu殻)irIu𣪍)irIu𡴋)irIu𣫺)irIu汎)irIu𣲼)irIu沿)irIu泍)irIu汧)irIu洖)irIu派)irIr)irIr)irIu浩)irIu浸)irIu涅)irIu𣴞)irIu洴)irIu港)i rIu湮)i rIu㴳)i rIr4)i rIu滇)i rIu𣻑)irIu淹)irIu潮)irIu𣽞)irIu𣾎)irIu濆)irIu瀹)irIr5)irIu瀛)irIu㶖)irIu灊)irIu災)irIu灷)irIu炭)irIu𠔥)irIu煅)irIu𤉣)irIu熜)ir)i rIu爨)i!rIr6)i"rIu牐)i#rIu𤘈)i$rIu犀)i%rIu犕)i&rIu𤜵rrrrr_seg_765rr8cCr)N)d)i'rIu𤠔)i(rIu獺)i)rIu王)i*rIu㺬)i+rIu玥)i,rIu㺸)i.rIu瑇)i/rIu瑜)i0rIr7)i1rIu璅)i2rIu瓊)i3rIu㼛)i4rIu甤)i5rIu𤰶)i6rIu甾)i7rIu𤲒)i8rIr)i9rIu𢆟)i:rIu瘐)i;rIu𤾡)i<rIu𤾸)i=rIu𥁄)i>rIu㿼)i?rIu䀈)i@rIr8)iArIu𥃳)iBrIu𥃲)iCrIu𥄙)iDrIu𥄳)iErIu眞)iFrIu真)iHrIr9)iIrIrB)iJrIu瞋)iKrIu䁆)iLrIu䂖)iMrIu𥐝)iNrIu硎)iOrIr)iPrIr:)iQrIu䃣)iRrIu𥘦)iSrIr!)iTrIu𥚚)iUrIu𥛅)iVrIr )iWrIu秫)iXrIu䄯)iYrIr")iZrIu穊)i[rIu穏)i\rIu𥥼)i]rIu𥪧)i_r)i`rIu䈂)iarIu𥮫)ibrIu篆)icrIu築)idrIu䈧)ierIu𥲀)ifrIu糒)igrIu䊠)ihrIu糨)iirIu糣)ijrIu紀)ikrIu𥾆)ilrIu絣)imrIu䌁)inrIu緇)iorIu縂)iprIu繅)iqrIu䌴)irrIu𦈨)isrIu𦉇)itrIu䍙)iurIu𦋙)ivrIu罺)iwrIu𦌾)ixrIu羕)iyrIu翺)izrIr$)i{rIu𦓚)i|rIu𦔣)i}rIu聠)i~rIu𦖨)irIu聰)irIu𣍟)irIu䏕)irIu育)irIu脃)irIu䐋)irIu脾)irIu媵)irIu𦞧)irIu𦞵)irIu𣎓)irIu𣎜)irIr5)irIu舄)irIu辞rrrrr_seg_77rr9cCr)N)d)irIu䑫)irIu芑)irIu芋)irIu芝)irIu劳)irIu花)irIu芳)irIu芽)irIu苦)irIu𦬼)irIr)irIu茝)irIu荣)irIu莭)irIu茣)irIu莽)irIu菧)irIr%)irIu荓)irIu菊)irIu菌)irIu菜)irIu𦰶)irIu𦵫)irIu𦳕)irIu䔫)irIu蓱)irIu蓳)irIu蔖)irIu𧏊)irIu蕤)irIu𦼬)irIu䕝)irIu䕡)irIu𦾱)irIu𧃒)irIu䕫)irIu虐)irIr)irIu虧)irIu虩)irIu蚩)irIu蚈)irIu蜎)irIu蛢)irIr;)irIu蜨)irIu蝫)irIu螆)ir)irIu蟡)irIu蠁)irIu䗹)irIu衠)irIr-)irIu𧙧)irIu裗)irIu裞)irIu䘵)irIu裺)irIu㒻)irIu𧢮)irIu𧥦)irIu䚾)irIu䛇)irIu誠)irIr<)irIr=)irIr/)irIu𧲨)irIu貫)irIu賁)irIu贛)irIu起)irIu𧼯)irIu𠠄)irIu跋)irIu趼)irIu跰)irIu𠣞)irIu軔)irIr>)irIu𨗒)irIu𨗭)irIu邔)irIu郱)irIu鄑)irIu𨜮)irIu鄛)irIu鈸)irIu鋗)irIu鋘)irIu鉼)irIu鏹)irIu鐕)irIu𨯺)irIu開)irIu䦕)irIu閷)irIu𨵷rrrrr_seg_78 rr:cCr)N)0)irIu䧦)irIu雃)irIu嶲)irIu霣)irIu𩅅)irIu𩈚)irIu䩮)irIu䩶)irIu韠)irIu𩐊)irIu䪲)irIu𩒖)irIr?)irIu頩)irIu𩖶)irIu飢)irIu䬳)irIu餩)irIu馧)irIu駂)irIu駾)irIu䯎)i rIu𩬰)i rIr@)i rIu鱀)i rIu鳽)i rIu䳎)irIu䳭)irIu鵧)irIu𪃎)irIu䳸)irIu𪄅)irIu𪈎)irIu𪊑)irIr6)irIu䵖)irIr7)irIu黾)irIu鼅)irIu鼏)irIu鼖)irIr8)irIu𪘀)ir)ir4)iKr)ir)irrrrrr_seg_79p rr;N)Wtypingrrr __version__rrrQrYrdrjrrrrrrrrrrrrrrrrrr rrrr)r<rprwrrrrrrrrrrr r1rIrLrrrrrr rrrrrrrrrrrrrr r!r$r%r&r'r+r,r1r3r4r7r8r9r:r;tuple uts46datarrrrsiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii5      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPKH]yy6python3.10/site-packages/pip/_vendor/idna/uts46data.pynu[# This file is automatically generated by tools/idna-data from typing import List, Tuple, Union """IDNA Mapping Table from UTS46.""" __version__ = '13.0.0' def _seg_0(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x0, '3'), (0x1, '3'), (0x2, '3'), (0x3, '3'), (0x4, '3'), (0x5, '3'), (0x6, '3'), (0x7, '3'), (0x8, '3'), (0x9, '3'), (0xA, '3'), (0xB, '3'), (0xC, '3'), (0xD, '3'), (0xE, '3'), (0xF, '3'), (0x10, '3'), (0x11, '3'), (0x12, '3'), (0x13, '3'), (0x14, '3'), (0x15, '3'), (0x16, '3'), (0x17, '3'), (0x18, '3'), (0x19, '3'), (0x1A, '3'), (0x1B, '3'), (0x1C, '3'), (0x1D, '3'), (0x1E, '3'), (0x1F, '3'), (0x20, '3'), (0x21, '3'), (0x22, '3'), (0x23, '3'), (0x24, '3'), (0x25, '3'), (0x26, '3'), (0x27, '3'), (0x28, '3'), (0x29, '3'), (0x2A, '3'), (0x2B, '3'), (0x2C, '3'), (0x2D, 'V'), (0x2E, 'V'), (0x2F, '3'), (0x30, 'V'), (0x31, 'V'), (0x32, 'V'), (0x33, 'V'), (0x34, 'V'), (0x35, 'V'), (0x36, 'V'), (0x37, 'V'), (0x38, 'V'), (0x39, 'V'), (0x3A, '3'), (0x3B, '3'), (0x3C, '3'), (0x3D, '3'), (0x3E, '3'), (0x3F, '3'), (0x40, '3'), (0x41, 'M', 'a'), (0x42, 'M', 'b'), (0x43, 'M', 'c'), (0x44, 'M', 'd'), (0x45, 'M', 'e'), (0x46, 'M', 'f'), (0x47, 'M', 'g'), (0x48, 'M', 'h'), (0x49, 'M', 'i'), (0x4A, 'M', 'j'), (0x4B, 'M', 'k'), (0x4C, 'M', 'l'), (0x4D, 'M', 'm'), (0x4E, 'M', 'n'), (0x4F, 'M', 'o'), (0x50, 'M', 'p'), (0x51, 'M', 'q'), (0x52, 'M', 'r'), (0x53, 'M', 's'), (0x54, 'M', 't'), (0x55, 'M', 'u'), (0x56, 'M', 'v'), (0x57, 'M', 'w'), (0x58, 'M', 'x'), (0x59, 'M', 'y'), (0x5A, 'M', 'z'), (0x5B, '3'), (0x5C, '3'), (0x5D, '3'), (0x5E, '3'), (0x5F, '3'), (0x60, '3'), (0x61, 'V'), (0x62, 'V'), (0x63, 'V'), ] def _seg_1(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x64, 'V'), (0x65, 'V'), (0x66, 'V'), (0x67, 'V'), (0x68, 'V'), (0x69, 'V'), (0x6A, 'V'), (0x6B, 'V'), (0x6C, 'V'), (0x6D, 'V'), (0x6E, 'V'), (0x6F, 'V'), (0x70, 'V'), (0x71, 'V'), (0x72, 'V'), (0x73, 'V'), (0x74, 'V'), (0x75, 'V'), (0x76, 'V'), (0x77, 'V'), (0x78, 'V'), (0x79, 'V'), (0x7A, 'V'), (0x7B, '3'), (0x7C, '3'), (0x7D, '3'), (0x7E, '3'), (0x7F, '3'), (0x80, 'X'), (0x81, 'X'), (0x82, 'X'), (0x83, 'X'), (0x84, 'X'), (0x85, 'X'), (0x86, 'X'), (0x87, 'X'), (0x88, 'X'), (0x89, 'X'), (0x8A, 'X'), (0x8B, 'X'), (0x8C, 'X'), (0x8D, 'X'), (0x8E, 'X'), (0x8F, 'X'), (0x90, 'X'), (0x91, 'X'), (0x92, 'X'), (0x93, 'X'), (0x94, 'X'), (0x95, 'X'), (0x96, 'X'), (0x97, 'X'), (0x98, 'X'), (0x99, 'X'), (0x9A, 'X'), (0x9B, 'X'), (0x9C, 'X'), (0x9D, 'X'), (0x9E, 'X'), (0x9F, 'X'), (0xA0, '3', ' '), (0xA1, 'V'), (0xA2, 'V'), (0xA3, 'V'), (0xA4, 'V'), (0xA5, 'V'), (0xA6, 'V'), (0xA7, 'V'), (0xA8, '3', ' ̈'), (0xA9, 'V'), (0xAA, 'M', 'a'), (0xAB, 'V'), (0xAC, 'V'), (0xAD, 'I'), (0xAE, 'V'), (0xAF, '3', ' ̄'), (0xB0, 'V'), (0xB1, 'V'), (0xB2, 'M', '2'), (0xB3, 'M', '3'), (0xB4, '3', ' ́'), (0xB5, 'M', 'μ'), (0xB6, 'V'), (0xB7, 'V'), (0xB8, '3', ' ̧'), (0xB9, 'M', '1'), (0xBA, 'M', 'o'), (0xBB, 'V'), (0xBC, 'M', '1⁄4'), (0xBD, 'M', '1⁄2'), (0xBE, 'M', '3⁄4'), (0xBF, 'V'), (0xC0, 'M', 'à'), (0xC1, 'M', 'á'), (0xC2, 'M', 'â'), (0xC3, 'M', 'ã'), (0xC4, 'M', 'ä'), (0xC5, 'M', 'å'), (0xC6, 'M', 'æ'), (0xC7, 'M', 'ç'), ] def _seg_2(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xC8, 'M', 'è'), (0xC9, 'M', 'é'), (0xCA, 'M', 'ê'), (0xCB, 'M', 'ë'), (0xCC, 'M', 'ì'), (0xCD, 'M', 'í'), (0xCE, 'M', 'î'), (0xCF, 'M', 'ï'), (0xD0, 'M', 'ð'), (0xD1, 'M', 'ñ'), (0xD2, 'M', 'ò'), (0xD3, 'M', 'ó'), (0xD4, 'M', 'ô'), (0xD5, 'M', 'õ'), (0xD6, 'M', 'ö'), (0xD7, 'V'), (0xD8, 'M', 'ø'), (0xD9, 'M', 'ù'), (0xDA, 'M', 'ú'), (0xDB, 'M', 'û'), (0xDC, 'M', 'ü'), (0xDD, 'M', 'ý'), (0xDE, 'M', 'þ'), (0xDF, 'D', 'ss'), (0xE0, 'V'), (0xE1, 'V'), (0xE2, 'V'), (0xE3, 'V'), (0xE4, 'V'), (0xE5, 'V'), (0xE6, 'V'), (0xE7, 'V'), (0xE8, 'V'), (0xE9, 'V'), (0xEA, 'V'), (0xEB, 'V'), (0xEC, 'V'), (0xED, 'V'), (0xEE, 'V'), (0xEF, 'V'), (0xF0, 'V'), (0xF1, 'V'), (0xF2, 'V'), (0xF3, 'V'), (0xF4, 'V'), (0xF5, 'V'), (0xF6, 'V'), (0xF7, 'V'), (0xF8, 'V'), (0xF9, 'V'), (0xFA, 'V'), (0xFB, 'V'), (0xFC, 'V'), (0xFD, 'V'), (0xFE, 'V'), (0xFF, 'V'), (0x100, 'M', 'ā'), (0x101, 'V'), (0x102, 'M', 'ă'), (0x103, 'V'), (0x104, 'M', 'ą'), (0x105, 'V'), (0x106, 'M', 'ć'), (0x107, 'V'), (0x108, 'M', 'ĉ'), (0x109, 'V'), (0x10A, 'M', 'ċ'), (0x10B, 'V'), (0x10C, 'M', 'č'), (0x10D, 'V'), (0x10E, 'M', 'ď'), (0x10F, 'V'), (0x110, 'M', 'đ'), (0x111, 'V'), (0x112, 'M', 'ē'), (0x113, 'V'), (0x114, 'M', 'ĕ'), (0x115, 'V'), (0x116, 'M', 'ė'), (0x117, 'V'), (0x118, 'M', 'ę'), (0x119, 'V'), (0x11A, 'M', 'ě'), (0x11B, 'V'), (0x11C, 'M', 'ĝ'), (0x11D, 'V'), (0x11E, 'M', 'ğ'), (0x11F, 'V'), (0x120, 'M', 'ġ'), (0x121, 'V'), (0x122, 'M', 'ģ'), (0x123, 'V'), (0x124, 'M', 'ĥ'), (0x125, 'V'), (0x126, 'M', 'ħ'), (0x127, 'V'), (0x128, 'M', 'ĩ'), (0x129, 'V'), (0x12A, 'M', 'ī'), (0x12B, 'V'), ] def _seg_3(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x12C, 'M', 'ĭ'), (0x12D, 'V'), (0x12E, 'M', 'į'), (0x12F, 'V'), (0x130, 'M', 'i̇'), (0x131, 'V'), (0x132, 'M', 'ij'), (0x134, 'M', 'ĵ'), (0x135, 'V'), (0x136, 'M', 'ķ'), (0x137, 'V'), (0x139, 'M', 'ĺ'), (0x13A, 'V'), (0x13B, 'M', 'ļ'), (0x13C, 'V'), (0x13D, 'M', 'ľ'), (0x13E, 'V'), (0x13F, 'M', 'l·'), (0x141, 'M', 'ł'), (0x142, 'V'), (0x143, 'M', 'ń'), (0x144, 'V'), (0x145, 'M', 'ņ'), (0x146, 'V'), (0x147, 'M', 'ň'), (0x148, 'V'), (0x149, 'M', 'ʼn'), (0x14A, 'M', 'ŋ'), (0x14B, 'V'), (0x14C, 'M', 'ō'), (0x14D, 'V'), (0x14E, 'M', 'ŏ'), (0x14F, 'V'), (0x150, 'M', 'ő'), (0x151, 'V'), (0x152, 'M', 'œ'), (0x153, 'V'), (0x154, 'M', 'ŕ'), (0x155, 'V'), (0x156, 'M', 'ŗ'), (0x157, 'V'), (0x158, 'M', 'ř'), (0x159, 'V'), (0x15A, 'M', 'ś'), (0x15B, 'V'), (0x15C, 'M', 'ŝ'), (0x15D, 'V'), (0x15E, 'M', 'ş'), (0x15F, 'V'), (0x160, 'M', 'š'), (0x161, 'V'), (0x162, 'M', 'ţ'), (0x163, 'V'), (0x164, 'M', 'ť'), (0x165, 'V'), (0x166, 'M', 'ŧ'), (0x167, 'V'), (0x168, 'M', 'ũ'), (0x169, 'V'), (0x16A, 'M', 'ū'), (0x16B, 'V'), (0x16C, 'M', 'ŭ'), (0x16D, 'V'), (0x16E, 'M', 'ů'), (0x16F, 'V'), (0x170, 'M', 'ű'), (0x171, 'V'), (0x172, 'M', 'ų'), (0x173, 'V'), (0x174, 'M', 'ŵ'), (0x175, 'V'), (0x176, 'M', 'ŷ'), (0x177, 'V'), (0x178, 'M', 'ÿ'), (0x179, 'M', 'ź'), (0x17A, 'V'), (0x17B, 'M', 'ż'), (0x17C, 'V'), (0x17D, 'M', 'ž'), (0x17E, 'V'), (0x17F, 'M', 's'), (0x180, 'V'), (0x181, 'M', 'ɓ'), (0x182, 'M', 'ƃ'), (0x183, 'V'), (0x184, 'M', 'ƅ'), (0x185, 'V'), (0x186, 'M', 'ɔ'), (0x187, 'M', 'ƈ'), (0x188, 'V'), (0x189, 'M', 'ɖ'), (0x18A, 'M', 'ɗ'), (0x18B, 'M', 'ƌ'), (0x18C, 'V'), (0x18E, 'M', 'ǝ'), (0x18F, 'M', 'ə'), (0x190, 'M', 'ɛ'), (0x191, 'M', 'ƒ'), (0x192, 'V'), (0x193, 'M', 'ɠ'), ] def _seg_4(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x194, 'M', 'ɣ'), (0x195, 'V'), (0x196, 'M', 'ɩ'), (0x197, 'M', 'ɨ'), (0x198, 'M', 'ƙ'), (0x199, 'V'), (0x19C, 'M', 'ɯ'), (0x19D, 'M', 'ɲ'), (0x19E, 'V'), (0x19F, 'M', 'ɵ'), (0x1A0, 'M', 'ơ'), (0x1A1, 'V'), (0x1A2, 'M', 'ƣ'), (0x1A3, 'V'), (0x1A4, 'M', 'ƥ'), (0x1A5, 'V'), (0x1A6, 'M', 'ʀ'), (0x1A7, 'M', 'ƨ'), (0x1A8, 'V'), (0x1A9, 'M', 'ʃ'), (0x1AA, 'V'), (0x1AC, 'M', 'ƭ'), (0x1AD, 'V'), (0x1AE, 'M', 'ʈ'), (0x1AF, 'M', 'ư'), (0x1B0, 'V'), (0x1B1, 'M', 'ʊ'), (0x1B2, 'M', 'ʋ'), (0x1B3, 'M', 'ƴ'), (0x1B4, 'V'), (0x1B5, 'M', 'ƶ'), (0x1B6, 'V'), (0x1B7, 'M', 'ʒ'), (0x1B8, 'M', 'ƹ'), (0x1B9, 'V'), (0x1BC, 'M', 'ƽ'), (0x1BD, 'V'), (0x1C4, 'M', 'dž'), (0x1C7, 'M', 'lj'), (0x1CA, 'M', 'nj'), (0x1CD, 'M', 'ǎ'), (0x1CE, 'V'), (0x1CF, 'M', 'ǐ'), (0x1D0, 'V'), (0x1D1, 'M', 'ǒ'), (0x1D2, 'V'), (0x1D3, 'M', 'ǔ'), (0x1D4, 'V'), (0x1D5, 'M', 'ǖ'), (0x1D6, 'V'), (0x1D7, 'M', 'ǘ'), (0x1D8, 'V'), (0x1D9, 'M', 'ǚ'), (0x1DA, 'V'), (0x1DB, 'M', 'ǜ'), (0x1DC, 'V'), (0x1DE, 'M', 'ǟ'), (0x1DF, 'V'), (0x1E0, 'M', 'ǡ'), (0x1E1, 'V'), (0x1E2, 'M', 'ǣ'), (0x1E3, 'V'), (0x1E4, 'M', 'ǥ'), (0x1E5, 'V'), (0x1E6, 'M', 'ǧ'), (0x1E7, 'V'), (0x1E8, 'M', 'ǩ'), (0x1E9, 'V'), (0x1EA, 'M', 'ǫ'), (0x1EB, 'V'), (0x1EC, 'M', 'ǭ'), (0x1ED, 'V'), (0x1EE, 'M', 'ǯ'), (0x1EF, 'V'), (0x1F1, 'M', 'dz'), (0x1F4, 'M', 'ǵ'), (0x1F5, 'V'), (0x1F6, 'M', 'ƕ'), (0x1F7, 'M', 'ƿ'), (0x1F8, 'M', 'ǹ'), (0x1F9, 'V'), (0x1FA, 'M', 'ǻ'), (0x1FB, 'V'), (0x1FC, 'M', 'ǽ'), (0x1FD, 'V'), (0x1FE, 'M', 'ǿ'), (0x1FF, 'V'), (0x200, 'M', 'ȁ'), (0x201, 'V'), (0x202, 'M', 'ȃ'), (0x203, 'V'), (0x204, 'M', 'ȅ'), (0x205, 'V'), (0x206, 'M', 'ȇ'), (0x207, 'V'), (0x208, 'M', 'ȉ'), (0x209, 'V'), (0x20A, 'M', 'ȋ'), (0x20B, 'V'), (0x20C, 'M', 'ȍ'), ] def _seg_5(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x20D, 'V'), (0x20E, 'M', 'ȏ'), (0x20F, 'V'), (0x210, 'M', 'ȑ'), (0x211, 'V'), (0x212, 'M', 'ȓ'), (0x213, 'V'), (0x214, 'M', 'ȕ'), (0x215, 'V'), (0x216, 'M', 'ȗ'), (0x217, 'V'), (0x218, 'M', 'ș'), (0x219, 'V'), (0x21A, 'M', 'ț'), (0x21B, 'V'), (0x21C, 'M', 'ȝ'), (0x21D, 'V'), (0x21E, 'M', 'ȟ'), (0x21F, 'V'), (0x220, 'M', 'ƞ'), (0x221, 'V'), (0x222, 'M', 'ȣ'), (0x223, 'V'), (0x224, 'M', 'ȥ'), (0x225, 'V'), (0x226, 'M', 'ȧ'), (0x227, 'V'), (0x228, 'M', 'ȩ'), (0x229, 'V'), (0x22A, 'M', 'ȫ'), (0x22B, 'V'), (0x22C, 'M', 'ȭ'), (0x22D, 'V'), (0x22E, 'M', 'ȯ'), (0x22F, 'V'), (0x230, 'M', 'ȱ'), (0x231, 'V'), (0x232, 'M', 'ȳ'), (0x233, 'V'), (0x23A, 'M', 'ⱥ'), (0x23B, 'M', 'ȼ'), (0x23C, 'V'), (0x23D, 'M', 'ƚ'), (0x23E, 'M', 'ⱦ'), (0x23F, 'V'), (0x241, 'M', 'ɂ'), (0x242, 'V'), (0x243, 'M', 'ƀ'), (0x244, 'M', 'ʉ'), (0x245, 'M', 'ʌ'), (0x246, 'M', 'ɇ'), (0x247, 'V'), (0x248, 'M', 'ɉ'), (0x249, 'V'), (0x24A, 'M', 'ɋ'), (0x24B, 'V'), (0x24C, 'M', 'ɍ'), (0x24D, 'V'), (0x24E, 'M', 'ɏ'), (0x24F, 'V'), (0x2B0, 'M', 'h'), (0x2B1, 'M', 'ɦ'), (0x2B2, 'M', 'j'), (0x2B3, 'M', 'r'), (0x2B4, 'M', 'ɹ'), (0x2B5, 'M', 'ɻ'), (0x2B6, 'M', 'ʁ'), (0x2B7, 'M', 'w'), (0x2B8, 'M', 'y'), (0x2B9, 'V'), (0x2D8, '3', ' ̆'), (0x2D9, '3', ' ̇'), (0x2DA, '3', ' ̊'), (0x2DB, '3', ' ̨'), (0x2DC, '3', ' ̃'), (0x2DD, '3', ' ̋'), (0x2DE, 'V'), (0x2E0, 'M', 'ɣ'), (0x2E1, 'M', 'l'), (0x2E2, 'M', 's'), (0x2E3, 'M', 'x'), (0x2E4, 'M', 'ʕ'), (0x2E5, 'V'), (0x340, 'M', '̀'), (0x341, 'M', '́'), (0x342, 'V'), (0x343, 'M', '̓'), (0x344, 'M', '̈́'), (0x345, 'M', 'ι'), (0x346, 'V'), (0x34F, 'I'), (0x350, 'V'), (0x370, 'M', 'ͱ'), (0x371, 'V'), (0x372, 'M', 'ͳ'), (0x373, 'V'), (0x374, 'M', 'ʹ'), (0x375, 'V'), (0x376, 'M', 'ͷ'), (0x377, 'V'), ] def _seg_6(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x378, 'X'), (0x37A, '3', ' ι'), (0x37B, 'V'), (0x37E, '3', ';'), (0x37F, 'M', 'ϳ'), (0x380, 'X'), (0x384, '3', ' ́'), (0x385, '3', ' ̈́'), (0x386, 'M', 'ά'), (0x387, 'M', '·'), (0x388, 'M', 'έ'), (0x389, 'M', 'ή'), (0x38A, 'M', 'ί'), (0x38B, 'X'), (0x38C, 'M', 'ό'), (0x38D, 'X'), (0x38E, 'M', 'ύ'), (0x38F, 'M', 'ώ'), (0x390, 'V'), (0x391, 'M', 'α'), (0x392, 'M', 'β'), (0x393, 'M', 'γ'), (0x394, 'M', 'δ'), (0x395, 'M', 'ε'), (0x396, 'M', 'ζ'), (0x397, 'M', 'η'), (0x398, 'M', 'θ'), (0x399, 'M', 'ι'), (0x39A, 'M', 'κ'), (0x39B, 'M', 'λ'), (0x39C, 'M', 'μ'), (0x39D, 'M', 'ν'), (0x39E, 'M', 'ξ'), (0x39F, 'M', 'ο'), (0x3A0, 'M', 'π'), (0x3A1, 'M', 'ρ'), (0x3A2, 'X'), (0x3A3, 'M', 'σ'), (0x3A4, 'M', 'τ'), (0x3A5, 'M', 'υ'), (0x3A6, 'M', 'φ'), (0x3A7, 'M', 'χ'), (0x3A8, 'M', 'ψ'), (0x3A9, 'M', 'ω'), (0x3AA, 'M', 'ϊ'), (0x3AB, 'M', 'ϋ'), (0x3AC, 'V'), (0x3C2, 'D', 'σ'), (0x3C3, 'V'), (0x3CF, 'M', 'ϗ'), (0x3D0, 'M', 'β'), (0x3D1, 'M', 'θ'), (0x3D2, 'M', 'υ'), (0x3D3, 'M', 'ύ'), (0x3D4, 'M', 'ϋ'), (0x3D5, 'M', 'φ'), (0x3D6, 'M', 'π'), (0x3D7, 'V'), (0x3D8, 'M', 'ϙ'), (0x3D9, 'V'), (0x3DA, 'M', 'ϛ'), (0x3DB, 'V'), (0x3DC, 'M', 'ϝ'), (0x3DD, 'V'), (0x3DE, 'M', 'ϟ'), (0x3DF, 'V'), (0x3E0, 'M', 'ϡ'), (0x3E1, 'V'), (0x3E2, 'M', 'ϣ'), (0x3E3, 'V'), (0x3E4, 'M', 'ϥ'), (0x3E5, 'V'), (0x3E6, 'M', 'ϧ'), (0x3E7, 'V'), (0x3E8, 'M', 'ϩ'), (0x3E9, 'V'), (0x3EA, 'M', 'ϫ'), (0x3EB, 'V'), (0x3EC, 'M', 'ϭ'), (0x3ED, 'V'), (0x3EE, 'M', 'ϯ'), (0x3EF, 'V'), (0x3F0, 'M', 'κ'), (0x3F1, 'M', 'ρ'), (0x3F2, 'M', 'σ'), (0x3F3, 'V'), (0x3F4, 'M', 'θ'), (0x3F5, 'M', 'ε'), (0x3F6, 'V'), (0x3F7, 'M', 'ϸ'), (0x3F8, 'V'), (0x3F9, 'M', 'σ'), (0x3FA, 'M', 'ϻ'), (0x3FB, 'V'), (0x3FD, 'M', 'ͻ'), (0x3FE, 'M', 'ͼ'), (0x3FF, 'M', 'ͽ'), (0x400, 'M', 'ѐ'), (0x401, 'M', 'ё'), (0x402, 'M', 'ђ'), ] def _seg_7(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x403, 'M', 'ѓ'), (0x404, 'M', 'є'), (0x405, 'M', 'ѕ'), (0x406, 'M', 'і'), (0x407, 'M', 'ї'), (0x408, 'M', 'ј'), (0x409, 'M', 'љ'), (0x40A, 'M', 'њ'), (0x40B, 'M', 'ћ'), (0x40C, 'M', 'ќ'), (0x40D, 'M', 'ѝ'), (0x40E, 'M', 'ў'), (0x40F, 'M', 'џ'), (0x410, 'M', 'а'), (0x411, 'M', 'б'), (0x412, 'M', 'в'), (0x413, 'M', 'г'), (0x414, 'M', 'д'), (0x415, 'M', 'е'), (0x416, 'M', 'ж'), (0x417, 'M', 'з'), (0x418, 'M', 'и'), (0x419, 'M', 'й'), (0x41A, 'M', 'к'), (0x41B, 'M', 'л'), (0x41C, 'M', 'м'), (0x41D, 'M', 'н'), (0x41E, 'M', 'о'), (0x41F, 'M', 'п'), (0x420, 'M', 'р'), (0x421, 'M', 'с'), (0x422, 'M', 'т'), (0x423, 'M', 'у'), (0x424, 'M', 'ф'), (0x425, 'M', 'х'), (0x426, 'M', 'ц'), (0x427, 'M', 'ч'), (0x428, 'M', 'ш'), (0x429, 'M', 'щ'), (0x42A, 'M', 'ъ'), (0x42B, 'M', 'ы'), (0x42C, 'M', 'ь'), (0x42D, 'M', 'э'), (0x42E, 'M', 'ю'), (0x42F, 'M', 'я'), (0x430, 'V'), (0x460, 'M', 'ѡ'), (0x461, 'V'), (0x462, 'M', 'ѣ'), (0x463, 'V'), (0x464, 'M', 'ѥ'), (0x465, 'V'), (0x466, 'M', 'ѧ'), (0x467, 'V'), (0x468, 'M', 'ѩ'), (0x469, 'V'), (0x46A, 'M', 'ѫ'), (0x46B, 'V'), (0x46C, 'M', 'ѭ'), (0x46D, 'V'), (0x46E, 'M', 'ѯ'), (0x46F, 'V'), (0x470, 'M', 'ѱ'), (0x471, 'V'), (0x472, 'M', 'ѳ'), (0x473, 'V'), (0x474, 'M', 'ѵ'), (0x475, 'V'), (0x476, 'M', 'ѷ'), (0x477, 'V'), (0x478, 'M', 'ѹ'), (0x479, 'V'), (0x47A, 'M', 'ѻ'), (0x47B, 'V'), (0x47C, 'M', 'ѽ'), (0x47D, 'V'), (0x47E, 'M', 'ѿ'), (0x47F, 'V'), (0x480, 'M', 'ҁ'), (0x481, 'V'), (0x48A, 'M', 'ҋ'), (0x48B, 'V'), (0x48C, 'M', 'ҍ'), (0x48D, 'V'), (0x48E, 'M', 'ҏ'), (0x48F, 'V'), (0x490, 'M', 'ґ'), (0x491, 'V'), (0x492, 'M', 'ғ'), (0x493, 'V'), (0x494, 'M', 'ҕ'), (0x495, 'V'), (0x496, 'M', 'җ'), (0x497, 'V'), (0x498, 'M', 'ҙ'), (0x499, 'V'), (0x49A, 'M', 'қ'), (0x49B, 'V'), (0x49C, 'M', 'ҝ'), (0x49D, 'V'), ] def _seg_8(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x49E, 'M', 'ҟ'), (0x49F, 'V'), (0x4A0, 'M', 'ҡ'), (0x4A1, 'V'), (0x4A2, 'M', 'ң'), (0x4A3, 'V'), (0x4A4, 'M', 'ҥ'), (0x4A5, 'V'), (0x4A6, 'M', 'ҧ'), (0x4A7, 'V'), (0x4A8, 'M', 'ҩ'), (0x4A9, 'V'), (0x4AA, 'M', 'ҫ'), (0x4AB, 'V'), (0x4AC, 'M', 'ҭ'), (0x4AD, 'V'), (0x4AE, 'M', 'ү'), (0x4AF, 'V'), (0x4B0, 'M', 'ұ'), (0x4B1, 'V'), (0x4B2, 'M', 'ҳ'), (0x4B3, 'V'), (0x4B4, 'M', 'ҵ'), (0x4B5, 'V'), (0x4B6, 'M', 'ҷ'), (0x4B7, 'V'), (0x4B8, 'M', 'ҹ'), (0x4B9, 'V'), (0x4BA, 'M', 'һ'), (0x4BB, 'V'), (0x4BC, 'M', 'ҽ'), (0x4BD, 'V'), (0x4BE, 'M', 'ҿ'), (0x4BF, 'V'), (0x4C0, 'X'), (0x4C1, 'M', 'ӂ'), (0x4C2, 'V'), (0x4C3, 'M', 'ӄ'), (0x4C4, 'V'), (0x4C5, 'M', 'ӆ'), (0x4C6, 'V'), (0x4C7, 'M', 'ӈ'), (0x4C8, 'V'), (0x4C9, 'M', 'ӊ'), (0x4CA, 'V'), (0x4CB, 'M', 'ӌ'), (0x4CC, 'V'), (0x4CD, 'M', 'ӎ'), (0x4CE, 'V'), (0x4D0, 'M', 'ӑ'), (0x4D1, 'V'), (0x4D2, 'M', 'ӓ'), (0x4D3, 'V'), (0x4D4, 'M', 'ӕ'), (0x4D5, 'V'), (0x4D6, 'M', 'ӗ'), (0x4D7, 'V'), (0x4D8, 'M', 'ә'), (0x4D9, 'V'), (0x4DA, 'M', 'ӛ'), (0x4DB, 'V'), (0x4DC, 'M', 'ӝ'), (0x4DD, 'V'), (0x4DE, 'M', 'ӟ'), (0x4DF, 'V'), (0x4E0, 'M', 'ӡ'), (0x4E1, 'V'), (0x4E2, 'M', 'ӣ'), (0x4E3, 'V'), (0x4E4, 'M', 'ӥ'), (0x4E5, 'V'), (0x4E6, 'M', 'ӧ'), (0x4E7, 'V'), (0x4E8, 'M', 'ө'), (0x4E9, 'V'), (0x4EA, 'M', 'ӫ'), (0x4EB, 'V'), (0x4EC, 'M', 'ӭ'), (0x4ED, 'V'), (0x4EE, 'M', 'ӯ'), (0x4EF, 'V'), (0x4F0, 'M', 'ӱ'), (0x4F1, 'V'), (0x4F2, 'M', 'ӳ'), (0x4F3, 'V'), (0x4F4, 'M', 'ӵ'), (0x4F5, 'V'), (0x4F6, 'M', 'ӷ'), (0x4F7, 'V'), (0x4F8, 'M', 'ӹ'), (0x4F9, 'V'), (0x4FA, 'M', 'ӻ'), (0x4FB, 'V'), (0x4FC, 'M', 'ӽ'), (0x4FD, 'V'), (0x4FE, 'M', 'ӿ'), (0x4FF, 'V'), (0x500, 'M', 'ԁ'), (0x501, 'V'), (0x502, 'M', 'ԃ'), ] def _seg_9(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x503, 'V'), (0x504, 'M', 'ԅ'), (0x505, 'V'), (0x506, 'M', 'ԇ'), (0x507, 'V'), (0x508, 'M', 'ԉ'), (0x509, 'V'), (0x50A, 'M', 'ԋ'), (0x50B, 'V'), (0x50C, 'M', 'ԍ'), (0x50D, 'V'), (0x50E, 'M', 'ԏ'), (0x50F, 'V'), (0x510, 'M', 'ԑ'), (0x511, 'V'), (0x512, 'M', 'ԓ'), (0x513, 'V'), (0x514, 'M', 'ԕ'), (0x515, 'V'), (0x516, 'M', 'ԗ'), (0x517, 'V'), (0x518, 'M', 'ԙ'), (0x519, 'V'), (0x51A, 'M', 'ԛ'), (0x51B, 'V'), (0x51C, 'M', 'ԝ'), (0x51D, 'V'), (0x51E, 'M', 'ԟ'), (0x51F, 'V'), (0x520, 'M', 'ԡ'), (0x521, 'V'), (0x522, 'M', 'ԣ'), (0x523, 'V'), (0x524, 'M', 'ԥ'), (0x525, 'V'), (0x526, 'M', 'ԧ'), (0x527, 'V'), (0x528, 'M', 'ԩ'), (0x529, 'V'), (0x52A, 'M', 'ԫ'), (0x52B, 'V'), (0x52C, 'M', 'ԭ'), (0x52D, 'V'), (0x52E, 'M', 'ԯ'), (0x52F, 'V'), (0x530, 'X'), (0x531, 'M', 'ա'), (0x532, 'M', 'բ'), (0x533, 'M', 'գ'), (0x534, 'M', 'դ'), (0x535, 'M', 'ե'), (0x536, 'M', 'զ'), (0x537, 'M', 'է'), (0x538, 'M', 'ը'), (0x539, 'M', 'թ'), (0x53A, 'M', 'ժ'), (0x53B, 'M', 'ի'), (0x53C, 'M', 'լ'), (0x53D, 'M', 'խ'), (0x53E, 'M', 'ծ'), (0x53F, 'M', 'կ'), (0x540, 'M', 'հ'), (0x541, 'M', 'ձ'), (0x542, 'M', 'ղ'), (0x543, 'M', 'ճ'), (0x544, 'M', 'մ'), (0x545, 'M', 'յ'), (0x546, 'M', 'ն'), (0x547, 'M', 'շ'), (0x548, 'M', 'ո'), (0x549, 'M', 'չ'), (0x54A, 'M', 'պ'), (0x54B, 'M', 'ջ'), (0x54C, 'M', 'ռ'), (0x54D, 'M', 'ս'), (0x54E, 'M', 'վ'), (0x54F, 'M', 'տ'), (0x550, 'M', 'ր'), (0x551, 'M', 'ց'), (0x552, 'M', 'ւ'), (0x553, 'M', 'փ'), (0x554, 'M', 'ք'), (0x555, 'M', 'օ'), (0x556, 'M', 'ֆ'), (0x557, 'X'), (0x559, 'V'), (0x587, 'M', 'եւ'), (0x588, 'V'), (0x58B, 'X'), (0x58D, 'V'), (0x590, 'X'), (0x591, 'V'), (0x5C8, 'X'), (0x5D0, 'V'), (0x5EB, 'X'), (0x5EF, 'V'), (0x5F5, 'X'), (0x606, 'V'), (0x61C, 'X'), (0x61E, 'V'), ] def _seg_10(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x675, 'M', 'اٴ'), (0x676, 'M', 'وٴ'), (0x677, 'M', 'ۇٴ'), (0x678, 'M', 'يٴ'), (0x679, 'V'), (0x6DD, 'X'), (0x6DE, 'V'), (0x70E, 'X'), (0x710, 'V'), (0x74B, 'X'), (0x74D, 'V'), (0x7B2, 'X'), (0x7C0, 'V'), (0x7FB, 'X'), (0x7FD, 'V'), (0x82E, 'X'), (0x830, 'V'), (0x83F, 'X'), (0x840, 'V'), (0x85C, 'X'), (0x85E, 'V'), (0x85F, 'X'), (0x860, 'V'), (0x86B, 'X'), (0x8A0, 'V'), (0x8B5, 'X'), (0x8B6, 'V'), (0x8C8, 'X'), (0x8D3, 'V'), (0x8E2, 'X'), (0x8E3, 'V'), (0x958, 'M', 'क़'), (0x959, 'M', 'ख़'), (0x95A, 'M', 'ग़'), (0x95B, 'M', 'ज़'), (0x95C, 'M', 'ड़'), (0x95D, 'M', 'ढ़'), (0x95E, 'M', 'फ़'), (0x95F, 'M', 'य़'), (0x960, 'V'), (0x984, 'X'), (0x985, 'V'), (0x98D, 'X'), (0x98F, 'V'), (0x991, 'X'), (0x993, 'V'), (0x9A9, 'X'), (0x9AA, 'V'), (0x9B1, 'X'), (0x9B2, 'V'), (0x9B3, 'X'), (0x9B6, 'V'), (0x9BA, 'X'), (0x9BC, 'V'), (0x9C5, 'X'), (0x9C7, 'V'), (0x9C9, 'X'), (0x9CB, 'V'), (0x9CF, 'X'), (0x9D7, 'V'), (0x9D8, 'X'), (0x9DC, 'M', 'ড়'), (0x9DD, 'M', 'ঢ়'), (0x9DE, 'X'), (0x9DF, 'M', 'য়'), (0x9E0, 'V'), (0x9E4, 'X'), (0x9E6, 'V'), (0x9FF, 'X'), (0xA01, 'V'), (0xA04, 'X'), (0xA05, 'V'), (0xA0B, 'X'), (0xA0F, 'V'), (0xA11, 'X'), (0xA13, 'V'), (0xA29, 'X'), (0xA2A, 'V'), (0xA31, 'X'), (0xA32, 'V'), (0xA33, 'M', 'ਲ਼'), (0xA34, 'X'), (0xA35, 'V'), (0xA36, 'M', 'ਸ਼'), (0xA37, 'X'), (0xA38, 'V'), (0xA3A, 'X'), (0xA3C, 'V'), (0xA3D, 'X'), (0xA3E, 'V'), (0xA43, 'X'), (0xA47, 'V'), (0xA49, 'X'), (0xA4B, 'V'), (0xA4E, 'X'), (0xA51, 'V'), (0xA52, 'X'), (0xA59, 'M', 'ਖ਼'), (0xA5A, 'M', 'ਗ਼'), (0xA5B, 'M', 'ਜ਼'), ] def _seg_11(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xA5C, 'V'), (0xA5D, 'X'), (0xA5E, 'M', 'ਫ਼'), (0xA5F, 'X'), (0xA66, 'V'), (0xA77, 'X'), (0xA81, 'V'), (0xA84, 'X'), (0xA85, 'V'), (0xA8E, 'X'), (0xA8F, 'V'), (0xA92, 'X'), (0xA93, 'V'), (0xAA9, 'X'), (0xAAA, 'V'), (0xAB1, 'X'), (0xAB2, 'V'), (0xAB4, 'X'), (0xAB5, 'V'), (0xABA, 'X'), (0xABC, 'V'), (0xAC6, 'X'), (0xAC7, 'V'), (0xACA, 'X'), (0xACB, 'V'), (0xACE, 'X'), (0xAD0, 'V'), (0xAD1, 'X'), (0xAE0, 'V'), (0xAE4, 'X'), (0xAE6, 'V'), (0xAF2, 'X'), (0xAF9, 'V'), (0xB00, 'X'), (0xB01, 'V'), (0xB04, 'X'), (0xB05, 'V'), (0xB0D, 'X'), (0xB0F, 'V'), (0xB11, 'X'), (0xB13, 'V'), (0xB29, 'X'), (0xB2A, 'V'), (0xB31, 'X'), (0xB32, 'V'), (0xB34, 'X'), (0xB35, 'V'), (0xB3A, 'X'), (0xB3C, 'V'), (0xB45, 'X'), (0xB47, 'V'), (0xB49, 'X'), (0xB4B, 'V'), (0xB4E, 'X'), (0xB55, 'V'), (0xB58, 'X'), (0xB5C, 'M', 'ଡ଼'), (0xB5D, 'M', 'ଢ଼'), (0xB5E, 'X'), (0xB5F, 'V'), (0xB64, 'X'), (0xB66, 'V'), (0xB78, 'X'), (0xB82, 'V'), (0xB84, 'X'), (0xB85, 'V'), (0xB8B, 'X'), (0xB8E, 'V'), (0xB91, 'X'), (0xB92, 'V'), (0xB96, 'X'), (0xB99, 'V'), (0xB9B, 'X'), (0xB9C, 'V'), (0xB9D, 'X'), (0xB9E, 'V'), (0xBA0, 'X'), (0xBA3, 'V'), (0xBA5, 'X'), (0xBA8, 'V'), (0xBAB, 'X'), (0xBAE, 'V'), (0xBBA, 'X'), (0xBBE, 'V'), (0xBC3, 'X'), (0xBC6, 'V'), (0xBC9, 'X'), (0xBCA, 'V'), (0xBCE, 'X'), (0xBD0, 'V'), (0xBD1, 'X'), (0xBD7, 'V'), (0xBD8, 'X'), (0xBE6, 'V'), (0xBFB, 'X'), (0xC00, 'V'), (0xC0D, 'X'), (0xC0E, 'V'), (0xC11, 'X'), (0xC12, 'V'), ] def _seg_12(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xC29, 'X'), (0xC2A, 'V'), (0xC3A, 'X'), (0xC3D, 'V'), (0xC45, 'X'), (0xC46, 'V'), (0xC49, 'X'), (0xC4A, 'V'), (0xC4E, 'X'), (0xC55, 'V'), (0xC57, 'X'), (0xC58, 'V'), (0xC5B, 'X'), (0xC60, 'V'), (0xC64, 'X'), (0xC66, 'V'), (0xC70, 'X'), (0xC77, 'V'), (0xC8D, 'X'), (0xC8E, 'V'), (0xC91, 'X'), (0xC92, 'V'), (0xCA9, 'X'), (0xCAA, 'V'), (0xCB4, 'X'), (0xCB5, 'V'), (0xCBA, 'X'), (0xCBC, 'V'), (0xCC5, 'X'), (0xCC6, 'V'), (0xCC9, 'X'), (0xCCA, 'V'), (0xCCE, 'X'), (0xCD5, 'V'), (0xCD7, 'X'), (0xCDE, 'V'), (0xCDF, 'X'), (0xCE0, 'V'), (0xCE4, 'X'), (0xCE6, 'V'), (0xCF0, 'X'), (0xCF1, 'V'), (0xCF3, 'X'), (0xD00, 'V'), (0xD0D, 'X'), (0xD0E, 'V'), (0xD11, 'X'), (0xD12, 'V'), (0xD45, 'X'), (0xD46, 'V'), (0xD49, 'X'), (0xD4A, 'V'), (0xD50, 'X'), (0xD54, 'V'), (0xD64, 'X'), (0xD66, 'V'), (0xD80, 'X'), (0xD81, 'V'), (0xD84, 'X'), (0xD85, 'V'), (0xD97, 'X'), (0xD9A, 'V'), (0xDB2, 'X'), (0xDB3, 'V'), (0xDBC, 'X'), (0xDBD, 'V'), (0xDBE, 'X'), (0xDC0, 'V'), (0xDC7, 'X'), (0xDCA, 'V'), (0xDCB, 'X'), (0xDCF, 'V'), (0xDD5, 'X'), (0xDD6, 'V'), (0xDD7, 'X'), (0xDD8, 'V'), (0xDE0, 'X'), (0xDE6, 'V'), (0xDF0, 'X'), (0xDF2, 'V'), (0xDF5, 'X'), (0xE01, 'V'), (0xE33, 'M', 'ํา'), (0xE34, 'V'), (0xE3B, 'X'), (0xE3F, 'V'), (0xE5C, 'X'), (0xE81, 'V'), (0xE83, 'X'), (0xE84, 'V'), (0xE85, 'X'), (0xE86, 'V'), (0xE8B, 'X'), (0xE8C, 'V'), (0xEA4, 'X'), (0xEA5, 'V'), (0xEA6, 'X'), (0xEA7, 'V'), (0xEB3, 'M', 'ໍາ'), (0xEB4, 'V'), ] def _seg_13(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xEBE, 'X'), (0xEC0, 'V'), (0xEC5, 'X'), (0xEC6, 'V'), (0xEC7, 'X'), (0xEC8, 'V'), (0xECE, 'X'), (0xED0, 'V'), (0xEDA, 'X'), (0xEDC, 'M', 'ຫນ'), (0xEDD, 'M', 'ຫມ'), (0xEDE, 'V'), (0xEE0, 'X'), (0xF00, 'V'), (0xF0C, 'M', '་'), (0xF0D, 'V'), (0xF43, 'M', 'གྷ'), (0xF44, 'V'), (0xF48, 'X'), (0xF49, 'V'), (0xF4D, 'M', 'ཌྷ'), (0xF4E, 'V'), (0xF52, 'M', 'དྷ'), (0xF53, 'V'), (0xF57, 'M', 'བྷ'), (0xF58, 'V'), (0xF5C, 'M', 'ཛྷ'), (0xF5D, 'V'), (0xF69, 'M', 'ཀྵ'), (0xF6A, 'V'), (0xF6D, 'X'), (0xF71, 'V'), (0xF73, 'M', 'ཱི'), (0xF74, 'V'), (0xF75, 'M', 'ཱུ'), (0xF76, 'M', 'ྲྀ'), (0xF77, 'M', 'ྲཱྀ'), (0xF78, 'M', 'ླྀ'), (0xF79, 'M', 'ླཱྀ'), (0xF7A, 'V'), (0xF81, 'M', 'ཱྀ'), (0xF82, 'V'), (0xF93, 'M', 'ྒྷ'), (0xF94, 'V'), (0xF98, 'X'), (0xF99, 'V'), (0xF9D, 'M', 'ྜྷ'), (0xF9E, 'V'), (0xFA2, 'M', 'ྡྷ'), (0xFA3, 'V'), (0xFA7, 'M', 'ྦྷ'), (0xFA8, 'V'), (0xFAC, 'M', 'ྫྷ'), (0xFAD, 'V'), (0xFB9, 'M', 'ྐྵ'), (0xFBA, 'V'), (0xFBD, 'X'), (0xFBE, 'V'), (0xFCD, 'X'), (0xFCE, 'V'), (0xFDB, 'X'), (0x1000, 'V'), (0x10A0, 'X'), (0x10C7, 'M', 'ⴧ'), (0x10C8, 'X'), (0x10CD, 'M', 'ⴭ'), (0x10CE, 'X'), (0x10D0, 'V'), (0x10FC, 'M', 'ნ'), (0x10FD, 'V'), (0x115F, 'X'), (0x1161, 'V'), (0x1249, 'X'), (0x124A, 'V'), (0x124E, 'X'), (0x1250, 'V'), (0x1257, 'X'), (0x1258, 'V'), (0x1259, 'X'), (0x125A, 'V'), (0x125E, 'X'), (0x1260, 'V'), (0x1289, 'X'), (0x128A, 'V'), (0x128E, 'X'), (0x1290, 'V'), (0x12B1, 'X'), (0x12B2, 'V'), (0x12B6, 'X'), (0x12B8, 'V'), (0x12BF, 'X'), (0x12C0, 'V'), (0x12C1, 'X'), (0x12C2, 'V'), (0x12C6, 'X'), (0x12C8, 'V'), (0x12D7, 'X'), (0x12D8, 'V'), (0x1311, 'X'), (0x1312, 'V'), ] def _seg_14(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1316, 'X'), (0x1318, 'V'), (0x135B, 'X'), (0x135D, 'V'), (0x137D, 'X'), (0x1380, 'V'), (0x139A, 'X'), (0x13A0, 'V'), (0x13F6, 'X'), (0x13F8, 'M', 'Ᏸ'), (0x13F9, 'M', 'Ᏹ'), (0x13FA, 'M', 'Ᏺ'), (0x13FB, 'M', 'Ᏻ'), (0x13FC, 'M', 'Ᏼ'), (0x13FD, 'M', 'Ᏽ'), (0x13FE, 'X'), (0x1400, 'V'), (0x1680, 'X'), (0x1681, 'V'), (0x169D, 'X'), (0x16A0, 'V'), (0x16F9, 'X'), (0x1700, 'V'), (0x170D, 'X'), (0x170E, 'V'), (0x1715, 'X'), (0x1720, 'V'), (0x1737, 'X'), (0x1740, 'V'), (0x1754, 'X'), (0x1760, 'V'), (0x176D, 'X'), (0x176E, 'V'), (0x1771, 'X'), (0x1772, 'V'), (0x1774, 'X'), (0x1780, 'V'), (0x17B4, 'X'), (0x17B6, 'V'), (0x17DE, 'X'), (0x17E0, 'V'), (0x17EA, 'X'), (0x17F0, 'V'), (0x17FA, 'X'), (0x1800, 'V'), (0x1806, 'X'), (0x1807, 'V'), (0x180B, 'I'), (0x180E, 'X'), (0x1810, 'V'), (0x181A, 'X'), (0x1820, 'V'), (0x1879, 'X'), (0x1880, 'V'), (0x18AB, 'X'), (0x18B0, 'V'), (0x18F6, 'X'), (0x1900, 'V'), (0x191F, 'X'), (0x1920, 'V'), (0x192C, 'X'), (0x1930, 'V'), (0x193C, 'X'), (0x1940, 'V'), (0x1941, 'X'), (0x1944, 'V'), (0x196E, 'X'), (0x1970, 'V'), (0x1975, 'X'), (0x1980, 'V'), (0x19AC, 'X'), (0x19B0, 'V'), (0x19CA, 'X'), (0x19D0, 'V'), (0x19DB, 'X'), (0x19DE, 'V'), (0x1A1C, 'X'), (0x1A1E, 'V'), (0x1A5F, 'X'), (0x1A60, 'V'), (0x1A7D, 'X'), (0x1A7F, 'V'), (0x1A8A, 'X'), (0x1A90, 'V'), (0x1A9A, 'X'), (0x1AA0, 'V'), (0x1AAE, 'X'), (0x1AB0, 'V'), (0x1AC1, 'X'), (0x1B00, 'V'), (0x1B4C, 'X'), (0x1B50, 'V'), (0x1B7D, 'X'), (0x1B80, 'V'), (0x1BF4, 'X'), (0x1BFC, 'V'), (0x1C38, 'X'), (0x1C3B, 'V'), (0x1C4A, 'X'), (0x1C4D, 'V'), ] def _seg_15(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1C80, 'M', 'в'), (0x1C81, 'M', 'д'), (0x1C82, 'M', 'о'), (0x1C83, 'M', 'с'), (0x1C84, 'M', 'т'), (0x1C86, 'M', 'ъ'), (0x1C87, 'M', 'ѣ'), (0x1C88, 'M', 'ꙋ'), (0x1C89, 'X'), (0x1C90, 'M', 'ა'), (0x1C91, 'M', 'ბ'), (0x1C92, 'M', 'გ'), (0x1C93, 'M', 'დ'), (0x1C94, 'M', 'ე'), (0x1C95, 'M', 'ვ'), (0x1C96, 'M', 'ზ'), (0x1C97, 'M', 'თ'), (0x1C98, 'M', 'ი'), (0x1C99, 'M', 'კ'), (0x1C9A, 'M', 'ლ'), (0x1C9B, 'M', 'მ'), (0x1C9C, 'M', 'ნ'), (0x1C9D, 'M', 'ო'), (0x1C9E, 'M', 'პ'), (0x1C9F, 'M', 'ჟ'), (0x1CA0, 'M', 'რ'), (0x1CA1, 'M', 'ს'), (0x1CA2, 'M', 'ტ'), (0x1CA3, 'M', 'უ'), (0x1CA4, 'M', 'ფ'), (0x1CA5, 'M', 'ქ'), (0x1CA6, 'M', 'ღ'), (0x1CA7, 'M', 'ყ'), (0x1CA8, 'M', 'შ'), (0x1CA9, 'M', 'ჩ'), (0x1CAA, 'M', 'ც'), (0x1CAB, 'M', 'ძ'), (0x1CAC, 'M', 'წ'), (0x1CAD, 'M', 'ჭ'), (0x1CAE, 'M', 'ხ'), (0x1CAF, 'M', 'ჯ'), (0x1CB0, 'M', 'ჰ'), (0x1CB1, 'M', 'ჱ'), (0x1CB2, 'M', 'ჲ'), (0x1CB3, 'M', 'ჳ'), (0x1CB4, 'M', 'ჴ'), (0x1CB5, 'M', 'ჵ'), (0x1CB6, 'M', 'ჶ'), (0x1CB7, 'M', 'ჷ'), (0x1CB8, 'M', 'ჸ'), (0x1CB9, 'M', 'ჹ'), (0x1CBA, 'M', 'ჺ'), (0x1CBB, 'X'), (0x1CBD, 'M', 'ჽ'), (0x1CBE, 'M', 'ჾ'), (0x1CBF, 'M', 'ჿ'), (0x1CC0, 'V'), (0x1CC8, 'X'), (0x1CD0, 'V'), (0x1CFB, 'X'), (0x1D00, 'V'), (0x1D2C, 'M', 'a'), (0x1D2D, 'M', 'æ'), (0x1D2E, 'M', 'b'), (0x1D2F, 'V'), (0x1D30, 'M', 'd'), (0x1D31, 'M', 'e'), (0x1D32, 'M', 'ǝ'), (0x1D33, 'M', 'g'), (0x1D34, 'M', 'h'), (0x1D35, 'M', 'i'), (0x1D36, 'M', 'j'), (0x1D37, 'M', 'k'), (0x1D38, 'M', 'l'), (0x1D39, 'M', 'm'), (0x1D3A, 'M', 'n'), (0x1D3B, 'V'), (0x1D3C, 'M', 'o'), (0x1D3D, 'M', 'ȣ'), (0x1D3E, 'M', 'p'), (0x1D3F, 'M', 'r'), (0x1D40, 'M', 't'), (0x1D41, 'M', 'u'), (0x1D42, 'M', 'w'), (0x1D43, 'M', 'a'), (0x1D44, 'M', 'ɐ'), (0x1D45, 'M', 'ɑ'), (0x1D46, 'M', 'ᴂ'), (0x1D47, 'M', 'b'), (0x1D48, 'M', 'd'), (0x1D49, 'M', 'e'), (0x1D4A, 'M', 'ə'), (0x1D4B, 'M', 'ɛ'), (0x1D4C, 'M', 'ɜ'), (0x1D4D, 'M', 'g'), (0x1D4E, 'V'), (0x1D4F, 'M', 'k'), (0x1D50, 'M', 'm'), (0x1D51, 'M', 'ŋ'), (0x1D52, 'M', 'o'), ] def _seg_16(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D53, 'M', 'ɔ'), (0x1D54, 'M', 'ᴖ'), (0x1D55, 'M', 'ᴗ'), (0x1D56, 'M', 'p'), (0x1D57, 'M', 't'), (0x1D58, 'M', 'u'), (0x1D59, 'M', 'ᴝ'), (0x1D5A, 'M', 'ɯ'), (0x1D5B, 'M', 'v'), (0x1D5C, 'M', 'ᴥ'), (0x1D5D, 'M', 'β'), (0x1D5E, 'M', 'γ'), (0x1D5F, 'M', 'δ'), (0x1D60, 'M', 'φ'), (0x1D61, 'M', 'χ'), (0x1D62, 'M', 'i'), (0x1D63, 'M', 'r'), (0x1D64, 'M', 'u'), (0x1D65, 'M', 'v'), (0x1D66, 'M', 'β'), (0x1D67, 'M', 'γ'), (0x1D68, 'M', 'ρ'), (0x1D69, 'M', 'φ'), (0x1D6A, 'M', 'χ'), (0x1D6B, 'V'), (0x1D78, 'M', 'н'), (0x1D79, 'V'), (0x1D9B, 'M', 'ɒ'), (0x1D9C, 'M', 'c'), (0x1D9D, 'M', 'ɕ'), (0x1D9E, 'M', 'ð'), (0x1D9F, 'M', 'ɜ'), (0x1DA0, 'M', 'f'), (0x1DA1, 'M', 'ɟ'), (0x1DA2, 'M', 'ɡ'), (0x1DA3, 'M', 'ɥ'), (0x1DA4, 'M', 'ɨ'), (0x1DA5, 'M', 'ɩ'), (0x1DA6, 'M', 'ɪ'), (0x1DA7, 'M', 'ᵻ'), (0x1DA8, 'M', 'ʝ'), (0x1DA9, 'M', 'ɭ'), (0x1DAA, 'M', 'ᶅ'), (0x1DAB, 'M', 'ʟ'), (0x1DAC, 'M', 'ɱ'), (0x1DAD, 'M', 'ɰ'), (0x1DAE, 'M', 'ɲ'), (0x1DAF, 'M', 'ɳ'), (0x1DB0, 'M', 'ɴ'), (0x1DB1, 'M', 'ɵ'), (0x1DB2, 'M', 'ɸ'), (0x1DB3, 'M', 'ʂ'), (0x1DB4, 'M', 'ʃ'), (0x1DB5, 'M', 'ƫ'), (0x1DB6, 'M', 'ʉ'), (0x1DB7, 'M', 'ʊ'), (0x1DB8, 'M', 'ᴜ'), (0x1DB9, 'M', 'ʋ'), (0x1DBA, 'M', 'ʌ'), (0x1DBB, 'M', 'z'), (0x1DBC, 'M', 'ʐ'), (0x1DBD, 'M', 'ʑ'), (0x1DBE, 'M', 'ʒ'), (0x1DBF, 'M', 'θ'), (0x1DC0, 'V'), (0x1DFA, 'X'), (0x1DFB, 'V'), (0x1E00, 'M', 'ḁ'), (0x1E01, 'V'), (0x1E02, 'M', 'ḃ'), (0x1E03, 'V'), (0x1E04, 'M', 'ḅ'), (0x1E05, 'V'), (0x1E06, 'M', 'ḇ'), (0x1E07, 'V'), (0x1E08, 'M', 'ḉ'), (0x1E09, 'V'), (0x1E0A, 'M', 'ḋ'), (0x1E0B, 'V'), (0x1E0C, 'M', 'ḍ'), (0x1E0D, 'V'), (0x1E0E, 'M', 'ḏ'), (0x1E0F, 'V'), (0x1E10, 'M', 'ḑ'), (0x1E11, 'V'), (0x1E12, 'M', 'ḓ'), (0x1E13, 'V'), (0x1E14, 'M', 'ḕ'), (0x1E15, 'V'), (0x1E16, 'M', 'ḗ'), (0x1E17, 'V'), (0x1E18, 'M', 'ḙ'), (0x1E19, 'V'), (0x1E1A, 'M', 'ḛ'), (0x1E1B, 'V'), (0x1E1C, 'M', 'ḝ'), (0x1E1D, 'V'), (0x1E1E, 'M', 'ḟ'), (0x1E1F, 'V'), (0x1E20, 'M', 'ḡ'), ] def _seg_17(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1E21, 'V'), (0x1E22, 'M', 'ḣ'), (0x1E23, 'V'), (0x1E24, 'M', 'ḥ'), (0x1E25, 'V'), (0x1E26, 'M', 'ḧ'), (0x1E27, 'V'), (0x1E28, 'M', 'ḩ'), (0x1E29, 'V'), (0x1E2A, 'M', 'ḫ'), (0x1E2B, 'V'), (0x1E2C, 'M', 'ḭ'), (0x1E2D, 'V'), (0x1E2E, 'M', 'ḯ'), (0x1E2F, 'V'), (0x1E30, 'M', 'ḱ'), (0x1E31, 'V'), (0x1E32, 'M', 'ḳ'), (0x1E33, 'V'), (0x1E34, 'M', 'ḵ'), (0x1E35, 'V'), (0x1E36, 'M', 'ḷ'), (0x1E37, 'V'), (0x1E38, 'M', 'ḹ'), (0x1E39, 'V'), (0x1E3A, 'M', 'ḻ'), (0x1E3B, 'V'), (0x1E3C, 'M', 'ḽ'), (0x1E3D, 'V'), (0x1E3E, 'M', 'ḿ'), (0x1E3F, 'V'), (0x1E40, 'M', 'ṁ'), (0x1E41, 'V'), (0x1E42, 'M', 'ṃ'), (0x1E43, 'V'), (0x1E44, 'M', 'ṅ'), (0x1E45, 'V'), (0x1E46, 'M', 'ṇ'), (0x1E47, 'V'), (0x1E48, 'M', 'ṉ'), (0x1E49, 'V'), (0x1E4A, 'M', 'ṋ'), (0x1E4B, 'V'), (0x1E4C, 'M', 'ṍ'), (0x1E4D, 'V'), (0x1E4E, 'M', 'ṏ'), (0x1E4F, 'V'), (0x1E50, 'M', 'ṑ'), (0x1E51, 'V'), (0x1E52, 'M', 'ṓ'), (0x1E53, 'V'), (0x1E54, 'M', 'ṕ'), (0x1E55, 'V'), (0x1E56, 'M', 'ṗ'), (0x1E57, 'V'), (0x1E58, 'M', 'ṙ'), (0x1E59, 'V'), (0x1E5A, 'M', 'ṛ'), (0x1E5B, 'V'), (0x1E5C, 'M', 'ṝ'), (0x1E5D, 'V'), (0x1E5E, 'M', 'ṟ'), (0x1E5F, 'V'), (0x1E60, 'M', 'ṡ'), (0x1E61, 'V'), (0x1E62, 'M', 'ṣ'), (0x1E63, 'V'), (0x1E64, 'M', 'ṥ'), (0x1E65, 'V'), (0x1E66, 'M', 'ṧ'), (0x1E67, 'V'), (0x1E68, 'M', 'ṩ'), (0x1E69, 'V'), (0x1E6A, 'M', 'ṫ'), (0x1E6B, 'V'), (0x1E6C, 'M', 'ṭ'), (0x1E6D, 'V'), (0x1E6E, 'M', 'ṯ'), (0x1E6F, 'V'), (0x1E70, 'M', 'ṱ'), (0x1E71, 'V'), (0x1E72, 'M', 'ṳ'), (0x1E73, 'V'), (0x1E74, 'M', 'ṵ'), (0x1E75, 'V'), (0x1E76, 'M', 'ṷ'), (0x1E77, 'V'), (0x1E78, 'M', 'ṹ'), (0x1E79, 'V'), (0x1E7A, 'M', 'ṻ'), (0x1E7B, 'V'), (0x1E7C, 'M', 'ṽ'), (0x1E7D, 'V'), (0x1E7E, 'M', 'ṿ'), (0x1E7F, 'V'), (0x1E80, 'M', 'ẁ'), (0x1E81, 'V'), (0x1E82, 'M', 'ẃ'), (0x1E83, 'V'), (0x1E84, 'M', 'ẅ'), ] def _seg_18(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1E85, 'V'), (0x1E86, 'M', 'ẇ'), (0x1E87, 'V'), (0x1E88, 'M', 'ẉ'), (0x1E89, 'V'), (0x1E8A, 'M', 'ẋ'), (0x1E8B, 'V'), (0x1E8C, 'M', 'ẍ'), (0x1E8D, 'V'), (0x1E8E, 'M', 'ẏ'), (0x1E8F, 'V'), (0x1E90, 'M', 'ẑ'), (0x1E91, 'V'), (0x1E92, 'M', 'ẓ'), (0x1E93, 'V'), (0x1E94, 'M', 'ẕ'), (0x1E95, 'V'), (0x1E9A, 'M', 'aʾ'), (0x1E9B, 'M', 'ṡ'), (0x1E9C, 'V'), (0x1E9E, 'M', 'ss'), (0x1E9F, 'V'), (0x1EA0, 'M', 'ạ'), (0x1EA1, 'V'), (0x1EA2, 'M', 'ả'), (0x1EA3, 'V'), (0x1EA4, 'M', 'ấ'), (0x1EA5, 'V'), (0x1EA6, 'M', 'ầ'), (0x1EA7, 'V'), (0x1EA8, 'M', 'ẩ'), (0x1EA9, 'V'), (0x1EAA, 'M', 'ẫ'), (0x1EAB, 'V'), (0x1EAC, 'M', 'ậ'), (0x1EAD, 'V'), (0x1EAE, 'M', 'ắ'), (0x1EAF, 'V'), (0x1EB0, 'M', 'ằ'), (0x1EB1, 'V'), (0x1EB2, 'M', 'ẳ'), (0x1EB3, 'V'), (0x1EB4, 'M', 'ẵ'), (0x1EB5, 'V'), (0x1EB6, 'M', 'ặ'), (0x1EB7, 'V'), (0x1EB8, 'M', 'ẹ'), (0x1EB9, 'V'), (0x1EBA, 'M', 'ẻ'), (0x1EBB, 'V'), (0x1EBC, 'M', 'ẽ'), (0x1EBD, 'V'), (0x1EBE, 'M', 'ế'), (0x1EBF, 'V'), (0x1EC0, 'M', 'ề'), (0x1EC1, 'V'), (0x1EC2, 'M', 'ể'), (0x1EC3, 'V'), (0x1EC4, 'M', 'ễ'), (0x1EC5, 'V'), (0x1EC6, 'M', 'ệ'), (0x1EC7, 'V'), (0x1EC8, 'M', 'ỉ'), (0x1EC9, 'V'), (0x1ECA, 'M', 'ị'), (0x1ECB, 'V'), (0x1ECC, 'M', 'ọ'), (0x1ECD, 'V'), (0x1ECE, 'M', 'ỏ'), (0x1ECF, 'V'), (0x1ED0, 'M', 'ố'), (0x1ED1, 'V'), (0x1ED2, 'M', 'ồ'), (0x1ED3, 'V'), (0x1ED4, 'M', 'ổ'), (0x1ED5, 'V'), (0x1ED6, 'M', 'ỗ'), (0x1ED7, 'V'), (0x1ED8, 'M', 'ộ'), (0x1ED9, 'V'), (0x1EDA, 'M', 'ớ'), (0x1EDB, 'V'), (0x1EDC, 'M', 'ờ'), (0x1EDD, 'V'), (0x1EDE, 'M', 'ở'), (0x1EDF, 'V'), (0x1EE0, 'M', 'ỡ'), (0x1EE1, 'V'), (0x1EE2, 'M', 'ợ'), (0x1EE3, 'V'), (0x1EE4, 'M', 'ụ'), (0x1EE5, 'V'), (0x1EE6, 'M', 'ủ'), (0x1EE7, 'V'), (0x1EE8, 'M', 'ứ'), (0x1EE9, 'V'), (0x1EEA, 'M', 'ừ'), (0x1EEB, 'V'), (0x1EEC, 'M', 'ử'), (0x1EED, 'V'), ] def _seg_19(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1EEE, 'M', 'ữ'), (0x1EEF, 'V'), (0x1EF0, 'M', 'ự'), (0x1EF1, 'V'), (0x1EF2, 'M', 'ỳ'), (0x1EF3, 'V'), (0x1EF4, 'M', 'ỵ'), (0x1EF5, 'V'), (0x1EF6, 'M', 'ỷ'), (0x1EF7, 'V'), (0x1EF8, 'M', 'ỹ'), (0x1EF9, 'V'), (0x1EFA, 'M', 'ỻ'), (0x1EFB, 'V'), (0x1EFC, 'M', 'ỽ'), (0x1EFD, 'V'), (0x1EFE, 'M', 'ỿ'), (0x1EFF, 'V'), (0x1F08, 'M', 'ἀ'), (0x1F09, 'M', 'ἁ'), (0x1F0A, 'M', 'ἂ'), (0x1F0B, 'M', 'ἃ'), (0x1F0C, 'M', 'ἄ'), (0x1F0D, 'M', 'ἅ'), (0x1F0E, 'M', 'ἆ'), (0x1F0F, 'M', 'ἇ'), (0x1F10, 'V'), (0x1F16, 'X'), (0x1F18, 'M', 'ἐ'), (0x1F19, 'M', 'ἑ'), (0x1F1A, 'M', 'ἒ'), (0x1F1B, 'M', 'ἓ'), (0x1F1C, 'M', 'ἔ'), (0x1F1D, 'M', 'ἕ'), (0x1F1E, 'X'), (0x1F20, 'V'), (0x1F28, 'M', 'ἠ'), (0x1F29, 'M', 'ἡ'), (0x1F2A, 'M', 'ἢ'), (0x1F2B, 'M', 'ἣ'), (0x1F2C, 'M', 'ἤ'), (0x1F2D, 'M', 'ἥ'), (0x1F2E, 'M', 'ἦ'), (0x1F2F, 'M', 'ἧ'), (0x1F30, 'V'), (0x1F38, 'M', 'ἰ'), (0x1F39, 'M', 'ἱ'), (0x1F3A, 'M', 'ἲ'), (0x1F3B, 'M', 'ἳ'), (0x1F3C, 'M', 'ἴ'), (0x1F3D, 'M', 'ἵ'), (0x1F3E, 'M', 'ἶ'), (0x1F3F, 'M', 'ἷ'), (0x1F40, 'V'), (0x1F46, 'X'), (0x1F48, 'M', 'ὀ'), (0x1F49, 'M', 'ὁ'), (0x1F4A, 'M', 'ὂ'), (0x1F4B, 'M', 'ὃ'), (0x1F4C, 'M', 'ὄ'), (0x1F4D, 'M', 'ὅ'), (0x1F4E, 'X'), (0x1F50, 'V'), (0x1F58, 'X'), (0x1F59, 'M', 'ὑ'), (0x1F5A, 'X'), (0x1F5B, 'M', 'ὓ'), (0x1F5C, 'X'), (0x1F5D, 'M', 'ὕ'), (0x1F5E, 'X'), (0x1F5F, 'M', 'ὗ'), (0x1F60, 'V'), (0x1F68, 'M', 'ὠ'), (0x1F69, 'M', 'ὡ'), (0x1F6A, 'M', 'ὢ'), (0x1F6B, 'M', 'ὣ'), (0x1F6C, 'M', 'ὤ'), (0x1F6D, 'M', 'ὥ'), (0x1F6E, 'M', 'ὦ'), (0x1F6F, 'M', 'ὧ'), (0x1F70, 'V'), (0x1F71, 'M', 'ά'), (0x1F72, 'V'), (0x1F73, 'M', 'έ'), (0x1F74, 'V'), (0x1F75, 'M', 'ή'), (0x1F76, 'V'), (0x1F77, 'M', 'ί'), (0x1F78, 'V'), (0x1F79, 'M', 'ό'), (0x1F7A, 'V'), (0x1F7B, 'M', 'ύ'), (0x1F7C, 'V'), (0x1F7D, 'M', 'ώ'), (0x1F7E, 'X'), (0x1F80, 'M', 'ἀι'), (0x1F81, 'M', 'ἁι'), (0x1F82, 'M', 'ἂι'), (0x1F83, 'M', 'ἃι'), (0x1F84, 'M', 'ἄι'), ] def _seg_20(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1F85, 'M', 'ἅι'), (0x1F86, 'M', 'ἆι'), (0x1F87, 'M', 'ἇι'), (0x1F88, 'M', 'ἀι'), (0x1F89, 'M', 'ἁι'), (0x1F8A, 'M', 'ἂι'), (0x1F8B, 'M', 'ἃι'), (0x1F8C, 'M', 'ἄι'), (0x1F8D, 'M', 'ἅι'), (0x1F8E, 'M', 'ἆι'), (0x1F8F, 'M', 'ἇι'), (0x1F90, 'M', 'ἠι'), (0x1F91, 'M', 'ἡι'), (0x1F92, 'M', 'ἢι'), (0x1F93, 'M', 'ἣι'), (0x1F94, 'M', 'ἤι'), (0x1F95, 'M', 'ἥι'), (0x1F96, 'M', 'ἦι'), (0x1F97, 'M', 'ἧι'), (0x1F98, 'M', 'ἠι'), (0x1F99, 'M', 'ἡι'), (0x1F9A, 'M', 'ἢι'), (0x1F9B, 'M', 'ἣι'), (0x1F9C, 'M', 'ἤι'), (0x1F9D, 'M', 'ἥι'), (0x1F9E, 'M', 'ἦι'), (0x1F9F, 'M', 'ἧι'), (0x1FA0, 'M', 'ὠι'), (0x1FA1, 'M', 'ὡι'), (0x1FA2, 'M', 'ὢι'), (0x1FA3, 'M', 'ὣι'), (0x1FA4, 'M', 'ὤι'), (0x1FA5, 'M', 'ὥι'), (0x1FA6, 'M', 'ὦι'), (0x1FA7, 'M', 'ὧι'), (0x1FA8, 'M', 'ὠι'), (0x1FA9, 'M', 'ὡι'), (0x1FAA, 'M', 'ὢι'), (0x1FAB, 'M', 'ὣι'), (0x1FAC, 'M', 'ὤι'), (0x1FAD, 'M', 'ὥι'), (0x1FAE, 'M', 'ὦι'), (0x1FAF, 'M', 'ὧι'), (0x1FB0, 'V'), (0x1FB2, 'M', 'ὰι'), (0x1FB3, 'M', 'αι'), (0x1FB4, 'M', 'άι'), (0x1FB5, 'X'), (0x1FB6, 'V'), (0x1FB7, 'M', 'ᾶι'), (0x1FB8, 'M', 'ᾰ'), (0x1FB9, 'M', 'ᾱ'), (0x1FBA, 'M', 'ὰ'), (0x1FBB, 'M', 'ά'), (0x1FBC, 'M', 'αι'), (0x1FBD, '3', ' ̓'), (0x1FBE, 'M', 'ι'), (0x1FBF, '3', ' ̓'), (0x1FC0, '3', ' ͂'), (0x1FC1, '3', ' ̈͂'), (0x1FC2, 'M', 'ὴι'), (0x1FC3, 'M', 'ηι'), (0x1FC4, 'M', 'ήι'), (0x1FC5, 'X'), (0x1FC6, 'V'), (0x1FC7, 'M', 'ῆι'), (0x1FC8, 'M', 'ὲ'), (0x1FC9, 'M', 'έ'), (0x1FCA, 'M', 'ὴ'), (0x1FCB, 'M', 'ή'), (0x1FCC, 'M', 'ηι'), (0x1FCD, '3', ' ̓̀'), (0x1FCE, '3', ' ̓́'), (0x1FCF, '3', ' ̓͂'), (0x1FD0, 'V'), (0x1FD3, 'M', 'ΐ'), (0x1FD4, 'X'), (0x1FD6, 'V'), (0x1FD8, 'M', 'ῐ'), (0x1FD9, 'M', 'ῑ'), (0x1FDA, 'M', 'ὶ'), (0x1FDB, 'M', 'ί'), (0x1FDC, 'X'), (0x1FDD, '3', ' ̔̀'), (0x1FDE, '3', ' ̔́'), (0x1FDF, '3', ' ̔͂'), (0x1FE0, 'V'), (0x1FE3, 'M', 'ΰ'), (0x1FE4, 'V'), (0x1FE8, 'M', 'ῠ'), (0x1FE9, 'M', 'ῡ'), (0x1FEA, 'M', 'ὺ'), (0x1FEB, 'M', 'ύ'), (0x1FEC, 'M', 'ῥ'), (0x1FED, '3', ' ̈̀'), (0x1FEE, '3', ' ̈́'), (0x1FEF, '3', '`'), (0x1FF0, 'X'), (0x1FF2, 'M', 'ὼι'), (0x1FF3, 'M', 'ωι'), ] def _seg_21(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1FF4, 'M', 'ώι'), (0x1FF5, 'X'), (0x1FF6, 'V'), (0x1FF7, 'M', 'ῶι'), (0x1FF8, 'M', 'ὸ'), (0x1FF9, 'M', 'ό'), (0x1FFA, 'M', 'ὼ'), (0x1FFB, 'M', 'ώ'), (0x1FFC, 'M', 'ωι'), (0x1FFD, '3', ' ́'), (0x1FFE, '3', ' ̔'), (0x1FFF, 'X'), (0x2000, '3', ' '), (0x200B, 'I'), (0x200C, 'D', ''), (0x200E, 'X'), (0x2010, 'V'), (0x2011, 'M', '‐'), (0x2012, 'V'), (0x2017, '3', ' ̳'), (0x2018, 'V'), (0x2024, 'X'), (0x2027, 'V'), (0x2028, 'X'), (0x202F, '3', ' '), (0x2030, 'V'), (0x2033, 'M', '′′'), (0x2034, 'M', '′′′'), (0x2035, 'V'), (0x2036, 'M', '‵‵'), (0x2037, 'M', '‵‵‵'), (0x2038, 'V'), (0x203C, '3', '!!'), (0x203D, 'V'), (0x203E, '3', ' ̅'), (0x203F, 'V'), (0x2047, '3', '??'), (0x2048, '3', '?!'), (0x2049, '3', '!?'), (0x204A, 'V'), (0x2057, 'M', '′′′′'), (0x2058, 'V'), (0x205F, '3', ' '), (0x2060, 'I'), (0x2061, 'X'), (0x2064, 'I'), (0x2065, 'X'), (0x2070, 'M', '0'), (0x2071, 'M', 'i'), (0x2072, 'X'), (0x2074, 'M', '4'), (0x2075, 'M', '5'), (0x2076, 'M', '6'), (0x2077, 'M', '7'), (0x2078, 'M', '8'), (0x2079, 'M', '9'), (0x207A, '3', '+'), (0x207B, 'M', '−'), (0x207C, '3', '='), (0x207D, '3', '('), (0x207E, '3', ')'), (0x207F, 'M', 'n'), (0x2080, 'M', '0'), (0x2081, 'M', '1'), (0x2082, 'M', '2'), (0x2083, 'M', '3'), (0x2084, 'M', '4'), (0x2085, 'M', '5'), (0x2086, 'M', '6'), (0x2087, 'M', '7'), (0x2088, 'M', '8'), (0x2089, 'M', '9'), (0x208A, '3', '+'), (0x208B, 'M', '−'), (0x208C, '3', '='), (0x208D, '3', '('), (0x208E, '3', ')'), (0x208F, 'X'), (0x2090, 'M', 'a'), (0x2091, 'M', 'e'), (0x2092, 'M', 'o'), (0x2093, 'M', 'x'), (0x2094, 'M', 'ə'), (0x2095, 'M', 'h'), (0x2096, 'M', 'k'), (0x2097, 'M', 'l'), (0x2098, 'M', 'm'), (0x2099, 'M', 'n'), (0x209A, 'M', 'p'), (0x209B, 'M', 's'), (0x209C, 'M', 't'), (0x209D, 'X'), (0x20A0, 'V'), (0x20A8, 'M', 'rs'), (0x20A9, 'V'), (0x20C0, 'X'), (0x20D0, 'V'), (0x20F1, 'X'), (0x2100, '3', 'a/c'), (0x2101, '3', 'a/s'), ] def _seg_22(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2102, 'M', 'c'), (0x2103, 'M', '°c'), (0x2104, 'V'), (0x2105, '3', 'c/o'), (0x2106, '3', 'c/u'), (0x2107, 'M', 'ɛ'), (0x2108, 'V'), (0x2109, 'M', '°f'), (0x210A, 'M', 'g'), (0x210B, 'M', 'h'), (0x210F, 'M', 'ħ'), (0x2110, 'M', 'i'), (0x2112, 'M', 'l'), (0x2114, 'V'), (0x2115, 'M', 'n'), (0x2116, 'M', 'no'), (0x2117, 'V'), (0x2119, 'M', 'p'), (0x211A, 'M', 'q'), (0x211B, 'M', 'r'), (0x211E, 'V'), (0x2120, 'M', 'sm'), (0x2121, 'M', 'tel'), (0x2122, 'M', 'tm'), (0x2123, 'V'), (0x2124, 'M', 'z'), (0x2125, 'V'), (0x2126, 'M', 'ω'), (0x2127, 'V'), (0x2128, 'M', 'z'), (0x2129, 'V'), (0x212A, 'M', 'k'), (0x212B, 'M', 'å'), (0x212C, 'M', 'b'), (0x212D, 'M', 'c'), (0x212E, 'V'), (0x212F, 'M', 'e'), (0x2131, 'M', 'f'), (0x2132, 'X'), (0x2133, 'M', 'm'), (0x2134, 'M', 'o'), (0x2135, 'M', 'א'), (0x2136, 'M', 'ב'), (0x2137, 'M', 'ג'), (0x2138, 'M', 'ד'), (0x2139, 'M', 'i'), (0x213A, 'V'), (0x213B, 'M', 'fax'), (0x213C, 'M', 'π'), (0x213D, 'M', 'γ'), (0x213F, 'M', 'π'), (0x2140, 'M', '∑'), (0x2141, 'V'), (0x2145, 'M', 'd'), (0x2147, 'M', 'e'), (0x2148, 'M', 'i'), (0x2149, 'M', 'j'), (0x214A, 'V'), (0x2150, 'M', '1⁄7'), (0x2151, 'M', '1⁄9'), (0x2152, 'M', '1⁄10'), (0x2153, 'M', '1⁄3'), (0x2154, 'M', '2⁄3'), (0x2155, 'M', '1⁄5'), (0x2156, 'M', '2⁄5'), (0x2157, 'M', '3⁄5'), (0x2158, 'M', '4⁄5'), (0x2159, 'M', '1⁄6'), (0x215A, 'M', '5⁄6'), (0x215B, 'M', '1⁄8'), (0x215C, 'M', '3⁄8'), (0x215D, 'M', '5⁄8'), (0x215E, 'M', '7⁄8'), (0x215F, 'M', '1⁄'), (0x2160, 'M', 'i'), (0x2161, 'M', 'ii'), (0x2162, 'M', 'iii'), (0x2163, 'M', 'iv'), (0x2164, 'M', 'v'), (0x2165, 'M', 'vi'), (0x2166, 'M', 'vii'), (0x2167, 'M', 'viii'), (0x2168, 'M', 'ix'), (0x2169, 'M', 'x'), (0x216A, 'M', 'xi'), (0x216B, 'M', 'xii'), (0x216C, 'M', 'l'), (0x216D, 'M', 'c'), (0x216E, 'M', 'd'), (0x216F, 'M', 'm'), (0x2170, 'M', 'i'), (0x2171, 'M', 'ii'), (0x2172, 'M', 'iii'), (0x2173, 'M', 'iv'), (0x2174, 'M', 'v'), (0x2175, 'M', 'vi'), (0x2176, 'M', 'vii'), (0x2177, 'M', 'viii'), (0x2178, 'M', 'ix'), (0x2179, 'M', 'x'), ] def _seg_23(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x217A, 'M', 'xi'), (0x217B, 'M', 'xii'), (0x217C, 'M', 'l'), (0x217D, 'M', 'c'), (0x217E, 'M', 'd'), (0x217F, 'M', 'm'), (0x2180, 'V'), (0x2183, 'X'), (0x2184, 'V'), (0x2189, 'M', '0⁄3'), (0x218A, 'V'), (0x218C, 'X'), (0x2190, 'V'), (0x222C, 'M', '∫∫'), (0x222D, 'M', '∫∫∫'), (0x222E, 'V'), (0x222F, 'M', '∮∮'), (0x2230, 'M', '∮∮∮'), (0x2231, 'V'), (0x2260, '3'), (0x2261, 'V'), (0x226E, '3'), (0x2270, 'V'), (0x2329, 'M', '〈'), (0x232A, 'M', '〉'), (0x232B, 'V'), (0x2427, 'X'), (0x2440, 'V'), (0x244B, 'X'), (0x2460, 'M', '1'), (0x2461, 'M', '2'), (0x2462, 'M', '3'), (0x2463, 'M', '4'), (0x2464, 'M', '5'), (0x2465, 'M', '6'), (0x2466, 'M', '7'), (0x2467, 'M', '8'), (0x2468, 'M', '9'), (0x2469, 'M', '10'), (0x246A, 'M', '11'), (0x246B, 'M', '12'), (0x246C, 'M', '13'), (0x246D, 'M', '14'), (0x246E, 'M', '15'), (0x246F, 'M', '16'), (0x2470, 'M', '17'), (0x2471, 'M', '18'), (0x2472, 'M', '19'), (0x2473, 'M', '20'), (0x2474, '3', '(1)'), (0x2475, '3', '(2)'), (0x2476, '3', '(3)'), (0x2477, '3', '(4)'), (0x2478, '3', '(5)'), (0x2479, '3', '(6)'), (0x247A, '3', '(7)'), (0x247B, '3', '(8)'), (0x247C, '3', '(9)'), (0x247D, '3', '(10)'), (0x247E, '3', '(11)'), (0x247F, '3', '(12)'), (0x2480, '3', '(13)'), (0x2481, '3', '(14)'), (0x2482, '3', '(15)'), (0x2483, '3', '(16)'), (0x2484, '3', '(17)'), (0x2485, '3', '(18)'), (0x2486, '3', '(19)'), (0x2487, '3', '(20)'), (0x2488, 'X'), (0x249C, '3', '(a)'), (0x249D, '3', '(b)'), (0x249E, '3', '(c)'), (0x249F, '3', '(d)'), (0x24A0, '3', '(e)'), (0x24A1, '3', '(f)'), (0x24A2, '3', '(g)'), (0x24A3, '3', '(h)'), (0x24A4, '3', '(i)'), (0x24A5, '3', '(j)'), (0x24A6, '3', '(k)'), (0x24A7, '3', '(l)'), (0x24A8, '3', '(m)'), (0x24A9, '3', '(n)'), (0x24AA, '3', '(o)'), (0x24AB, '3', '(p)'), (0x24AC, '3', '(q)'), (0x24AD, '3', '(r)'), (0x24AE, '3', '(s)'), (0x24AF, '3', '(t)'), (0x24B0, '3', '(u)'), (0x24B1, '3', '(v)'), (0x24B2, '3', '(w)'), (0x24B3, '3', '(x)'), (0x24B4, '3', '(y)'), (0x24B5, '3', '(z)'), (0x24B6, 'M', 'a'), (0x24B7, 'M', 'b'), (0x24B8, 'M', 'c'), (0x24B9, 'M', 'd'), ] def _seg_24(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x24BA, 'M', 'e'), (0x24BB, 'M', 'f'), (0x24BC, 'M', 'g'), (0x24BD, 'M', 'h'), (0x24BE, 'M', 'i'), (0x24BF, 'M', 'j'), (0x24C0, 'M', 'k'), (0x24C1, 'M', 'l'), (0x24C2, 'M', 'm'), (0x24C3, 'M', 'n'), (0x24C4, 'M', 'o'), (0x24C5, 'M', 'p'), (0x24C6, 'M', 'q'), (0x24C7, 'M', 'r'), (0x24C8, 'M', 's'), (0x24C9, 'M', 't'), (0x24CA, 'M', 'u'), (0x24CB, 'M', 'v'), (0x24CC, 'M', 'w'), (0x24CD, 'M', 'x'), (0x24CE, 'M', 'y'), (0x24CF, 'M', 'z'), (0x24D0, 'M', 'a'), (0x24D1, 'M', 'b'), (0x24D2, 'M', 'c'), (0x24D3, 'M', 'd'), (0x24D4, 'M', 'e'), (0x24D5, 'M', 'f'), (0x24D6, 'M', 'g'), (0x24D7, 'M', 'h'), (0x24D8, 'M', 'i'), (0x24D9, 'M', 'j'), (0x24DA, 'M', 'k'), (0x24DB, 'M', 'l'), (0x24DC, 'M', 'm'), (0x24DD, 'M', 'n'), (0x24DE, 'M', 'o'), (0x24DF, 'M', 'p'), (0x24E0, 'M', 'q'), (0x24E1, 'M', 'r'), (0x24E2, 'M', 's'), (0x24E3, 'M', 't'), (0x24E4, 'M', 'u'), (0x24E5, 'M', 'v'), (0x24E6, 'M', 'w'), (0x24E7, 'M', 'x'), (0x24E8, 'M', 'y'), (0x24E9, 'M', 'z'), (0x24EA, 'M', '0'), (0x24EB, 'V'), (0x2A0C, 'M', '∫∫∫∫'), (0x2A0D, 'V'), (0x2A74, '3', '::='), (0x2A75, '3', '=='), (0x2A76, '3', '==='), (0x2A77, 'V'), (0x2ADC, 'M', '⫝̸'), (0x2ADD, 'V'), (0x2B74, 'X'), (0x2B76, 'V'), (0x2B96, 'X'), (0x2B97, 'V'), (0x2C00, 'M', 'ⰰ'), (0x2C01, 'M', 'ⰱ'), (0x2C02, 'M', 'ⰲ'), (0x2C03, 'M', 'ⰳ'), (0x2C04, 'M', 'ⰴ'), (0x2C05, 'M', 'ⰵ'), (0x2C06, 'M', 'ⰶ'), (0x2C07, 'M', 'ⰷ'), (0x2C08, 'M', 'ⰸ'), (0x2C09, 'M', 'ⰹ'), (0x2C0A, 'M', 'ⰺ'), (0x2C0B, 'M', 'ⰻ'), (0x2C0C, 'M', 'ⰼ'), (0x2C0D, 'M', 'ⰽ'), (0x2C0E, 'M', 'ⰾ'), (0x2C0F, 'M', 'ⰿ'), (0x2C10, 'M', 'ⱀ'), (0x2C11, 'M', 'ⱁ'), (0x2C12, 'M', 'ⱂ'), (0x2C13, 'M', 'ⱃ'), (0x2C14, 'M', 'ⱄ'), (0x2C15, 'M', 'ⱅ'), (0x2C16, 'M', 'ⱆ'), (0x2C17, 'M', 'ⱇ'), (0x2C18, 'M', 'ⱈ'), (0x2C19, 'M', 'ⱉ'), (0x2C1A, 'M', 'ⱊ'), (0x2C1B, 'M', 'ⱋ'), (0x2C1C, 'M', 'ⱌ'), (0x2C1D, 'M', 'ⱍ'), (0x2C1E, 'M', 'ⱎ'), (0x2C1F, 'M', 'ⱏ'), (0x2C20, 'M', 'ⱐ'), (0x2C21, 'M', 'ⱑ'), (0x2C22, 'M', 'ⱒ'), (0x2C23, 'M', 'ⱓ'), (0x2C24, 'M', 'ⱔ'), (0x2C25, 'M', 'ⱕ'), ] def _seg_25(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2C26, 'M', 'ⱖ'), (0x2C27, 'M', 'ⱗ'), (0x2C28, 'M', 'ⱘ'), (0x2C29, 'M', 'ⱙ'), (0x2C2A, 'M', 'ⱚ'), (0x2C2B, 'M', 'ⱛ'), (0x2C2C, 'M', 'ⱜ'), (0x2C2D, 'M', 'ⱝ'), (0x2C2E, 'M', 'ⱞ'), (0x2C2F, 'X'), (0x2C30, 'V'), (0x2C5F, 'X'), (0x2C60, 'M', 'ⱡ'), (0x2C61, 'V'), (0x2C62, 'M', 'ɫ'), (0x2C63, 'M', 'ᵽ'), (0x2C64, 'M', 'ɽ'), (0x2C65, 'V'), (0x2C67, 'M', 'ⱨ'), (0x2C68, 'V'), (0x2C69, 'M', 'ⱪ'), (0x2C6A, 'V'), (0x2C6B, 'M', 'ⱬ'), (0x2C6C, 'V'), (0x2C6D, 'M', 'ɑ'), (0x2C6E, 'M', 'ɱ'), (0x2C6F, 'M', 'ɐ'), (0x2C70, 'M', 'ɒ'), (0x2C71, 'V'), (0x2C72, 'M', 'ⱳ'), (0x2C73, 'V'), (0x2C75, 'M', 'ⱶ'), (0x2C76, 'V'), (0x2C7C, 'M', 'j'), (0x2C7D, 'M', 'v'), (0x2C7E, 'M', 'ȿ'), (0x2C7F, 'M', 'ɀ'), (0x2C80, 'M', 'ⲁ'), (0x2C81, 'V'), (0x2C82, 'M', 'ⲃ'), (0x2C83, 'V'), (0x2C84, 'M', 'ⲅ'), (0x2C85, 'V'), (0x2C86, 'M', 'ⲇ'), (0x2C87, 'V'), (0x2C88, 'M', 'ⲉ'), (0x2C89, 'V'), (0x2C8A, 'M', 'ⲋ'), (0x2C8B, 'V'), (0x2C8C, 'M', 'ⲍ'), (0x2C8D, 'V'), (0x2C8E, 'M', 'ⲏ'), (0x2C8F, 'V'), (0x2C90, 'M', 'ⲑ'), (0x2C91, 'V'), (0x2C92, 'M', 'ⲓ'), (0x2C93, 'V'), (0x2C94, 'M', 'ⲕ'), (0x2C95, 'V'), (0x2C96, 'M', 'ⲗ'), (0x2C97, 'V'), (0x2C98, 'M', 'ⲙ'), (0x2C99, 'V'), (0x2C9A, 'M', 'ⲛ'), (0x2C9B, 'V'), (0x2C9C, 'M', 'ⲝ'), (0x2C9D, 'V'), (0x2C9E, 'M', 'ⲟ'), (0x2C9F, 'V'), (0x2CA0, 'M', 'ⲡ'), (0x2CA1, 'V'), (0x2CA2, 'M', 'ⲣ'), (0x2CA3, 'V'), (0x2CA4, 'M', 'ⲥ'), (0x2CA5, 'V'), (0x2CA6, 'M', 'ⲧ'), (0x2CA7, 'V'), (0x2CA8, 'M', 'ⲩ'), (0x2CA9, 'V'), (0x2CAA, 'M', 'ⲫ'), (0x2CAB, 'V'), (0x2CAC, 'M', 'ⲭ'), (0x2CAD, 'V'), (0x2CAE, 'M', 'ⲯ'), (0x2CAF, 'V'), (0x2CB0, 'M', 'ⲱ'), (0x2CB1, 'V'), (0x2CB2, 'M', 'ⲳ'), (0x2CB3, 'V'), (0x2CB4, 'M', 'ⲵ'), (0x2CB5, 'V'), (0x2CB6, 'M', 'ⲷ'), (0x2CB7, 'V'), (0x2CB8, 'M', 'ⲹ'), (0x2CB9, 'V'), (0x2CBA, 'M', 'ⲻ'), (0x2CBB, 'V'), (0x2CBC, 'M', 'ⲽ'), (0x2CBD, 'V'), (0x2CBE, 'M', 'ⲿ'), ] def _seg_26(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2CBF, 'V'), (0x2CC0, 'M', 'ⳁ'), (0x2CC1, 'V'), (0x2CC2, 'M', 'ⳃ'), (0x2CC3, 'V'), (0x2CC4, 'M', 'ⳅ'), (0x2CC5, 'V'), (0x2CC6, 'M', 'ⳇ'), (0x2CC7, 'V'), (0x2CC8, 'M', 'ⳉ'), (0x2CC9, 'V'), (0x2CCA, 'M', 'ⳋ'), (0x2CCB, 'V'), (0x2CCC, 'M', 'ⳍ'), (0x2CCD, 'V'), (0x2CCE, 'M', 'ⳏ'), (0x2CCF, 'V'), (0x2CD0, 'M', 'ⳑ'), (0x2CD1, 'V'), (0x2CD2, 'M', 'ⳓ'), (0x2CD3, 'V'), (0x2CD4, 'M', 'ⳕ'), (0x2CD5, 'V'), (0x2CD6, 'M', 'ⳗ'), (0x2CD7, 'V'), (0x2CD8, 'M', 'ⳙ'), (0x2CD9, 'V'), (0x2CDA, 'M', 'ⳛ'), (0x2CDB, 'V'), (0x2CDC, 'M', 'ⳝ'), (0x2CDD, 'V'), (0x2CDE, 'M', 'ⳟ'), (0x2CDF, 'V'), (0x2CE0, 'M', 'ⳡ'), (0x2CE1, 'V'), (0x2CE2, 'M', 'ⳣ'), (0x2CE3, 'V'), (0x2CEB, 'M', 'ⳬ'), (0x2CEC, 'V'), (0x2CED, 'M', 'ⳮ'), (0x2CEE, 'V'), (0x2CF2, 'M', 'ⳳ'), (0x2CF3, 'V'), (0x2CF4, 'X'), (0x2CF9, 'V'), (0x2D26, 'X'), (0x2D27, 'V'), (0x2D28, 'X'), (0x2D2D, 'V'), (0x2D2E, 'X'), (0x2D30, 'V'), (0x2D68, 'X'), (0x2D6F, 'M', 'ⵡ'), (0x2D70, 'V'), (0x2D71, 'X'), (0x2D7F, 'V'), (0x2D97, 'X'), (0x2DA0, 'V'), (0x2DA7, 'X'), (0x2DA8, 'V'), (0x2DAF, 'X'), (0x2DB0, 'V'), (0x2DB7, 'X'), (0x2DB8, 'V'), (0x2DBF, 'X'), (0x2DC0, 'V'), (0x2DC7, 'X'), (0x2DC8, 'V'), (0x2DCF, 'X'), (0x2DD0, 'V'), (0x2DD7, 'X'), (0x2DD8, 'V'), (0x2DDF, 'X'), (0x2DE0, 'V'), (0x2E53, 'X'), (0x2E80, 'V'), (0x2E9A, 'X'), (0x2E9B, 'V'), (0x2E9F, 'M', '母'), (0x2EA0, 'V'), (0x2EF3, 'M', '龟'), (0x2EF4, 'X'), (0x2F00, 'M', '一'), (0x2F01, 'M', '丨'), (0x2F02, 'M', '丶'), (0x2F03, 'M', '丿'), (0x2F04, 'M', '乙'), (0x2F05, 'M', '亅'), (0x2F06, 'M', '二'), (0x2F07, 'M', '亠'), (0x2F08, 'M', '人'), (0x2F09, 'M', '儿'), (0x2F0A, 'M', '入'), (0x2F0B, 'M', '八'), (0x2F0C, 'M', '冂'), (0x2F0D, 'M', '冖'), (0x2F0E, 'M', '冫'), (0x2F0F, 'M', '几'), (0x2F10, 'M', '凵'), (0x2F11, 'M', '刀'), ] def _seg_27(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F12, 'M', '力'), (0x2F13, 'M', '勹'), (0x2F14, 'M', '匕'), (0x2F15, 'M', '匚'), (0x2F16, 'M', '匸'), (0x2F17, 'M', '十'), (0x2F18, 'M', '卜'), (0x2F19, 'M', '卩'), (0x2F1A, 'M', '厂'), (0x2F1B, 'M', '厶'), (0x2F1C, 'M', '又'), (0x2F1D, 'M', '口'), (0x2F1E, 'M', '囗'), (0x2F1F, 'M', '土'), (0x2F20, 'M', '士'), (0x2F21, 'M', '夂'), (0x2F22, 'M', '夊'), (0x2F23, 'M', '夕'), (0x2F24, 'M', '大'), (0x2F25, 'M', '女'), (0x2F26, 'M', '子'), (0x2F27, 'M', '宀'), (0x2F28, 'M', '寸'), (0x2F29, 'M', '小'), (0x2F2A, 'M', '尢'), (0x2F2B, 'M', '尸'), (0x2F2C, 'M', '屮'), (0x2F2D, 'M', '山'), (0x2F2E, 'M', '巛'), (0x2F2F, 'M', '工'), (0x2F30, 'M', '己'), (0x2F31, 'M', '巾'), (0x2F32, 'M', '干'), (0x2F33, 'M', '幺'), (0x2F34, 'M', '广'), (0x2F35, 'M', '廴'), (0x2F36, 'M', '廾'), (0x2F37, 'M', '弋'), (0x2F38, 'M', '弓'), (0x2F39, 'M', '彐'), (0x2F3A, 'M', '彡'), (0x2F3B, 'M', '彳'), (0x2F3C, 'M', '心'), (0x2F3D, 'M', '戈'), (0x2F3E, 'M', '戶'), (0x2F3F, 'M', '手'), (0x2F40, 'M', '支'), (0x2F41, 'M', '攴'), (0x2F42, 'M', '文'), (0x2F43, 'M', '斗'), (0x2F44, 'M', '斤'), (0x2F45, 'M', '方'), (0x2F46, 'M', '无'), (0x2F47, 'M', '日'), (0x2F48, 'M', '曰'), (0x2F49, 'M', '月'), (0x2F4A, 'M', '木'), (0x2F4B, 'M', '欠'), (0x2F4C, 'M', '止'), (0x2F4D, 'M', '歹'), (0x2F4E, 'M', '殳'), (0x2F4F, 'M', '毋'), (0x2F50, 'M', '比'), (0x2F51, 'M', '毛'), (0x2F52, 'M', '氏'), (0x2F53, 'M', '气'), (0x2F54, 'M', '水'), (0x2F55, 'M', '火'), (0x2F56, 'M', '爪'), (0x2F57, 'M', '父'), (0x2F58, 'M', '爻'), (0x2F59, 'M', '爿'), (0x2F5A, 'M', '片'), (0x2F5B, 'M', '牙'), (0x2F5C, 'M', '牛'), (0x2F5D, 'M', '犬'), (0x2F5E, 'M', '玄'), (0x2F5F, 'M', '玉'), (0x2F60, 'M', '瓜'), (0x2F61, 'M', '瓦'), (0x2F62, 'M', '甘'), (0x2F63, 'M', '生'), (0x2F64, 'M', '用'), (0x2F65, 'M', '田'), (0x2F66, 'M', '疋'), (0x2F67, 'M', '疒'), (0x2F68, 'M', '癶'), (0x2F69, 'M', '白'), (0x2F6A, 'M', '皮'), (0x2F6B, 'M', '皿'), (0x2F6C, 'M', '目'), (0x2F6D, 'M', '矛'), (0x2F6E, 'M', '矢'), (0x2F6F, 'M', '石'), (0x2F70, 'M', '示'), (0x2F71, 'M', '禸'), (0x2F72, 'M', '禾'), (0x2F73, 'M', '穴'), (0x2F74, 'M', '立'), (0x2F75, 'M', '竹'), ] def _seg_28(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F76, 'M', '米'), (0x2F77, 'M', '糸'), (0x2F78, 'M', '缶'), (0x2F79, 'M', '网'), (0x2F7A, 'M', '羊'), (0x2F7B, 'M', '羽'), (0x2F7C, 'M', '老'), (0x2F7D, 'M', '而'), (0x2F7E, 'M', '耒'), (0x2F7F, 'M', '耳'), (0x2F80, 'M', '聿'), (0x2F81, 'M', '肉'), (0x2F82, 'M', '臣'), (0x2F83, 'M', '自'), (0x2F84, 'M', '至'), (0x2F85, 'M', '臼'), (0x2F86, 'M', '舌'), (0x2F87, 'M', '舛'), (0x2F88, 'M', '舟'), (0x2F89, 'M', '艮'), (0x2F8A, 'M', '色'), (0x2F8B, 'M', '艸'), (0x2F8C, 'M', '虍'), (0x2F8D, 'M', '虫'), (0x2F8E, 'M', '血'), (0x2F8F, 'M', '行'), (0x2F90, 'M', '衣'), (0x2F91, 'M', '襾'), (0x2F92, 'M', '見'), (0x2F93, 'M', '角'), (0x2F94, 'M', '言'), (0x2F95, 'M', '谷'), (0x2F96, 'M', '豆'), (0x2F97, 'M', '豕'), (0x2F98, 'M', '豸'), (0x2F99, 'M', '貝'), (0x2F9A, 'M', '赤'), (0x2F9B, 'M', '走'), (0x2F9C, 'M', '足'), (0x2F9D, 'M', '身'), (0x2F9E, 'M', '車'), (0x2F9F, 'M', '辛'), (0x2FA0, 'M', '辰'), (0x2FA1, 'M', '辵'), (0x2FA2, 'M', '邑'), (0x2FA3, 'M', '酉'), (0x2FA4, 'M', '釆'), (0x2FA5, 'M', '里'), (0x2FA6, 'M', '金'), (0x2FA7, 'M', '長'), (0x2FA8, 'M', '門'), (0x2FA9, 'M', '阜'), (0x2FAA, 'M', '隶'), (0x2FAB, 'M', '隹'), (0x2FAC, 'M', '雨'), (0x2FAD, 'M', '靑'), (0x2FAE, 'M', '非'), (0x2FAF, 'M', '面'), (0x2FB0, 'M', '革'), (0x2FB1, 'M', '韋'), (0x2FB2, 'M', '韭'), (0x2FB3, 'M', '音'), (0x2FB4, 'M', '頁'), (0x2FB5, 'M', '風'), (0x2FB6, 'M', '飛'), (0x2FB7, 'M', '食'), (0x2FB8, 'M', '首'), (0x2FB9, 'M', '香'), (0x2FBA, 'M', '馬'), (0x2FBB, 'M', '骨'), (0x2FBC, 'M', '高'), (0x2FBD, 'M', '髟'), (0x2FBE, 'M', '鬥'), (0x2FBF, 'M', '鬯'), (0x2FC0, 'M', '鬲'), (0x2FC1, 'M', '鬼'), (0x2FC2, 'M', '魚'), (0x2FC3, 'M', '鳥'), (0x2FC4, 'M', '鹵'), (0x2FC5, 'M', '鹿'), (0x2FC6, 'M', '麥'), (0x2FC7, 'M', '麻'), (0x2FC8, 'M', '黃'), (0x2FC9, 'M', '黍'), (0x2FCA, 'M', '黑'), (0x2FCB, 'M', '黹'), (0x2FCC, 'M', '黽'), (0x2FCD, 'M', '鼎'), (0x2FCE, 'M', '鼓'), (0x2FCF, 'M', '鼠'), (0x2FD0, 'M', '鼻'), (0x2FD1, 'M', '齊'), (0x2FD2, 'M', '齒'), (0x2FD3, 'M', '龍'), (0x2FD4, 'M', '龜'), (0x2FD5, 'M', '龠'), (0x2FD6, 'X'), (0x3000, '3', ' '), (0x3001, 'V'), (0x3002, 'M', '.'), ] def _seg_29(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x3003, 'V'), (0x3036, 'M', '〒'), (0x3037, 'V'), (0x3038, 'M', '十'), (0x3039, 'M', '卄'), (0x303A, 'M', '卅'), (0x303B, 'V'), (0x3040, 'X'), (0x3041, 'V'), (0x3097, 'X'), (0x3099, 'V'), (0x309B, '3', ' ゙'), (0x309C, '3', ' ゚'), (0x309D, 'V'), (0x309F, 'M', 'より'), (0x30A0, 'V'), (0x30FF, 'M', 'コト'), (0x3100, 'X'), (0x3105, 'V'), (0x3130, 'X'), (0x3131, 'M', 'ᄀ'), (0x3132, 'M', 'ᄁ'), (0x3133, 'M', 'ᆪ'), (0x3134, 'M', 'ᄂ'), (0x3135, 'M', 'ᆬ'), (0x3136, 'M', 'ᆭ'), (0x3137, 'M', 'ᄃ'), (0x3138, 'M', 'ᄄ'), (0x3139, 'M', 'ᄅ'), (0x313A, 'M', 'ᆰ'), (0x313B, 'M', 'ᆱ'), (0x313C, 'M', 'ᆲ'), (0x313D, 'M', 'ᆳ'), (0x313E, 'M', 'ᆴ'), (0x313F, 'M', 'ᆵ'), (0x3140, 'M', 'ᄚ'), (0x3141, 'M', 'ᄆ'), (0x3142, 'M', 'ᄇ'), (0x3143, 'M', 'ᄈ'), (0x3144, 'M', 'ᄡ'), (0x3145, 'M', 'ᄉ'), (0x3146, 'M', 'ᄊ'), (0x3147, 'M', 'ᄋ'), (0x3148, 'M', 'ᄌ'), (0x3149, 'M', 'ᄍ'), (0x314A, 'M', 'ᄎ'), (0x314B, 'M', 'ᄏ'), (0x314C, 'M', 'ᄐ'), (0x314D, 'M', 'ᄑ'), (0x314E, 'M', 'ᄒ'), (0x314F, 'M', 'ᅡ'), (0x3150, 'M', 'ᅢ'), (0x3151, 'M', 'ᅣ'), (0x3152, 'M', 'ᅤ'), (0x3153, 'M', 'ᅥ'), (0x3154, 'M', 'ᅦ'), (0x3155, 'M', 'ᅧ'), (0x3156, 'M', 'ᅨ'), (0x3157, 'M', 'ᅩ'), (0x3158, 'M', 'ᅪ'), (0x3159, 'M', 'ᅫ'), (0x315A, 'M', 'ᅬ'), (0x315B, 'M', 'ᅭ'), (0x315C, 'M', 'ᅮ'), (0x315D, 'M', 'ᅯ'), (0x315E, 'M', 'ᅰ'), (0x315F, 'M', 'ᅱ'), (0x3160, 'M', 'ᅲ'), (0x3161, 'M', 'ᅳ'), (0x3162, 'M', 'ᅴ'), (0x3163, 'M', 'ᅵ'), (0x3164, 'X'), (0x3165, 'M', 'ᄔ'), (0x3166, 'M', 'ᄕ'), (0x3167, 'M', 'ᇇ'), (0x3168, 'M', 'ᇈ'), (0x3169, 'M', 'ᇌ'), (0x316A, 'M', 'ᇎ'), (0x316B, 'M', 'ᇓ'), (0x316C, 'M', 'ᇗ'), (0x316D, 'M', 'ᇙ'), (0x316E, 'M', 'ᄜ'), (0x316F, 'M', 'ᇝ'), (0x3170, 'M', 'ᇟ'), (0x3171, 'M', 'ᄝ'), (0x3172, 'M', 'ᄞ'), (0x3173, 'M', 'ᄠ'), (0x3174, 'M', 'ᄢ'), (0x3175, 'M', 'ᄣ'), (0x3176, 'M', 'ᄧ'), (0x3177, 'M', 'ᄩ'), (0x3178, 'M', 'ᄫ'), (0x3179, 'M', 'ᄬ'), (0x317A, 'M', 'ᄭ'), (0x317B, 'M', 'ᄮ'), (0x317C, 'M', 'ᄯ'), (0x317D, 'M', 'ᄲ'), (0x317E, 'M', 'ᄶ'), (0x317F, 'M', 'ᅀ'), (0x3180, 'M', 'ᅇ'), ] def _seg_30(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x3181, 'M', 'ᅌ'), (0x3182, 'M', 'ᇱ'), (0x3183, 'M', 'ᇲ'), (0x3184, 'M', 'ᅗ'), (0x3185, 'M', 'ᅘ'), (0x3186, 'M', 'ᅙ'), (0x3187, 'M', 'ᆄ'), (0x3188, 'M', 'ᆅ'), (0x3189, 'M', 'ᆈ'), (0x318A, 'M', 'ᆑ'), (0x318B, 'M', 'ᆒ'), (0x318C, 'M', 'ᆔ'), (0x318D, 'M', 'ᆞ'), (0x318E, 'M', 'ᆡ'), (0x318F, 'X'), (0x3190, 'V'), (0x3192, 'M', '一'), (0x3193, 'M', '二'), (0x3194, 'M', '三'), (0x3195, 'M', '四'), (0x3196, 'M', '上'), (0x3197, 'M', '中'), (0x3198, 'M', '下'), (0x3199, 'M', '甲'), (0x319A, 'M', '乙'), (0x319B, 'M', '丙'), (0x319C, 'M', '丁'), (0x319D, 'M', '天'), (0x319E, 'M', '地'), (0x319F, 'M', '人'), (0x31A0, 'V'), (0x31E4, 'X'), (0x31F0, 'V'), (0x3200, '3', '(ᄀ)'), (0x3201, '3', '(ᄂ)'), (0x3202, '3', '(ᄃ)'), (0x3203, '3', '(ᄅ)'), (0x3204, '3', '(ᄆ)'), (0x3205, '3', '(ᄇ)'), (0x3206, '3', '(ᄉ)'), (0x3207, '3', '(ᄋ)'), (0x3208, '3', '(ᄌ)'), (0x3209, '3', '(ᄎ)'), (0x320A, '3', '(ᄏ)'), (0x320B, '3', '(ᄐ)'), (0x320C, '3', '(ᄑ)'), (0x320D, '3', '(ᄒ)'), (0x320E, '3', '(가)'), (0x320F, '3', '(나)'), (0x3210, '3', '(다)'), (0x3211, '3', '(라)'), (0x3212, '3', '(마)'), (0x3213, '3', '(바)'), (0x3214, '3', '(사)'), (0x3215, '3', '(아)'), (0x3216, '3', '(자)'), (0x3217, '3', '(차)'), (0x3218, '3', '(카)'), (0x3219, '3', '(타)'), (0x321A, '3', '(파)'), (0x321B, '3', '(하)'), (0x321C, '3', '(주)'), (0x321D, '3', '(오전)'), (0x321E, '3', '(오후)'), (0x321F, 'X'), (0x3220, '3', '(一)'), (0x3221, '3', '(二)'), (0x3222, '3', '(三)'), (0x3223, '3', '(四)'), (0x3224, '3', '(五)'), (0x3225, '3', '(六)'), (0x3226, '3', '(七)'), (0x3227, '3', '(八)'), (0x3228, '3', '(九)'), (0x3229, '3', '(十)'), (0x322A, '3', '(月)'), (0x322B, '3', '(火)'), (0x322C, '3', '(水)'), (0x322D, '3', '(木)'), (0x322E, '3', '(金)'), (0x322F, '3', '(土)'), (0x3230, '3', '(日)'), (0x3231, '3', '(株)'), (0x3232, '3', '(有)'), (0x3233, '3', '(社)'), (0x3234, '3', '(名)'), (0x3235, '3', '(特)'), (0x3236, '3', '(財)'), (0x3237, '3', '(祝)'), (0x3238, '3', '(労)'), (0x3239, '3', '(代)'), (0x323A, '3', '(呼)'), (0x323B, '3', '(学)'), (0x323C, '3', '(監)'), (0x323D, '3', '(企)'), (0x323E, '3', '(資)'), (0x323F, '3', '(協)'), (0x3240, '3', '(祭)'), (0x3241, '3', '(休)'), (0x3242, '3', '(自)'), ] def _seg_31(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x3243, '3', '(至)'), (0x3244, 'M', '問'), (0x3245, 'M', '幼'), (0x3246, 'M', '文'), (0x3247, 'M', '箏'), (0x3248, 'V'), (0x3250, 'M', 'pte'), (0x3251, 'M', '21'), (0x3252, 'M', '22'), (0x3253, 'M', '23'), (0x3254, 'M', '24'), (0x3255, 'M', '25'), (0x3256, 'M', '26'), (0x3257, 'M', '27'), (0x3258, 'M', '28'), (0x3259, 'M', '29'), (0x325A, 'M', '30'), (0x325B, 'M', '31'), (0x325C, 'M', '32'), (0x325D, 'M', '33'), (0x325E, 'M', '34'), (0x325F, 'M', '35'), (0x3260, 'M', 'ᄀ'), (0x3261, 'M', 'ᄂ'), (0x3262, 'M', 'ᄃ'), (0x3263, 'M', 'ᄅ'), (0x3264, 'M', 'ᄆ'), (0x3265, 'M', 'ᄇ'), (0x3266, 'M', 'ᄉ'), (0x3267, 'M', 'ᄋ'), (0x3268, 'M', 'ᄌ'), (0x3269, 'M', 'ᄎ'), (0x326A, 'M', 'ᄏ'), (0x326B, 'M', 'ᄐ'), (0x326C, 'M', 'ᄑ'), (0x326D, 'M', 'ᄒ'), (0x326E, 'M', '가'), (0x326F, 'M', '나'), (0x3270, 'M', '다'), (0x3271, 'M', '라'), (0x3272, 'M', '마'), (0x3273, 'M', '바'), (0x3274, 'M', '사'), (0x3275, 'M', '아'), (0x3276, 'M', '자'), (0x3277, 'M', '차'), (0x3278, 'M', '카'), (0x3279, 'M', '타'), (0x327A, 'M', '파'), (0x327B, 'M', '하'), (0x327C, 'M', '참고'), (0x327D, 'M', '주의'), (0x327E, 'M', '우'), (0x327F, 'V'), (0x3280, 'M', '一'), (0x3281, 'M', '二'), (0x3282, 'M', '三'), (0x3283, 'M', '四'), (0x3284, 'M', '五'), (0x3285, 'M', '六'), (0x3286, 'M', '七'), (0x3287, 'M', '八'), (0x3288, 'M', '九'), (0x3289, 'M', '十'), (0x328A, 'M', '月'), (0x328B, 'M', '火'), (0x328C, 'M', '水'), (0x328D, 'M', '木'), (0x328E, 'M', '金'), (0x328F, 'M', '土'), (0x3290, 'M', '日'), (0x3291, 'M', '株'), (0x3292, 'M', '有'), (0x3293, 'M', '社'), (0x3294, 'M', '名'), (0x3295, 'M', '特'), (0x3296, 'M', '財'), (0x3297, 'M', '祝'), (0x3298, 'M', '労'), (0x3299, 'M', '秘'), (0x329A, 'M', '男'), (0x329B, 'M', '女'), (0x329C, 'M', '適'), (0x329D, 'M', '優'), (0x329E, 'M', '印'), (0x329F, 'M', '注'), (0x32A0, 'M', '項'), (0x32A1, 'M', '休'), (0x32A2, 'M', '写'), (0x32A3, 'M', '正'), (0x32A4, 'M', '上'), (0x32A5, 'M', '中'), (0x32A6, 'M', '下'), (0x32A7, 'M', '左'), (0x32A8, 'M', '右'), (0x32A9, 'M', '医'), (0x32AA, 'M', '宗'), (0x32AB, 'M', '学'), (0x32AC, 'M', '監'), (0x32AD, 'M', '企'), ] def _seg_32(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x32AE, 'M', '資'), (0x32AF, 'M', '協'), (0x32B0, 'M', '夜'), (0x32B1, 'M', '36'), (0x32B2, 'M', '37'), (0x32B3, 'M', '38'), (0x32B4, 'M', '39'), (0x32B5, 'M', '40'), (0x32B6, 'M', '41'), (0x32B7, 'M', '42'), (0x32B8, 'M', '43'), (0x32B9, 'M', '44'), (0x32BA, 'M', '45'), (0x32BB, 'M', '46'), (0x32BC, 'M', '47'), (0x32BD, 'M', '48'), (0x32BE, 'M', '49'), (0x32BF, 'M', '50'), (0x32C0, 'M', '1月'), (0x32C1, 'M', '2月'), (0x32C2, 'M', '3月'), (0x32C3, 'M', '4月'), (0x32C4, 'M', '5月'), (0x32C5, 'M', '6月'), (0x32C6, 'M', '7月'), (0x32C7, 'M', '8月'), (0x32C8, 'M', '9月'), (0x32C9, 'M', '10月'), (0x32CA, 'M', '11月'), (0x32CB, 'M', '12月'), (0x32CC, 'M', 'hg'), (0x32CD, 'M', 'erg'), (0x32CE, 'M', 'ev'), (0x32CF, 'M', 'ltd'), (0x32D0, 'M', 'ア'), (0x32D1, 'M', 'イ'), (0x32D2, 'M', 'ウ'), (0x32D3, 'M', 'エ'), (0x32D4, 'M', 'オ'), (0x32D5, 'M', 'カ'), (0x32D6, 'M', 'キ'), (0x32D7, 'M', 'ク'), (0x32D8, 'M', 'ケ'), (0x32D9, 'M', 'コ'), (0x32DA, 'M', 'サ'), (0x32DB, 'M', 'シ'), (0x32DC, 'M', 'ス'), (0x32DD, 'M', 'セ'), (0x32DE, 'M', 'ソ'), (0x32DF, 'M', 'タ'), (0x32E0, 'M', 'チ'), (0x32E1, 'M', 'ツ'), (0x32E2, 'M', 'テ'), (0x32E3, 'M', 'ト'), (0x32E4, 'M', 'ナ'), (0x32E5, 'M', 'ニ'), (0x32E6, 'M', 'ヌ'), (0x32E7, 'M', 'ネ'), (0x32E8, 'M', 'ノ'), (0x32E9, 'M', 'ハ'), (0x32EA, 'M', 'ヒ'), (0x32EB, 'M', 'フ'), (0x32EC, 'M', 'ヘ'), (0x32ED, 'M', 'ホ'), (0x32EE, 'M', 'マ'), (0x32EF, 'M', 'ミ'), (0x32F0, 'M', 'ム'), (0x32F1, 'M', 'メ'), (0x32F2, 'M', 'モ'), (0x32F3, 'M', 'ヤ'), (0x32F4, 'M', 'ユ'), (0x32F5, 'M', 'ヨ'), (0x32F6, 'M', 'ラ'), (0x32F7, 'M', 'リ'), (0x32F8, 'M', 'ル'), (0x32F9, 'M', 'レ'), (0x32FA, 'M', 'ロ'), (0x32FB, 'M', 'ワ'), (0x32FC, 'M', 'ヰ'), (0x32FD, 'M', 'ヱ'), (0x32FE, 'M', 'ヲ'), (0x32FF, 'M', '令和'), (0x3300, 'M', 'アパート'), (0x3301, 'M', 'アルファ'), (0x3302, 'M', 'アンペア'), (0x3303, 'M', 'アール'), (0x3304, 'M', 'イニング'), (0x3305, 'M', 'インチ'), (0x3306, 'M', 'ウォン'), (0x3307, 'M', 'エスクード'), (0x3308, 'M', 'エーカー'), (0x3309, 'M', 'オンス'), (0x330A, 'M', 'オーム'), (0x330B, 'M', 'カイリ'), (0x330C, 'M', 'カラット'), (0x330D, 'M', 'カロリー'), (0x330E, 'M', 'ガロン'), (0x330F, 'M', 'ガンマ'), (0x3310, 'M', 'ギガ'), (0x3311, 'M', 'ギニー'), ] def _seg_33(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x3312, 'M', 'キュリー'), (0x3313, 'M', 'ギルダー'), (0x3314, 'M', 'キロ'), (0x3315, 'M', 'キログラム'), (0x3316, 'M', 'キロメートル'), (0x3317, 'M', 'キロワット'), (0x3318, 'M', 'グラム'), (0x3319, 'M', 'グラムトン'), (0x331A, 'M', 'クルゼイロ'), (0x331B, 'M', 'クローネ'), (0x331C, 'M', 'ケース'), (0x331D, 'M', 'コルナ'), (0x331E, 'M', 'コーポ'), (0x331F, 'M', 'サイクル'), (0x3320, 'M', 'サンチーム'), (0x3321, 'M', 'シリング'), (0x3322, 'M', 'センチ'), (0x3323, 'M', 'セント'), (0x3324, 'M', 'ダース'), (0x3325, 'M', 'デシ'), (0x3326, 'M', 'ドル'), (0x3327, 'M', 'トン'), (0x3328, 'M', 'ナノ'), (0x3329, 'M', 'ノット'), (0x332A, 'M', 'ハイツ'), (0x332B, 'M', 'パーセント'), (0x332C, 'M', 'パーツ'), (0x332D, 'M', 'バーレル'), (0x332E, 'M', 'ピアストル'), (0x332F, 'M', 'ピクル'), (0x3330, 'M', 'ピコ'), (0x3331, 'M', 'ビル'), (0x3332, 'M', 'ファラッド'), (0x3333, 'M', 'フィート'), (0x3334, 'M', 'ブッシェル'), (0x3335, 'M', 'フラン'), (0x3336, 'M', 'ヘクタール'), (0x3337, 'M', 'ペソ'), (0x3338, 'M', 'ペニヒ'), (0x3339, 'M', 'ヘルツ'), (0x333A, 'M', 'ペンス'), (0x333B, 'M', 'ページ'), (0x333C, 'M', 'ベータ'), (0x333D, 'M', 'ポイント'), (0x333E, 'M', 'ボルト'), (0x333F, 'M', 'ホン'), (0x3340, 'M', 'ポンド'), (0x3341, 'M', 'ホール'), (0x3342, 'M', 'ホーン'), (0x3343, 'M', 'マイクロ'), (0x3344, 'M', 'マイル'), (0x3345, 'M', 'マッハ'), (0x3346, 'M', 'マルク'), (0x3347, 'M', 'マンション'), (0x3348, 'M', 'ミクロン'), (0x3349, 'M', 'ミリ'), (0x334A, 'M', 'ミリバール'), (0x334B, 'M', 'メガ'), (0x334C, 'M', 'メガトン'), (0x334D, 'M', 'メートル'), (0x334E, 'M', 'ヤード'), (0x334F, 'M', 'ヤール'), (0x3350, 'M', 'ユアン'), (0x3351, 'M', 'リットル'), (0x3352, 'M', 'リラ'), (0x3353, 'M', 'ルピー'), (0x3354, 'M', 'ルーブル'), (0x3355, 'M', 'レム'), (0x3356, 'M', 'レントゲン'), (0x3357, 'M', 'ワット'), (0x3358, 'M', '0点'), (0x3359, 'M', '1点'), (0x335A, 'M', '2点'), (0x335B, 'M', '3点'), (0x335C, 'M', '4点'), (0x335D, 'M', '5点'), (0x335E, 'M', '6点'), (0x335F, 'M', '7点'), (0x3360, 'M', '8点'), (0x3361, 'M', '9点'), (0x3362, 'M', '10点'), (0x3363, 'M', '11点'), (0x3364, 'M', '12点'), (0x3365, 'M', '13点'), (0x3366, 'M', '14点'), (0x3367, 'M', '15点'), (0x3368, 'M', '16点'), (0x3369, 'M', '17点'), (0x336A, 'M', '18点'), (0x336B, 'M', '19点'), (0x336C, 'M', '20点'), (0x336D, 'M', '21点'), (0x336E, 'M', '22点'), (0x336F, 'M', '23点'), (0x3370, 'M', '24点'), (0x3371, 'M', 'hpa'), (0x3372, 'M', 'da'), (0x3373, 'M', 'au'), (0x3374, 'M', 'bar'), (0x3375, 'M', 'ov'), ] def _seg_34(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x3376, 'M', 'pc'), (0x3377, 'M', 'dm'), (0x3378, 'M', 'dm2'), (0x3379, 'M', 'dm3'), (0x337A, 'M', 'iu'), (0x337B, 'M', '平成'), (0x337C, 'M', '昭和'), (0x337D, 'M', '大正'), (0x337E, 'M', '明治'), (0x337F, 'M', '株式会社'), (0x3380, 'M', 'pa'), (0x3381, 'M', 'na'), (0x3382, 'M', 'μa'), (0x3383, 'M', 'ma'), (0x3384, 'M', 'ka'), (0x3385, 'M', 'kb'), (0x3386, 'M', 'mb'), (0x3387, 'M', 'gb'), (0x3388, 'M', 'cal'), (0x3389, 'M', 'kcal'), (0x338A, 'M', 'pf'), (0x338B, 'M', 'nf'), (0x338C, 'M', 'μf'), (0x338D, 'M', 'μg'), (0x338E, 'M', 'mg'), (0x338F, 'M', 'kg'), (0x3390, 'M', 'hz'), (0x3391, 'M', 'khz'), (0x3392, 'M', 'mhz'), (0x3393, 'M', 'ghz'), (0x3394, 'M', 'thz'), (0x3395, 'M', 'μl'), (0x3396, 'M', 'ml'), (0x3397, 'M', 'dl'), (0x3398, 'M', 'kl'), (0x3399, 'M', 'fm'), (0x339A, 'M', 'nm'), (0x339B, 'M', 'μm'), (0x339C, 'M', 'mm'), (0x339D, 'M', 'cm'), (0x339E, 'M', 'km'), (0x339F, 'M', 'mm2'), (0x33A0, 'M', 'cm2'), (0x33A1, 'M', 'm2'), (0x33A2, 'M', 'km2'), (0x33A3, 'M', 'mm3'), (0x33A4, 'M', 'cm3'), (0x33A5, 'M', 'm3'), (0x33A6, 'M', 'km3'), (0x33A7, 'M', 'm∕s'), (0x33A8, 'M', 'm∕s2'), (0x33A9, 'M', 'pa'), (0x33AA, 'M', 'kpa'), (0x33AB, 'M', 'mpa'), (0x33AC, 'M', 'gpa'), (0x33AD, 'M', 'rad'), (0x33AE, 'M', 'rad∕s'), (0x33AF, 'M', 'rad∕s2'), (0x33B0, 'M', 'ps'), (0x33B1, 'M', 'ns'), (0x33B2, 'M', 'μs'), (0x33B3, 'M', 'ms'), (0x33B4, 'M', 'pv'), (0x33B5, 'M', 'nv'), (0x33B6, 'M', 'μv'), (0x33B7, 'M', 'mv'), (0x33B8, 'M', 'kv'), (0x33B9, 'M', 'mv'), (0x33BA, 'M', 'pw'), (0x33BB, 'M', 'nw'), (0x33BC, 'M', 'μw'), (0x33BD, 'M', 'mw'), (0x33BE, 'M', 'kw'), (0x33BF, 'M', 'mw'), (0x33C0, 'M', 'kω'), (0x33C1, 'M', 'mω'), (0x33C2, 'X'), (0x33C3, 'M', 'bq'), (0x33C4, 'M', 'cc'), (0x33C5, 'M', 'cd'), (0x33C6, 'M', 'c∕kg'), (0x33C7, 'X'), (0x33C8, 'M', 'db'), (0x33C9, 'M', 'gy'), (0x33CA, 'M', 'ha'), (0x33CB, 'M', 'hp'), (0x33CC, 'M', 'in'), (0x33CD, 'M', 'kk'), (0x33CE, 'M', 'km'), (0x33CF, 'M', 'kt'), (0x33D0, 'M', 'lm'), (0x33D1, 'M', 'ln'), (0x33D2, 'M', 'log'), (0x33D3, 'M', 'lx'), (0x33D4, 'M', 'mb'), (0x33D5, 'M', 'mil'), (0x33D6, 'M', 'mol'), (0x33D7, 'M', 'ph'), (0x33D8, 'X'), (0x33D9, 'M', 'ppm'), ] def _seg_35(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x33DA, 'M', 'pr'), (0x33DB, 'M', 'sr'), (0x33DC, 'M', 'sv'), (0x33DD, 'M', 'wb'), (0x33DE, 'M', 'v∕m'), (0x33DF, 'M', 'a∕m'), (0x33E0, 'M', '1日'), (0x33E1, 'M', '2日'), (0x33E2, 'M', '3日'), (0x33E3, 'M', '4日'), (0x33E4, 'M', '5日'), (0x33E5, 'M', '6日'), (0x33E6, 'M', '7日'), (0x33E7, 'M', '8日'), (0x33E8, 'M', '9日'), (0x33E9, 'M', '10日'), (0x33EA, 'M', '11日'), (0x33EB, 'M', '12日'), (0x33EC, 'M', '13日'), (0x33ED, 'M', '14日'), (0x33EE, 'M', '15日'), (0x33EF, 'M', '16日'), (0x33F0, 'M', '17日'), (0x33F1, 'M', '18日'), (0x33F2, 'M', '19日'), (0x33F3, 'M', '20日'), (0x33F4, 'M', '21日'), (0x33F5, 'M', '22日'), (0x33F6, 'M', '23日'), (0x33F7, 'M', '24日'), (0x33F8, 'M', '25日'), (0x33F9, 'M', '26日'), (0x33FA, 'M', '27日'), (0x33FB, 'M', '28日'), (0x33FC, 'M', '29日'), (0x33FD, 'M', '30日'), (0x33FE, 'M', '31日'), (0x33FF, 'M', 'gal'), (0x3400, 'V'), (0x9FFD, 'X'), (0xA000, 'V'), (0xA48D, 'X'), (0xA490, 'V'), (0xA4C7, 'X'), (0xA4D0, 'V'), (0xA62C, 'X'), (0xA640, 'M', 'ꙁ'), (0xA641, 'V'), (0xA642, 'M', 'ꙃ'), (0xA643, 'V'), (0xA644, 'M', 'ꙅ'), (0xA645, 'V'), (0xA646, 'M', 'ꙇ'), (0xA647, 'V'), (0xA648, 'M', 'ꙉ'), (0xA649, 'V'), (0xA64A, 'M', 'ꙋ'), (0xA64B, 'V'), (0xA64C, 'M', 'ꙍ'), (0xA64D, 'V'), (0xA64E, 'M', 'ꙏ'), (0xA64F, 'V'), (0xA650, 'M', 'ꙑ'), (0xA651, 'V'), (0xA652, 'M', 'ꙓ'), (0xA653, 'V'), (0xA654, 'M', 'ꙕ'), (0xA655, 'V'), (0xA656, 'M', 'ꙗ'), (0xA657, 'V'), (0xA658, 'M', 'ꙙ'), (0xA659, 'V'), (0xA65A, 'M', 'ꙛ'), (0xA65B, 'V'), (0xA65C, 'M', 'ꙝ'), (0xA65D, 'V'), (0xA65E, 'M', 'ꙟ'), (0xA65F, 'V'), (0xA660, 'M', 'ꙡ'), (0xA661, 'V'), (0xA662, 'M', 'ꙣ'), (0xA663, 'V'), (0xA664, 'M', 'ꙥ'), (0xA665, 'V'), (0xA666, 'M', 'ꙧ'), (0xA667, 'V'), (0xA668, 'M', 'ꙩ'), (0xA669, 'V'), (0xA66A, 'M', 'ꙫ'), (0xA66B, 'V'), (0xA66C, 'M', 'ꙭ'), (0xA66D, 'V'), (0xA680, 'M', 'ꚁ'), (0xA681, 'V'), (0xA682, 'M', 'ꚃ'), (0xA683, 'V'), (0xA684, 'M', 'ꚅ'), (0xA685, 'V'), (0xA686, 'M', 'ꚇ'), (0xA687, 'V'), ] def _seg_36(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xA688, 'M', 'ꚉ'), (0xA689, 'V'), (0xA68A, 'M', 'ꚋ'), (0xA68B, 'V'), (0xA68C, 'M', 'ꚍ'), (0xA68D, 'V'), (0xA68E, 'M', 'ꚏ'), (0xA68F, 'V'), (0xA690, 'M', 'ꚑ'), (0xA691, 'V'), (0xA692, 'M', 'ꚓ'), (0xA693, 'V'), (0xA694, 'M', 'ꚕ'), (0xA695, 'V'), (0xA696, 'M', 'ꚗ'), (0xA697, 'V'), (0xA698, 'M', 'ꚙ'), (0xA699, 'V'), (0xA69A, 'M', 'ꚛ'), (0xA69B, 'V'), (0xA69C, 'M', 'ъ'), (0xA69D, 'M', 'ь'), (0xA69E, 'V'), (0xA6F8, 'X'), (0xA700, 'V'), (0xA722, 'M', 'ꜣ'), (0xA723, 'V'), (0xA724, 'M', 'ꜥ'), (0xA725, 'V'), (0xA726, 'M', 'ꜧ'), (0xA727, 'V'), (0xA728, 'M', 'ꜩ'), (0xA729, 'V'), (0xA72A, 'M', 'ꜫ'), (0xA72B, 'V'), (0xA72C, 'M', 'ꜭ'), (0xA72D, 'V'), (0xA72E, 'M', 'ꜯ'), (0xA72F, 'V'), (0xA732, 'M', 'ꜳ'), (0xA733, 'V'), (0xA734, 'M', 'ꜵ'), (0xA735, 'V'), (0xA736, 'M', 'ꜷ'), (0xA737, 'V'), (0xA738, 'M', 'ꜹ'), (0xA739, 'V'), (0xA73A, 'M', 'ꜻ'), (0xA73B, 'V'), (0xA73C, 'M', 'ꜽ'), (0xA73D, 'V'), (0xA73E, 'M', 'ꜿ'), (0xA73F, 'V'), (0xA740, 'M', 'ꝁ'), (0xA741, 'V'), (0xA742, 'M', 'ꝃ'), (0xA743, 'V'), (0xA744, 'M', 'ꝅ'), (0xA745, 'V'), (0xA746, 'M', 'ꝇ'), (0xA747, 'V'), (0xA748, 'M', 'ꝉ'), (0xA749, 'V'), (0xA74A, 'M', 'ꝋ'), (0xA74B, 'V'), (0xA74C, 'M', 'ꝍ'), (0xA74D, 'V'), (0xA74E, 'M', 'ꝏ'), (0xA74F, 'V'), (0xA750, 'M', 'ꝑ'), (0xA751, 'V'), (0xA752, 'M', 'ꝓ'), (0xA753, 'V'), (0xA754, 'M', 'ꝕ'), (0xA755, 'V'), (0xA756, 'M', 'ꝗ'), (0xA757, 'V'), (0xA758, 'M', 'ꝙ'), (0xA759, 'V'), (0xA75A, 'M', 'ꝛ'), (0xA75B, 'V'), (0xA75C, 'M', 'ꝝ'), (0xA75D, 'V'), (0xA75E, 'M', 'ꝟ'), (0xA75F, 'V'), (0xA760, 'M', 'ꝡ'), (0xA761, 'V'), (0xA762, 'M', 'ꝣ'), (0xA763, 'V'), (0xA764, 'M', 'ꝥ'), (0xA765, 'V'), (0xA766, 'M', 'ꝧ'), (0xA767, 'V'), (0xA768, 'M', 'ꝩ'), (0xA769, 'V'), (0xA76A, 'M', 'ꝫ'), (0xA76B, 'V'), (0xA76C, 'M', 'ꝭ'), (0xA76D, 'V'), (0xA76E, 'M', 'ꝯ'), ] def _seg_37(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xA76F, 'V'), (0xA770, 'M', 'ꝯ'), (0xA771, 'V'), (0xA779, 'M', 'ꝺ'), (0xA77A, 'V'), (0xA77B, 'M', 'ꝼ'), (0xA77C, 'V'), (0xA77D, 'M', 'ᵹ'), (0xA77E, 'M', 'ꝿ'), (0xA77F, 'V'), (0xA780, 'M', 'ꞁ'), (0xA781, 'V'), (0xA782, 'M', 'ꞃ'), (0xA783, 'V'), (0xA784, 'M', 'ꞅ'), (0xA785, 'V'), (0xA786, 'M', 'ꞇ'), (0xA787, 'V'), (0xA78B, 'M', 'ꞌ'), (0xA78C, 'V'), (0xA78D, 'M', 'ɥ'), (0xA78E, 'V'), (0xA790, 'M', 'ꞑ'), (0xA791, 'V'), (0xA792, 'M', 'ꞓ'), (0xA793, 'V'), (0xA796, 'M', 'ꞗ'), (0xA797, 'V'), (0xA798, 'M', 'ꞙ'), (0xA799, 'V'), (0xA79A, 'M', 'ꞛ'), (0xA79B, 'V'), (0xA79C, 'M', 'ꞝ'), (0xA79D, 'V'), (0xA79E, 'M', 'ꞟ'), (0xA79F, 'V'), (0xA7A0, 'M', 'ꞡ'), (0xA7A1, 'V'), (0xA7A2, 'M', 'ꞣ'), (0xA7A3, 'V'), (0xA7A4, 'M', 'ꞥ'), (0xA7A5, 'V'), (0xA7A6, 'M', 'ꞧ'), (0xA7A7, 'V'), (0xA7A8, 'M', 'ꞩ'), (0xA7A9, 'V'), (0xA7AA, 'M', 'ɦ'), (0xA7AB, 'M', 'ɜ'), (0xA7AC, 'M', 'ɡ'), (0xA7AD, 'M', 'ɬ'), (0xA7AE, 'M', 'ɪ'), (0xA7AF, 'V'), (0xA7B0, 'M', 'ʞ'), (0xA7B1, 'M', 'ʇ'), (0xA7B2, 'M', 'ʝ'), (0xA7B3, 'M', 'ꭓ'), (0xA7B4, 'M', 'ꞵ'), (0xA7B5, 'V'), (0xA7B6, 'M', 'ꞷ'), (0xA7B7, 'V'), (0xA7B8, 'M', 'ꞹ'), (0xA7B9, 'V'), (0xA7BA, 'M', 'ꞻ'), (0xA7BB, 'V'), (0xA7BC, 'M', 'ꞽ'), (0xA7BD, 'V'), (0xA7BE, 'M', 'ꞿ'), (0xA7BF, 'V'), (0xA7C0, 'X'), (0xA7C2, 'M', 'ꟃ'), (0xA7C3, 'V'), (0xA7C4, 'M', 'ꞔ'), (0xA7C5, 'M', 'ʂ'), (0xA7C6, 'M', 'ᶎ'), (0xA7C7, 'M', 'ꟈ'), (0xA7C8, 'V'), (0xA7C9, 'M', 'ꟊ'), (0xA7CA, 'V'), (0xA7CB, 'X'), (0xA7F5, 'M', 'ꟶ'), (0xA7F6, 'V'), (0xA7F8, 'M', 'ħ'), (0xA7F9, 'M', 'œ'), (0xA7FA, 'V'), (0xA82D, 'X'), (0xA830, 'V'), (0xA83A, 'X'), (0xA840, 'V'), (0xA878, 'X'), (0xA880, 'V'), (0xA8C6, 'X'), (0xA8CE, 'V'), (0xA8DA, 'X'), (0xA8E0, 'V'), (0xA954, 'X'), (0xA95F, 'V'), (0xA97D, 'X'), (0xA980, 'V'), (0xA9CE, 'X'), (0xA9CF, 'V'), ] def _seg_38(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xA9DA, 'X'), (0xA9DE, 'V'), (0xA9FF, 'X'), (0xAA00, 'V'), (0xAA37, 'X'), (0xAA40, 'V'), (0xAA4E, 'X'), (0xAA50, 'V'), (0xAA5A, 'X'), (0xAA5C, 'V'), (0xAAC3, 'X'), (0xAADB, 'V'), (0xAAF7, 'X'), (0xAB01, 'V'), (0xAB07, 'X'), (0xAB09, 'V'), (0xAB0F, 'X'), (0xAB11, 'V'), (0xAB17, 'X'), (0xAB20, 'V'), (0xAB27, 'X'), (0xAB28, 'V'), (0xAB2F, 'X'), (0xAB30, 'V'), (0xAB5C, 'M', 'ꜧ'), (0xAB5D, 'M', 'ꬷ'), (0xAB5E, 'M', 'ɫ'), (0xAB5F, 'M', 'ꭒ'), (0xAB60, 'V'), (0xAB69, 'M', 'ʍ'), (0xAB6A, 'V'), (0xAB6C, 'X'), (0xAB70, 'M', 'Ꭰ'), (0xAB71, 'M', 'Ꭱ'), (0xAB72, 'M', 'Ꭲ'), (0xAB73, 'M', 'Ꭳ'), (0xAB74, 'M', 'Ꭴ'), (0xAB75, 'M', 'Ꭵ'), (0xAB76, 'M', 'Ꭶ'), (0xAB77, 'M', 'Ꭷ'), (0xAB78, 'M', 'Ꭸ'), (0xAB79, 'M', 'Ꭹ'), (0xAB7A, 'M', 'Ꭺ'), (0xAB7B, 'M', 'Ꭻ'), (0xAB7C, 'M', 'Ꭼ'), (0xAB7D, 'M', 'Ꭽ'), (0xAB7E, 'M', 'Ꭾ'), (0xAB7F, 'M', 'Ꭿ'), (0xAB80, 'M', 'Ꮀ'), (0xAB81, 'M', 'Ꮁ'), (0xAB82, 'M', 'Ꮂ'), (0xAB83, 'M', 'Ꮃ'), (0xAB84, 'M', 'Ꮄ'), (0xAB85, 'M', 'Ꮅ'), (0xAB86, 'M', 'Ꮆ'), (0xAB87, 'M', 'Ꮇ'), (0xAB88, 'M', 'Ꮈ'), (0xAB89, 'M', 'Ꮉ'), (0xAB8A, 'M', 'Ꮊ'), (0xAB8B, 'M', 'Ꮋ'), (0xAB8C, 'M', 'Ꮌ'), (0xAB8D, 'M', 'Ꮍ'), (0xAB8E, 'M', 'Ꮎ'), (0xAB8F, 'M', 'Ꮏ'), (0xAB90, 'M', 'Ꮐ'), (0xAB91, 'M', 'Ꮑ'), (0xAB92, 'M', 'Ꮒ'), (0xAB93, 'M', 'Ꮓ'), (0xAB94, 'M', 'Ꮔ'), (0xAB95, 'M', 'Ꮕ'), (0xAB96, 'M', 'Ꮖ'), (0xAB97, 'M', 'Ꮗ'), (0xAB98, 'M', 'Ꮘ'), (0xAB99, 'M', 'Ꮙ'), (0xAB9A, 'M', 'Ꮚ'), (0xAB9B, 'M', 'Ꮛ'), (0xAB9C, 'M', 'Ꮜ'), (0xAB9D, 'M', 'Ꮝ'), (0xAB9E, 'M', 'Ꮞ'), (0xAB9F, 'M', 'Ꮟ'), (0xABA0, 'M', 'Ꮠ'), (0xABA1, 'M', 'Ꮡ'), (0xABA2, 'M', 'Ꮢ'), (0xABA3, 'M', 'Ꮣ'), (0xABA4, 'M', 'Ꮤ'), (0xABA5, 'M', 'Ꮥ'), (0xABA6, 'M', 'Ꮦ'), (0xABA7, 'M', 'Ꮧ'), (0xABA8, 'M', 'Ꮨ'), (0xABA9, 'M', 'Ꮩ'), (0xABAA, 'M', 'Ꮪ'), (0xABAB, 'M', 'Ꮫ'), (0xABAC, 'M', 'Ꮬ'), (0xABAD, 'M', 'Ꮭ'), (0xABAE, 'M', 'Ꮮ'), (0xABAF, 'M', 'Ꮯ'), (0xABB0, 'M', 'Ꮰ'), (0xABB1, 'M', 'Ꮱ'), (0xABB2, 'M', 'Ꮲ'), (0xABB3, 'M', 'Ꮳ'), ] def _seg_39(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xABB4, 'M', 'Ꮴ'), (0xABB5, 'M', 'Ꮵ'), (0xABB6, 'M', 'Ꮶ'), (0xABB7, 'M', 'Ꮷ'), (0xABB8, 'M', 'Ꮸ'), (0xABB9, 'M', 'Ꮹ'), (0xABBA, 'M', 'Ꮺ'), (0xABBB, 'M', 'Ꮻ'), (0xABBC, 'M', 'Ꮼ'), (0xABBD, 'M', 'Ꮽ'), (0xABBE, 'M', 'Ꮾ'), (0xABBF, 'M', 'Ꮿ'), (0xABC0, 'V'), (0xABEE, 'X'), (0xABF0, 'V'), (0xABFA, 'X'), (0xAC00, 'V'), (0xD7A4, 'X'), (0xD7B0, 'V'), (0xD7C7, 'X'), (0xD7CB, 'V'), (0xD7FC, 'X'), (0xF900, 'M', '豈'), (0xF901, 'M', '更'), (0xF902, 'M', '車'), (0xF903, 'M', '賈'), (0xF904, 'M', '滑'), (0xF905, 'M', '串'), (0xF906, 'M', '句'), (0xF907, 'M', '龜'), (0xF909, 'M', '契'), (0xF90A, 'M', '金'), (0xF90B, 'M', '喇'), (0xF90C, 'M', '奈'), (0xF90D, 'M', '懶'), (0xF90E, 'M', '癩'), (0xF90F, 'M', '羅'), (0xF910, 'M', '蘿'), (0xF911, 'M', '螺'), (0xF912, 'M', '裸'), (0xF913, 'M', '邏'), (0xF914, 'M', '樂'), (0xF915, 'M', '洛'), (0xF916, 'M', '烙'), (0xF917, 'M', '珞'), (0xF918, 'M', '落'), (0xF919, 'M', '酪'), (0xF91A, 'M', '駱'), (0xF91B, 'M', '亂'), (0xF91C, 'M', '卵'), (0xF91D, 'M', '欄'), (0xF91E, 'M', '爛'), (0xF91F, 'M', '蘭'), (0xF920, 'M', '鸞'), (0xF921, 'M', '嵐'), (0xF922, 'M', '濫'), (0xF923, 'M', '藍'), (0xF924, 'M', '襤'), (0xF925, 'M', '拉'), (0xF926, 'M', '臘'), (0xF927, 'M', '蠟'), (0xF928, 'M', '廊'), (0xF929, 'M', '朗'), (0xF92A, 'M', '浪'), (0xF92B, 'M', '狼'), (0xF92C, 'M', '郎'), (0xF92D, 'M', '來'), (0xF92E, 'M', '冷'), (0xF92F, 'M', '勞'), (0xF930, 'M', '擄'), (0xF931, 'M', '櫓'), (0xF932, 'M', '爐'), (0xF933, 'M', '盧'), (0xF934, 'M', '老'), (0xF935, 'M', '蘆'), (0xF936, 'M', '虜'), (0xF937, 'M', '路'), (0xF938, 'M', '露'), (0xF939, 'M', '魯'), (0xF93A, 'M', '鷺'), (0xF93B, 'M', '碌'), (0xF93C, 'M', '祿'), (0xF93D, 'M', '綠'), (0xF93E, 'M', '菉'), (0xF93F, 'M', '錄'), (0xF940, 'M', '鹿'), (0xF941, 'M', '論'), (0xF942, 'M', '壟'), (0xF943, 'M', '弄'), (0xF944, 'M', '籠'), (0xF945, 'M', '聾'), (0xF946, 'M', '牢'), (0xF947, 'M', '磊'), (0xF948, 'M', '賂'), (0xF949, 'M', '雷'), (0xF94A, 'M', '壘'), (0xF94B, 'M', '屢'), (0xF94C, 'M', '樓'), (0xF94D, 'M', '淚'), (0xF94E, 'M', '漏'), ] def _seg_40(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xF94F, 'M', '累'), (0xF950, 'M', '縷'), (0xF951, 'M', '陋'), (0xF952, 'M', '勒'), (0xF953, 'M', '肋'), (0xF954, 'M', '凜'), (0xF955, 'M', '凌'), (0xF956, 'M', '稜'), (0xF957, 'M', '綾'), (0xF958, 'M', '菱'), (0xF959, 'M', '陵'), (0xF95A, 'M', '讀'), (0xF95B, 'M', '拏'), (0xF95C, 'M', '樂'), (0xF95D, 'M', '諾'), (0xF95E, 'M', '丹'), (0xF95F, 'M', '寧'), (0xF960, 'M', '怒'), (0xF961, 'M', '率'), (0xF962, 'M', '異'), (0xF963, 'M', '北'), (0xF964, 'M', '磻'), (0xF965, 'M', '便'), (0xF966, 'M', '復'), (0xF967, 'M', '不'), (0xF968, 'M', '泌'), (0xF969, 'M', '數'), (0xF96A, 'M', '索'), (0xF96B, 'M', '參'), (0xF96C, 'M', '塞'), (0xF96D, 'M', '省'), (0xF96E, 'M', '葉'), (0xF96F, 'M', '說'), (0xF970, 'M', '殺'), (0xF971, 'M', '辰'), (0xF972, 'M', '沈'), (0xF973, 'M', '拾'), (0xF974, 'M', '若'), (0xF975, 'M', '掠'), (0xF976, 'M', '略'), (0xF977, 'M', '亮'), (0xF978, 'M', '兩'), (0xF979, 'M', '凉'), (0xF97A, 'M', '梁'), (0xF97B, 'M', '糧'), (0xF97C, 'M', '良'), (0xF97D, 'M', '諒'), (0xF97E, 'M', '量'), (0xF97F, 'M', '勵'), (0xF980, 'M', '呂'), (0xF981, 'M', '女'), (0xF982, 'M', '廬'), (0xF983, 'M', '旅'), (0xF984, 'M', '濾'), (0xF985, 'M', '礪'), (0xF986, 'M', '閭'), (0xF987, 'M', '驪'), (0xF988, 'M', '麗'), (0xF989, 'M', '黎'), (0xF98A, 'M', '力'), (0xF98B, 'M', '曆'), (0xF98C, 'M', '歷'), (0xF98D, 'M', '轢'), (0xF98E, 'M', '年'), (0xF98F, 'M', '憐'), (0xF990, 'M', '戀'), (0xF991, 'M', '撚'), (0xF992, 'M', '漣'), (0xF993, 'M', '煉'), (0xF994, 'M', '璉'), (0xF995, 'M', '秊'), (0xF996, 'M', '練'), (0xF997, 'M', '聯'), (0xF998, 'M', '輦'), (0xF999, 'M', '蓮'), (0xF99A, 'M', '連'), (0xF99B, 'M', '鍊'), (0xF99C, 'M', '列'), (0xF99D, 'M', '劣'), (0xF99E, 'M', '咽'), (0xF99F, 'M', '烈'), (0xF9A0, 'M', '裂'), (0xF9A1, 'M', '說'), (0xF9A2, 'M', '廉'), (0xF9A3, 'M', '念'), (0xF9A4, 'M', '捻'), (0xF9A5, 'M', '殮'), (0xF9A6, 'M', '簾'), (0xF9A7, 'M', '獵'), (0xF9A8, 'M', '令'), (0xF9A9, 'M', '囹'), (0xF9AA, 'M', '寧'), (0xF9AB, 'M', '嶺'), (0xF9AC, 'M', '怜'), (0xF9AD, 'M', '玲'), (0xF9AE, 'M', '瑩'), (0xF9AF, 'M', '羚'), (0xF9B0, 'M', '聆'), (0xF9B1, 'M', '鈴'), (0xF9B2, 'M', '零'), ] def _seg_41(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xF9B3, 'M', '靈'), (0xF9B4, 'M', '領'), (0xF9B5, 'M', '例'), (0xF9B6, 'M', '禮'), (0xF9B7, 'M', '醴'), (0xF9B8, 'M', '隸'), (0xF9B9, 'M', '惡'), (0xF9BA, 'M', '了'), (0xF9BB, 'M', '僚'), (0xF9BC, 'M', '寮'), (0xF9BD, 'M', '尿'), (0xF9BE, 'M', '料'), (0xF9BF, 'M', '樂'), (0xF9C0, 'M', '燎'), (0xF9C1, 'M', '療'), (0xF9C2, 'M', '蓼'), (0xF9C3, 'M', '遼'), (0xF9C4, 'M', '龍'), (0xF9C5, 'M', '暈'), (0xF9C6, 'M', '阮'), (0xF9C7, 'M', '劉'), (0xF9C8, 'M', '杻'), (0xF9C9, 'M', '柳'), (0xF9CA, 'M', '流'), (0xF9CB, 'M', '溜'), (0xF9CC, 'M', '琉'), (0xF9CD, 'M', '留'), (0xF9CE, 'M', '硫'), (0xF9CF, 'M', '紐'), (0xF9D0, 'M', '類'), (0xF9D1, 'M', '六'), (0xF9D2, 'M', '戮'), (0xF9D3, 'M', '陸'), (0xF9D4, 'M', '倫'), (0xF9D5, 'M', '崙'), (0xF9D6, 'M', '淪'), (0xF9D7, 'M', '輪'), (0xF9D8, 'M', '律'), (0xF9D9, 'M', '慄'), (0xF9DA, 'M', '栗'), (0xF9DB, 'M', '率'), (0xF9DC, 'M', '隆'), (0xF9DD, 'M', '利'), (0xF9DE, 'M', '吏'), (0xF9DF, 'M', '履'), (0xF9E0, 'M', '易'), (0xF9E1, 'M', '李'), (0xF9E2, 'M', '梨'), (0xF9E3, 'M', '泥'), (0xF9E4, 'M', '理'), (0xF9E5, 'M', '痢'), (0xF9E6, 'M', '罹'), (0xF9E7, 'M', '裏'), (0xF9E8, 'M', '裡'), (0xF9E9, 'M', '里'), (0xF9EA, 'M', '離'), (0xF9EB, 'M', '匿'), (0xF9EC, 'M', '溺'), (0xF9ED, 'M', '吝'), (0xF9EE, 'M', '燐'), (0xF9EF, 'M', '璘'), (0xF9F0, 'M', '藺'), (0xF9F1, 'M', '隣'), (0xF9F2, 'M', '鱗'), (0xF9F3, 'M', '麟'), (0xF9F4, 'M', '林'), (0xF9F5, 'M', '淋'), (0xF9F6, 'M', '臨'), (0xF9F7, 'M', '立'), (0xF9F8, 'M', '笠'), (0xF9F9, 'M', '粒'), (0xF9FA, 'M', '狀'), (0xF9FB, 'M', '炙'), (0xF9FC, 'M', '識'), (0xF9FD, 'M', '什'), (0xF9FE, 'M', '茶'), (0xF9FF, 'M', '刺'), (0xFA00, 'M', '切'), (0xFA01, 'M', '度'), (0xFA02, 'M', '拓'), (0xFA03, 'M', '糖'), (0xFA04, 'M', '宅'), (0xFA05, 'M', '洞'), (0xFA06, 'M', '暴'), (0xFA07, 'M', '輻'), (0xFA08, 'M', '行'), (0xFA09, 'M', '降'), (0xFA0A, 'M', '見'), (0xFA0B, 'M', '廓'), (0xFA0C, 'M', '兀'), (0xFA0D, 'M', '嗀'), (0xFA0E, 'V'), (0xFA10, 'M', '塚'), (0xFA11, 'V'), (0xFA12, 'M', '晴'), (0xFA13, 'V'), (0xFA15, 'M', '凞'), (0xFA16, 'M', '猪'), (0xFA17, 'M', '益'), (0xFA18, 'M', '礼'), ] def _seg_42(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFA19, 'M', '神'), (0xFA1A, 'M', '祥'), (0xFA1B, 'M', '福'), (0xFA1C, 'M', '靖'), (0xFA1D, 'M', '精'), (0xFA1E, 'M', '羽'), (0xFA1F, 'V'), (0xFA20, 'M', '蘒'), (0xFA21, 'V'), (0xFA22, 'M', '諸'), (0xFA23, 'V'), (0xFA25, 'M', '逸'), (0xFA26, 'M', '都'), (0xFA27, 'V'), (0xFA2A, 'M', '飯'), (0xFA2B, 'M', '飼'), (0xFA2C, 'M', '館'), (0xFA2D, 'M', '鶴'), (0xFA2E, 'M', '郞'), (0xFA2F, 'M', '隷'), (0xFA30, 'M', '侮'), (0xFA31, 'M', '僧'), (0xFA32, 'M', '免'), (0xFA33, 'M', '勉'), (0xFA34, 'M', '勤'), (0xFA35, 'M', '卑'), (0xFA36, 'M', '喝'), (0xFA37, 'M', '嘆'), (0xFA38, 'M', '器'), (0xFA39, 'M', '塀'), (0xFA3A, 'M', '墨'), (0xFA3B, 'M', '層'), (0xFA3C, 'M', '屮'), (0xFA3D, 'M', '悔'), (0xFA3E, 'M', '慨'), (0xFA3F, 'M', '憎'), (0xFA40, 'M', '懲'), (0xFA41, 'M', '敏'), (0xFA42, 'M', '既'), (0xFA43, 'M', '暑'), (0xFA44, 'M', '梅'), (0xFA45, 'M', '海'), (0xFA46, 'M', '渚'), (0xFA47, 'M', '漢'), (0xFA48, 'M', '煮'), (0xFA49, 'M', '爫'), (0xFA4A, 'M', '琢'), (0xFA4B, 'M', '碑'), (0xFA4C, 'M', '社'), (0xFA4D, 'M', '祉'), (0xFA4E, 'M', '祈'), (0xFA4F, 'M', '祐'), (0xFA50, 'M', '祖'), (0xFA51, 'M', '祝'), (0xFA52, 'M', '禍'), (0xFA53, 'M', '禎'), (0xFA54, 'M', '穀'), (0xFA55, 'M', '突'), (0xFA56, 'M', '節'), (0xFA57, 'M', '練'), (0xFA58, 'M', '縉'), (0xFA59, 'M', '繁'), (0xFA5A, 'M', '署'), (0xFA5B, 'M', '者'), (0xFA5C, 'M', '臭'), (0xFA5D, 'M', '艹'), (0xFA5F, 'M', '著'), (0xFA60, 'M', '褐'), (0xFA61, 'M', '視'), (0xFA62, 'M', '謁'), (0xFA63, 'M', '謹'), (0xFA64, 'M', '賓'), (0xFA65, 'M', '贈'), (0xFA66, 'M', '辶'), (0xFA67, 'M', '逸'), (0xFA68, 'M', '難'), (0xFA69, 'M', '響'), (0xFA6A, 'M', '頻'), (0xFA6B, 'M', '恵'), (0xFA6C, 'M', '𤋮'), (0xFA6D, 'M', '舘'), (0xFA6E, 'X'), (0xFA70, 'M', '並'), (0xFA71, 'M', '况'), (0xFA72, 'M', '全'), (0xFA73, 'M', '侀'), (0xFA74, 'M', '充'), (0xFA75, 'M', '冀'), (0xFA76, 'M', '勇'), (0xFA77, 'M', '勺'), (0xFA78, 'M', '喝'), (0xFA79, 'M', '啕'), (0xFA7A, 'M', '喙'), (0xFA7B, 'M', '嗢'), (0xFA7C, 'M', '塚'), (0xFA7D, 'M', '墳'), (0xFA7E, 'M', '奄'), (0xFA7F, 'M', '奔'), (0xFA80, 'M', '婢'), (0xFA81, 'M', '嬨'), ] def _seg_43(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFA82, 'M', '廒'), (0xFA83, 'M', '廙'), (0xFA84, 'M', '彩'), (0xFA85, 'M', '徭'), (0xFA86, 'M', '惘'), (0xFA87, 'M', '慎'), (0xFA88, 'M', '愈'), (0xFA89, 'M', '憎'), (0xFA8A, 'M', '慠'), (0xFA8B, 'M', '懲'), (0xFA8C, 'M', '戴'), (0xFA8D, 'M', '揄'), (0xFA8E, 'M', '搜'), (0xFA8F, 'M', '摒'), (0xFA90, 'M', '敖'), (0xFA91, 'M', '晴'), (0xFA92, 'M', '朗'), (0xFA93, 'M', '望'), (0xFA94, 'M', '杖'), (0xFA95, 'M', '歹'), (0xFA96, 'M', '殺'), (0xFA97, 'M', '流'), (0xFA98, 'M', '滛'), (0xFA99, 'M', '滋'), (0xFA9A, 'M', '漢'), (0xFA9B, 'M', '瀞'), (0xFA9C, 'M', '煮'), (0xFA9D, 'M', '瞧'), (0xFA9E, 'M', '爵'), (0xFA9F, 'M', '犯'), (0xFAA0, 'M', '猪'), (0xFAA1, 'M', '瑱'), (0xFAA2, 'M', '甆'), (0xFAA3, 'M', '画'), (0xFAA4, 'M', '瘝'), (0xFAA5, 'M', '瘟'), (0xFAA6, 'M', '益'), (0xFAA7, 'M', '盛'), (0xFAA8, 'M', '直'), (0xFAA9, 'M', '睊'), (0xFAAA, 'M', '着'), (0xFAAB, 'M', '磌'), (0xFAAC, 'M', '窱'), (0xFAAD, 'M', '節'), (0xFAAE, 'M', '类'), (0xFAAF, 'M', '絛'), (0xFAB0, 'M', '練'), (0xFAB1, 'M', '缾'), (0xFAB2, 'M', '者'), (0xFAB3, 'M', '荒'), (0xFAB4, 'M', '華'), (0xFAB5, 'M', '蝹'), (0xFAB6, 'M', '襁'), (0xFAB7, 'M', '覆'), (0xFAB8, 'M', '視'), (0xFAB9, 'M', '調'), (0xFABA, 'M', '諸'), (0xFABB, 'M', '請'), (0xFABC, 'M', '謁'), (0xFABD, 'M', '諾'), (0xFABE, 'M', '諭'), (0xFABF, 'M', '謹'), (0xFAC0, 'M', '變'), (0xFAC1, 'M', '贈'), (0xFAC2, 'M', '輸'), (0xFAC3, 'M', '遲'), (0xFAC4, 'M', '醙'), (0xFAC5, 'M', '鉶'), (0xFAC6, 'M', '陼'), (0xFAC7, 'M', '難'), (0xFAC8, 'M', '靖'), (0xFAC9, 'M', '韛'), (0xFACA, 'M', '響'), (0xFACB, 'M', '頋'), (0xFACC, 'M', '頻'), (0xFACD, 'M', '鬒'), (0xFACE, 'M', '龜'), (0xFACF, 'M', '𢡊'), (0xFAD0, 'M', '𢡄'), (0xFAD1, 'M', '𣏕'), (0xFAD2, 'M', '㮝'), (0xFAD3, 'M', '䀘'), (0xFAD4, 'M', '䀹'), (0xFAD5, 'M', '𥉉'), (0xFAD6, 'M', '𥳐'), (0xFAD7, 'M', '𧻓'), (0xFAD8, 'M', '齃'), (0xFAD9, 'M', '龎'), (0xFADA, 'X'), (0xFB00, 'M', 'ff'), (0xFB01, 'M', 'fi'), (0xFB02, 'M', 'fl'), (0xFB03, 'M', 'ffi'), (0xFB04, 'M', 'ffl'), (0xFB05, 'M', 'st'), (0xFB07, 'X'), (0xFB13, 'M', 'մն'), (0xFB14, 'M', 'մե'), (0xFB15, 'M', 'մի'), (0xFB16, 'M', 'վն'), ] def _seg_44(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFB17, 'M', 'մխ'), (0xFB18, 'X'), (0xFB1D, 'M', 'יִ'), (0xFB1E, 'V'), (0xFB1F, 'M', 'ײַ'), (0xFB20, 'M', 'ע'), (0xFB21, 'M', 'א'), (0xFB22, 'M', 'ד'), (0xFB23, 'M', 'ה'), (0xFB24, 'M', 'כ'), (0xFB25, 'M', 'ל'), (0xFB26, 'M', 'ם'), (0xFB27, 'M', 'ר'), (0xFB28, 'M', 'ת'), (0xFB29, '3', '+'), (0xFB2A, 'M', 'שׁ'), (0xFB2B, 'M', 'שׂ'), (0xFB2C, 'M', 'שּׁ'), (0xFB2D, 'M', 'שּׂ'), (0xFB2E, 'M', 'אַ'), (0xFB2F, 'M', 'אָ'), (0xFB30, 'M', 'אּ'), (0xFB31, 'M', 'בּ'), (0xFB32, 'M', 'גּ'), (0xFB33, 'M', 'דּ'), (0xFB34, 'M', 'הּ'), (0xFB35, 'M', 'וּ'), (0xFB36, 'M', 'זּ'), (0xFB37, 'X'), (0xFB38, 'M', 'טּ'), (0xFB39, 'M', 'יּ'), (0xFB3A, 'M', 'ךּ'), (0xFB3B, 'M', 'כּ'), (0xFB3C, 'M', 'לּ'), (0xFB3D, 'X'), (0xFB3E, 'M', 'מּ'), (0xFB3F, 'X'), (0xFB40, 'M', 'נּ'), (0xFB41, 'M', 'סּ'), (0xFB42, 'X'), (0xFB43, 'M', 'ףּ'), (0xFB44, 'M', 'פּ'), (0xFB45, 'X'), (0xFB46, 'M', 'צּ'), (0xFB47, 'M', 'קּ'), (0xFB48, 'M', 'רּ'), (0xFB49, 'M', 'שּ'), (0xFB4A, 'M', 'תּ'), (0xFB4B, 'M', 'וֹ'), (0xFB4C, 'M', 'בֿ'), (0xFB4D, 'M', 'כֿ'), (0xFB4E, 'M', 'פֿ'), (0xFB4F, 'M', 'אל'), (0xFB50, 'M', 'ٱ'), (0xFB52, 'M', 'ٻ'), (0xFB56, 'M', 'پ'), (0xFB5A, 'M', 'ڀ'), (0xFB5E, 'M', 'ٺ'), (0xFB62, 'M', 'ٿ'), (0xFB66, 'M', 'ٹ'), (0xFB6A, 'M', 'ڤ'), (0xFB6E, 'M', 'ڦ'), (0xFB72, 'M', 'ڄ'), (0xFB76, 'M', 'ڃ'), (0xFB7A, 'M', 'چ'), (0xFB7E, 'M', 'ڇ'), (0xFB82, 'M', 'ڍ'), (0xFB84, 'M', 'ڌ'), (0xFB86, 'M', 'ڎ'), (0xFB88, 'M', 'ڈ'), (0xFB8A, 'M', 'ژ'), (0xFB8C, 'M', 'ڑ'), (0xFB8E, 'M', 'ک'), (0xFB92, 'M', 'گ'), (0xFB96, 'M', 'ڳ'), (0xFB9A, 'M', 'ڱ'), (0xFB9E, 'M', 'ں'), (0xFBA0, 'M', 'ڻ'), (0xFBA4, 'M', 'ۀ'), (0xFBA6, 'M', 'ہ'), (0xFBAA, 'M', 'ھ'), (0xFBAE, 'M', 'ے'), (0xFBB0, 'M', 'ۓ'), (0xFBB2, 'V'), (0xFBC2, 'X'), (0xFBD3, 'M', 'ڭ'), (0xFBD7, 'M', 'ۇ'), (0xFBD9, 'M', 'ۆ'), (0xFBDB, 'M', 'ۈ'), (0xFBDD, 'M', 'ۇٴ'), (0xFBDE, 'M', 'ۋ'), (0xFBE0, 'M', 'ۅ'), (0xFBE2, 'M', 'ۉ'), (0xFBE4, 'M', 'ې'), (0xFBE8, 'M', 'ى'), (0xFBEA, 'M', 'ئا'), (0xFBEC, 'M', 'ئە'), (0xFBEE, 'M', 'ئو'), (0xFBF0, 'M', 'ئۇ'), (0xFBF2, 'M', 'ئۆ'), ] def _seg_45(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFBF4, 'M', 'ئۈ'), (0xFBF6, 'M', 'ئې'), (0xFBF9, 'M', 'ئى'), (0xFBFC, 'M', 'ی'), (0xFC00, 'M', 'ئج'), (0xFC01, 'M', 'ئح'), (0xFC02, 'M', 'ئم'), (0xFC03, 'M', 'ئى'), (0xFC04, 'M', 'ئي'), (0xFC05, 'M', 'بج'), (0xFC06, 'M', 'بح'), (0xFC07, 'M', 'بخ'), (0xFC08, 'M', 'بم'), (0xFC09, 'M', 'بى'), (0xFC0A, 'M', 'بي'), (0xFC0B, 'M', 'تج'), (0xFC0C, 'M', 'تح'), (0xFC0D, 'M', 'تخ'), (0xFC0E, 'M', 'تم'), (0xFC0F, 'M', 'تى'), (0xFC10, 'M', 'تي'), (0xFC11, 'M', 'ثج'), (0xFC12, 'M', 'ثم'), (0xFC13, 'M', 'ثى'), (0xFC14, 'M', 'ثي'), (0xFC15, 'M', 'جح'), (0xFC16, 'M', 'جم'), (0xFC17, 'M', 'حج'), (0xFC18, 'M', 'حم'), (0xFC19, 'M', 'خج'), (0xFC1A, 'M', 'خح'), (0xFC1B, 'M', 'خم'), (0xFC1C, 'M', 'سج'), (0xFC1D, 'M', 'سح'), (0xFC1E, 'M', 'سخ'), (0xFC1F, 'M', 'سم'), (0xFC20, 'M', 'صح'), (0xFC21, 'M', 'صم'), (0xFC22, 'M', 'ضج'), (0xFC23, 'M', 'ضح'), (0xFC24, 'M', 'ضخ'), (0xFC25, 'M', 'ضم'), (0xFC26, 'M', 'طح'), (0xFC27, 'M', 'طم'), (0xFC28, 'M', 'ظم'), (0xFC29, 'M', 'عج'), (0xFC2A, 'M', 'عم'), (0xFC2B, 'M', 'غج'), (0xFC2C, 'M', 'غم'), (0xFC2D, 'M', 'فج'), (0xFC2E, 'M', 'فح'), (0xFC2F, 'M', 'فخ'), (0xFC30, 'M', 'فم'), (0xFC31, 'M', 'فى'), (0xFC32, 'M', 'في'), (0xFC33, 'M', 'قح'), (0xFC34, 'M', 'قم'), (0xFC35, 'M', 'قى'), (0xFC36, 'M', 'قي'), (0xFC37, 'M', 'كا'), (0xFC38, 'M', 'كج'), (0xFC39, 'M', 'كح'), (0xFC3A, 'M', 'كخ'), (0xFC3B, 'M', 'كل'), (0xFC3C, 'M', 'كم'), (0xFC3D, 'M', 'كى'), (0xFC3E, 'M', 'كي'), (0xFC3F, 'M', 'لج'), (0xFC40, 'M', 'لح'), (0xFC41, 'M', 'لخ'), (0xFC42, 'M', 'لم'), (0xFC43, 'M', 'لى'), (0xFC44, 'M', 'لي'), (0xFC45, 'M', 'مج'), (0xFC46, 'M', 'مح'), (0xFC47, 'M', 'مخ'), (0xFC48, 'M', 'مم'), (0xFC49, 'M', 'مى'), (0xFC4A, 'M', 'مي'), (0xFC4B, 'M', 'نج'), (0xFC4C, 'M', 'نح'), (0xFC4D, 'M', 'نخ'), (0xFC4E, 'M', 'نم'), (0xFC4F, 'M', 'نى'), (0xFC50, 'M', 'ني'), (0xFC51, 'M', 'هج'), (0xFC52, 'M', 'هم'), (0xFC53, 'M', 'هى'), (0xFC54, 'M', 'هي'), (0xFC55, 'M', 'يج'), (0xFC56, 'M', 'يح'), (0xFC57, 'M', 'يخ'), (0xFC58, 'M', 'يم'), (0xFC59, 'M', 'يى'), (0xFC5A, 'M', 'يي'), (0xFC5B, 'M', 'ذٰ'), (0xFC5C, 'M', 'رٰ'), (0xFC5D, 'M', 'ىٰ'), (0xFC5E, '3', ' ٌّ'), (0xFC5F, '3', ' ٍّ'), ] def _seg_46(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFC60, '3', ' َّ'), (0xFC61, '3', ' ُّ'), (0xFC62, '3', ' ِّ'), (0xFC63, '3', ' ّٰ'), (0xFC64, 'M', 'ئر'), (0xFC65, 'M', 'ئز'), (0xFC66, 'M', 'ئم'), (0xFC67, 'M', 'ئن'), (0xFC68, 'M', 'ئى'), (0xFC69, 'M', 'ئي'), (0xFC6A, 'M', 'بر'), (0xFC6B, 'M', 'بز'), (0xFC6C, 'M', 'بم'), (0xFC6D, 'M', 'بن'), (0xFC6E, 'M', 'بى'), (0xFC6F, 'M', 'بي'), (0xFC70, 'M', 'تر'), (0xFC71, 'M', 'تز'), (0xFC72, 'M', 'تم'), (0xFC73, 'M', 'تن'), (0xFC74, 'M', 'تى'), (0xFC75, 'M', 'تي'), (0xFC76, 'M', 'ثر'), (0xFC77, 'M', 'ثز'), (0xFC78, 'M', 'ثم'), (0xFC79, 'M', 'ثن'), (0xFC7A, 'M', 'ثى'), (0xFC7B, 'M', 'ثي'), (0xFC7C, 'M', 'فى'), (0xFC7D, 'M', 'في'), (0xFC7E, 'M', 'قى'), (0xFC7F, 'M', 'قي'), (0xFC80, 'M', 'كا'), (0xFC81, 'M', 'كل'), (0xFC82, 'M', 'كم'), (0xFC83, 'M', 'كى'), (0xFC84, 'M', 'كي'), (0xFC85, 'M', 'لم'), (0xFC86, 'M', 'لى'), (0xFC87, 'M', 'لي'), (0xFC88, 'M', 'ما'), (0xFC89, 'M', 'مم'), (0xFC8A, 'M', 'نر'), (0xFC8B, 'M', 'نز'), (0xFC8C, 'M', 'نم'), (0xFC8D, 'M', 'نن'), (0xFC8E, 'M', 'نى'), (0xFC8F, 'M', 'ني'), (0xFC90, 'M', 'ىٰ'), (0xFC91, 'M', 'ير'), (0xFC92, 'M', 'يز'), (0xFC93, 'M', 'يم'), (0xFC94, 'M', 'ين'), (0xFC95, 'M', 'يى'), (0xFC96, 'M', 'يي'), (0xFC97, 'M', 'ئج'), (0xFC98, 'M', 'ئح'), (0xFC99, 'M', 'ئخ'), (0xFC9A, 'M', 'ئم'), (0xFC9B, 'M', 'ئه'), (0xFC9C, 'M', 'بج'), (0xFC9D, 'M', 'بح'), (0xFC9E, 'M', 'بخ'), (0xFC9F, 'M', 'بم'), (0xFCA0, 'M', 'به'), (0xFCA1, 'M', 'تج'), (0xFCA2, 'M', 'تح'), (0xFCA3, 'M', 'تخ'), (0xFCA4, 'M', 'تم'), (0xFCA5, 'M', 'ته'), (0xFCA6, 'M', 'ثم'), (0xFCA7, 'M', 'جح'), (0xFCA8, 'M', 'جم'), (0xFCA9, 'M', 'حج'), (0xFCAA, 'M', 'حم'), (0xFCAB, 'M', 'خج'), (0xFCAC, 'M', 'خم'), (0xFCAD, 'M', 'سج'), (0xFCAE, 'M', 'سح'), (0xFCAF, 'M', 'سخ'), (0xFCB0, 'M', 'سم'), (0xFCB1, 'M', 'صح'), (0xFCB2, 'M', 'صخ'), (0xFCB3, 'M', 'صم'), (0xFCB4, 'M', 'ضج'), (0xFCB5, 'M', 'ضح'), (0xFCB6, 'M', 'ضخ'), (0xFCB7, 'M', 'ضم'), (0xFCB8, 'M', 'طح'), (0xFCB9, 'M', 'ظم'), (0xFCBA, 'M', 'عج'), (0xFCBB, 'M', 'عم'), (0xFCBC, 'M', 'غج'), (0xFCBD, 'M', 'غم'), (0xFCBE, 'M', 'فج'), (0xFCBF, 'M', 'فح'), (0xFCC0, 'M', 'فخ'), (0xFCC1, 'M', 'فم'), (0xFCC2, 'M', 'قح'), (0xFCC3, 'M', 'قم'), ] def _seg_47(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFCC4, 'M', 'كج'), (0xFCC5, 'M', 'كح'), (0xFCC6, 'M', 'كخ'), (0xFCC7, 'M', 'كل'), (0xFCC8, 'M', 'كم'), (0xFCC9, 'M', 'لج'), (0xFCCA, 'M', 'لح'), (0xFCCB, 'M', 'لخ'), (0xFCCC, 'M', 'لم'), (0xFCCD, 'M', 'له'), (0xFCCE, 'M', 'مج'), (0xFCCF, 'M', 'مح'), (0xFCD0, 'M', 'مخ'), (0xFCD1, 'M', 'مم'), (0xFCD2, 'M', 'نج'), (0xFCD3, 'M', 'نح'), (0xFCD4, 'M', 'نخ'), (0xFCD5, 'M', 'نم'), (0xFCD6, 'M', 'نه'), (0xFCD7, 'M', 'هج'), (0xFCD8, 'M', 'هم'), (0xFCD9, 'M', 'هٰ'), (0xFCDA, 'M', 'يج'), (0xFCDB, 'M', 'يح'), (0xFCDC, 'M', 'يخ'), (0xFCDD, 'M', 'يم'), (0xFCDE, 'M', 'يه'), (0xFCDF, 'M', 'ئم'), (0xFCE0, 'M', 'ئه'), (0xFCE1, 'M', 'بم'), (0xFCE2, 'M', 'به'), (0xFCE3, 'M', 'تم'), (0xFCE4, 'M', 'ته'), (0xFCE5, 'M', 'ثم'), (0xFCE6, 'M', 'ثه'), (0xFCE7, 'M', 'سم'), (0xFCE8, 'M', 'سه'), (0xFCE9, 'M', 'شم'), (0xFCEA, 'M', 'شه'), (0xFCEB, 'M', 'كل'), (0xFCEC, 'M', 'كم'), (0xFCED, 'M', 'لم'), (0xFCEE, 'M', 'نم'), (0xFCEF, 'M', 'نه'), (0xFCF0, 'M', 'يم'), (0xFCF1, 'M', 'يه'), (0xFCF2, 'M', 'ـَّ'), (0xFCF3, 'M', 'ـُّ'), (0xFCF4, 'M', 'ـِّ'), (0xFCF5, 'M', 'طى'), (0xFCF6, 'M', 'طي'), (0xFCF7, 'M', 'عى'), (0xFCF8, 'M', 'عي'), (0xFCF9, 'M', 'غى'), (0xFCFA, 'M', 'غي'), (0xFCFB, 'M', 'سى'), (0xFCFC, 'M', 'سي'), (0xFCFD, 'M', 'شى'), (0xFCFE, 'M', 'شي'), (0xFCFF, 'M', 'حى'), (0xFD00, 'M', 'حي'), (0xFD01, 'M', 'جى'), (0xFD02, 'M', 'جي'), (0xFD03, 'M', 'خى'), (0xFD04, 'M', 'خي'), (0xFD05, 'M', 'صى'), (0xFD06, 'M', 'صي'), (0xFD07, 'M', 'ضى'), (0xFD08, 'M', 'ضي'), (0xFD09, 'M', 'شج'), (0xFD0A, 'M', 'شح'), (0xFD0B, 'M', 'شخ'), (0xFD0C, 'M', 'شم'), (0xFD0D, 'M', 'شر'), (0xFD0E, 'M', 'سر'), (0xFD0F, 'M', 'صر'), (0xFD10, 'M', 'ضر'), (0xFD11, 'M', 'طى'), (0xFD12, 'M', 'طي'), (0xFD13, 'M', 'عى'), (0xFD14, 'M', 'عي'), (0xFD15, 'M', 'غى'), (0xFD16, 'M', 'غي'), (0xFD17, 'M', 'سى'), (0xFD18, 'M', 'سي'), (0xFD19, 'M', 'شى'), (0xFD1A, 'M', 'شي'), (0xFD1B, 'M', 'حى'), (0xFD1C, 'M', 'حي'), (0xFD1D, 'M', 'جى'), (0xFD1E, 'M', 'جي'), (0xFD1F, 'M', 'خى'), (0xFD20, 'M', 'خي'), (0xFD21, 'M', 'صى'), (0xFD22, 'M', 'صي'), (0xFD23, 'M', 'ضى'), (0xFD24, 'M', 'ضي'), (0xFD25, 'M', 'شج'), (0xFD26, 'M', 'شح'), (0xFD27, 'M', 'شخ'), ] def _seg_48(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFD28, 'M', 'شم'), (0xFD29, 'M', 'شر'), (0xFD2A, 'M', 'سر'), (0xFD2B, 'M', 'صر'), (0xFD2C, 'M', 'ضر'), (0xFD2D, 'M', 'شج'), (0xFD2E, 'M', 'شح'), (0xFD2F, 'M', 'شخ'), (0xFD30, 'M', 'شم'), (0xFD31, 'M', 'سه'), (0xFD32, 'M', 'شه'), (0xFD33, 'M', 'طم'), (0xFD34, 'M', 'سج'), (0xFD35, 'M', 'سح'), (0xFD36, 'M', 'سخ'), (0xFD37, 'M', 'شج'), (0xFD38, 'M', 'شح'), (0xFD39, 'M', 'شخ'), (0xFD3A, 'M', 'طم'), (0xFD3B, 'M', 'ظم'), (0xFD3C, 'M', 'اً'), (0xFD3E, 'V'), (0xFD40, 'X'), (0xFD50, 'M', 'تجم'), (0xFD51, 'M', 'تحج'), (0xFD53, 'M', 'تحم'), (0xFD54, 'M', 'تخم'), (0xFD55, 'M', 'تمج'), (0xFD56, 'M', 'تمح'), (0xFD57, 'M', 'تمخ'), (0xFD58, 'M', 'جمح'), (0xFD5A, 'M', 'حمي'), (0xFD5B, 'M', 'حمى'), (0xFD5C, 'M', 'سحج'), (0xFD5D, 'M', 'سجح'), (0xFD5E, 'M', 'سجى'), (0xFD5F, 'M', 'سمح'), (0xFD61, 'M', 'سمج'), (0xFD62, 'M', 'سمم'), (0xFD64, 'M', 'صحح'), (0xFD66, 'M', 'صمم'), (0xFD67, 'M', 'شحم'), (0xFD69, 'M', 'شجي'), (0xFD6A, 'M', 'شمخ'), (0xFD6C, 'M', 'شمم'), (0xFD6E, 'M', 'ضحى'), (0xFD6F, 'M', 'ضخم'), (0xFD71, 'M', 'طمح'), (0xFD73, 'M', 'طمم'), (0xFD74, 'M', 'طمي'), (0xFD75, 'M', 'عجم'), (0xFD76, 'M', 'عمم'), (0xFD78, 'M', 'عمى'), (0xFD79, 'M', 'غمم'), (0xFD7A, 'M', 'غمي'), (0xFD7B, 'M', 'غمى'), (0xFD7C, 'M', 'فخم'), (0xFD7E, 'M', 'قمح'), (0xFD7F, 'M', 'قمم'), (0xFD80, 'M', 'لحم'), (0xFD81, 'M', 'لحي'), (0xFD82, 'M', 'لحى'), (0xFD83, 'M', 'لجج'), (0xFD85, 'M', 'لخم'), (0xFD87, 'M', 'لمح'), (0xFD89, 'M', 'محج'), (0xFD8A, 'M', 'محم'), (0xFD8B, 'M', 'محي'), (0xFD8C, 'M', 'مجح'), (0xFD8D, 'M', 'مجم'), (0xFD8E, 'M', 'مخج'), (0xFD8F, 'M', 'مخم'), (0xFD90, 'X'), (0xFD92, 'M', 'مجخ'), (0xFD93, 'M', 'همج'), (0xFD94, 'M', 'همم'), (0xFD95, 'M', 'نحم'), (0xFD96, 'M', 'نحى'), (0xFD97, 'M', 'نجم'), (0xFD99, 'M', 'نجى'), (0xFD9A, 'M', 'نمي'), (0xFD9B, 'M', 'نمى'), (0xFD9C, 'M', 'يمم'), (0xFD9E, 'M', 'بخي'), (0xFD9F, 'M', 'تجي'), (0xFDA0, 'M', 'تجى'), (0xFDA1, 'M', 'تخي'), (0xFDA2, 'M', 'تخى'), (0xFDA3, 'M', 'تمي'), (0xFDA4, 'M', 'تمى'), (0xFDA5, 'M', 'جمي'), (0xFDA6, 'M', 'جحى'), (0xFDA7, 'M', 'جمى'), (0xFDA8, 'M', 'سخى'), (0xFDA9, 'M', 'صحي'), (0xFDAA, 'M', 'شحي'), (0xFDAB, 'M', 'ضحي'), (0xFDAC, 'M', 'لجي'), (0xFDAD, 'M', 'لمي'), (0xFDAE, 'M', 'يحي'), ] def _seg_49(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFDAF, 'M', 'يجي'), (0xFDB0, 'M', 'يمي'), (0xFDB1, 'M', 'ممي'), (0xFDB2, 'M', 'قمي'), (0xFDB3, 'M', 'نحي'), (0xFDB4, 'M', 'قمح'), (0xFDB5, 'M', 'لحم'), (0xFDB6, 'M', 'عمي'), (0xFDB7, 'M', 'كمي'), (0xFDB8, 'M', 'نجح'), (0xFDB9, 'M', 'مخي'), (0xFDBA, 'M', 'لجم'), (0xFDBB, 'M', 'كمم'), (0xFDBC, 'M', 'لجم'), (0xFDBD, 'M', 'نجح'), (0xFDBE, 'M', 'جحي'), (0xFDBF, 'M', 'حجي'), (0xFDC0, 'M', 'مجي'), (0xFDC1, 'M', 'فمي'), (0xFDC2, 'M', 'بحي'), (0xFDC3, 'M', 'كمم'), (0xFDC4, 'M', 'عجم'), (0xFDC5, 'M', 'صمم'), (0xFDC6, 'M', 'سخي'), (0xFDC7, 'M', 'نجي'), (0xFDC8, 'X'), (0xFDF0, 'M', 'صلے'), (0xFDF1, 'M', 'قلے'), (0xFDF2, 'M', 'الله'), (0xFDF3, 'M', 'اكبر'), (0xFDF4, 'M', 'محمد'), (0xFDF5, 'M', 'صلعم'), (0xFDF6, 'M', 'رسول'), (0xFDF7, 'M', 'عليه'), (0xFDF8, 'M', 'وسلم'), (0xFDF9, 'M', 'صلى'), (0xFDFA, '3', 'صلى الله عليه وسلم'), (0xFDFB, '3', 'جل جلاله'), (0xFDFC, 'M', 'ریال'), (0xFDFD, 'V'), (0xFDFE, 'X'), (0xFE00, 'I'), (0xFE10, '3', ','), (0xFE11, 'M', '、'), (0xFE12, 'X'), (0xFE13, '3', ':'), (0xFE14, '3', ';'), (0xFE15, '3', '!'), (0xFE16, '3', '?'), (0xFE17, 'M', '〖'), (0xFE18, 'M', '〗'), (0xFE19, 'X'), (0xFE20, 'V'), (0xFE30, 'X'), (0xFE31, 'M', '—'), (0xFE32, 'M', '–'), (0xFE33, '3', '_'), (0xFE35, '3', '('), (0xFE36, '3', ')'), (0xFE37, '3', '{'), (0xFE38, '3', '}'), (0xFE39, 'M', '〔'), (0xFE3A, 'M', '〕'), (0xFE3B, 'M', '【'), (0xFE3C, 'M', '】'), (0xFE3D, 'M', '《'), (0xFE3E, 'M', '》'), (0xFE3F, 'M', '〈'), (0xFE40, 'M', '〉'), (0xFE41, 'M', '「'), (0xFE42, 'M', '」'), (0xFE43, 'M', '『'), (0xFE44, 'M', '』'), (0xFE45, 'V'), (0xFE47, '3', '['), (0xFE48, '3', ']'), (0xFE49, '3', ' ̅'), (0xFE4D, '3', '_'), (0xFE50, '3', ','), (0xFE51, 'M', '、'), (0xFE52, 'X'), (0xFE54, '3', ';'), (0xFE55, '3', ':'), (0xFE56, '3', '?'), (0xFE57, '3', '!'), (0xFE58, 'M', '—'), (0xFE59, '3', '('), (0xFE5A, '3', ')'), (0xFE5B, '3', '{'), (0xFE5C, '3', '}'), (0xFE5D, 'M', '〔'), (0xFE5E, 'M', '〕'), (0xFE5F, '3', '#'), (0xFE60, '3', '&'), (0xFE61, '3', '*'), (0xFE62, '3', '+'), (0xFE63, 'M', '-'), (0xFE64, '3', '<'), (0xFE65, '3', '>'), (0xFE66, '3', '='), ] def _seg_50(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFE67, 'X'), (0xFE68, '3', '\\'), (0xFE69, '3', '$'), (0xFE6A, '3', '%'), (0xFE6B, '3', '@'), (0xFE6C, 'X'), (0xFE70, '3', ' ً'), (0xFE71, 'M', 'ـً'), (0xFE72, '3', ' ٌ'), (0xFE73, 'V'), (0xFE74, '3', ' ٍ'), (0xFE75, 'X'), (0xFE76, '3', ' َ'), (0xFE77, 'M', 'ـَ'), (0xFE78, '3', ' ُ'), (0xFE79, 'M', 'ـُ'), (0xFE7A, '3', ' ِ'), (0xFE7B, 'M', 'ـِ'), (0xFE7C, '3', ' ّ'), (0xFE7D, 'M', 'ـّ'), (0xFE7E, '3', ' ْ'), (0xFE7F, 'M', 'ـْ'), (0xFE80, 'M', 'ء'), (0xFE81, 'M', 'آ'), (0xFE83, 'M', 'أ'), (0xFE85, 'M', 'ؤ'), (0xFE87, 'M', 'إ'), (0xFE89, 'M', 'ئ'), (0xFE8D, 'M', 'ا'), (0xFE8F, 'M', 'ب'), (0xFE93, 'M', 'ة'), (0xFE95, 'M', 'ت'), (0xFE99, 'M', 'ث'), (0xFE9D, 'M', 'ج'), (0xFEA1, 'M', 'ح'), (0xFEA5, 'M', 'خ'), (0xFEA9, 'M', 'د'), (0xFEAB, 'M', 'ذ'), (0xFEAD, 'M', 'ر'), (0xFEAF, 'M', 'ز'), (0xFEB1, 'M', 'س'), (0xFEB5, 'M', 'ش'), (0xFEB9, 'M', 'ص'), (0xFEBD, 'M', 'ض'), (0xFEC1, 'M', 'ط'), (0xFEC5, 'M', 'ظ'), (0xFEC9, 'M', 'ع'), (0xFECD, 'M', 'غ'), (0xFED1, 'M', 'ف'), (0xFED5, 'M', 'ق'), (0xFED9, 'M', 'ك'), (0xFEDD, 'M', 'ل'), (0xFEE1, 'M', 'م'), (0xFEE5, 'M', 'ن'), (0xFEE9, 'M', 'ه'), (0xFEED, 'M', 'و'), (0xFEEF, 'M', 'ى'), (0xFEF1, 'M', 'ي'), (0xFEF5, 'M', 'لآ'), (0xFEF7, 'M', 'لأ'), (0xFEF9, 'M', 'لإ'), (0xFEFB, 'M', 'لا'), (0xFEFD, 'X'), (0xFEFF, 'I'), (0xFF00, 'X'), (0xFF01, '3', '!'), (0xFF02, '3', '"'), (0xFF03, '3', '#'), (0xFF04, '3', '$'), (0xFF05, '3', '%'), (0xFF06, '3', '&'), (0xFF07, '3', '\''), (0xFF08, '3', '('), (0xFF09, '3', ')'), (0xFF0A, '3', '*'), (0xFF0B, '3', '+'), (0xFF0C, '3', ','), (0xFF0D, 'M', '-'), (0xFF0E, 'M', '.'), (0xFF0F, '3', '/'), (0xFF10, 'M', '0'), (0xFF11, 'M', '1'), (0xFF12, 'M', '2'), (0xFF13, 'M', '3'), (0xFF14, 'M', '4'), (0xFF15, 'M', '5'), (0xFF16, 'M', '6'), (0xFF17, 'M', '7'), (0xFF18, 'M', '8'), (0xFF19, 'M', '9'), (0xFF1A, '3', ':'), (0xFF1B, '3', ';'), (0xFF1C, '3', '<'), (0xFF1D, '3', '='), (0xFF1E, '3', '>'), (0xFF1F, '3', '?'), (0xFF20, '3', '@'), (0xFF21, 'M', 'a'), (0xFF22, 'M', 'b'), (0xFF23, 'M', 'c'), ] def _seg_51(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFF24, 'M', 'd'), (0xFF25, 'M', 'e'), (0xFF26, 'M', 'f'), (0xFF27, 'M', 'g'), (0xFF28, 'M', 'h'), (0xFF29, 'M', 'i'), (0xFF2A, 'M', 'j'), (0xFF2B, 'M', 'k'), (0xFF2C, 'M', 'l'), (0xFF2D, 'M', 'm'), (0xFF2E, 'M', 'n'), (0xFF2F, 'M', 'o'), (0xFF30, 'M', 'p'), (0xFF31, 'M', 'q'), (0xFF32, 'M', 'r'), (0xFF33, 'M', 's'), (0xFF34, 'M', 't'), (0xFF35, 'M', 'u'), (0xFF36, 'M', 'v'), (0xFF37, 'M', 'w'), (0xFF38, 'M', 'x'), (0xFF39, 'M', 'y'), (0xFF3A, 'M', 'z'), (0xFF3B, '3', '['), (0xFF3C, '3', '\\'), (0xFF3D, '3', ']'), (0xFF3E, '3', '^'), (0xFF3F, '3', '_'), (0xFF40, '3', '`'), (0xFF41, 'M', 'a'), (0xFF42, 'M', 'b'), (0xFF43, 'M', 'c'), (0xFF44, 'M', 'd'), (0xFF45, 'M', 'e'), (0xFF46, 'M', 'f'), (0xFF47, 'M', 'g'), (0xFF48, 'M', 'h'), (0xFF49, 'M', 'i'), (0xFF4A, 'M', 'j'), (0xFF4B, 'M', 'k'), (0xFF4C, 'M', 'l'), (0xFF4D, 'M', 'm'), (0xFF4E, 'M', 'n'), (0xFF4F, 'M', 'o'), (0xFF50, 'M', 'p'), (0xFF51, 'M', 'q'), (0xFF52, 'M', 'r'), (0xFF53, 'M', 's'), (0xFF54, 'M', 't'), (0xFF55, 'M', 'u'), (0xFF56, 'M', 'v'), (0xFF57, 'M', 'w'), (0xFF58, 'M', 'x'), (0xFF59, 'M', 'y'), (0xFF5A, 'M', 'z'), (0xFF5B, '3', '{'), (0xFF5C, '3', '|'), (0xFF5D, '3', '}'), (0xFF5E, '3', '~'), (0xFF5F, 'M', '⦅'), (0xFF60, 'M', '⦆'), (0xFF61, 'M', '.'), (0xFF62, 'M', '「'), (0xFF63, 'M', '」'), (0xFF64, 'M', '、'), (0xFF65, 'M', '・'), (0xFF66, 'M', 'ヲ'), (0xFF67, 'M', 'ァ'), (0xFF68, 'M', 'ィ'), (0xFF69, 'M', 'ゥ'), (0xFF6A, 'M', 'ェ'), (0xFF6B, 'M', 'ォ'), (0xFF6C, 'M', 'ャ'), (0xFF6D, 'M', 'ュ'), (0xFF6E, 'M', 'ョ'), (0xFF6F, 'M', 'ッ'), (0xFF70, 'M', 'ー'), (0xFF71, 'M', 'ア'), (0xFF72, 'M', 'イ'), (0xFF73, 'M', 'ウ'), (0xFF74, 'M', 'エ'), (0xFF75, 'M', 'オ'), (0xFF76, 'M', 'カ'), (0xFF77, 'M', 'キ'), (0xFF78, 'M', 'ク'), (0xFF79, 'M', 'ケ'), (0xFF7A, 'M', 'コ'), (0xFF7B, 'M', 'サ'), (0xFF7C, 'M', 'シ'), (0xFF7D, 'M', 'ス'), (0xFF7E, 'M', 'セ'), (0xFF7F, 'M', 'ソ'), (0xFF80, 'M', 'タ'), (0xFF81, 'M', 'チ'), (0xFF82, 'M', 'ツ'), (0xFF83, 'M', 'テ'), (0xFF84, 'M', 'ト'), (0xFF85, 'M', 'ナ'), (0xFF86, 'M', 'ニ'), (0xFF87, 'M', 'ヌ'), ] def _seg_52(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0xFF88, 'M', 'ネ'), (0xFF89, 'M', 'ノ'), (0xFF8A, 'M', 'ハ'), (0xFF8B, 'M', 'ヒ'), (0xFF8C, 'M', 'フ'), (0xFF8D, 'M', 'ヘ'), (0xFF8E, 'M', 'ホ'), (0xFF8F, 'M', 'マ'), (0xFF90, 'M', 'ミ'), (0xFF91, 'M', 'ム'), (0xFF92, 'M', 'メ'), (0xFF93, 'M', 'モ'), (0xFF94, 'M', 'ヤ'), (0xFF95, 'M', 'ユ'), (0xFF96, 'M', 'ヨ'), (0xFF97, 'M', 'ラ'), (0xFF98, 'M', 'リ'), (0xFF99, 'M', 'ル'), (0xFF9A, 'M', 'レ'), (0xFF9B, 'M', 'ロ'), (0xFF9C, 'M', 'ワ'), (0xFF9D, 'M', 'ン'), (0xFF9E, 'M', '゙'), (0xFF9F, 'M', '゚'), (0xFFA0, 'X'), (0xFFA1, 'M', 'ᄀ'), (0xFFA2, 'M', 'ᄁ'), (0xFFA3, 'M', 'ᆪ'), (0xFFA4, 'M', 'ᄂ'), (0xFFA5, 'M', 'ᆬ'), (0xFFA6, 'M', 'ᆭ'), (0xFFA7, 'M', 'ᄃ'), (0xFFA8, 'M', 'ᄄ'), (0xFFA9, 'M', 'ᄅ'), (0xFFAA, 'M', 'ᆰ'), (0xFFAB, 'M', 'ᆱ'), (0xFFAC, 'M', 'ᆲ'), (0xFFAD, 'M', 'ᆳ'), (0xFFAE, 'M', 'ᆴ'), (0xFFAF, 'M', 'ᆵ'), (0xFFB0, 'M', 'ᄚ'), (0xFFB1, 'M', 'ᄆ'), (0xFFB2, 'M', 'ᄇ'), (0xFFB3, 'M', 'ᄈ'), (0xFFB4, 'M', 'ᄡ'), (0xFFB5, 'M', 'ᄉ'), (0xFFB6, 'M', 'ᄊ'), (0xFFB7, 'M', 'ᄋ'), (0xFFB8, 'M', 'ᄌ'), (0xFFB9, 'M', 'ᄍ'), (0xFFBA, 'M', 'ᄎ'), (0xFFBB, 'M', 'ᄏ'), (0xFFBC, 'M', 'ᄐ'), (0xFFBD, 'M', 'ᄑ'), (0xFFBE, 'M', 'ᄒ'), (0xFFBF, 'X'), (0xFFC2, 'M', 'ᅡ'), (0xFFC3, 'M', 'ᅢ'), (0xFFC4, 'M', 'ᅣ'), (0xFFC5, 'M', 'ᅤ'), (0xFFC6, 'M', 'ᅥ'), (0xFFC7, 'M', 'ᅦ'), (0xFFC8, 'X'), (0xFFCA, 'M', 'ᅧ'), (0xFFCB, 'M', 'ᅨ'), (0xFFCC, 'M', 'ᅩ'), (0xFFCD, 'M', 'ᅪ'), (0xFFCE, 'M', 'ᅫ'), (0xFFCF, 'M', 'ᅬ'), (0xFFD0, 'X'), (0xFFD2, 'M', 'ᅭ'), (0xFFD3, 'M', 'ᅮ'), (0xFFD4, 'M', 'ᅯ'), (0xFFD5, 'M', 'ᅰ'), (0xFFD6, 'M', 'ᅱ'), (0xFFD7, 'M', 'ᅲ'), (0xFFD8, 'X'), (0xFFDA, 'M', 'ᅳ'), (0xFFDB, 'M', 'ᅴ'), (0xFFDC, 'M', 'ᅵ'), (0xFFDD, 'X'), (0xFFE0, 'M', '¢'), (0xFFE1, 'M', '£'), (0xFFE2, 'M', '¬'), (0xFFE3, '3', ' ̄'), (0xFFE4, 'M', '¦'), (0xFFE5, 'M', '¥'), (0xFFE6, 'M', '₩'), (0xFFE7, 'X'), (0xFFE8, 'M', '│'), (0xFFE9, 'M', '←'), (0xFFEA, 'M', '↑'), (0xFFEB, 'M', '→'), (0xFFEC, 'M', '↓'), (0xFFED, 'M', '■'), (0xFFEE, 'M', '○'), (0xFFEF, 'X'), (0x10000, 'V'), (0x1000C, 'X'), (0x1000D, 'V'), ] def _seg_53(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x10027, 'X'), (0x10028, 'V'), (0x1003B, 'X'), (0x1003C, 'V'), (0x1003E, 'X'), (0x1003F, 'V'), (0x1004E, 'X'), (0x10050, 'V'), (0x1005E, 'X'), (0x10080, 'V'), (0x100FB, 'X'), (0x10100, 'V'), (0x10103, 'X'), (0x10107, 'V'), (0x10134, 'X'), (0x10137, 'V'), (0x1018F, 'X'), (0x10190, 'V'), (0x1019D, 'X'), (0x101A0, 'V'), (0x101A1, 'X'), (0x101D0, 'V'), (0x101FE, 'X'), (0x10280, 'V'), (0x1029D, 'X'), (0x102A0, 'V'), (0x102D1, 'X'), (0x102E0, 'V'), (0x102FC, 'X'), (0x10300, 'V'), (0x10324, 'X'), (0x1032D, 'V'), (0x1034B, 'X'), (0x10350, 'V'), (0x1037B, 'X'), (0x10380, 'V'), (0x1039E, 'X'), (0x1039F, 'V'), (0x103C4, 'X'), (0x103C8, 'V'), (0x103D6, 'X'), (0x10400, 'M', '𐐨'), (0x10401, 'M', '𐐩'), (0x10402, 'M', '𐐪'), (0x10403, 'M', '𐐫'), (0x10404, 'M', '𐐬'), (0x10405, 'M', '𐐭'), (0x10406, 'M', '𐐮'), (0x10407, 'M', '𐐯'), (0x10408, 'M', '𐐰'), (0x10409, 'M', '𐐱'), (0x1040A, 'M', '𐐲'), (0x1040B, 'M', '𐐳'), (0x1040C, 'M', '𐐴'), (0x1040D, 'M', '𐐵'), (0x1040E, 'M', '𐐶'), (0x1040F, 'M', '𐐷'), (0x10410, 'M', '𐐸'), (0x10411, 'M', '𐐹'), (0x10412, 'M', '𐐺'), (0x10413, 'M', '𐐻'), (0x10414, 'M', '𐐼'), (0x10415, 'M', '𐐽'), (0x10416, 'M', '𐐾'), (0x10417, 'M', '𐐿'), (0x10418, 'M', '𐑀'), (0x10419, 'M', '𐑁'), (0x1041A, 'M', '𐑂'), (0x1041B, 'M', '𐑃'), (0x1041C, 'M', '𐑄'), (0x1041D, 'M', '𐑅'), (0x1041E, 'M', '𐑆'), (0x1041F, 'M', '𐑇'), (0x10420, 'M', '𐑈'), (0x10421, 'M', '𐑉'), (0x10422, 'M', '𐑊'), (0x10423, 'M', '𐑋'), (0x10424, 'M', '𐑌'), (0x10425, 'M', '𐑍'), (0x10426, 'M', '𐑎'), (0x10427, 'M', '𐑏'), (0x10428, 'V'), (0x1049E, 'X'), (0x104A0, 'V'), (0x104AA, 'X'), (0x104B0, 'M', '𐓘'), (0x104B1, 'M', '𐓙'), (0x104B2, 'M', '𐓚'), (0x104B3, 'M', '𐓛'), (0x104B4, 'M', '𐓜'), (0x104B5, 'M', '𐓝'), (0x104B6, 'M', '𐓞'), (0x104B7, 'M', '𐓟'), (0x104B8, 'M', '𐓠'), (0x104B9, 'M', '𐓡'), (0x104BA, 'M', '𐓢'), (0x104BB, 'M', '𐓣'), (0x104BC, 'M', '𐓤'), (0x104BD, 'M', '𐓥'), (0x104BE, 'M', '𐓦'), ] def _seg_54(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x104BF, 'M', '𐓧'), (0x104C0, 'M', '𐓨'), (0x104C1, 'M', '𐓩'), (0x104C2, 'M', '𐓪'), (0x104C3, 'M', '𐓫'), (0x104C4, 'M', '𐓬'), (0x104C5, 'M', '𐓭'), (0x104C6, 'M', '𐓮'), (0x104C7, 'M', '𐓯'), (0x104C8, 'M', '𐓰'), (0x104C9, 'M', '𐓱'), (0x104CA, 'M', '𐓲'), (0x104CB, 'M', '𐓳'), (0x104CC, 'M', '𐓴'), (0x104CD, 'M', '𐓵'), (0x104CE, 'M', '𐓶'), (0x104CF, 'M', '𐓷'), (0x104D0, 'M', '𐓸'), (0x104D1, 'M', '𐓹'), (0x104D2, 'M', '𐓺'), (0x104D3, 'M', '𐓻'), (0x104D4, 'X'), (0x104D8, 'V'), (0x104FC, 'X'), (0x10500, 'V'), (0x10528, 'X'), (0x10530, 'V'), (0x10564, 'X'), (0x1056F, 'V'), (0x10570, 'X'), (0x10600, 'V'), (0x10737, 'X'), (0x10740, 'V'), (0x10756, 'X'), (0x10760, 'V'), (0x10768, 'X'), (0x10800, 'V'), (0x10806, 'X'), (0x10808, 'V'), (0x10809, 'X'), (0x1080A, 'V'), (0x10836, 'X'), (0x10837, 'V'), (0x10839, 'X'), (0x1083C, 'V'), (0x1083D, 'X'), (0x1083F, 'V'), (0x10856, 'X'), (0x10857, 'V'), (0x1089F, 'X'), (0x108A7, 'V'), (0x108B0, 'X'), (0x108E0, 'V'), (0x108F3, 'X'), (0x108F4, 'V'), (0x108F6, 'X'), (0x108FB, 'V'), (0x1091C, 'X'), (0x1091F, 'V'), (0x1093A, 'X'), (0x1093F, 'V'), (0x10940, 'X'), (0x10980, 'V'), (0x109B8, 'X'), (0x109BC, 'V'), (0x109D0, 'X'), (0x109D2, 'V'), (0x10A04, 'X'), (0x10A05, 'V'), (0x10A07, 'X'), (0x10A0C, 'V'), (0x10A14, 'X'), (0x10A15, 'V'), (0x10A18, 'X'), (0x10A19, 'V'), (0x10A36, 'X'), (0x10A38, 'V'), (0x10A3B, 'X'), (0x10A3F, 'V'), (0x10A49, 'X'), (0x10A50, 'V'), (0x10A59, 'X'), (0x10A60, 'V'), (0x10AA0, 'X'), (0x10AC0, 'V'), (0x10AE7, 'X'), (0x10AEB, 'V'), (0x10AF7, 'X'), (0x10B00, 'V'), (0x10B36, 'X'), (0x10B39, 'V'), (0x10B56, 'X'), (0x10B58, 'V'), (0x10B73, 'X'), (0x10B78, 'V'), (0x10B92, 'X'), (0x10B99, 'V'), (0x10B9D, 'X'), (0x10BA9, 'V'), (0x10BB0, 'X'), ] def _seg_55(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x10C00, 'V'), (0x10C49, 'X'), (0x10C80, 'M', '𐳀'), (0x10C81, 'M', '𐳁'), (0x10C82, 'M', '𐳂'), (0x10C83, 'M', '𐳃'), (0x10C84, 'M', '𐳄'), (0x10C85, 'M', '𐳅'), (0x10C86, 'M', '𐳆'), (0x10C87, 'M', '𐳇'), (0x10C88, 'M', '𐳈'), (0x10C89, 'M', '𐳉'), (0x10C8A, 'M', '𐳊'), (0x10C8B, 'M', '𐳋'), (0x10C8C, 'M', '𐳌'), (0x10C8D, 'M', '𐳍'), (0x10C8E, 'M', '𐳎'), (0x10C8F, 'M', '𐳏'), (0x10C90, 'M', '𐳐'), (0x10C91, 'M', '𐳑'), (0x10C92, 'M', '𐳒'), (0x10C93, 'M', '𐳓'), (0x10C94, 'M', '𐳔'), (0x10C95, 'M', '𐳕'), (0x10C96, 'M', '𐳖'), (0x10C97, 'M', '𐳗'), (0x10C98, 'M', '𐳘'), (0x10C99, 'M', '𐳙'), (0x10C9A, 'M', '𐳚'), (0x10C9B, 'M', '𐳛'), (0x10C9C, 'M', '𐳜'), (0x10C9D, 'M', '𐳝'), (0x10C9E, 'M', '𐳞'), (0x10C9F, 'M', '𐳟'), (0x10CA0, 'M', '𐳠'), (0x10CA1, 'M', '𐳡'), (0x10CA2, 'M', '𐳢'), (0x10CA3, 'M', '𐳣'), (0x10CA4, 'M', '𐳤'), (0x10CA5, 'M', '𐳥'), (0x10CA6, 'M', '𐳦'), (0x10CA7, 'M', '𐳧'), (0x10CA8, 'M', '𐳨'), (0x10CA9, 'M', '𐳩'), (0x10CAA, 'M', '𐳪'), (0x10CAB, 'M', '𐳫'), (0x10CAC, 'M', '𐳬'), (0x10CAD, 'M', '𐳭'), (0x10CAE, 'M', '𐳮'), (0x10CAF, 'M', '𐳯'), (0x10CB0, 'M', '𐳰'), (0x10CB1, 'M', '𐳱'), (0x10CB2, 'M', '𐳲'), (0x10CB3, 'X'), (0x10CC0, 'V'), (0x10CF3, 'X'), (0x10CFA, 'V'), (0x10D28, 'X'), (0x10D30, 'V'), (0x10D3A, 'X'), (0x10E60, 'V'), (0x10E7F, 'X'), (0x10E80, 'V'), (0x10EAA, 'X'), (0x10EAB, 'V'), (0x10EAE, 'X'), (0x10EB0, 'V'), (0x10EB2, 'X'), (0x10F00, 'V'), (0x10F28, 'X'), (0x10F30, 'V'), (0x10F5A, 'X'), (0x10FB0, 'V'), (0x10FCC, 'X'), (0x10FE0, 'V'), (0x10FF7, 'X'), (0x11000, 'V'), (0x1104E, 'X'), (0x11052, 'V'), (0x11070, 'X'), (0x1107F, 'V'), (0x110BD, 'X'), (0x110BE, 'V'), (0x110C2, 'X'), (0x110D0, 'V'), (0x110E9, 'X'), (0x110F0, 'V'), (0x110FA, 'X'), (0x11100, 'V'), (0x11135, 'X'), (0x11136, 'V'), (0x11148, 'X'), (0x11150, 'V'), (0x11177, 'X'), (0x11180, 'V'), (0x111E0, 'X'), (0x111E1, 'V'), (0x111F5, 'X'), (0x11200, 'V'), (0x11212, 'X'), ] def _seg_56(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x11213, 'V'), (0x1123F, 'X'), (0x11280, 'V'), (0x11287, 'X'), (0x11288, 'V'), (0x11289, 'X'), (0x1128A, 'V'), (0x1128E, 'X'), (0x1128F, 'V'), (0x1129E, 'X'), (0x1129F, 'V'), (0x112AA, 'X'), (0x112B0, 'V'), (0x112EB, 'X'), (0x112F0, 'V'), (0x112FA, 'X'), (0x11300, 'V'), (0x11304, 'X'), (0x11305, 'V'), (0x1130D, 'X'), (0x1130F, 'V'), (0x11311, 'X'), (0x11313, 'V'), (0x11329, 'X'), (0x1132A, 'V'), (0x11331, 'X'), (0x11332, 'V'), (0x11334, 'X'), (0x11335, 'V'), (0x1133A, 'X'), (0x1133B, 'V'), (0x11345, 'X'), (0x11347, 'V'), (0x11349, 'X'), (0x1134B, 'V'), (0x1134E, 'X'), (0x11350, 'V'), (0x11351, 'X'), (0x11357, 'V'), (0x11358, 'X'), (0x1135D, 'V'), (0x11364, 'X'), (0x11366, 'V'), (0x1136D, 'X'), (0x11370, 'V'), (0x11375, 'X'), (0x11400, 'V'), (0x1145C, 'X'), (0x1145D, 'V'), (0x11462, 'X'), (0x11480, 'V'), (0x114C8, 'X'), (0x114D0, 'V'), (0x114DA, 'X'), (0x11580, 'V'), (0x115B6, 'X'), (0x115B8, 'V'), (0x115DE, 'X'), (0x11600, 'V'), (0x11645, 'X'), (0x11650, 'V'), (0x1165A, 'X'), (0x11660, 'V'), (0x1166D, 'X'), (0x11680, 'V'), (0x116B9, 'X'), (0x116C0, 'V'), (0x116CA, 'X'), (0x11700, 'V'), (0x1171B, 'X'), (0x1171D, 'V'), (0x1172C, 'X'), (0x11730, 'V'), (0x11740, 'X'), (0x11800, 'V'), (0x1183C, 'X'), (0x118A0, 'M', '𑣀'), (0x118A1, 'M', '𑣁'), (0x118A2, 'M', '𑣂'), (0x118A3, 'M', '𑣃'), (0x118A4, 'M', '𑣄'), (0x118A5, 'M', '𑣅'), (0x118A6, 'M', '𑣆'), (0x118A7, 'M', '𑣇'), (0x118A8, 'M', '𑣈'), (0x118A9, 'M', '𑣉'), (0x118AA, 'M', '𑣊'), (0x118AB, 'M', '𑣋'), (0x118AC, 'M', '𑣌'), (0x118AD, 'M', '𑣍'), (0x118AE, 'M', '𑣎'), (0x118AF, 'M', '𑣏'), (0x118B0, 'M', '𑣐'), (0x118B1, 'M', '𑣑'), (0x118B2, 'M', '𑣒'), (0x118B3, 'M', '𑣓'), (0x118B4, 'M', '𑣔'), (0x118B5, 'M', '𑣕'), (0x118B6, 'M', '𑣖'), (0x118B7, 'M', '𑣗'), ] def _seg_57(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x118B8, 'M', '𑣘'), (0x118B9, 'M', '𑣙'), (0x118BA, 'M', '𑣚'), (0x118BB, 'M', '𑣛'), (0x118BC, 'M', '𑣜'), (0x118BD, 'M', '𑣝'), (0x118BE, 'M', '𑣞'), (0x118BF, 'M', '𑣟'), (0x118C0, 'V'), (0x118F3, 'X'), (0x118FF, 'V'), (0x11907, 'X'), (0x11909, 'V'), (0x1190A, 'X'), (0x1190C, 'V'), (0x11914, 'X'), (0x11915, 'V'), (0x11917, 'X'), (0x11918, 'V'), (0x11936, 'X'), (0x11937, 'V'), (0x11939, 'X'), (0x1193B, 'V'), (0x11947, 'X'), (0x11950, 'V'), (0x1195A, 'X'), (0x119A0, 'V'), (0x119A8, 'X'), (0x119AA, 'V'), (0x119D8, 'X'), (0x119DA, 'V'), (0x119E5, 'X'), (0x11A00, 'V'), (0x11A48, 'X'), (0x11A50, 'V'), (0x11AA3, 'X'), (0x11AC0, 'V'), (0x11AF9, 'X'), (0x11C00, 'V'), (0x11C09, 'X'), (0x11C0A, 'V'), (0x11C37, 'X'), (0x11C38, 'V'), (0x11C46, 'X'), (0x11C50, 'V'), (0x11C6D, 'X'), (0x11C70, 'V'), (0x11C90, 'X'), (0x11C92, 'V'), (0x11CA8, 'X'), (0x11CA9, 'V'), (0x11CB7, 'X'), (0x11D00, 'V'), (0x11D07, 'X'), (0x11D08, 'V'), (0x11D0A, 'X'), (0x11D0B, 'V'), (0x11D37, 'X'), (0x11D3A, 'V'), (0x11D3B, 'X'), (0x11D3C, 'V'), (0x11D3E, 'X'), (0x11D3F, 'V'), (0x11D48, 'X'), (0x11D50, 'V'), (0x11D5A, 'X'), (0x11D60, 'V'), (0x11D66, 'X'), (0x11D67, 'V'), (0x11D69, 'X'), (0x11D6A, 'V'), (0x11D8F, 'X'), (0x11D90, 'V'), (0x11D92, 'X'), (0x11D93, 'V'), (0x11D99, 'X'), (0x11DA0, 'V'), (0x11DAA, 'X'), (0x11EE0, 'V'), (0x11EF9, 'X'), (0x11FB0, 'V'), (0x11FB1, 'X'), (0x11FC0, 'V'), (0x11FF2, 'X'), (0x11FFF, 'V'), (0x1239A, 'X'), (0x12400, 'V'), (0x1246F, 'X'), (0x12470, 'V'), (0x12475, 'X'), (0x12480, 'V'), (0x12544, 'X'), (0x13000, 'V'), (0x1342F, 'X'), (0x14400, 'V'), (0x14647, 'X'), (0x16800, 'V'), (0x16A39, 'X'), (0x16A40, 'V'), (0x16A5F, 'X'), ] def _seg_58(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x16A60, 'V'), (0x16A6A, 'X'), (0x16A6E, 'V'), (0x16A70, 'X'), (0x16AD0, 'V'), (0x16AEE, 'X'), (0x16AF0, 'V'), (0x16AF6, 'X'), (0x16B00, 'V'), (0x16B46, 'X'), (0x16B50, 'V'), (0x16B5A, 'X'), (0x16B5B, 'V'), (0x16B62, 'X'), (0x16B63, 'V'), (0x16B78, 'X'), (0x16B7D, 'V'), (0x16B90, 'X'), (0x16E40, 'M', '𖹠'), (0x16E41, 'M', '𖹡'), (0x16E42, 'M', '𖹢'), (0x16E43, 'M', '𖹣'), (0x16E44, 'M', '𖹤'), (0x16E45, 'M', '𖹥'), (0x16E46, 'M', '𖹦'), (0x16E47, 'M', '𖹧'), (0x16E48, 'M', '𖹨'), (0x16E49, 'M', '𖹩'), (0x16E4A, 'M', '𖹪'), (0x16E4B, 'M', '𖹫'), (0x16E4C, 'M', '𖹬'), (0x16E4D, 'M', '𖹭'), (0x16E4E, 'M', '𖹮'), (0x16E4F, 'M', '𖹯'), (0x16E50, 'M', '𖹰'), (0x16E51, 'M', '𖹱'), (0x16E52, 'M', '𖹲'), (0x16E53, 'M', '𖹳'), (0x16E54, 'M', '𖹴'), (0x16E55, 'M', '𖹵'), (0x16E56, 'M', '𖹶'), (0x16E57, 'M', '𖹷'), (0x16E58, 'M', '𖹸'), (0x16E59, 'M', '𖹹'), (0x16E5A, 'M', '𖹺'), (0x16E5B, 'M', '𖹻'), (0x16E5C, 'M', '𖹼'), (0x16E5D, 'M', '𖹽'), (0x16E5E, 'M', '𖹾'), (0x16E5F, 'M', '𖹿'), (0x16E60, 'V'), (0x16E9B, 'X'), (0x16F00, 'V'), (0x16F4B, 'X'), (0x16F4F, 'V'), (0x16F88, 'X'), (0x16F8F, 'V'), (0x16FA0, 'X'), (0x16FE0, 'V'), (0x16FE5, 'X'), (0x16FF0, 'V'), (0x16FF2, 'X'), (0x17000, 'V'), (0x187F8, 'X'), (0x18800, 'V'), (0x18CD6, 'X'), (0x18D00, 'V'), (0x18D09, 'X'), (0x1B000, 'V'), (0x1B11F, 'X'), (0x1B150, 'V'), (0x1B153, 'X'), (0x1B164, 'V'), (0x1B168, 'X'), (0x1B170, 'V'), (0x1B2FC, 'X'), (0x1BC00, 'V'), (0x1BC6B, 'X'), (0x1BC70, 'V'), (0x1BC7D, 'X'), (0x1BC80, 'V'), (0x1BC89, 'X'), (0x1BC90, 'V'), (0x1BC9A, 'X'), (0x1BC9C, 'V'), (0x1BCA0, 'I'), (0x1BCA4, 'X'), (0x1D000, 'V'), (0x1D0F6, 'X'), (0x1D100, 'V'), (0x1D127, 'X'), (0x1D129, 'V'), (0x1D15E, 'M', '𝅗𝅥'), (0x1D15F, 'M', '𝅘𝅥'), (0x1D160, 'M', '𝅘𝅥𝅮'), (0x1D161, 'M', '𝅘𝅥𝅯'), (0x1D162, 'M', '𝅘𝅥𝅰'), (0x1D163, 'M', '𝅘𝅥𝅱'), (0x1D164, 'M', '𝅘𝅥𝅲'), (0x1D165, 'V'), ] def _seg_59(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D173, 'X'), (0x1D17B, 'V'), (0x1D1BB, 'M', '𝆹𝅥'), (0x1D1BC, 'M', '𝆺𝅥'), (0x1D1BD, 'M', '𝆹𝅥𝅮'), (0x1D1BE, 'M', '𝆺𝅥𝅮'), (0x1D1BF, 'M', '𝆹𝅥𝅯'), (0x1D1C0, 'M', '𝆺𝅥𝅯'), (0x1D1C1, 'V'), (0x1D1E9, 'X'), (0x1D200, 'V'), (0x1D246, 'X'), (0x1D2E0, 'V'), (0x1D2F4, 'X'), (0x1D300, 'V'), (0x1D357, 'X'), (0x1D360, 'V'), (0x1D379, 'X'), (0x1D400, 'M', 'a'), (0x1D401, 'M', 'b'), (0x1D402, 'M', 'c'), (0x1D403, 'M', 'd'), (0x1D404, 'M', 'e'), (0x1D405, 'M', 'f'), (0x1D406, 'M', 'g'), (0x1D407, 'M', 'h'), (0x1D408, 'M', 'i'), (0x1D409, 'M', 'j'), (0x1D40A, 'M', 'k'), (0x1D40B, 'M', 'l'), (0x1D40C, 'M', 'm'), (0x1D40D, 'M', 'n'), (0x1D40E, 'M', 'o'), (0x1D40F, 'M', 'p'), (0x1D410, 'M', 'q'), (0x1D411, 'M', 'r'), (0x1D412, 'M', 's'), (0x1D413, 'M', 't'), (0x1D414, 'M', 'u'), (0x1D415, 'M', 'v'), (0x1D416, 'M', 'w'), (0x1D417, 'M', 'x'), (0x1D418, 'M', 'y'), (0x1D419, 'M', 'z'), (0x1D41A, 'M', 'a'), (0x1D41B, 'M', 'b'), (0x1D41C, 'M', 'c'), (0x1D41D, 'M', 'd'), (0x1D41E, 'M', 'e'), (0x1D41F, 'M', 'f'), (0x1D420, 'M', 'g'), (0x1D421, 'M', 'h'), (0x1D422, 'M', 'i'), (0x1D423, 'M', 'j'), (0x1D424, 'M', 'k'), (0x1D425, 'M', 'l'), (0x1D426, 'M', 'm'), (0x1D427, 'M', 'n'), (0x1D428, 'M', 'o'), (0x1D429, 'M', 'p'), (0x1D42A, 'M', 'q'), (0x1D42B, 'M', 'r'), (0x1D42C, 'M', 's'), (0x1D42D, 'M', 't'), (0x1D42E, 'M', 'u'), (0x1D42F, 'M', 'v'), (0x1D430, 'M', 'w'), (0x1D431, 'M', 'x'), (0x1D432, 'M', 'y'), (0x1D433, 'M', 'z'), (0x1D434, 'M', 'a'), (0x1D435, 'M', 'b'), (0x1D436, 'M', 'c'), (0x1D437, 'M', 'd'), (0x1D438, 'M', 'e'), (0x1D439, 'M', 'f'), (0x1D43A, 'M', 'g'), (0x1D43B, 'M', 'h'), (0x1D43C, 'M', 'i'), (0x1D43D, 'M', 'j'), (0x1D43E, 'M', 'k'), (0x1D43F, 'M', 'l'), (0x1D440, 'M', 'm'), (0x1D441, 'M', 'n'), (0x1D442, 'M', 'o'), (0x1D443, 'M', 'p'), (0x1D444, 'M', 'q'), (0x1D445, 'M', 'r'), (0x1D446, 'M', 's'), (0x1D447, 'M', 't'), (0x1D448, 'M', 'u'), (0x1D449, 'M', 'v'), (0x1D44A, 'M', 'w'), (0x1D44B, 'M', 'x'), (0x1D44C, 'M', 'y'), (0x1D44D, 'M', 'z'), (0x1D44E, 'M', 'a'), (0x1D44F, 'M', 'b'), (0x1D450, 'M', 'c'), (0x1D451, 'M', 'd'), ] def _seg_60(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D452, 'M', 'e'), (0x1D453, 'M', 'f'), (0x1D454, 'M', 'g'), (0x1D455, 'X'), (0x1D456, 'M', 'i'), (0x1D457, 'M', 'j'), (0x1D458, 'M', 'k'), (0x1D459, 'M', 'l'), (0x1D45A, 'M', 'm'), (0x1D45B, 'M', 'n'), (0x1D45C, 'M', 'o'), (0x1D45D, 'M', 'p'), (0x1D45E, 'M', 'q'), (0x1D45F, 'M', 'r'), (0x1D460, 'M', 's'), (0x1D461, 'M', 't'), (0x1D462, 'M', 'u'), (0x1D463, 'M', 'v'), (0x1D464, 'M', 'w'), (0x1D465, 'M', 'x'), (0x1D466, 'M', 'y'), (0x1D467, 'M', 'z'), (0x1D468, 'M', 'a'), (0x1D469, 'M', 'b'), (0x1D46A, 'M', 'c'), (0x1D46B, 'M', 'd'), (0x1D46C, 'M', 'e'), (0x1D46D, 'M', 'f'), (0x1D46E, 'M', 'g'), (0x1D46F, 'M', 'h'), (0x1D470, 'M', 'i'), (0x1D471, 'M', 'j'), (0x1D472, 'M', 'k'), (0x1D473, 'M', 'l'), (0x1D474, 'M', 'm'), (0x1D475, 'M', 'n'), (0x1D476, 'M', 'o'), (0x1D477, 'M', 'p'), (0x1D478, 'M', 'q'), (0x1D479, 'M', 'r'), (0x1D47A, 'M', 's'), (0x1D47B, 'M', 't'), (0x1D47C, 'M', 'u'), (0x1D47D, 'M', 'v'), (0x1D47E, 'M', 'w'), (0x1D47F, 'M', 'x'), (0x1D480, 'M', 'y'), (0x1D481, 'M', 'z'), (0x1D482, 'M', 'a'), (0x1D483, 'M', 'b'), (0x1D484, 'M', 'c'), (0x1D485, 'M', 'd'), (0x1D486, 'M', 'e'), (0x1D487, 'M', 'f'), (0x1D488, 'M', 'g'), (0x1D489, 'M', 'h'), (0x1D48A, 'M', 'i'), (0x1D48B, 'M', 'j'), (0x1D48C, 'M', 'k'), (0x1D48D, 'M', 'l'), (0x1D48E, 'M', 'm'), (0x1D48F, 'M', 'n'), (0x1D490, 'M', 'o'), (0x1D491, 'M', 'p'), (0x1D492, 'M', 'q'), (0x1D493, 'M', 'r'), (0x1D494, 'M', 's'), (0x1D495, 'M', 't'), (0x1D496, 'M', 'u'), (0x1D497, 'M', 'v'), (0x1D498, 'M', 'w'), (0x1D499, 'M', 'x'), (0x1D49A, 'M', 'y'), (0x1D49B, 'M', 'z'), (0x1D49C, 'M', 'a'), (0x1D49D, 'X'), (0x1D49E, 'M', 'c'), (0x1D49F, 'M', 'd'), (0x1D4A0, 'X'), (0x1D4A2, 'M', 'g'), (0x1D4A3, 'X'), (0x1D4A5, 'M', 'j'), (0x1D4A6, 'M', 'k'), (0x1D4A7, 'X'), (0x1D4A9, 'M', 'n'), (0x1D4AA, 'M', 'o'), (0x1D4AB, 'M', 'p'), (0x1D4AC, 'M', 'q'), (0x1D4AD, 'X'), (0x1D4AE, 'M', 's'), (0x1D4AF, 'M', 't'), (0x1D4B0, 'M', 'u'), (0x1D4B1, 'M', 'v'), (0x1D4B2, 'M', 'w'), (0x1D4B3, 'M', 'x'), (0x1D4B4, 'M', 'y'), (0x1D4B5, 'M', 'z'), (0x1D4B6, 'M', 'a'), (0x1D4B7, 'M', 'b'), (0x1D4B8, 'M', 'c'), ] def _seg_61(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D4B9, 'M', 'd'), (0x1D4BA, 'X'), (0x1D4BB, 'M', 'f'), (0x1D4BC, 'X'), (0x1D4BD, 'M', 'h'), (0x1D4BE, 'M', 'i'), (0x1D4BF, 'M', 'j'), (0x1D4C0, 'M', 'k'), (0x1D4C1, 'M', 'l'), (0x1D4C2, 'M', 'm'), (0x1D4C3, 'M', 'n'), (0x1D4C4, 'X'), (0x1D4C5, 'M', 'p'), (0x1D4C6, 'M', 'q'), (0x1D4C7, 'M', 'r'), (0x1D4C8, 'M', 's'), (0x1D4C9, 'M', 't'), (0x1D4CA, 'M', 'u'), (0x1D4CB, 'M', 'v'), (0x1D4CC, 'M', 'w'), (0x1D4CD, 'M', 'x'), (0x1D4CE, 'M', 'y'), (0x1D4CF, 'M', 'z'), (0x1D4D0, 'M', 'a'), (0x1D4D1, 'M', 'b'), (0x1D4D2, 'M', 'c'), (0x1D4D3, 'M', 'd'), (0x1D4D4, 'M', 'e'), (0x1D4D5, 'M', 'f'), (0x1D4D6, 'M', 'g'), (0x1D4D7, 'M', 'h'), (0x1D4D8, 'M', 'i'), (0x1D4D9, 'M', 'j'), (0x1D4DA, 'M', 'k'), (0x1D4DB, 'M', 'l'), (0x1D4DC, 'M', 'm'), (0x1D4DD, 'M', 'n'), (0x1D4DE, 'M', 'o'), (0x1D4DF, 'M', 'p'), (0x1D4E0, 'M', 'q'), (0x1D4E1, 'M', 'r'), (0x1D4E2, 'M', 's'), (0x1D4E3, 'M', 't'), (0x1D4E4, 'M', 'u'), (0x1D4E5, 'M', 'v'), (0x1D4E6, 'M', 'w'), (0x1D4E7, 'M', 'x'), (0x1D4E8, 'M', 'y'), (0x1D4E9, 'M', 'z'), (0x1D4EA, 'M', 'a'), (0x1D4EB, 'M', 'b'), (0x1D4EC, 'M', 'c'), (0x1D4ED, 'M', 'd'), (0x1D4EE, 'M', 'e'), (0x1D4EF, 'M', 'f'), (0x1D4F0, 'M', 'g'), (0x1D4F1, 'M', 'h'), (0x1D4F2, 'M', 'i'), (0x1D4F3, 'M', 'j'), (0x1D4F4, 'M', 'k'), (0x1D4F5, 'M', 'l'), (0x1D4F6, 'M', 'm'), (0x1D4F7, 'M', 'n'), (0x1D4F8, 'M', 'o'), (0x1D4F9, 'M', 'p'), (0x1D4FA, 'M', 'q'), (0x1D4FB, 'M', 'r'), (0x1D4FC, 'M', 's'), (0x1D4FD, 'M', 't'), (0x1D4FE, 'M', 'u'), (0x1D4FF, 'M', 'v'), (0x1D500, 'M', 'w'), (0x1D501, 'M', 'x'), (0x1D502, 'M', 'y'), (0x1D503, 'M', 'z'), (0x1D504, 'M', 'a'), (0x1D505, 'M', 'b'), (0x1D506, 'X'), (0x1D507, 'M', 'd'), (0x1D508, 'M', 'e'), (0x1D509, 'M', 'f'), (0x1D50A, 'M', 'g'), (0x1D50B, 'X'), (0x1D50D, 'M', 'j'), (0x1D50E, 'M', 'k'), (0x1D50F, 'M', 'l'), (0x1D510, 'M', 'm'), (0x1D511, 'M', 'n'), (0x1D512, 'M', 'o'), (0x1D513, 'M', 'p'), (0x1D514, 'M', 'q'), (0x1D515, 'X'), (0x1D516, 'M', 's'), (0x1D517, 'M', 't'), (0x1D518, 'M', 'u'), (0x1D519, 'M', 'v'), (0x1D51A, 'M', 'w'), (0x1D51B, 'M', 'x'), (0x1D51C, 'M', 'y'), (0x1D51D, 'X'), ] def _seg_62(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D51E, 'M', 'a'), (0x1D51F, 'M', 'b'), (0x1D520, 'M', 'c'), (0x1D521, 'M', 'd'), (0x1D522, 'M', 'e'), (0x1D523, 'M', 'f'), (0x1D524, 'M', 'g'), (0x1D525, 'M', 'h'), (0x1D526, 'M', 'i'), (0x1D527, 'M', 'j'), (0x1D528, 'M', 'k'), (0x1D529, 'M', 'l'), (0x1D52A, 'M', 'm'), (0x1D52B, 'M', 'n'), (0x1D52C, 'M', 'o'), (0x1D52D, 'M', 'p'), (0x1D52E, 'M', 'q'), (0x1D52F, 'M', 'r'), (0x1D530, 'M', 's'), (0x1D531, 'M', 't'), (0x1D532, 'M', 'u'), (0x1D533, 'M', 'v'), (0x1D534, 'M', 'w'), (0x1D535, 'M', 'x'), (0x1D536, 'M', 'y'), (0x1D537, 'M', 'z'), (0x1D538, 'M', 'a'), (0x1D539, 'M', 'b'), (0x1D53A, 'X'), (0x1D53B, 'M', 'd'), (0x1D53C, 'M', 'e'), (0x1D53D, 'M', 'f'), (0x1D53E, 'M', 'g'), (0x1D53F, 'X'), (0x1D540, 'M', 'i'), (0x1D541, 'M', 'j'), (0x1D542, 'M', 'k'), (0x1D543, 'M', 'l'), (0x1D544, 'M', 'm'), (0x1D545, 'X'), (0x1D546, 'M', 'o'), (0x1D547, 'X'), (0x1D54A, 'M', 's'), (0x1D54B, 'M', 't'), (0x1D54C, 'M', 'u'), (0x1D54D, 'M', 'v'), (0x1D54E, 'M', 'w'), (0x1D54F, 'M', 'x'), (0x1D550, 'M', 'y'), (0x1D551, 'X'), (0x1D552, 'M', 'a'), (0x1D553, 'M', 'b'), (0x1D554, 'M', 'c'), (0x1D555, 'M', 'd'), (0x1D556, 'M', 'e'), (0x1D557, 'M', 'f'), (0x1D558, 'M', 'g'), (0x1D559, 'M', 'h'), (0x1D55A, 'M', 'i'), (0x1D55B, 'M', 'j'), (0x1D55C, 'M', 'k'), (0x1D55D, 'M', 'l'), (0x1D55E, 'M', 'm'), (0x1D55F, 'M', 'n'), (0x1D560, 'M', 'o'), (0x1D561, 'M', 'p'), (0x1D562, 'M', 'q'), (0x1D563, 'M', 'r'), (0x1D564, 'M', 's'), (0x1D565, 'M', 't'), (0x1D566, 'M', 'u'), (0x1D567, 'M', 'v'), (0x1D568, 'M', 'w'), (0x1D569, 'M', 'x'), (0x1D56A, 'M', 'y'), (0x1D56B, 'M', 'z'), (0x1D56C, 'M', 'a'), (0x1D56D, 'M', 'b'), (0x1D56E, 'M', 'c'), (0x1D56F, 'M', 'd'), (0x1D570, 'M', 'e'), (0x1D571, 'M', 'f'), (0x1D572, 'M', 'g'), (0x1D573, 'M', 'h'), (0x1D574, 'M', 'i'), (0x1D575, 'M', 'j'), (0x1D576, 'M', 'k'), (0x1D577, 'M', 'l'), (0x1D578, 'M', 'm'), (0x1D579, 'M', 'n'), (0x1D57A, 'M', 'o'), (0x1D57B, 'M', 'p'), (0x1D57C, 'M', 'q'), (0x1D57D, 'M', 'r'), (0x1D57E, 'M', 's'), (0x1D57F, 'M', 't'), (0x1D580, 'M', 'u'), (0x1D581, 'M', 'v'), (0x1D582, 'M', 'w'), (0x1D583, 'M', 'x'), ] def _seg_63(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D584, 'M', 'y'), (0x1D585, 'M', 'z'), (0x1D586, 'M', 'a'), (0x1D587, 'M', 'b'), (0x1D588, 'M', 'c'), (0x1D589, 'M', 'd'), (0x1D58A, 'M', 'e'), (0x1D58B, 'M', 'f'), (0x1D58C, 'M', 'g'), (0x1D58D, 'M', 'h'), (0x1D58E, 'M', 'i'), (0x1D58F, 'M', 'j'), (0x1D590, 'M', 'k'), (0x1D591, 'M', 'l'), (0x1D592, 'M', 'm'), (0x1D593, 'M', 'n'), (0x1D594, 'M', 'o'), (0x1D595, 'M', 'p'), (0x1D596, 'M', 'q'), (0x1D597, 'M', 'r'), (0x1D598, 'M', 's'), (0x1D599, 'M', 't'), (0x1D59A, 'M', 'u'), (0x1D59B, 'M', 'v'), (0x1D59C, 'M', 'w'), (0x1D59D, 'M', 'x'), (0x1D59E, 'M', 'y'), (0x1D59F, 'M', 'z'), (0x1D5A0, 'M', 'a'), (0x1D5A1, 'M', 'b'), (0x1D5A2, 'M', 'c'), (0x1D5A3, 'M', 'd'), (0x1D5A4, 'M', 'e'), (0x1D5A5, 'M', 'f'), (0x1D5A6, 'M', 'g'), (0x1D5A7, 'M', 'h'), (0x1D5A8, 'M', 'i'), (0x1D5A9, 'M', 'j'), (0x1D5AA, 'M', 'k'), (0x1D5AB, 'M', 'l'), (0x1D5AC, 'M', 'm'), (0x1D5AD, 'M', 'n'), (0x1D5AE, 'M', 'o'), (0x1D5AF, 'M', 'p'), (0x1D5B0, 'M', 'q'), (0x1D5B1, 'M', 'r'), (0x1D5B2, 'M', 's'), (0x1D5B3, 'M', 't'), (0x1D5B4, 'M', 'u'), (0x1D5B5, 'M', 'v'), (0x1D5B6, 'M', 'w'), (0x1D5B7, 'M', 'x'), (0x1D5B8, 'M', 'y'), (0x1D5B9, 'M', 'z'), (0x1D5BA, 'M', 'a'), (0x1D5BB, 'M', 'b'), (0x1D5BC, 'M', 'c'), (0x1D5BD, 'M', 'd'), (0x1D5BE, 'M', 'e'), (0x1D5BF, 'M', 'f'), (0x1D5C0, 'M', 'g'), (0x1D5C1, 'M', 'h'), (0x1D5C2, 'M', 'i'), (0x1D5C3, 'M', 'j'), (0x1D5C4, 'M', 'k'), (0x1D5C5, 'M', 'l'), (0x1D5C6, 'M', 'm'), (0x1D5C7, 'M', 'n'), (0x1D5C8, 'M', 'o'), (0x1D5C9, 'M', 'p'), (0x1D5CA, 'M', 'q'), (0x1D5CB, 'M', 'r'), (0x1D5CC, 'M', 's'), (0x1D5CD, 'M', 't'), (0x1D5CE, 'M', 'u'), (0x1D5CF, 'M', 'v'), (0x1D5D0, 'M', 'w'), (0x1D5D1, 'M', 'x'), (0x1D5D2, 'M', 'y'), (0x1D5D3, 'M', 'z'), (0x1D5D4, 'M', 'a'), (0x1D5D5, 'M', 'b'), (0x1D5D6, 'M', 'c'), (0x1D5D7, 'M', 'd'), (0x1D5D8, 'M', 'e'), (0x1D5D9, 'M', 'f'), (0x1D5DA, 'M', 'g'), (0x1D5DB, 'M', 'h'), (0x1D5DC, 'M', 'i'), (0x1D5DD, 'M', 'j'), (0x1D5DE, 'M', 'k'), (0x1D5DF, 'M', 'l'), (0x1D5E0, 'M', 'm'), (0x1D5E1, 'M', 'n'), (0x1D5E2, 'M', 'o'), (0x1D5E3, 'M', 'p'), (0x1D5E4, 'M', 'q'), (0x1D5E5, 'M', 'r'), (0x1D5E6, 'M', 's'), (0x1D5E7, 'M', 't'), ] def _seg_64(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D5E8, 'M', 'u'), (0x1D5E9, 'M', 'v'), (0x1D5EA, 'M', 'w'), (0x1D5EB, 'M', 'x'), (0x1D5EC, 'M', 'y'), (0x1D5ED, 'M', 'z'), (0x1D5EE, 'M', 'a'), (0x1D5EF, 'M', 'b'), (0x1D5F0, 'M', 'c'), (0x1D5F1, 'M', 'd'), (0x1D5F2, 'M', 'e'), (0x1D5F3, 'M', 'f'), (0x1D5F4, 'M', 'g'), (0x1D5F5, 'M', 'h'), (0x1D5F6, 'M', 'i'), (0x1D5F7, 'M', 'j'), (0x1D5F8, 'M', 'k'), (0x1D5F9, 'M', 'l'), (0x1D5FA, 'M', 'm'), (0x1D5FB, 'M', 'n'), (0x1D5FC, 'M', 'o'), (0x1D5FD, 'M', 'p'), (0x1D5FE, 'M', 'q'), (0x1D5FF, 'M', 'r'), (0x1D600, 'M', 's'), (0x1D601, 'M', 't'), (0x1D602, 'M', 'u'), (0x1D603, 'M', 'v'), (0x1D604, 'M', 'w'), (0x1D605, 'M', 'x'), (0x1D606, 'M', 'y'), (0x1D607, 'M', 'z'), (0x1D608, 'M', 'a'), (0x1D609, 'M', 'b'), (0x1D60A, 'M', 'c'), (0x1D60B, 'M', 'd'), (0x1D60C, 'M', 'e'), (0x1D60D, 'M', 'f'), (0x1D60E, 'M', 'g'), (0x1D60F, 'M', 'h'), (0x1D610, 'M', 'i'), (0x1D611, 'M', 'j'), (0x1D612, 'M', 'k'), (0x1D613, 'M', 'l'), (0x1D614, 'M', 'm'), (0x1D615, 'M', 'n'), (0x1D616, 'M', 'o'), (0x1D617, 'M', 'p'), (0x1D618, 'M', 'q'), (0x1D619, 'M', 'r'), (0x1D61A, 'M', 's'), (0x1D61B, 'M', 't'), (0x1D61C, 'M', 'u'), (0x1D61D, 'M', 'v'), (0x1D61E, 'M', 'w'), (0x1D61F, 'M', 'x'), (0x1D620, 'M', 'y'), (0x1D621, 'M', 'z'), (0x1D622, 'M', 'a'), (0x1D623, 'M', 'b'), (0x1D624, 'M', 'c'), (0x1D625, 'M', 'd'), (0x1D626, 'M', 'e'), (0x1D627, 'M', 'f'), (0x1D628, 'M', 'g'), (0x1D629, 'M', 'h'), (0x1D62A, 'M', 'i'), (0x1D62B, 'M', 'j'), (0x1D62C, 'M', 'k'), (0x1D62D, 'M', 'l'), (0x1D62E, 'M', 'm'), (0x1D62F, 'M', 'n'), (0x1D630, 'M', 'o'), (0x1D631, 'M', 'p'), (0x1D632, 'M', 'q'), (0x1D633, 'M', 'r'), (0x1D634, 'M', 's'), (0x1D635, 'M', 't'), (0x1D636, 'M', 'u'), (0x1D637, 'M', 'v'), (0x1D638, 'M', 'w'), (0x1D639, 'M', 'x'), (0x1D63A, 'M', 'y'), (0x1D63B, 'M', 'z'), (0x1D63C, 'M', 'a'), (0x1D63D, 'M', 'b'), (0x1D63E, 'M', 'c'), (0x1D63F, 'M', 'd'), (0x1D640, 'M', 'e'), (0x1D641, 'M', 'f'), (0x1D642, 'M', 'g'), (0x1D643, 'M', 'h'), (0x1D644, 'M', 'i'), (0x1D645, 'M', 'j'), (0x1D646, 'M', 'k'), (0x1D647, 'M', 'l'), (0x1D648, 'M', 'm'), (0x1D649, 'M', 'n'), (0x1D64A, 'M', 'o'), (0x1D64B, 'M', 'p'), ] def _seg_65(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D64C, 'M', 'q'), (0x1D64D, 'M', 'r'), (0x1D64E, 'M', 's'), (0x1D64F, 'M', 't'), (0x1D650, 'M', 'u'), (0x1D651, 'M', 'v'), (0x1D652, 'M', 'w'), (0x1D653, 'M', 'x'), (0x1D654, 'M', 'y'), (0x1D655, 'M', 'z'), (0x1D656, 'M', 'a'), (0x1D657, 'M', 'b'), (0x1D658, 'M', 'c'), (0x1D659, 'M', 'd'), (0x1D65A, 'M', 'e'), (0x1D65B, 'M', 'f'), (0x1D65C, 'M', 'g'), (0x1D65D, 'M', 'h'), (0x1D65E, 'M', 'i'), (0x1D65F, 'M', 'j'), (0x1D660, 'M', 'k'), (0x1D661, 'M', 'l'), (0x1D662, 'M', 'm'), (0x1D663, 'M', 'n'), (0x1D664, 'M', 'o'), (0x1D665, 'M', 'p'), (0x1D666, 'M', 'q'), (0x1D667, 'M', 'r'), (0x1D668, 'M', 's'), (0x1D669, 'M', 't'), (0x1D66A, 'M', 'u'), (0x1D66B, 'M', 'v'), (0x1D66C, 'M', 'w'), (0x1D66D, 'M', 'x'), (0x1D66E, 'M', 'y'), (0x1D66F, 'M', 'z'), (0x1D670, 'M', 'a'), (0x1D671, 'M', 'b'), (0x1D672, 'M', 'c'), (0x1D673, 'M', 'd'), (0x1D674, 'M', 'e'), (0x1D675, 'M', 'f'), (0x1D676, 'M', 'g'), (0x1D677, 'M', 'h'), (0x1D678, 'M', 'i'), (0x1D679, 'M', 'j'), (0x1D67A, 'M', 'k'), (0x1D67B, 'M', 'l'), (0x1D67C, 'M', 'm'), (0x1D67D, 'M', 'n'), (0x1D67E, 'M', 'o'), (0x1D67F, 'M', 'p'), (0x1D680, 'M', 'q'), (0x1D681, 'M', 'r'), (0x1D682, 'M', 's'), (0x1D683, 'M', 't'), (0x1D684, 'M', 'u'), (0x1D685, 'M', 'v'), (0x1D686, 'M', 'w'), (0x1D687, 'M', 'x'), (0x1D688, 'M', 'y'), (0x1D689, 'M', 'z'), (0x1D68A, 'M', 'a'), (0x1D68B, 'M', 'b'), (0x1D68C, 'M', 'c'), (0x1D68D, 'M', 'd'), (0x1D68E, 'M', 'e'), (0x1D68F, 'M', 'f'), (0x1D690, 'M', 'g'), (0x1D691, 'M', 'h'), (0x1D692, 'M', 'i'), (0x1D693, 'M', 'j'), (0x1D694, 'M', 'k'), (0x1D695, 'M', 'l'), (0x1D696, 'M', 'm'), (0x1D697, 'M', 'n'), (0x1D698, 'M', 'o'), (0x1D699, 'M', 'p'), (0x1D69A, 'M', 'q'), (0x1D69B, 'M', 'r'), (0x1D69C, 'M', 's'), (0x1D69D, 'M', 't'), (0x1D69E, 'M', 'u'), (0x1D69F, 'M', 'v'), (0x1D6A0, 'M', 'w'), (0x1D6A1, 'M', 'x'), (0x1D6A2, 'M', 'y'), (0x1D6A3, 'M', 'z'), (0x1D6A4, 'M', 'ı'), (0x1D6A5, 'M', 'ȷ'), (0x1D6A6, 'X'), (0x1D6A8, 'M', 'α'), (0x1D6A9, 'M', 'β'), (0x1D6AA, 'M', 'γ'), (0x1D6AB, 'M', 'δ'), (0x1D6AC, 'M', 'ε'), (0x1D6AD, 'M', 'ζ'), (0x1D6AE, 'M', 'η'), (0x1D6AF, 'M', 'θ'), (0x1D6B0, 'M', 'ι'), ] def _seg_66(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D6B1, 'M', 'κ'), (0x1D6B2, 'M', 'λ'), (0x1D6B3, 'M', 'μ'), (0x1D6B4, 'M', 'ν'), (0x1D6B5, 'M', 'ξ'), (0x1D6B6, 'M', 'ο'), (0x1D6B7, 'M', 'π'), (0x1D6B8, 'M', 'ρ'), (0x1D6B9, 'M', 'θ'), (0x1D6BA, 'M', 'σ'), (0x1D6BB, 'M', 'τ'), (0x1D6BC, 'M', 'υ'), (0x1D6BD, 'M', 'φ'), (0x1D6BE, 'M', 'χ'), (0x1D6BF, 'M', 'ψ'), (0x1D6C0, 'M', 'ω'), (0x1D6C1, 'M', '∇'), (0x1D6C2, 'M', 'α'), (0x1D6C3, 'M', 'β'), (0x1D6C4, 'M', 'γ'), (0x1D6C5, 'M', 'δ'), (0x1D6C6, 'M', 'ε'), (0x1D6C7, 'M', 'ζ'), (0x1D6C8, 'M', 'η'), (0x1D6C9, 'M', 'θ'), (0x1D6CA, 'M', 'ι'), (0x1D6CB, 'M', 'κ'), (0x1D6CC, 'M', 'λ'), (0x1D6CD, 'M', 'μ'), (0x1D6CE, 'M', 'ν'), (0x1D6CF, 'M', 'ξ'), (0x1D6D0, 'M', 'ο'), (0x1D6D1, 'M', 'π'), (0x1D6D2, 'M', 'ρ'), (0x1D6D3, 'M', 'σ'), (0x1D6D5, 'M', 'τ'), (0x1D6D6, 'M', 'υ'), (0x1D6D7, 'M', 'φ'), (0x1D6D8, 'M', 'χ'), (0x1D6D9, 'M', 'ψ'), (0x1D6DA, 'M', 'ω'), (0x1D6DB, 'M', '∂'), (0x1D6DC, 'M', 'ε'), (0x1D6DD, 'M', 'θ'), (0x1D6DE, 'M', 'κ'), (0x1D6DF, 'M', 'φ'), (0x1D6E0, 'M', 'ρ'), (0x1D6E1, 'M', 'π'), (0x1D6E2, 'M', 'α'), (0x1D6E3, 'M', 'β'), (0x1D6E4, 'M', 'γ'), (0x1D6E5, 'M', 'δ'), (0x1D6E6, 'M', 'ε'), (0x1D6E7, 'M', 'ζ'), (0x1D6E8, 'M', 'η'), (0x1D6E9, 'M', 'θ'), (0x1D6EA, 'M', 'ι'), (0x1D6EB, 'M', 'κ'), (0x1D6EC, 'M', 'λ'), (0x1D6ED, 'M', 'μ'), (0x1D6EE, 'M', 'ν'), (0x1D6EF, 'M', 'ξ'), (0x1D6F0, 'M', 'ο'), (0x1D6F1, 'M', 'π'), (0x1D6F2, 'M', 'ρ'), (0x1D6F3, 'M', 'θ'), (0x1D6F4, 'M', 'σ'), (0x1D6F5, 'M', 'τ'), (0x1D6F6, 'M', 'υ'), (0x1D6F7, 'M', 'φ'), (0x1D6F8, 'M', 'χ'), (0x1D6F9, 'M', 'ψ'), (0x1D6FA, 'M', 'ω'), (0x1D6FB, 'M', '∇'), (0x1D6FC, 'M', 'α'), (0x1D6FD, 'M', 'β'), (0x1D6FE, 'M', 'γ'), (0x1D6FF, 'M', 'δ'), (0x1D700, 'M', 'ε'), (0x1D701, 'M', 'ζ'), (0x1D702, 'M', 'η'), (0x1D703, 'M', 'θ'), (0x1D704, 'M', 'ι'), (0x1D705, 'M', 'κ'), (0x1D706, 'M', 'λ'), (0x1D707, 'M', 'μ'), (0x1D708, 'M', 'ν'), (0x1D709, 'M', 'ξ'), (0x1D70A, 'M', 'ο'), (0x1D70B, 'M', 'π'), (0x1D70C, 'M', 'ρ'), (0x1D70D, 'M', 'σ'), (0x1D70F, 'M', 'τ'), (0x1D710, 'M', 'υ'), (0x1D711, 'M', 'φ'), (0x1D712, 'M', 'χ'), (0x1D713, 'M', 'ψ'), (0x1D714, 'M', 'ω'), (0x1D715, 'M', '∂'), (0x1D716, 'M', 'ε'), ] def _seg_67(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D717, 'M', 'θ'), (0x1D718, 'M', 'κ'), (0x1D719, 'M', 'φ'), (0x1D71A, 'M', 'ρ'), (0x1D71B, 'M', 'π'), (0x1D71C, 'M', 'α'), (0x1D71D, 'M', 'β'), (0x1D71E, 'M', 'γ'), (0x1D71F, 'M', 'δ'), (0x1D720, 'M', 'ε'), (0x1D721, 'M', 'ζ'), (0x1D722, 'M', 'η'), (0x1D723, 'M', 'θ'), (0x1D724, 'M', 'ι'), (0x1D725, 'M', 'κ'), (0x1D726, 'M', 'λ'), (0x1D727, 'M', 'μ'), (0x1D728, 'M', 'ν'), (0x1D729, 'M', 'ξ'), (0x1D72A, 'M', 'ο'), (0x1D72B, 'M', 'π'), (0x1D72C, 'M', 'ρ'), (0x1D72D, 'M', 'θ'), (0x1D72E, 'M', 'σ'), (0x1D72F, 'M', 'τ'), (0x1D730, 'M', 'υ'), (0x1D731, 'M', 'φ'), (0x1D732, 'M', 'χ'), (0x1D733, 'M', 'ψ'), (0x1D734, 'M', 'ω'), (0x1D735, 'M', '∇'), (0x1D736, 'M', 'α'), (0x1D737, 'M', 'β'), (0x1D738, 'M', 'γ'), (0x1D739, 'M', 'δ'), (0x1D73A, 'M', 'ε'), (0x1D73B, 'M', 'ζ'), (0x1D73C, 'M', 'η'), (0x1D73D, 'M', 'θ'), (0x1D73E, 'M', 'ι'), (0x1D73F, 'M', 'κ'), (0x1D740, 'M', 'λ'), (0x1D741, 'M', 'μ'), (0x1D742, 'M', 'ν'), (0x1D743, 'M', 'ξ'), (0x1D744, 'M', 'ο'), (0x1D745, 'M', 'π'), (0x1D746, 'M', 'ρ'), (0x1D747, 'M', 'σ'), (0x1D749, 'M', 'τ'), (0x1D74A, 'M', 'υ'), (0x1D74B, 'M', 'φ'), (0x1D74C, 'M', 'χ'), (0x1D74D, 'M', 'ψ'), (0x1D74E, 'M', 'ω'), (0x1D74F, 'M', '∂'), (0x1D750, 'M', 'ε'), (0x1D751, 'M', 'θ'), (0x1D752, 'M', 'κ'), (0x1D753, 'M', 'φ'), (0x1D754, 'M', 'ρ'), (0x1D755, 'M', 'π'), (0x1D756, 'M', 'α'), (0x1D757, 'M', 'β'), (0x1D758, 'M', 'γ'), (0x1D759, 'M', 'δ'), (0x1D75A, 'M', 'ε'), (0x1D75B, 'M', 'ζ'), (0x1D75C, 'M', 'η'), (0x1D75D, 'M', 'θ'), (0x1D75E, 'M', 'ι'), (0x1D75F, 'M', 'κ'), (0x1D760, 'M', 'λ'), (0x1D761, 'M', 'μ'), (0x1D762, 'M', 'ν'), (0x1D763, 'M', 'ξ'), (0x1D764, 'M', 'ο'), (0x1D765, 'M', 'π'), (0x1D766, 'M', 'ρ'), (0x1D767, 'M', 'θ'), (0x1D768, 'M', 'σ'), (0x1D769, 'M', 'τ'), (0x1D76A, 'M', 'υ'), (0x1D76B, 'M', 'φ'), (0x1D76C, 'M', 'χ'), (0x1D76D, 'M', 'ψ'), (0x1D76E, 'M', 'ω'), (0x1D76F, 'M', '∇'), (0x1D770, 'M', 'α'), (0x1D771, 'M', 'β'), (0x1D772, 'M', 'γ'), (0x1D773, 'M', 'δ'), (0x1D774, 'M', 'ε'), (0x1D775, 'M', 'ζ'), (0x1D776, 'M', 'η'), (0x1D777, 'M', 'θ'), (0x1D778, 'M', 'ι'), (0x1D779, 'M', 'κ'), (0x1D77A, 'M', 'λ'), (0x1D77B, 'M', 'μ'), ] def _seg_68(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D77C, 'M', 'ν'), (0x1D77D, 'M', 'ξ'), (0x1D77E, 'M', 'ο'), (0x1D77F, 'M', 'π'), (0x1D780, 'M', 'ρ'), (0x1D781, 'M', 'σ'), (0x1D783, 'M', 'τ'), (0x1D784, 'M', 'υ'), (0x1D785, 'M', 'φ'), (0x1D786, 'M', 'χ'), (0x1D787, 'M', 'ψ'), (0x1D788, 'M', 'ω'), (0x1D789, 'M', '∂'), (0x1D78A, 'M', 'ε'), (0x1D78B, 'M', 'θ'), (0x1D78C, 'M', 'κ'), (0x1D78D, 'M', 'φ'), (0x1D78E, 'M', 'ρ'), (0x1D78F, 'M', 'π'), (0x1D790, 'M', 'α'), (0x1D791, 'M', 'β'), (0x1D792, 'M', 'γ'), (0x1D793, 'M', 'δ'), (0x1D794, 'M', 'ε'), (0x1D795, 'M', 'ζ'), (0x1D796, 'M', 'η'), (0x1D797, 'M', 'θ'), (0x1D798, 'M', 'ι'), (0x1D799, 'M', 'κ'), (0x1D79A, 'M', 'λ'), (0x1D79B, 'M', 'μ'), (0x1D79C, 'M', 'ν'), (0x1D79D, 'M', 'ξ'), (0x1D79E, 'M', 'ο'), (0x1D79F, 'M', 'π'), (0x1D7A0, 'M', 'ρ'), (0x1D7A1, 'M', 'θ'), (0x1D7A2, 'M', 'σ'), (0x1D7A3, 'M', 'τ'), (0x1D7A4, 'M', 'υ'), (0x1D7A5, 'M', 'φ'), (0x1D7A6, 'M', 'χ'), (0x1D7A7, 'M', 'ψ'), (0x1D7A8, 'M', 'ω'), (0x1D7A9, 'M', '∇'), (0x1D7AA, 'M', 'α'), (0x1D7AB, 'M', 'β'), (0x1D7AC, 'M', 'γ'), (0x1D7AD, 'M', 'δ'), (0x1D7AE, 'M', 'ε'), (0x1D7AF, 'M', 'ζ'), (0x1D7B0, 'M', 'η'), (0x1D7B1, 'M', 'θ'), (0x1D7B2, 'M', 'ι'), (0x1D7B3, 'M', 'κ'), (0x1D7B4, 'M', 'λ'), (0x1D7B5, 'M', 'μ'), (0x1D7B6, 'M', 'ν'), (0x1D7B7, 'M', 'ξ'), (0x1D7B8, 'M', 'ο'), (0x1D7B9, 'M', 'π'), (0x1D7BA, 'M', 'ρ'), (0x1D7BB, 'M', 'σ'), (0x1D7BD, 'M', 'τ'), (0x1D7BE, 'M', 'υ'), (0x1D7BF, 'M', 'φ'), (0x1D7C0, 'M', 'χ'), (0x1D7C1, 'M', 'ψ'), (0x1D7C2, 'M', 'ω'), (0x1D7C3, 'M', '∂'), (0x1D7C4, 'M', 'ε'), (0x1D7C5, 'M', 'θ'), (0x1D7C6, 'M', 'κ'), (0x1D7C7, 'M', 'φ'), (0x1D7C8, 'M', 'ρ'), (0x1D7C9, 'M', 'π'), (0x1D7CA, 'M', 'ϝ'), (0x1D7CC, 'X'), (0x1D7CE, 'M', '0'), (0x1D7CF, 'M', '1'), (0x1D7D0, 'M', '2'), (0x1D7D1, 'M', '3'), (0x1D7D2, 'M', '4'), (0x1D7D3, 'M', '5'), (0x1D7D4, 'M', '6'), (0x1D7D5, 'M', '7'), (0x1D7D6, 'M', '8'), (0x1D7D7, 'M', '9'), (0x1D7D8, 'M', '0'), (0x1D7D9, 'M', '1'), (0x1D7DA, 'M', '2'), (0x1D7DB, 'M', '3'), (0x1D7DC, 'M', '4'), (0x1D7DD, 'M', '5'), (0x1D7DE, 'M', '6'), (0x1D7DF, 'M', '7'), (0x1D7E0, 'M', '8'), (0x1D7E1, 'M', '9'), (0x1D7E2, 'M', '0'), (0x1D7E3, 'M', '1'), ] def _seg_69(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1D7E4, 'M', '2'), (0x1D7E5, 'M', '3'), (0x1D7E6, 'M', '4'), (0x1D7E7, 'M', '5'), (0x1D7E8, 'M', '6'), (0x1D7E9, 'M', '7'), (0x1D7EA, 'M', '8'), (0x1D7EB, 'M', '9'), (0x1D7EC, 'M', '0'), (0x1D7ED, 'M', '1'), (0x1D7EE, 'M', '2'), (0x1D7EF, 'M', '3'), (0x1D7F0, 'M', '4'), (0x1D7F1, 'M', '5'), (0x1D7F2, 'M', '6'), (0x1D7F3, 'M', '7'), (0x1D7F4, 'M', '8'), (0x1D7F5, 'M', '9'), (0x1D7F6, 'M', '0'), (0x1D7F7, 'M', '1'), (0x1D7F8, 'M', '2'), (0x1D7F9, 'M', '3'), (0x1D7FA, 'M', '4'), (0x1D7FB, 'M', '5'), (0x1D7FC, 'M', '6'), (0x1D7FD, 'M', '7'), (0x1D7FE, 'M', '8'), (0x1D7FF, 'M', '9'), (0x1D800, 'V'), (0x1DA8C, 'X'), (0x1DA9B, 'V'), (0x1DAA0, 'X'), (0x1DAA1, 'V'), (0x1DAB0, 'X'), (0x1E000, 'V'), (0x1E007, 'X'), (0x1E008, 'V'), (0x1E019, 'X'), (0x1E01B, 'V'), (0x1E022, 'X'), (0x1E023, 'V'), (0x1E025, 'X'), (0x1E026, 'V'), (0x1E02B, 'X'), (0x1E100, 'V'), (0x1E12D, 'X'), (0x1E130, 'V'), (0x1E13E, 'X'), (0x1E140, 'V'), (0x1E14A, 'X'), (0x1E14E, 'V'), (0x1E150, 'X'), (0x1E2C0, 'V'), (0x1E2FA, 'X'), (0x1E2FF, 'V'), (0x1E300, 'X'), (0x1E800, 'V'), (0x1E8C5, 'X'), (0x1E8C7, 'V'), (0x1E8D7, 'X'), (0x1E900, 'M', '𞤢'), (0x1E901, 'M', '𞤣'), (0x1E902, 'M', '𞤤'), (0x1E903, 'M', '𞤥'), (0x1E904, 'M', '𞤦'), (0x1E905, 'M', '𞤧'), (0x1E906, 'M', '𞤨'), (0x1E907, 'M', '𞤩'), (0x1E908, 'M', '𞤪'), (0x1E909, 'M', '𞤫'), (0x1E90A, 'M', '𞤬'), (0x1E90B, 'M', '𞤭'), (0x1E90C, 'M', '𞤮'), (0x1E90D, 'M', '𞤯'), (0x1E90E, 'M', '𞤰'), (0x1E90F, 'M', '𞤱'), (0x1E910, 'M', '𞤲'), (0x1E911, 'M', '𞤳'), (0x1E912, 'M', '𞤴'), (0x1E913, 'M', '𞤵'), (0x1E914, 'M', '𞤶'), (0x1E915, 'M', '𞤷'), (0x1E916, 'M', '𞤸'), (0x1E917, 'M', '𞤹'), (0x1E918, 'M', '𞤺'), (0x1E919, 'M', '𞤻'), (0x1E91A, 'M', '𞤼'), (0x1E91B, 'M', '𞤽'), (0x1E91C, 'M', '𞤾'), (0x1E91D, 'M', '𞤿'), (0x1E91E, 'M', '𞥀'), (0x1E91F, 'M', '𞥁'), (0x1E920, 'M', '𞥂'), (0x1E921, 'M', '𞥃'), (0x1E922, 'V'), (0x1E94C, 'X'), (0x1E950, 'V'), (0x1E95A, 'X'), (0x1E95E, 'V'), (0x1E960, 'X'), ] def _seg_70(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1EC71, 'V'), (0x1ECB5, 'X'), (0x1ED01, 'V'), (0x1ED3E, 'X'), (0x1EE00, 'M', 'ا'), (0x1EE01, 'M', 'ب'), (0x1EE02, 'M', 'ج'), (0x1EE03, 'M', 'د'), (0x1EE04, 'X'), (0x1EE05, 'M', 'و'), (0x1EE06, 'M', 'ز'), (0x1EE07, 'M', 'ح'), (0x1EE08, 'M', 'ط'), (0x1EE09, 'M', 'ي'), (0x1EE0A, 'M', 'ك'), (0x1EE0B, 'M', 'ل'), (0x1EE0C, 'M', 'م'), (0x1EE0D, 'M', 'ن'), (0x1EE0E, 'M', 'س'), (0x1EE0F, 'M', 'ع'), (0x1EE10, 'M', 'ف'), (0x1EE11, 'M', 'ص'), (0x1EE12, 'M', 'ق'), (0x1EE13, 'M', 'ر'), (0x1EE14, 'M', 'ش'), (0x1EE15, 'M', 'ت'), (0x1EE16, 'M', 'ث'), (0x1EE17, 'M', 'خ'), (0x1EE18, 'M', 'ذ'), (0x1EE19, 'M', 'ض'), (0x1EE1A, 'M', 'ظ'), (0x1EE1B, 'M', 'غ'), (0x1EE1C, 'M', 'ٮ'), (0x1EE1D, 'M', 'ں'), (0x1EE1E, 'M', 'ڡ'), (0x1EE1F, 'M', 'ٯ'), (0x1EE20, 'X'), (0x1EE21, 'M', 'ب'), (0x1EE22, 'M', 'ج'), (0x1EE23, 'X'), (0x1EE24, 'M', 'ه'), (0x1EE25, 'X'), (0x1EE27, 'M', 'ح'), (0x1EE28, 'X'), (0x1EE29, 'M', 'ي'), (0x1EE2A, 'M', 'ك'), (0x1EE2B, 'M', 'ل'), (0x1EE2C, 'M', 'م'), (0x1EE2D, 'M', 'ن'), (0x1EE2E, 'M', 'س'), (0x1EE2F, 'M', 'ع'), (0x1EE30, 'M', 'ف'), (0x1EE31, 'M', 'ص'), (0x1EE32, 'M', 'ق'), (0x1EE33, 'X'), (0x1EE34, 'M', 'ش'), (0x1EE35, 'M', 'ت'), (0x1EE36, 'M', 'ث'), (0x1EE37, 'M', 'خ'), (0x1EE38, 'X'), (0x1EE39, 'M', 'ض'), (0x1EE3A, 'X'), (0x1EE3B, 'M', 'غ'), (0x1EE3C, 'X'), (0x1EE42, 'M', 'ج'), (0x1EE43, 'X'), (0x1EE47, 'M', 'ح'), (0x1EE48, 'X'), (0x1EE49, 'M', 'ي'), (0x1EE4A, 'X'), (0x1EE4B, 'M', 'ل'), (0x1EE4C, 'X'), (0x1EE4D, 'M', 'ن'), (0x1EE4E, 'M', 'س'), (0x1EE4F, 'M', 'ع'), (0x1EE50, 'X'), (0x1EE51, 'M', 'ص'), (0x1EE52, 'M', 'ق'), (0x1EE53, 'X'), (0x1EE54, 'M', 'ش'), (0x1EE55, 'X'), (0x1EE57, 'M', 'خ'), (0x1EE58, 'X'), (0x1EE59, 'M', 'ض'), (0x1EE5A, 'X'), (0x1EE5B, 'M', 'غ'), (0x1EE5C, 'X'), (0x1EE5D, 'M', 'ں'), (0x1EE5E, 'X'), (0x1EE5F, 'M', 'ٯ'), (0x1EE60, 'X'), (0x1EE61, 'M', 'ب'), (0x1EE62, 'M', 'ج'), (0x1EE63, 'X'), (0x1EE64, 'M', 'ه'), (0x1EE65, 'X'), (0x1EE67, 'M', 'ح'), (0x1EE68, 'M', 'ط'), (0x1EE69, 'M', 'ي'), (0x1EE6A, 'M', 'ك'), ] def _seg_71(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1EE6B, 'X'), (0x1EE6C, 'M', 'م'), (0x1EE6D, 'M', 'ن'), (0x1EE6E, 'M', 'س'), (0x1EE6F, 'M', 'ع'), (0x1EE70, 'M', 'ف'), (0x1EE71, 'M', 'ص'), (0x1EE72, 'M', 'ق'), (0x1EE73, 'X'), (0x1EE74, 'M', 'ش'), (0x1EE75, 'M', 'ت'), (0x1EE76, 'M', 'ث'), (0x1EE77, 'M', 'خ'), (0x1EE78, 'X'), (0x1EE79, 'M', 'ض'), (0x1EE7A, 'M', 'ظ'), (0x1EE7B, 'M', 'غ'), (0x1EE7C, 'M', 'ٮ'), (0x1EE7D, 'X'), (0x1EE7E, 'M', 'ڡ'), (0x1EE7F, 'X'), (0x1EE80, 'M', 'ا'), (0x1EE81, 'M', 'ب'), (0x1EE82, 'M', 'ج'), (0x1EE83, 'M', 'د'), (0x1EE84, 'M', 'ه'), (0x1EE85, 'M', 'و'), (0x1EE86, 'M', 'ز'), (0x1EE87, 'M', 'ح'), (0x1EE88, 'M', 'ط'), (0x1EE89, 'M', 'ي'), (0x1EE8A, 'X'), (0x1EE8B, 'M', 'ل'), (0x1EE8C, 'M', 'م'), (0x1EE8D, 'M', 'ن'), (0x1EE8E, 'M', 'س'), (0x1EE8F, 'M', 'ع'), (0x1EE90, 'M', 'ف'), (0x1EE91, 'M', 'ص'), (0x1EE92, 'M', 'ق'), (0x1EE93, 'M', 'ر'), (0x1EE94, 'M', 'ش'), (0x1EE95, 'M', 'ت'), (0x1EE96, 'M', 'ث'), (0x1EE97, 'M', 'خ'), (0x1EE98, 'M', 'ذ'), (0x1EE99, 'M', 'ض'), (0x1EE9A, 'M', 'ظ'), (0x1EE9B, 'M', 'غ'), (0x1EE9C, 'X'), (0x1EEA1, 'M', 'ب'), (0x1EEA2, 'M', 'ج'), (0x1EEA3, 'M', 'د'), (0x1EEA4, 'X'), (0x1EEA5, 'M', 'و'), (0x1EEA6, 'M', 'ز'), (0x1EEA7, 'M', 'ح'), (0x1EEA8, 'M', 'ط'), (0x1EEA9, 'M', 'ي'), (0x1EEAA, 'X'), (0x1EEAB, 'M', 'ل'), (0x1EEAC, 'M', 'م'), (0x1EEAD, 'M', 'ن'), (0x1EEAE, 'M', 'س'), (0x1EEAF, 'M', 'ع'), (0x1EEB0, 'M', 'ف'), (0x1EEB1, 'M', 'ص'), (0x1EEB2, 'M', 'ق'), (0x1EEB3, 'M', 'ر'), (0x1EEB4, 'M', 'ش'), (0x1EEB5, 'M', 'ت'), (0x1EEB6, 'M', 'ث'), (0x1EEB7, 'M', 'خ'), (0x1EEB8, 'M', 'ذ'), (0x1EEB9, 'M', 'ض'), (0x1EEBA, 'M', 'ظ'), (0x1EEBB, 'M', 'غ'), (0x1EEBC, 'X'), (0x1EEF0, 'V'), (0x1EEF2, 'X'), (0x1F000, 'V'), (0x1F02C, 'X'), (0x1F030, 'V'), (0x1F094, 'X'), (0x1F0A0, 'V'), (0x1F0AF, 'X'), (0x1F0B1, 'V'), (0x1F0C0, 'X'), (0x1F0C1, 'V'), (0x1F0D0, 'X'), (0x1F0D1, 'V'), (0x1F0F6, 'X'), (0x1F101, '3', '0,'), (0x1F102, '3', '1,'), (0x1F103, '3', '2,'), (0x1F104, '3', '3,'), (0x1F105, '3', '4,'), (0x1F106, '3', '5,'), (0x1F107, '3', '6,'), (0x1F108, '3', '7,'), ] def _seg_72(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1F109, '3', '8,'), (0x1F10A, '3', '9,'), (0x1F10B, 'V'), (0x1F110, '3', '(a)'), (0x1F111, '3', '(b)'), (0x1F112, '3', '(c)'), (0x1F113, '3', '(d)'), (0x1F114, '3', '(e)'), (0x1F115, '3', '(f)'), (0x1F116, '3', '(g)'), (0x1F117, '3', '(h)'), (0x1F118, '3', '(i)'), (0x1F119, '3', '(j)'), (0x1F11A, '3', '(k)'), (0x1F11B, '3', '(l)'), (0x1F11C, '3', '(m)'), (0x1F11D, '3', '(n)'), (0x1F11E, '3', '(o)'), (0x1F11F, '3', '(p)'), (0x1F120, '3', '(q)'), (0x1F121, '3', '(r)'), (0x1F122, '3', '(s)'), (0x1F123, '3', '(t)'), (0x1F124, '3', '(u)'), (0x1F125, '3', '(v)'), (0x1F126, '3', '(w)'), (0x1F127, '3', '(x)'), (0x1F128, '3', '(y)'), (0x1F129, '3', '(z)'), (0x1F12A, 'M', '〔s〕'), (0x1F12B, 'M', 'c'), (0x1F12C, 'M', 'r'), (0x1F12D, 'M', 'cd'), (0x1F12E, 'M', 'wz'), (0x1F12F, 'V'), (0x1F130, 'M', 'a'), (0x1F131, 'M', 'b'), (0x1F132, 'M', 'c'), (0x1F133, 'M', 'd'), (0x1F134, 'M', 'e'), (0x1F135, 'M', 'f'), (0x1F136, 'M', 'g'), (0x1F137, 'M', 'h'), (0x1F138, 'M', 'i'), (0x1F139, 'M', 'j'), (0x1F13A, 'M', 'k'), (0x1F13B, 'M', 'l'), (0x1F13C, 'M', 'm'), (0x1F13D, 'M', 'n'), (0x1F13E, 'M', 'o'), (0x1F13F, 'M', 'p'), (0x1F140, 'M', 'q'), (0x1F141, 'M', 'r'), (0x1F142, 'M', 's'), (0x1F143, 'M', 't'), (0x1F144, 'M', 'u'), (0x1F145, 'M', 'v'), (0x1F146, 'M', 'w'), (0x1F147, 'M', 'x'), (0x1F148, 'M', 'y'), (0x1F149, 'M', 'z'), (0x1F14A, 'M', 'hv'), (0x1F14B, 'M', 'mv'), (0x1F14C, 'M', 'sd'), (0x1F14D, 'M', 'ss'), (0x1F14E, 'M', 'ppv'), (0x1F14F, 'M', 'wc'), (0x1F150, 'V'), (0x1F16A, 'M', 'mc'), (0x1F16B, 'M', 'md'), (0x1F16C, 'M', 'mr'), (0x1F16D, 'V'), (0x1F190, 'M', 'dj'), (0x1F191, 'V'), (0x1F1AE, 'X'), (0x1F1E6, 'V'), (0x1F200, 'M', 'ほか'), (0x1F201, 'M', 'ココ'), (0x1F202, 'M', 'サ'), (0x1F203, 'X'), (0x1F210, 'M', '手'), (0x1F211, 'M', '字'), (0x1F212, 'M', '双'), (0x1F213, 'M', 'デ'), (0x1F214, 'M', '二'), (0x1F215, 'M', '多'), (0x1F216, 'M', '解'), (0x1F217, 'M', '天'), (0x1F218, 'M', '交'), (0x1F219, 'M', '映'), (0x1F21A, 'M', '無'), (0x1F21B, 'M', '料'), (0x1F21C, 'M', '前'), (0x1F21D, 'M', '後'), (0x1F21E, 'M', '再'), (0x1F21F, 'M', '新'), (0x1F220, 'M', '初'), (0x1F221, 'M', '終'), (0x1F222, 'M', '生'), (0x1F223, 'M', '販'), ] def _seg_73(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1F224, 'M', '声'), (0x1F225, 'M', '吹'), (0x1F226, 'M', '演'), (0x1F227, 'M', '投'), (0x1F228, 'M', '捕'), (0x1F229, 'M', '一'), (0x1F22A, 'M', '三'), (0x1F22B, 'M', '遊'), (0x1F22C, 'M', '左'), (0x1F22D, 'M', '中'), (0x1F22E, 'M', '右'), (0x1F22F, 'M', '指'), (0x1F230, 'M', '走'), (0x1F231, 'M', '打'), (0x1F232, 'M', '禁'), (0x1F233, 'M', '空'), (0x1F234, 'M', '合'), (0x1F235, 'M', '満'), (0x1F236, 'M', '有'), (0x1F237, 'M', '月'), (0x1F238, 'M', '申'), (0x1F239, 'M', '割'), (0x1F23A, 'M', '営'), (0x1F23B, 'M', '配'), (0x1F23C, 'X'), (0x1F240, 'M', '〔本〕'), (0x1F241, 'M', '〔三〕'), (0x1F242, 'M', '〔二〕'), (0x1F243, 'M', '〔安〕'), (0x1F244, 'M', '〔点〕'), (0x1F245, 'M', '〔打〕'), (0x1F246, 'M', '〔盗〕'), (0x1F247, 'M', '〔勝〕'), (0x1F248, 'M', '〔敗〕'), (0x1F249, 'X'), (0x1F250, 'M', '得'), (0x1F251, 'M', '可'), (0x1F252, 'X'), (0x1F260, 'V'), (0x1F266, 'X'), (0x1F300, 'V'), (0x1F6D8, 'X'), (0x1F6E0, 'V'), (0x1F6ED, 'X'), (0x1F6F0, 'V'), (0x1F6FD, 'X'), (0x1F700, 'V'), (0x1F774, 'X'), (0x1F780, 'V'), (0x1F7D9, 'X'), (0x1F7E0, 'V'), (0x1F7EC, 'X'), (0x1F800, 'V'), (0x1F80C, 'X'), (0x1F810, 'V'), (0x1F848, 'X'), (0x1F850, 'V'), (0x1F85A, 'X'), (0x1F860, 'V'), (0x1F888, 'X'), (0x1F890, 'V'), (0x1F8AE, 'X'), (0x1F8B0, 'V'), (0x1F8B2, 'X'), (0x1F900, 'V'), (0x1F979, 'X'), (0x1F97A, 'V'), (0x1F9CC, 'X'), (0x1F9CD, 'V'), (0x1FA54, 'X'), (0x1FA60, 'V'), (0x1FA6E, 'X'), (0x1FA70, 'V'), (0x1FA75, 'X'), (0x1FA78, 'V'), (0x1FA7B, 'X'), (0x1FA80, 'V'), (0x1FA87, 'X'), (0x1FA90, 'V'), (0x1FAA9, 'X'), (0x1FAB0, 'V'), (0x1FAB7, 'X'), (0x1FAC0, 'V'), (0x1FAC3, 'X'), (0x1FAD0, 'V'), (0x1FAD7, 'X'), (0x1FB00, 'V'), (0x1FB93, 'X'), (0x1FB94, 'V'), (0x1FBCB, 'X'), (0x1FBF0, 'M', '0'), (0x1FBF1, 'M', '1'), (0x1FBF2, 'M', '2'), (0x1FBF3, 'M', '3'), (0x1FBF4, 'M', '4'), (0x1FBF5, 'M', '5'), (0x1FBF6, 'M', '6'), (0x1FBF7, 'M', '7'), (0x1FBF8, 'M', '8'), (0x1FBF9, 'M', '9'), ] def _seg_74(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x1FBFA, 'X'), (0x20000, 'V'), (0x2A6DE, 'X'), (0x2A700, 'V'), (0x2B735, 'X'), (0x2B740, 'V'), (0x2B81E, 'X'), (0x2B820, 'V'), (0x2CEA2, 'X'), (0x2CEB0, 'V'), (0x2EBE1, 'X'), (0x2F800, 'M', '丽'), (0x2F801, 'M', '丸'), (0x2F802, 'M', '乁'), (0x2F803, 'M', '𠄢'), (0x2F804, 'M', '你'), (0x2F805, 'M', '侮'), (0x2F806, 'M', '侻'), (0x2F807, 'M', '倂'), (0x2F808, 'M', '偺'), (0x2F809, 'M', '備'), (0x2F80A, 'M', '僧'), (0x2F80B, 'M', '像'), (0x2F80C, 'M', '㒞'), (0x2F80D, 'M', '𠘺'), (0x2F80E, 'M', '免'), (0x2F80F, 'M', '兔'), (0x2F810, 'M', '兤'), (0x2F811, 'M', '具'), (0x2F812, 'M', '𠔜'), (0x2F813, 'M', '㒹'), (0x2F814, 'M', '內'), (0x2F815, 'M', '再'), (0x2F816, 'M', '𠕋'), (0x2F817, 'M', '冗'), (0x2F818, 'M', '冤'), (0x2F819, 'M', '仌'), (0x2F81A, 'M', '冬'), (0x2F81B, 'M', '况'), (0x2F81C, 'M', '𩇟'), (0x2F81D, 'M', '凵'), (0x2F81E, 'M', '刃'), (0x2F81F, 'M', '㓟'), (0x2F820, 'M', '刻'), (0x2F821, 'M', '剆'), (0x2F822, 'M', '割'), (0x2F823, 'M', '剷'), (0x2F824, 'M', '㔕'), (0x2F825, 'M', '勇'), (0x2F826, 'M', '勉'), (0x2F827, 'M', '勤'), (0x2F828, 'M', '勺'), (0x2F829, 'M', '包'), (0x2F82A, 'M', '匆'), (0x2F82B, 'M', '北'), (0x2F82C, 'M', '卉'), (0x2F82D, 'M', '卑'), (0x2F82E, 'M', '博'), (0x2F82F, 'M', '即'), (0x2F830, 'M', '卽'), (0x2F831, 'M', '卿'), (0x2F834, 'M', '𠨬'), (0x2F835, 'M', '灰'), (0x2F836, 'M', '及'), (0x2F837, 'M', '叟'), (0x2F838, 'M', '𠭣'), (0x2F839, 'M', '叫'), (0x2F83A, 'M', '叱'), (0x2F83B, 'M', '吆'), (0x2F83C, 'M', '咞'), (0x2F83D, 'M', '吸'), (0x2F83E, 'M', '呈'), (0x2F83F, 'M', '周'), (0x2F840, 'M', '咢'), (0x2F841, 'M', '哶'), (0x2F842, 'M', '唐'), (0x2F843, 'M', '啓'), (0x2F844, 'M', '啣'), (0x2F845, 'M', '善'), (0x2F847, 'M', '喙'), (0x2F848, 'M', '喫'), (0x2F849, 'M', '喳'), (0x2F84A, 'M', '嗂'), (0x2F84B, 'M', '圖'), (0x2F84C, 'M', '嘆'), (0x2F84D, 'M', '圗'), (0x2F84E, 'M', '噑'), (0x2F84F, 'M', '噴'), (0x2F850, 'M', '切'), (0x2F851, 'M', '壮'), (0x2F852, 'M', '城'), (0x2F853, 'M', '埴'), (0x2F854, 'M', '堍'), (0x2F855, 'M', '型'), (0x2F856, 'M', '堲'), (0x2F857, 'M', '報'), (0x2F858, 'M', '墬'), (0x2F859, 'M', '𡓤'), (0x2F85A, 'M', '売'), (0x2F85B, 'M', '壷'), ] def _seg_75(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F85C, 'M', '夆'), (0x2F85D, 'M', '多'), (0x2F85E, 'M', '夢'), (0x2F85F, 'M', '奢'), (0x2F860, 'M', '𡚨'), (0x2F861, 'M', '𡛪'), (0x2F862, 'M', '姬'), (0x2F863, 'M', '娛'), (0x2F864, 'M', '娧'), (0x2F865, 'M', '姘'), (0x2F866, 'M', '婦'), (0x2F867, 'M', '㛮'), (0x2F868, 'X'), (0x2F869, 'M', '嬈'), (0x2F86A, 'M', '嬾'), (0x2F86C, 'M', '𡧈'), (0x2F86D, 'M', '寃'), (0x2F86E, 'M', '寘'), (0x2F86F, 'M', '寧'), (0x2F870, 'M', '寳'), (0x2F871, 'M', '𡬘'), (0x2F872, 'M', '寿'), (0x2F873, 'M', '将'), (0x2F874, 'X'), (0x2F875, 'M', '尢'), (0x2F876, 'M', '㞁'), (0x2F877, 'M', '屠'), (0x2F878, 'M', '屮'), (0x2F879, 'M', '峀'), (0x2F87A, 'M', '岍'), (0x2F87B, 'M', '𡷤'), (0x2F87C, 'M', '嵃'), (0x2F87D, 'M', '𡷦'), (0x2F87E, 'M', '嵮'), (0x2F87F, 'M', '嵫'), (0x2F880, 'M', '嵼'), (0x2F881, 'M', '巡'), (0x2F882, 'M', '巢'), (0x2F883, 'M', '㠯'), (0x2F884, 'M', '巽'), (0x2F885, 'M', '帨'), (0x2F886, 'M', '帽'), (0x2F887, 'M', '幩'), (0x2F888, 'M', '㡢'), (0x2F889, 'M', '𢆃'), (0x2F88A, 'M', '㡼'), (0x2F88B, 'M', '庰'), (0x2F88C, 'M', '庳'), (0x2F88D, 'M', '庶'), (0x2F88E, 'M', '廊'), (0x2F88F, 'M', '𪎒'), (0x2F890, 'M', '廾'), (0x2F891, 'M', '𢌱'), (0x2F893, 'M', '舁'), (0x2F894, 'M', '弢'), (0x2F896, 'M', '㣇'), (0x2F897, 'M', '𣊸'), (0x2F898, 'M', '𦇚'), (0x2F899, 'M', '形'), (0x2F89A, 'M', '彫'), (0x2F89B, 'M', '㣣'), (0x2F89C, 'M', '徚'), (0x2F89D, 'M', '忍'), (0x2F89E, 'M', '志'), (0x2F89F, 'M', '忹'), (0x2F8A0, 'M', '悁'), (0x2F8A1, 'M', '㤺'), (0x2F8A2, 'M', '㤜'), (0x2F8A3, 'M', '悔'), (0x2F8A4, 'M', '𢛔'), (0x2F8A5, 'M', '惇'), (0x2F8A6, 'M', '慈'), (0x2F8A7, 'M', '慌'), (0x2F8A8, 'M', '慎'), (0x2F8A9, 'M', '慌'), (0x2F8AA, 'M', '慺'), (0x2F8AB, 'M', '憎'), (0x2F8AC, 'M', '憲'), (0x2F8AD, 'M', '憤'), (0x2F8AE, 'M', '憯'), (0x2F8AF, 'M', '懞'), (0x2F8B0, 'M', '懲'), (0x2F8B1, 'M', '懶'), (0x2F8B2, 'M', '成'), (0x2F8B3, 'M', '戛'), (0x2F8B4, 'M', '扝'), (0x2F8B5, 'M', '抱'), (0x2F8B6, 'M', '拔'), (0x2F8B7, 'M', '捐'), (0x2F8B8, 'M', '𢬌'), (0x2F8B9, 'M', '挽'), (0x2F8BA, 'M', '拼'), (0x2F8BB, 'M', '捨'), (0x2F8BC, 'M', '掃'), (0x2F8BD, 'M', '揤'), (0x2F8BE, 'M', '𢯱'), (0x2F8BF, 'M', '搢'), (0x2F8C0, 'M', '揅'), (0x2F8C1, 'M', '掩'), (0x2F8C2, 'M', '㨮'), ] def _seg_76(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F8C3, 'M', '摩'), (0x2F8C4, 'M', '摾'), (0x2F8C5, 'M', '撝'), (0x2F8C6, 'M', '摷'), (0x2F8C7, 'M', '㩬'), (0x2F8C8, 'M', '敏'), (0x2F8C9, 'M', '敬'), (0x2F8CA, 'M', '𣀊'), (0x2F8CB, 'M', '旣'), (0x2F8CC, 'M', '書'), (0x2F8CD, 'M', '晉'), (0x2F8CE, 'M', '㬙'), (0x2F8CF, 'M', '暑'), (0x2F8D0, 'M', '㬈'), (0x2F8D1, 'M', '㫤'), (0x2F8D2, 'M', '冒'), (0x2F8D3, 'M', '冕'), (0x2F8D4, 'M', '最'), (0x2F8D5, 'M', '暜'), (0x2F8D6, 'M', '肭'), (0x2F8D7, 'M', '䏙'), (0x2F8D8, 'M', '朗'), (0x2F8D9, 'M', '望'), (0x2F8DA, 'M', '朡'), (0x2F8DB, 'M', '杞'), (0x2F8DC, 'M', '杓'), (0x2F8DD, 'M', '𣏃'), (0x2F8DE, 'M', '㭉'), (0x2F8DF, 'M', '柺'), (0x2F8E0, 'M', '枅'), (0x2F8E1, 'M', '桒'), (0x2F8E2, 'M', '梅'), (0x2F8E3, 'M', '𣑭'), (0x2F8E4, 'M', '梎'), (0x2F8E5, 'M', '栟'), (0x2F8E6, 'M', '椔'), (0x2F8E7, 'M', '㮝'), (0x2F8E8, 'M', '楂'), (0x2F8E9, 'M', '榣'), (0x2F8EA, 'M', '槪'), (0x2F8EB, 'M', '檨'), (0x2F8EC, 'M', '𣚣'), (0x2F8ED, 'M', '櫛'), (0x2F8EE, 'M', '㰘'), (0x2F8EF, 'M', '次'), (0x2F8F0, 'M', '𣢧'), (0x2F8F1, 'M', '歔'), (0x2F8F2, 'M', '㱎'), (0x2F8F3, 'M', '歲'), (0x2F8F4, 'M', '殟'), (0x2F8F5, 'M', '殺'), (0x2F8F6, 'M', '殻'), (0x2F8F7, 'M', '𣪍'), (0x2F8F8, 'M', '𡴋'), (0x2F8F9, 'M', '𣫺'), (0x2F8FA, 'M', '汎'), (0x2F8FB, 'M', '𣲼'), (0x2F8FC, 'M', '沿'), (0x2F8FD, 'M', '泍'), (0x2F8FE, 'M', '汧'), (0x2F8FF, 'M', '洖'), (0x2F900, 'M', '派'), (0x2F901, 'M', '海'), (0x2F902, 'M', '流'), (0x2F903, 'M', '浩'), (0x2F904, 'M', '浸'), (0x2F905, 'M', '涅'), (0x2F906, 'M', '𣴞'), (0x2F907, 'M', '洴'), (0x2F908, 'M', '港'), (0x2F909, 'M', '湮'), (0x2F90A, 'M', '㴳'), (0x2F90B, 'M', '滋'), (0x2F90C, 'M', '滇'), (0x2F90D, 'M', '𣻑'), (0x2F90E, 'M', '淹'), (0x2F90F, 'M', '潮'), (0x2F910, 'M', '𣽞'), (0x2F911, 'M', '𣾎'), (0x2F912, 'M', '濆'), (0x2F913, 'M', '瀹'), (0x2F914, 'M', '瀞'), (0x2F915, 'M', '瀛'), (0x2F916, 'M', '㶖'), (0x2F917, 'M', '灊'), (0x2F918, 'M', '災'), (0x2F919, 'M', '灷'), (0x2F91A, 'M', '炭'), (0x2F91B, 'M', '𠔥'), (0x2F91C, 'M', '煅'), (0x2F91D, 'M', '𤉣'), (0x2F91E, 'M', '熜'), (0x2F91F, 'X'), (0x2F920, 'M', '爨'), (0x2F921, 'M', '爵'), (0x2F922, 'M', '牐'), (0x2F923, 'M', '𤘈'), (0x2F924, 'M', '犀'), (0x2F925, 'M', '犕'), (0x2F926, 'M', '𤜵'), ] def _seg_77(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F927, 'M', '𤠔'), (0x2F928, 'M', '獺'), (0x2F929, 'M', '王'), (0x2F92A, 'M', '㺬'), (0x2F92B, 'M', '玥'), (0x2F92C, 'M', '㺸'), (0x2F92E, 'M', '瑇'), (0x2F92F, 'M', '瑜'), (0x2F930, 'M', '瑱'), (0x2F931, 'M', '璅'), (0x2F932, 'M', '瓊'), (0x2F933, 'M', '㼛'), (0x2F934, 'M', '甤'), (0x2F935, 'M', '𤰶'), (0x2F936, 'M', '甾'), (0x2F937, 'M', '𤲒'), (0x2F938, 'M', '異'), (0x2F939, 'M', '𢆟'), (0x2F93A, 'M', '瘐'), (0x2F93B, 'M', '𤾡'), (0x2F93C, 'M', '𤾸'), (0x2F93D, 'M', '𥁄'), (0x2F93E, 'M', '㿼'), (0x2F93F, 'M', '䀈'), (0x2F940, 'M', '直'), (0x2F941, 'M', '𥃳'), (0x2F942, 'M', '𥃲'), (0x2F943, 'M', '𥄙'), (0x2F944, 'M', '𥄳'), (0x2F945, 'M', '眞'), (0x2F946, 'M', '真'), (0x2F948, 'M', '睊'), (0x2F949, 'M', '䀹'), (0x2F94A, 'M', '瞋'), (0x2F94B, 'M', '䁆'), (0x2F94C, 'M', '䂖'), (0x2F94D, 'M', '𥐝'), (0x2F94E, 'M', '硎'), (0x2F94F, 'M', '碌'), (0x2F950, 'M', '磌'), (0x2F951, 'M', '䃣'), (0x2F952, 'M', '𥘦'), (0x2F953, 'M', '祖'), (0x2F954, 'M', '𥚚'), (0x2F955, 'M', '𥛅'), (0x2F956, 'M', '福'), (0x2F957, 'M', '秫'), (0x2F958, 'M', '䄯'), (0x2F959, 'M', '穀'), (0x2F95A, 'M', '穊'), (0x2F95B, 'M', '穏'), (0x2F95C, 'M', '𥥼'), (0x2F95D, 'M', '𥪧'), (0x2F95F, 'X'), (0x2F960, 'M', '䈂'), (0x2F961, 'M', '𥮫'), (0x2F962, 'M', '篆'), (0x2F963, 'M', '築'), (0x2F964, 'M', '䈧'), (0x2F965, 'M', '𥲀'), (0x2F966, 'M', '糒'), (0x2F967, 'M', '䊠'), (0x2F968, 'M', '糨'), (0x2F969, 'M', '糣'), (0x2F96A, 'M', '紀'), (0x2F96B, 'M', '𥾆'), (0x2F96C, 'M', '絣'), (0x2F96D, 'M', '䌁'), (0x2F96E, 'M', '緇'), (0x2F96F, 'M', '縂'), (0x2F970, 'M', '繅'), (0x2F971, 'M', '䌴'), (0x2F972, 'M', '𦈨'), (0x2F973, 'M', '𦉇'), (0x2F974, 'M', '䍙'), (0x2F975, 'M', '𦋙'), (0x2F976, 'M', '罺'), (0x2F977, 'M', '𦌾'), (0x2F978, 'M', '羕'), (0x2F979, 'M', '翺'), (0x2F97A, 'M', '者'), (0x2F97B, 'M', '𦓚'), (0x2F97C, 'M', '𦔣'), (0x2F97D, 'M', '聠'), (0x2F97E, 'M', '𦖨'), (0x2F97F, 'M', '聰'), (0x2F980, 'M', '𣍟'), (0x2F981, 'M', '䏕'), (0x2F982, 'M', '育'), (0x2F983, 'M', '脃'), (0x2F984, 'M', '䐋'), (0x2F985, 'M', '脾'), (0x2F986, 'M', '媵'), (0x2F987, 'M', '𦞧'), (0x2F988, 'M', '𦞵'), (0x2F989, 'M', '𣎓'), (0x2F98A, 'M', '𣎜'), (0x2F98B, 'M', '舁'), (0x2F98C, 'M', '舄'), (0x2F98D, 'M', '辞'), ] def _seg_78(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F98E, 'M', '䑫'), (0x2F98F, 'M', '芑'), (0x2F990, 'M', '芋'), (0x2F991, 'M', '芝'), (0x2F992, 'M', '劳'), (0x2F993, 'M', '花'), (0x2F994, 'M', '芳'), (0x2F995, 'M', '芽'), (0x2F996, 'M', '苦'), (0x2F997, 'M', '𦬼'), (0x2F998, 'M', '若'), (0x2F999, 'M', '茝'), (0x2F99A, 'M', '荣'), (0x2F99B, 'M', '莭'), (0x2F99C, 'M', '茣'), (0x2F99D, 'M', '莽'), (0x2F99E, 'M', '菧'), (0x2F99F, 'M', '著'), (0x2F9A0, 'M', '荓'), (0x2F9A1, 'M', '菊'), (0x2F9A2, 'M', '菌'), (0x2F9A3, 'M', '菜'), (0x2F9A4, 'M', '𦰶'), (0x2F9A5, 'M', '𦵫'), (0x2F9A6, 'M', '𦳕'), (0x2F9A7, 'M', '䔫'), (0x2F9A8, 'M', '蓱'), (0x2F9A9, 'M', '蓳'), (0x2F9AA, 'M', '蔖'), (0x2F9AB, 'M', '𧏊'), (0x2F9AC, 'M', '蕤'), (0x2F9AD, 'M', '𦼬'), (0x2F9AE, 'M', '䕝'), (0x2F9AF, 'M', '䕡'), (0x2F9B0, 'M', '𦾱'), (0x2F9B1, 'M', '𧃒'), (0x2F9B2, 'M', '䕫'), (0x2F9B3, 'M', '虐'), (0x2F9B4, 'M', '虜'), (0x2F9B5, 'M', '虧'), (0x2F9B6, 'M', '虩'), (0x2F9B7, 'M', '蚩'), (0x2F9B8, 'M', '蚈'), (0x2F9B9, 'M', '蜎'), (0x2F9BA, 'M', '蛢'), (0x2F9BB, 'M', '蝹'), (0x2F9BC, 'M', '蜨'), (0x2F9BD, 'M', '蝫'), (0x2F9BE, 'M', '螆'), (0x2F9BF, 'X'), (0x2F9C0, 'M', '蟡'), (0x2F9C1, 'M', '蠁'), (0x2F9C2, 'M', '䗹'), (0x2F9C3, 'M', '衠'), (0x2F9C4, 'M', '衣'), (0x2F9C5, 'M', '𧙧'), (0x2F9C6, 'M', '裗'), (0x2F9C7, 'M', '裞'), (0x2F9C8, 'M', '䘵'), (0x2F9C9, 'M', '裺'), (0x2F9CA, 'M', '㒻'), (0x2F9CB, 'M', '𧢮'), (0x2F9CC, 'M', '𧥦'), (0x2F9CD, 'M', '䚾'), (0x2F9CE, 'M', '䛇'), (0x2F9CF, 'M', '誠'), (0x2F9D0, 'M', '諭'), (0x2F9D1, 'M', '變'), (0x2F9D2, 'M', '豕'), (0x2F9D3, 'M', '𧲨'), (0x2F9D4, 'M', '貫'), (0x2F9D5, 'M', '賁'), (0x2F9D6, 'M', '贛'), (0x2F9D7, 'M', '起'), (0x2F9D8, 'M', '𧼯'), (0x2F9D9, 'M', '𠠄'), (0x2F9DA, 'M', '跋'), (0x2F9DB, 'M', '趼'), (0x2F9DC, 'M', '跰'), (0x2F9DD, 'M', '𠣞'), (0x2F9DE, 'M', '軔'), (0x2F9DF, 'M', '輸'), (0x2F9E0, 'M', '𨗒'), (0x2F9E1, 'M', '𨗭'), (0x2F9E2, 'M', '邔'), (0x2F9E3, 'M', '郱'), (0x2F9E4, 'M', '鄑'), (0x2F9E5, 'M', '𨜮'), (0x2F9E6, 'M', '鄛'), (0x2F9E7, 'M', '鈸'), (0x2F9E8, 'M', '鋗'), (0x2F9E9, 'M', '鋘'), (0x2F9EA, 'M', '鉼'), (0x2F9EB, 'M', '鏹'), (0x2F9EC, 'M', '鐕'), (0x2F9ED, 'M', '𨯺'), (0x2F9EE, 'M', '開'), (0x2F9EF, 'M', '䦕'), (0x2F9F0, 'M', '閷'), (0x2F9F1, 'M', '𨵷'), ] def _seg_79(): # type: () -> List[Union[Tuple[int, str], Tuple[int, str, str]]] return [ (0x2F9F2, 'M', '䧦'), (0x2F9F3, 'M', '雃'), (0x2F9F4, 'M', '嶲'), (0x2F9F5, 'M', '霣'), (0x2F9F6, 'M', '𩅅'), (0x2F9F7, 'M', '𩈚'), (0x2F9F8, 'M', '䩮'), (0x2F9F9, 'M', '䩶'), (0x2F9FA, 'M', '韠'), (0x2F9FB, 'M', '𩐊'), (0x2F9FC, 'M', '䪲'), (0x2F9FD, 'M', '𩒖'), (0x2F9FE, 'M', '頋'), (0x2FA00, 'M', '頩'), (0x2FA01, 'M', '𩖶'), (0x2FA02, 'M', '飢'), (0x2FA03, 'M', '䬳'), (0x2FA04, 'M', '餩'), (0x2FA05, 'M', '馧'), (0x2FA06, 'M', '駂'), (0x2FA07, 'M', '駾'), (0x2FA08, 'M', '䯎'), (0x2FA09, 'M', '𩬰'), (0x2FA0A, 'M', '鬒'), (0x2FA0B, 'M', '鱀'), (0x2FA0C, 'M', '鳽'), (0x2FA0D, 'M', '䳎'), (0x2FA0E, 'M', '䳭'), (0x2FA0F, 'M', '鵧'), (0x2FA10, 'M', '𪃎'), (0x2FA11, 'M', '䳸'), (0x2FA12, 'M', '𪄅'), (0x2FA13, 'M', '𪈎'), (0x2FA14, 'M', '𪊑'), (0x2FA15, 'M', '麻'), (0x2FA16, 'M', '䵖'), (0x2FA17, 'M', '黹'), (0x2FA18, 'M', '黾'), (0x2FA19, 'M', '鼅'), (0x2FA1A, 'M', '鼏'), (0x2FA1B, 'M', '鼖'), (0x2FA1C, 'M', '鼻'), (0x2FA1D, 'M', '𪘀'), (0x2FA1E, 'X'), (0x30000, 'V'), (0x3134B, 'X'), (0xE0100, 'I'), (0xE01F0, 'X'), ] uts46data = tuple( _seg_0() + _seg_1() + _seg_2() + _seg_3() + _seg_4() + _seg_5() + _seg_6() + _seg_7() + _seg_8() + _seg_9() + _seg_10() + _seg_11() + _seg_12() + _seg_13() + _seg_14() + _seg_15() + _seg_16() + _seg_17() + _seg_18() + _seg_19() + _seg_20() + _seg_21() + _seg_22() + _seg_23() + _seg_24() + _seg_25() + _seg_26() + _seg_27() + _seg_28() + _seg_29() + _seg_30() + _seg_31() + _seg_32() + _seg_33() + _seg_34() + _seg_35() + _seg_36() + _seg_37() + _seg_38() + _seg_39() + _seg_40() + _seg_41() + _seg_42() + _seg_43() + _seg_44() + _seg_45() + _seg_46() + _seg_47() + _seg_48() + _seg_49() + _seg_50() + _seg_51() + _seg_52() + _seg_53() + _seg_54() + _seg_55() + _seg_56() + _seg_57() + _seg_58() + _seg_59() + _seg_60() + _seg_61() + _seg_62() + _seg_63() + _seg_64() + _seg_65() + _seg_66() + _seg_67() + _seg_68() + _seg_69() + _seg_70() + _seg_71() + _seg_72() + _seg_73() + _seg_74() + _seg_75() + _seg_76() + _seg_77() + _seg_78() + _seg_79() ) # type: Tuple[Union[Tuple[int, str], Tuple[int, str, str]], ...] PKH],][6python3.10/site-packages/pip/_vendor/idna/intranges.pynu[""" Given a list of integers, made up of (hopefully) a small number of long runs of consecutive integers, compute a representation of the form ((start1, end1), (start2, end2) ...). Then answer the question "was x present in the original list?" in time O(log(# runs)). """ import bisect from typing import List, Tuple def intranges_from_list(list_): # type: (List[int]) -> Tuple[int, ...] """Represent a list of integers as a sequence of ranges: ((start_0, end_0), (start_1, end_1), ...), such that the original integers are exactly those x such that start_i <= x < end_i for some i. Ranges are encoded as single integers (start << 32 | end), not as tuples. """ sorted_list = sorted(list_) ranges = [] last_write = -1 for i in range(len(sorted_list)): if i+1 < len(sorted_list): if sorted_list[i] == sorted_list[i+1]-1: continue current_range = sorted_list[last_write+1:i+1] ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) last_write = i return tuple(ranges) def _encode_range(start, end): # type: (int, int) -> int return (start << 32) | end def _decode_range(r): # type: (int) -> Tuple[int, int] return (r >> 32), (r & ((1 << 32) - 1)) def intranges_contain(int_, ranges): # type: (int, Tuple[int, ...]) -> bool """Determine if `int_` falls into one of the ranges in `ranges`.""" tuple_ = _encode_range(int_, 0) pos = bisect.bisect_left(ranges, tuple_) # we could be immediately ahead of a tuple (start, end) # with start < int_ <= end if pos > 0: left, right = _decode_range(ranges[pos-1]) if left <= int_ < right: return True # or we could be immediately behind a tuple (int_, end) if pos < len(ranges): left, _ = _decode_range(ranges[pos]) if left == int_: return True return False PKH]v2nn5python3.10/site-packages/pip/_vendor/idna/idnadata.pynu[# This file is automatically generated by tools/idna-data __version__ = '13.0.0' scripts = { 'Greek': ( 0x37000000374, 0x37500000378, 0x37a0000037e, 0x37f00000380, 0x38400000385, 0x38600000387, 0x3880000038b, 0x38c0000038d, 0x38e000003a2, 0x3a3000003e2, 0x3f000000400, 0x1d2600001d2b, 0x1d5d00001d62, 0x1d6600001d6b, 0x1dbf00001dc0, 0x1f0000001f16, 0x1f1800001f1e, 0x1f2000001f46, 0x1f4800001f4e, 0x1f5000001f58, 0x1f5900001f5a, 0x1f5b00001f5c, 0x1f5d00001f5e, 0x1f5f00001f7e, 0x1f8000001fb5, 0x1fb600001fc5, 0x1fc600001fd4, 0x1fd600001fdc, 0x1fdd00001ff0, 0x1ff200001ff5, 0x1ff600001fff, 0x212600002127, 0xab650000ab66, 0x101400001018f, 0x101a0000101a1, 0x1d2000001d246, ), 'Han': ( 0x2e8000002e9a, 0x2e9b00002ef4, 0x2f0000002fd6, 0x300500003006, 0x300700003008, 0x30210000302a, 0x30380000303c, 0x340000004dc0, 0x4e0000009ffd, 0xf9000000fa6e, 0xfa700000fada, 0x16ff000016ff2, 0x200000002a6de, 0x2a7000002b735, 0x2b7400002b81e, 0x2b8200002cea2, 0x2ceb00002ebe1, 0x2f8000002fa1e, 0x300000003134b, ), 'Hebrew': ( 0x591000005c8, 0x5d0000005eb, 0x5ef000005f5, 0xfb1d0000fb37, 0xfb380000fb3d, 0xfb3e0000fb3f, 0xfb400000fb42, 0xfb430000fb45, 0xfb460000fb50, ), 'Hiragana': ( 0x304100003097, 0x309d000030a0, 0x1b0010001b11f, 0x1b1500001b153, 0x1f2000001f201, ), 'Katakana': ( 0x30a1000030fb, 0x30fd00003100, 0x31f000003200, 0x32d0000032ff, 0x330000003358, 0xff660000ff70, 0xff710000ff9e, 0x1b0000001b001, 0x1b1640001b168, ), } joining_types = { 0x600: 85, 0x601: 85, 0x602: 85, 0x603: 85, 0x604: 85, 0x605: 85, 0x608: 85, 0x60b: 85, 0x620: 68, 0x621: 85, 0x622: 82, 0x623: 82, 0x624: 82, 0x625: 82, 0x626: 68, 0x627: 82, 0x628: 68, 0x629: 82, 0x62a: 68, 0x62b: 68, 0x62c: 68, 0x62d: 68, 0x62e: 68, 0x62f: 82, 0x630: 82, 0x631: 82, 0x632: 82, 0x633: 68, 0x634: 68, 0x635: 68, 0x636: 68, 0x637: 68, 0x638: 68, 0x639: 68, 0x63a: 68, 0x63b: 68, 0x63c: 68, 0x63d: 68, 0x63e: 68, 0x63f: 68, 0x640: 67, 0x641: 68, 0x642: 68, 0x643: 68, 0x644: 68, 0x645: 68, 0x646: 68, 0x647: 68, 0x648: 82, 0x649: 68, 0x64a: 68, 0x66e: 68, 0x66f: 68, 0x671: 82, 0x672: 82, 0x673: 82, 0x674: 85, 0x675: 82, 0x676: 82, 0x677: 82, 0x678: 68, 0x679: 68, 0x67a: 68, 0x67b: 68, 0x67c: 68, 0x67d: 68, 0x67e: 68, 0x67f: 68, 0x680: 68, 0x681: 68, 0x682: 68, 0x683: 68, 0x684: 68, 0x685: 68, 0x686: 68, 0x687: 68, 0x688: 82, 0x689: 82, 0x68a: 82, 0x68b: 82, 0x68c: 82, 0x68d: 82, 0x68e: 82, 0x68f: 82, 0x690: 82, 0x691: 82, 0x692: 82, 0x693: 82, 0x694: 82, 0x695: 82, 0x696: 82, 0x697: 82, 0x698: 82, 0x699: 82, 0x69a: 68, 0x69b: 68, 0x69c: 68, 0x69d: 68, 0x69e: 68, 0x69f: 68, 0x6a0: 68, 0x6a1: 68, 0x6a2: 68, 0x6a3: 68, 0x6a4: 68, 0x6a5: 68, 0x6a6: 68, 0x6a7: 68, 0x6a8: 68, 0x6a9: 68, 0x6aa: 68, 0x6ab: 68, 0x6ac: 68, 0x6ad: 68, 0x6ae: 68, 0x6af: 68, 0x6b0: 68, 0x6b1: 68, 0x6b2: 68, 0x6b3: 68, 0x6b4: 68, 0x6b5: 68, 0x6b6: 68, 0x6b7: 68, 0x6b8: 68, 0x6b9: 68, 0x6ba: 68, 0x6bb: 68, 0x6bc: 68, 0x6bd: 68, 0x6be: 68, 0x6bf: 68, 0x6c0: 82, 0x6c1: 68, 0x6c2: 68, 0x6c3: 82, 0x6c4: 82, 0x6c5: 82, 0x6c6: 82, 0x6c7: 82, 0x6c8: 82, 0x6c9: 82, 0x6ca: 82, 0x6cb: 82, 0x6cc: 68, 0x6cd: 82, 0x6ce: 68, 0x6cf: 82, 0x6d0: 68, 0x6d1: 68, 0x6d2: 82, 0x6d3: 82, 0x6d5: 82, 0x6dd: 85, 0x6ee: 82, 0x6ef: 82, 0x6fa: 68, 0x6fb: 68, 0x6fc: 68, 0x6ff: 68, 0x70f: 84, 0x710: 82, 0x712: 68, 0x713: 68, 0x714: 68, 0x715: 82, 0x716: 82, 0x717: 82, 0x718: 82, 0x719: 82, 0x71a: 68, 0x71b: 68, 0x71c: 68, 0x71d: 68, 0x71e: 82, 0x71f: 68, 0x720: 68, 0x721: 68, 0x722: 68, 0x723: 68, 0x724: 68, 0x725: 68, 0x726: 68, 0x727: 68, 0x728: 82, 0x729: 68, 0x72a: 82, 0x72b: 68, 0x72c: 82, 0x72d: 68, 0x72e: 68, 0x72f: 82, 0x74d: 82, 0x74e: 68, 0x74f: 68, 0x750: 68, 0x751: 68, 0x752: 68, 0x753: 68, 0x754: 68, 0x755: 68, 0x756: 68, 0x757: 68, 0x758: 68, 0x759: 82, 0x75a: 82, 0x75b: 82, 0x75c: 68, 0x75d: 68, 0x75e: 68, 0x75f: 68, 0x760: 68, 0x761: 68, 0x762: 68, 0x763: 68, 0x764: 68, 0x765: 68, 0x766: 68, 0x767: 68, 0x768: 68, 0x769: 68, 0x76a: 68, 0x76b: 82, 0x76c: 82, 0x76d: 68, 0x76e: 68, 0x76f: 68, 0x770: 68, 0x771: 82, 0x772: 68, 0x773: 82, 0x774: 82, 0x775: 68, 0x776: 68, 0x777: 68, 0x778: 82, 0x779: 82, 0x77a: 68, 0x77b: 68, 0x77c: 68, 0x77d: 68, 0x77e: 68, 0x77f: 68, 0x7ca: 68, 0x7cb: 68, 0x7cc: 68, 0x7cd: 68, 0x7ce: 68, 0x7cf: 68, 0x7d0: 68, 0x7d1: 68, 0x7d2: 68, 0x7d3: 68, 0x7d4: 68, 0x7d5: 68, 0x7d6: 68, 0x7d7: 68, 0x7d8: 68, 0x7d9: 68, 0x7da: 68, 0x7db: 68, 0x7dc: 68, 0x7dd: 68, 0x7de: 68, 0x7df: 68, 0x7e0: 68, 0x7e1: 68, 0x7e2: 68, 0x7e3: 68, 0x7e4: 68, 0x7e5: 68, 0x7e6: 68, 0x7e7: 68, 0x7e8: 68, 0x7e9: 68, 0x7ea: 68, 0x7fa: 67, 0x840: 82, 0x841: 68, 0x842: 68, 0x843: 68, 0x844: 68, 0x845: 68, 0x846: 82, 0x847: 82, 0x848: 68, 0x849: 82, 0x84a: 68, 0x84b: 68, 0x84c: 68, 0x84d: 68, 0x84e: 68, 0x84f: 68, 0x850: 68, 0x851: 68, 0x852: 68, 0x853: 68, 0x854: 82, 0x855: 68, 0x856: 82, 0x857: 82, 0x858: 82, 0x860: 68, 0x861: 85, 0x862: 68, 0x863: 68, 0x864: 68, 0x865: 68, 0x866: 85, 0x867: 82, 0x868: 68, 0x869: 82, 0x86a: 82, 0x8a0: 68, 0x8a1: 68, 0x8a2: 68, 0x8a3: 68, 0x8a4: 68, 0x8a5: 68, 0x8a6: 68, 0x8a7: 68, 0x8a8: 68, 0x8a9: 68, 0x8aa: 82, 0x8ab: 82, 0x8ac: 82, 0x8ad: 85, 0x8ae: 82, 0x8af: 68, 0x8b0: 68, 0x8b1: 82, 0x8b2: 82, 0x8b3: 68, 0x8b4: 68, 0x8b6: 68, 0x8b7: 68, 0x8b8: 68, 0x8b9: 82, 0x8ba: 68, 0x8bb: 68, 0x8bc: 68, 0x8bd: 68, 0x8be: 68, 0x8bf: 68, 0x8c0: 68, 0x8c1: 68, 0x8c2: 68, 0x8c3: 68, 0x8c4: 68, 0x8c5: 68, 0x8c6: 68, 0x8c7: 68, 0x8e2: 85, 0x1806: 85, 0x1807: 68, 0x180a: 67, 0x180e: 85, 0x1820: 68, 0x1821: 68, 0x1822: 68, 0x1823: 68, 0x1824: 68, 0x1825: 68, 0x1826: 68, 0x1827: 68, 0x1828: 68, 0x1829: 68, 0x182a: 68, 0x182b: 68, 0x182c: 68, 0x182d: 68, 0x182e: 68, 0x182f: 68, 0x1830: 68, 0x1831: 68, 0x1832: 68, 0x1833: 68, 0x1834: 68, 0x1835: 68, 0x1836: 68, 0x1837: 68, 0x1838: 68, 0x1839: 68, 0x183a: 68, 0x183b: 68, 0x183c: 68, 0x183d: 68, 0x183e: 68, 0x183f: 68, 0x1840: 68, 0x1841: 68, 0x1842: 68, 0x1843: 68, 0x1844: 68, 0x1845: 68, 0x1846: 68, 0x1847: 68, 0x1848: 68, 0x1849: 68, 0x184a: 68, 0x184b: 68, 0x184c: 68, 0x184d: 68, 0x184e: 68, 0x184f: 68, 0x1850: 68, 0x1851: 68, 0x1852: 68, 0x1853: 68, 0x1854: 68, 0x1855: 68, 0x1856: 68, 0x1857: 68, 0x1858: 68, 0x1859: 68, 0x185a: 68, 0x185b: 68, 0x185c: 68, 0x185d: 68, 0x185e: 68, 0x185f: 68, 0x1860: 68, 0x1861: 68, 0x1862: 68, 0x1863: 68, 0x1864: 68, 0x1865: 68, 0x1866: 68, 0x1867: 68, 0x1868: 68, 0x1869: 68, 0x186a: 68, 0x186b: 68, 0x186c: 68, 0x186d: 68, 0x186e: 68, 0x186f: 68, 0x1870: 68, 0x1871: 68, 0x1872: 68, 0x1873: 68, 0x1874: 68, 0x1875: 68, 0x1876: 68, 0x1877: 68, 0x1878: 68, 0x1880: 85, 0x1881: 85, 0x1882: 85, 0x1883: 85, 0x1884: 85, 0x1885: 84, 0x1886: 84, 0x1887: 68, 0x1888: 68, 0x1889: 68, 0x188a: 68, 0x188b: 68, 0x188c: 68, 0x188d: 68, 0x188e: 68, 0x188f: 68, 0x1890: 68, 0x1891: 68, 0x1892: 68, 0x1893: 68, 0x1894: 68, 0x1895: 68, 0x1896: 68, 0x1897: 68, 0x1898: 68, 0x1899: 68, 0x189a: 68, 0x189b: 68, 0x189c: 68, 0x189d: 68, 0x189e: 68, 0x189f: 68, 0x18a0: 68, 0x18a1: 68, 0x18a2: 68, 0x18a3: 68, 0x18a4: 68, 0x18a5: 68, 0x18a6: 68, 0x18a7: 68, 0x18a8: 68, 0x18aa: 68, 0x200c: 85, 0x200d: 67, 0x202f: 85, 0x2066: 85, 0x2067: 85, 0x2068: 85, 0x2069: 85, 0xa840: 68, 0xa841: 68, 0xa842: 68, 0xa843: 68, 0xa844: 68, 0xa845: 68, 0xa846: 68, 0xa847: 68, 0xa848: 68, 0xa849: 68, 0xa84a: 68, 0xa84b: 68, 0xa84c: 68, 0xa84d: 68, 0xa84e: 68, 0xa84f: 68, 0xa850: 68, 0xa851: 68, 0xa852: 68, 0xa853: 68, 0xa854: 68, 0xa855: 68, 0xa856: 68, 0xa857: 68, 0xa858: 68, 0xa859: 68, 0xa85a: 68, 0xa85b: 68, 0xa85c: 68, 0xa85d: 68, 0xa85e: 68, 0xa85f: 68, 0xa860: 68, 0xa861: 68, 0xa862: 68, 0xa863: 68, 0xa864: 68, 0xa865: 68, 0xa866: 68, 0xa867: 68, 0xa868: 68, 0xa869: 68, 0xa86a: 68, 0xa86b: 68, 0xa86c: 68, 0xa86d: 68, 0xa86e: 68, 0xa86f: 68, 0xa870: 68, 0xa871: 68, 0xa872: 76, 0xa873: 85, 0x10ac0: 68, 0x10ac1: 68, 0x10ac2: 68, 0x10ac3: 68, 0x10ac4: 68, 0x10ac5: 82, 0x10ac6: 85, 0x10ac7: 82, 0x10ac8: 85, 0x10ac9: 82, 0x10aca: 82, 0x10acb: 85, 0x10acc: 85, 0x10acd: 76, 0x10ace: 82, 0x10acf: 82, 0x10ad0: 82, 0x10ad1: 82, 0x10ad2: 82, 0x10ad3: 68, 0x10ad4: 68, 0x10ad5: 68, 0x10ad6: 68, 0x10ad7: 76, 0x10ad8: 68, 0x10ad9: 68, 0x10ada: 68, 0x10adb: 68, 0x10adc: 68, 0x10add: 82, 0x10ade: 68, 0x10adf: 68, 0x10ae0: 68, 0x10ae1: 82, 0x10ae2: 85, 0x10ae3: 85, 0x10ae4: 82, 0x10aeb: 68, 0x10aec: 68, 0x10aed: 68, 0x10aee: 68, 0x10aef: 82, 0x10b80: 68, 0x10b81: 82, 0x10b82: 68, 0x10b83: 82, 0x10b84: 82, 0x10b85: 82, 0x10b86: 68, 0x10b87: 68, 0x10b88: 68, 0x10b89: 82, 0x10b8a: 68, 0x10b8b: 68, 0x10b8c: 82, 0x10b8d: 68, 0x10b8e: 82, 0x10b8f: 82, 0x10b90: 68, 0x10b91: 82, 0x10ba9: 82, 0x10baa: 82, 0x10bab: 82, 0x10bac: 82, 0x10bad: 68, 0x10bae: 68, 0x10baf: 85, 0x10d00: 76, 0x10d01: 68, 0x10d02: 68, 0x10d03: 68, 0x10d04: 68, 0x10d05: 68, 0x10d06: 68, 0x10d07: 68, 0x10d08: 68, 0x10d09: 68, 0x10d0a: 68, 0x10d0b: 68, 0x10d0c: 68, 0x10d0d: 68, 0x10d0e: 68, 0x10d0f: 68, 0x10d10: 68, 0x10d11: 68, 0x10d12: 68, 0x10d13: 68, 0x10d14: 68, 0x10d15: 68, 0x10d16: 68, 0x10d17: 68, 0x10d18: 68, 0x10d19: 68, 0x10d1a: 68, 0x10d1b: 68, 0x10d1c: 68, 0x10d1d: 68, 0x10d1e: 68, 0x10d1f: 68, 0x10d20: 68, 0x10d21: 68, 0x10d22: 82, 0x10d23: 68, 0x10f30: 68, 0x10f31: 68, 0x10f32: 68, 0x10f33: 82, 0x10f34: 68, 0x10f35: 68, 0x10f36: 68, 0x10f37: 68, 0x10f38: 68, 0x10f39: 68, 0x10f3a: 68, 0x10f3b: 68, 0x10f3c: 68, 0x10f3d: 68, 0x10f3e: 68, 0x10f3f: 68, 0x10f40: 68, 0x10f41: 68, 0x10f42: 68, 0x10f43: 68, 0x10f44: 68, 0x10f45: 85, 0x10f51: 68, 0x10f52: 68, 0x10f53: 68, 0x10f54: 82, 0x10fb0: 68, 0x10fb1: 85, 0x10fb2: 68, 0x10fb3: 68, 0x10fb4: 82, 0x10fb5: 82, 0x10fb6: 82, 0x10fb7: 85, 0x10fb8: 68, 0x10fb9: 82, 0x10fba: 82, 0x10fbb: 68, 0x10fbc: 68, 0x10fbd: 82, 0x10fbe: 68, 0x10fbf: 68, 0x10fc0: 85, 0x10fc1: 68, 0x10fc2: 82, 0x10fc3: 82, 0x10fc4: 68, 0x10fc5: 85, 0x10fc6: 85, 0x10fc7: 85, 0x10fc8: 85, 0x10fc9: 82, 0x10fca: 68, 0x10fcb: 76, 0x110bd: 85, 0x110cd: 85, 0x1e900: 68, 0x1e901: 68, 0x1e902: 68, 0x1e903: 68, 0x1e904: 68, 0x1e905: 68, 0x1e906: 68, 0x1e907: 68, 0x1e908: 68, 0x1e909: 68, 0x1e90a: 68, 0x1e90b: 68, 0x1e90c: 68, 0x1e90d: 68, 0x1e90e: 68, 0x1e90f: 68, 0x1e910: 68, 0x1e911: 68, 0x1e912: 68, 0x1e913: 68, 0x1e914: 68, 0x1e915: 68, 0x1e916: 68, 0x1e917: 68, 0x1e918: 68, 0x1e919: 68, 0x1e91a: 68, 0x1e91b: 68, 0x1e91c: 68, 0x1e91d: 68, 0x1e91e: 68, 0x1e91f: 68, 0x1e920: 68, 0x1e921: 68, 0x1e922: 68, 0x1e923: 68, 0x1e924: 68, 0x1e925: 68, 0x1e926: 68, 0x1e927: 68, 0x1e928: 68, 0x1e929: 68, 0x1e92a: 68, 0x1e92b: 68, 0x1e92c: 68, 0x1e92d: 68, 0x1e92e: 68, 0x1e92f: 68, 0x1e930: 68, 0x1e931: 68, 0x1e932: 68, 0x1e933: 68, 0x1e934: 68, 0x1e935: 68, 0x1e936: 68, 0x1e937: 68, 0x1e938: 68, 0x1e939: 68, 0x1e93a: 68, 0x1e93b: 68, 0x1e93c: 68, 0x1e93d: 68, 0x1e93e: 68, 0x1e93f: 68, 0x1e940: 68, 0x1e941: 68, 0x1e942: 68, 0x1e943: 68, 0x1e94b: 84, } codepoint_classes = { 'PVALID': ( 0x2d0000002e, 0x300000003a, 0x610000007b, 0xdf000000f7, 0xf800000100, 0x10100000102, 0x10300000104, 0x10500000106, 0x10700000108, 0x1090000010a, 0x10b0000010c, 0x10d0000010e, 0x10f00000110, 0x11100000112, 0x11300000114, 0x11500000116, 0x11700000118, 0x1190000011a, 0x11b0000011c, 0x11d0000011e, 0x11f00000120, 0x12100000122, 0x12300000124, 0x12500000126, 0x12700000128, 0x1290000012a, 0x12b0000012c, 0x12d0000012e, 0x12f00000130, 0x13100000132, 0x13500000136, 0x13700000139, 0x13a0000013b, 0x13c0000013d, 0x13e0000013f, 0x14200000143, 0x14400000145, 0x14600000147, 0x14800000149, 0x14b0000014c, 0x14d0000014e, 0x14f00000150, 0x15100000152, 0x15300000154, 0x15500000156, 0x15700000158, 0x1590000015a, 0x15b0000015c, 0x15d0000015e, 0x15f00000160, 0x16100000162, 0x16300000164, 0x16500000166, 0x16700000168, 0x1690000016a, 0x16b0000016c, 0x16d0000016e, 0x16f00000170, 0x17100000172, 0x17300000174, 0x17500000176, 0x17700000178, 0x17a0000017b, 0x17c0000017d, 0x17e0000017f, 0x18000000181, 0x18300000184, 0x18500000186, 0x18800000189, 0x18c0000018e, 0x19200000193, 0x19500000196, 0x1990000019c, 0x19e0000019f, 0x1a1000001a2, 0x1a3000001a4, 0x1a5000001a6, 0x1a8000001a9, 0x1aa000001ac, 0x1ad000001ae, 0x1b0000001b1, 0x1b4000001b5, 0x1b6000001b7, 0x1b9000001bc, 0x1bd000001c4, 0x1ce000001cf, 0x1d0000001d1, 0x1d2000001d3, 0x1d4000001d5, 0x1d6000001d7, 0x1d8000001d9, 0x1da000001db, 0x1dc000001de, 0x1df000001e0, 0x1e1000001e2, 0x1e3000001e4, 0x1e5000001e6, 0x1e7000001e8, 0x1e9000001ea, 0x1eb000001ec, 0x1ed000001ee, 0x1ef000001f1, 0x1f5000001f6, 0x1f9000001fa, 0x1fb000001fc, 0x1fd000001fe, 0x1ff00000200, 0x20100000202, 0x20300000204, 0x20500000206, 0x20700000208, 0x2090000020a, 0x20b0000020c, 0x20d0000020e, 0x20f00000210, 0x21100000212, 0x21300000214, 0x21500000216, 0x21700000218, 0x2190000021a, 0x21b0000021c, 0x21d0000021e, 0x21f00000220, 0x22100000222, 0x22300000224, 0x22500000226, 0x22700000228, 0x2290000022a, 0x22b0000022c, 0x22d0000022e, 0x22f00000230, 0x23100000232, 0x2330000023a, 0x23c0000023d, 0x23f00000241, 0x24200000243, 0x24700000248, 0x2490000024a, 0x24b0000024c, 0x24d0000024e, 0x24f000002b0, 0x2b9000002c2, 0x2c6000002d2, 0x2ec000002ed, 0x2ee000002ef, 0x30000000340, 0x34200000343, 0x3460000034f, 0x35000000370, 0x37100000372, 0x37300000374, 0x37700000378, 0x37b0000037e, 0x39000000391, 0x3ac000003cf, 0x3d7000003d8, 0x3d9000003da, 0x3db000003dc, 0x3dd000003de, 0x3df000003e0, 0x3e1000003e2, 0x3e3000003e4, 0x3e5000003e6, 0x3e7000003e8, 0x3e9000003ea, 0x3eb000003ec, 0x3ed000003ee, 0x3ef000003f0, 0x3f3000003f4, 0x3f8000003f9, 0x3fb000003fd, 0x43000000460, 0x46100000462, 0x46300000464, 0x46500000466, 0x46700000468, 0x4690000046a, 0x46b0000046c, 0x46d0000046e, 0x46f00000470, 0x47100000472, 0x47300000474, 0x47500000476, 0x47700000478, 0x4790000047a, 0x47b0000047c, 0x47d0000047e, 0x47f00000480, 0x48100000482, 0x48300000488, 0x48b0000048c, 0x48d0000048e, 0x48f00000490, 0x49100000492, 0x49300000494, 0x49500000496, 0x49700000498, 0x4990000049a, 0x49b0000049c, 0x49d0000049e, 0x49f000004a0, 0x4a1000004a2, 0x4a3000004a4, 0x4a5000004a6, 0x4a7000004a8, 0x4a9000004aa, 0x4ab000004ac, 0x4ad000004ae, 0x4af000004b0, 0x4b1000004b2, 0x4b3000004b4, 0x4b5000004b6, 0x4b7000004b8, 0x4b9000004ba, 0x4bb000004bc, 0x4bd000004be, 0x4bf000004c0, 0x4c2000004c3, 0x4c4000004c5, 0x4c6000004c7, 0x4c8000004c9, 0x4ca000004cb, 0x4cc000004cd, 0x4ce000004d0, 0x4d1000004d2, 0x4d3000004d4, 0x4d5000004d6, 0x4d7000004d8, 0x4d9000004da, 0x4db000004dc, 0x4dd000004de, 0x4df000004e0, 0x4e1000004e2, 0x4e3000004e4, 0x4e5000004e6, 0x4e7000004e8, 0x4e9000004ea, 0x4eb000004ec, 0x4ed000004ee, 0x4ef000004f0, 0x4f1000004f2, 0x4f3000004f4, 0x4f5000004f6, 0x4f7000004f8, 0x4f9000004fa, 0x4fb000004fc, 0x4fd000004fe, 0x4ff00000500, 0x50100000502, 0x50300000504, 0x50500000506, 0x50700000508, 0x5090000050a, 0x50b0000050c, 0x50d0000050e, 0x50f00000510, 0x51100000512, 0x51300000514, 0x51500000516, 0x51700000518, 0x5190000051a, 0x51b0000051c, 0x51d0000051e, 0x51f00000520, 0x52100000522, 0x52300000524, 0x52500000526, 0x52700000528, 0x5290000052a, 0x52b0000052c, 0x52d0000052e, 0x52f00000530, 0x5590000055a, 0x56000000587, 0x58800000589, 0x591000005be, 0x5bf000005c0, 0x5c1000005c3, 0x5c4000005c6, 0x5c7000005c8, 0x5d0000005eb, 0x5ef000005f3, 0x6100000061b, 0x62000000640, 0x64100000660, 0x66e00000675, 0x679000006d4, 0x6d5000006dd, 0x6df000006e9, 0x6ea000006f0, 0x6fa00000700, 0x7100000074b, 0x74d000007b2, 0x7c0000007f6, 0x7fd000007fe, 0x8000000082e, 0x8400000085c, 0x8600000086b, 0x8a0000008b5, 0x8b6000008c8, 0x8d3000008e2, 0x8e300000958, 0x96000000964, 0x96600000970, 0x97100000984, 0x9850000098d, 0x98f00000991, 0x993000009a9, 0x9aa000009b1, 0x9b2000009b3, 0x9b6000009ba, 0x9bc000009c5, 0x9c7000009c9, 0x9cb000009cf, 0x9d7000009d8, 0x9e0000009e4, 0x9e6000009f2, 0x9fc000009fd, 0x9fe000009ff, 0xa0100000a04, 0xa0500000a0b, 0xa0f00000a11, 0xa1300000a29, 0xa2a00000a31, 0xa3200000a33, 0xa3500000a36, 0xa3800000a3a, 0xa3c00000a3d, 0xa3e00000a43, 0xa4700000a49, 0xa4b00000a4e, 0xa5100000a52, 0xa5c00000a5d, 0xa6600000a76, 0xa8100000a84, 0xa8500000a8e, 0xa8f00000a92, 0xa9300000aa9, 0xaaa00000ab1, 0xab200000ab4, 0xab500000aba, 0xabc00000ac6, 0xac700000aca, 0xacb00000ace, 0xad000000ad1, 0xae000000ae4, 0xae600000af0, 0xaf900000b00, 0xb0100000b04, 0xb0500000b0d, 0xb0f00000b11, 0xb1300000b29, 0xb2a00000b31, 0xb3200000b34, 0xb3500000b3a, 0xb3c00000b45, 0xb4700000b49, 0xb4b00000b4e, 0xb5500000b58, 0xb5f00000b64, 0xb6600000b70, 0xb7100000b72, 0xb8200000b84, 0xb8500000b8b, 0xb8e00000b91, 0xb9200000b96, 0xb9900000b9b, 0xb9c00000b9d, 0xb9e00000ba0, 0xba300000ba5, 0xba800000bab, 0xbae00000bba, 0xbbe00000bc3, 0xbc600000bc9, 0xbca00000bce, 0xbd000000bd1, 0xbd700000bd8, 0xbe600000bf0, 0xc0000000c0d, 0xc0e00000c11, 0xc1200000c29, 0xc2a00000c3a, 0xc3d00000c45, 0xc4600000c49, 0xc4a00000c4e, 0xc5500000c57, 0xc5800000c5b, 0xc6000000c64, 0xc6600000c70, 0xc8000000c84, 0xc8500000c8d, 0xc8e00000c91, 0xc9200000ca9, 0xcaa00000cb4, 0xcb500000cba, 0xcbc00000cc5, 0xcc600000cc9, 0xcca00000cce, 0xcd500000cd7, 0xcde00000cdf, 0xce000000ce4, 0xce600000cf0, 0xcf100000cf3, 0xd0000000d0d, 0xd0e00000d11, 0xd1200000d45, 0xd4600000d49, 0xd4a00000d4f, 0xd5400000d58, 0xd5f00000d64, 0xd6600000d70, 0xd7a00000d80, 0xd8100000d84, 0xd8500000d97, 0xd9a00000db2, 0xdb300000dbc, 0xdbd00000dbe, 0xdc000000dc7, 0xdca00000dcb, 0xdcf00000dd5, 0xdd600000dd7, 0xdd800000de0, 0xde600000df0, 0xdf200000df4, 0xe0100000e33, 0xe3400000e3b, 0xe4000000e4f, 0xe5000000e5a, 0xe8100000e83, 0xe8400000e85, 0xe8600000e8b, 0xe8c00000ea4, 0xea500000ea6, 0xea700000eb3, 0xeb400000ebe, 0xec000000ec5, 0xec600000ec7, 0xec800000ece, 0xed000000eda, 0xede00000ee0, 0xf0000000f01, 0xf0b00000f0c, 0xf1800000f1a, 0xf2000000f2a, 0xf3500000f36, 0xf3700000f38, 0xf3900000f3a, 0xf3e00000f43, 0xf4400000f48, 0xf4900000f4d, 0xf4e00000f52, 0xf5300000f57, 0xf5800000f5c, 0xf5d00000f69, 0xf6a00000f6d, 0xf7100000f73, 0xf7400000f75, 0xf7a00000f81, 0xf8200000f85, 0xf8600000f93, 0xf9400000f98, 0xf9900000f9d, 0xf9e00000fa2, 0xfa300000fa7, 0xfa800000fac, 0xfad00000fb9, 0xfba00000fbd, 0xfc600000fc7, 0x10000000104a, 0x10500000109e, 0x10d0000010fb, 0x10fd00001100, 0x120000001249, 0x124a0000124e, 0x125000001257, 0x125800001259, 0x125a0000125e, 0x126000001289, 0x128a0000128e, 0x1290000012b1, 0x12b2000012b6, 0x12b8000012bf, 0x12c0000012c1, 0x12c2000012c6, 0x12c8000012d7, 0x12d800001311, 0x131200001316, 0x13180000135b, 0x135d00001360, 0x138000001390, 0x13a0000013f6, 0x14010000166d, 0x166f00001680, 0x16810000169b, 0x16a0000016eb, 0x16f1000016f9, 0x17000000170d, 0x170e00001715, 0x172000001735, 0x174000001754, 0x17600000176d, 0x176e00001771, 0x177200001774, 0x1780000017b4, 0x17b6000017d4, 0x17d7000017d8, 0x17dc000017de, 0x17e0000017ea, 0x18100000181a, 0x182000001879, 0x1880000018ab, 0x18b0000018f6, 0x19000000191f, 0x19200000192c, 0x19300000193c, 0x19460000196e, 0x197000001975, 0x1980000019ac, 0x19b0000019ca, 0x19d0000019da, 0x1a0000001a1c, 0x1a2000001a5f, 0x1a6000001a7d, 0x1a7f00001a8a, 0x1a9000001a9a, 0x1aa700001aa8, 0x1ab000001abe, 0x1abf00001ac1, 0x1b0000001b4c, 0x1b5000001b5a, 0x1b6b00001b74, 0x1b8000001bf4, 0x1c0000001c38, 0x1c4000001c4a, 0x1c4d00001c7e, 0x1cd000001cd3, 0x1cd400001cfb, 0x1d0000001d2c, 0x1d2f00001d30, 0x1d3b00001d3c, 0x1d4e00001d4f, 0x1d6b00001d78, 0x1d7900001d9b, 0x1dc000001dfa, 0x1dfb00001e00, 0x1e0100001e02, 0x1e0300001e04, 0x1e0500001e06, 0x1e0700001e08, 0x1e0900001e0a, 0x1e0b00001e0c, 0x1e0d00001e0e, 0x1e0f00001e10, 0x1e1100001e12, 0x1e1300001e14, 0x1e1500001e16, 0x1e1700001e18, 0x1e1900001e1a, 0x1e1b00001e1c, 0x1e1d00001e1e, 0x1e1f00001e20, 0x1e2100001e22, 0x1e2300001e24, 0x1e2500001e26, 0x1e2700001e28, 0x1e2900001e2a, 0x1e2b00001e2c, 0x1e2d00001e2e, 0x1e2f00001e30, 0x1e3100001e32, 0x1e3300001e34, 0x1e3500001e36, 0x1e3700001e38, 0x1e3900001e3a, 0x1e3b00001e3c, 0x1e3d00001e3e, 0x1e3f00001e40, 0x1e4100001e42, 0x1e4300001e44, 0x1e4500001e46, 0x1e4700001e48, 0x1e4900001e4a, 0x1e4b00001e4c, 0x1e4d00001e4e, 0x1e4f00001e50, 0x1e5100001e52, 0x1e5300001e54, 0x1e5500001e56, 0x1e5700001e58, 0x1e5900001e5a, 0x1e5b00001e5c, 0x1e5d00001e5e, 0x1e5f00001e60, 0x1e6100001e62, 0x1e6300001e64, 0x1e6500001e66, 0x1e6700001e68, 0x1e6900001e6a, 0x1e6b00001e6c, 0x1e6d00001e6e, 0x1e6f00001e70, 0x1e7100001e72, 0x1e7300001e74, 0x1e7500001e76, 0x1e7700001e78, 0x1e7900001e7a, 0x1e7b00001e7c, 0x1e7d00001e7e, 0x1e7f00001e80, 0x1e8100001e82, 0x1e8300001e84, 0x1e8500001e86, 0x1e8700001e88, 0x1e8900001e8a, 0x1e8b00001e8c, 0x1e8d00001e8e, 0x1e8f00001e90, 0x1e9100001e92, 0x1e9300001e94, 0x1e9500001e9a, 0x1e9c00001e9e, 0x1e9f00001ea0, 0x1ea100001ea2, 0x1ea300001ea4, 0x1ea500001ea6, 0x1ea700001ea8, 0x1ea900001eaa, 0x1eab00001eac, 0x1ead00001eae, 0x1eaf00001eb0, 0x1eb100001eb2, 0x1eb300001eb4, 0x1eb500001eb6, 0x1eb700001eb8, 0x1eb900001eba, 0x1ebb00001ebc, 0x1ebd00001ebe, 0x1ebf00001ec0, 0x1ec100001ec2, 0x1ec300001ec4, 0x1ec500001ec6, 0x1ec700001ec8, 0x1ec900001eca, 0x1ecb00001ecc, 0x1ecd00001ece, 0x1ecf00001ed0, 0x1ed100001ed2, 0x1ed300001ed4, 0x1ed500001ed6, 0x1ed700001ed8, 0x1ed900001eda, 0x1edb00001edc, 0x1edd00001ede, 0x1edf00001ee0, 0x1ee100001ee2, 0x1ee300001ee4, 0x1ee500001ee6, 0x1ee700001ee8, 0x1ee900001eea, 0x1eeb00001eec, 0x1eed00001eee, 0x1eef00001ef0, 0x1ef100001ef2, 0x1ef300001ef4, 0x1ef500001ef6, 0x1ef700001ef8, 0x1ef900001efa, 0x1efb00001efc, 0x1efd00001efe, 0x1eff00001f08, 0x1f1000001f16, 0x1f2000001f28, 0x1f3000001f38, 0x1f4000001f46, 0x1f5000001f58, 0x1f6000001f68, 0x1f7000001f71, 0x1f7200001f73, 0x1f7400001f75, 0x1f7600001f77, 0x1f7800001f79, 0x1f7a00001f7b, 0x1f7c00001f7d, 0x1fb000001fb2, 0x1fb600001fb7, 0x1fc600001fc7, 0x1fd000001fd3, 0x1fd600001fd8, 0x1fe000001fe3, 0x1fe400001fe8, 0x1ff600001ff7, 0x214e0000214f, 0x218400002185, 0x2c3000002c5f, 0x2c6100002c62, 0x2c6500002c67, 0x2c6800002c69, 0x2c6a00002c6b, 0x2c6c00002c6d, 0x2c7100002c72, 0x2c7300002c75, 0x2c7600002c7c, 0x2c8100002c82, 0x2c8300002c84, 0x2c8500002c86, 0x2c8700002c88, 0x2c8900002c8a, 0x2c8b00002c8c, 0x2c8d00002c8e, 0x2c8f00002c90, 0x2c9100002c92, 0x2c9300002c94, 0x2c9500002c96, 0x2c9700002c98, 0x2c9900002c9a, 0x2c9b00002c9c, 0x2c9d00002c9e, 0x2c9f00002ca0, 0x2ca100002ca2, 0x2ca300002ca4, 0x2ca500002ca6, 0x2ca700002ca8, 0x2ca900002caa, 0x2cab00002cac, 0x2cad00002cae, 0x2caf00002cb0, 0x2cb100002cb2, 0x2cb300002cb4, 0x2cb500002cb6, 0x2cb700002cb8, 0x2cb900002cba, 0x2cbb00002cbc, 0x2cbd00002cbe, 0x2cbf00002cc0, 0x2cc100002cc2, 0x2cc300002cc4, 0x2cc500002cc6, 0x2cc700002cc8, 0x2cc900002cca, 0x2ccb00002ccc, 0x2ccd00002cce, 0x2ccf00002cd0, 0x2cd100002cd2, 0x2cd300002cd4, 0x2cd500002cd6, 0x2cd700002cd8, 0x2cd900002cda, 0x2cdb00002cdc, 0x2cdd00002cde, 0x2cdf00002ce0, 0x2ce100002ce2, 0x2ce300002ce5, 0x2cec00002ced, 0x2cee00002cf2, 0x2cf300002cf4, 0x2d0000002d26, 0x2d2700002d28, 0x2d2d00002d2e, 0x2d3000002d68, 0x2d7f00002d97, 0x2da000002da7, 0x2da800002daf, 0x2db000002db7, 0x2db800002dbf, 0x2dc000002dc7, 0x2dc800002dcf, 0x2dd000002dd7, 0x2dd800002ddf, 0x2de000002e00, 0x2e2f00002e30, 0x300500003008, 0x302a0000302e, 0x303c0000303d, 0x304100003097, 0x30990000309b, 0x309d0000309f, 0x30a1000030fb, 0x30fc000030ff, 0x310500003130, 0x31a0000031c0, 0x31f000003200, 0x340000004dc0, 0x4e0000009ffd, 0xa0000000a48d, 0xa4d00000a4fe, 0xa5000000a60d, 0xa6100000a62c, 0xa6410000a642, 0xa6430000a644, 0xa6450000a646, 0xa6470000a648, 0xa6490000a64a, 0xa64b0000a64c, 0xa64d0000a64e, 0xa64f0000a650, 0xa6510000a652, 0xa6530000a654, 0xa6550000a656, 0xa6570000a658, 0xa6590000a65a, 0xa65b0000a65c, 0xa65d0000a65e, 0xa65f0000a660, 0xa6610000a662, 0xa6630000a664, 0xa6650000a666, 0xa6670000a668, 0xa6690000a66a, 0xa66b0000a66c, 0xa66d0000a670, 0xa6740000a67e, 0xa67f0000a680, 0xa6810000a682, 0xa6830000a684, 0xa6850000a686, 0xa6870000a688, 0xa6890000a68a, 0xa68b0000a68c, 0xa68d0000a68e, 0xa68f0000a690, 0xa6910000a692, 0xa6930000a694, 0xa6950000a696, 0xa6970000a698, 0xa6990000a69a, 0xa69b0000a69c, 0xa69e0000a6e6, 0xa6f00000a6f2, 0xa7170000a720, 0xa7230000a724, 0xa7250000a726, 0xa7270000a728, 0xa7290000a72a, 0xa72b0000a72c, 0xa72d0000a72e, 0xa72f0000a732, 0xa7330000a734, 0xa7350000a736, 0xa7370000a738, 0xa7390000a73a, 0xa73b0000a73c, 0xa73d0000a73e, 0xa73f0000a740, 0xa7410000a742, 0xa7430000a744, 0xa7450000a746, 0xa7470000a748, 0xa7490000a74a, 0xa74b0000a74c, 0xa74d0000a74e, 0xa74f0000a750, 0xa7510000a752, 0xa7530000a754, 0xa7550000a756, 0xa7570000a758, 0xa7590000a75a, 0xa75b0000a75c, 0xa75d0000a75e, 0xa75f0000a760, 0xa7610000a762, 0xa7630000a764, 0xa7650000a766, 0xa7670000a768, 0xa7690000a76a, 0xa76b0000a76c, 0xa76d0000a76e, 0xa76f0000a770, 0xa7710000a779, 0xa77a0000a77b, 0xa77c0000a77d, 0xa77f0000a780, 0xa7810000a782, 0xa7830000a784, 0xa7850000a786, 0xa7870000a789, 0xa78c0000a78d, 0xa78e0000a790, 0xa7910000a792, 0xa7930000a796, 0xa7970000a798, 0xa7990000a79a, 0xa79b0000a79c, 0xa79d0000a79e, 0xa79f0000a7a0, 0xa7a10000a7a2, 0xa7a30000a7a4, 0xa7a50000a7a6, 0xa7a70000a7a8, 0xa7a90000a7aa, 0xa7af0000a7b0, 0xa7b50000a7b6, 0xa7b70000a7b8, 0xa7b90000a7ba, 0xa7bb0000a7bc, 0xa7bd0000a7be, 0xa7bf0000a7c0, 0xa7c30000a7c4, 0xa7c80000a7c9, 0xa7ca0000a7cb, 0xa7f60000a7f8, 0xa7fa0000a828, 0xa82c0000a82d, 0xa8400000a874, 0xa8800000a8c6, 0xa8d00000a8da, 0xa8e00000a8f8, 0xa8fb0000a8fc, 0xa8fd0000a92e, 0xa9300000a954, 0xa9800000a9c1, 0xa9cf0000a9da, 0xa9e00000a9ff, 0xaa000000aa37, 0xaa400000aa4e, 0xaa500000aa5a, 0xaa600000aa77, 0xaa7a0000aac3, 0xaadb0000aade, 0xaae00000aaf0, 0xaaf20000aaf7, 0xab010000ab07, 0xab090000ab0f, 0xab110000ab17, 0xab200000ab27, 0xab280000ab2f, 0xab300000ab5b, 0xab600000ab6a, 0xabc00000abeb, 0xabec0000abee, 0xabf00000abfa, 0xac000000d7a4, 0xfa0e0000fa10, 0xfa110000fa12, 0xfa130000fa15, 0xfa1f0000fa20, 0xfa210000fa22, 0xfa230000fa25, 0xfa270000fa2a, 0xfb1e0000fb1f, 0xfe200000fe30, 0xfe730000fe74, 0x100000001000c, 0x1000d00010027, 0x100280001003b, 0x1003c0001003e, 0x1003f0001004e, 0x100500001005e, 0x10080000100fb, 0x101fd000101fe, 0x102800001029d, 0x102a0000102d1, 0x102e0000102e1, 0x1030000010320, 0x1032d00010341, 0x103420001034a, 0x103500001037b, 0x103800001039e, 0x103a0000103c4, 0x103c8000103d0, 0x104280001049e, 0x104a0000104aa, 0x104d8000104fc, 0x1050000010528, 0x1053000010564, 0x1060000010737, 0x1074000010756, 0x1076000010768, 0x1080000010806, 0x1080800010809, 0x1080a00010836, 0x1083700010839, 0x1083c0001083d, 0x1083f00010856, 0x1086000010877, 0x108800001089f, 0x108e0000108f3, 0x108f4000108f6, 0x1090000010916, 0x109200001093a, 0x10980000109b8, 0x109be000109c0, 0x10a0000010a04, 0x10a0500010a07, 0x10a0c00010a14, 0x10a1500010a18, 0x10a1900010a36, 0x10a3800010a3b, 0x10a3f00010a40, 0x10a6000010a7d, 0x10a8000010a9d, 0x10ac000010ac8, 0x10ac900010ae7, 0x10b0000010b36, 0x10b4000010b56, 0x10b6000010b73, 0x10b8000010b92, 0x10c0000010c49, 0x10cc000010cf3, 0x10d0000010d28, 0x10d3000010d3a, 0x10e8000010eaa, 0x10eab00010ead, 0x10eb000010eb2, 0x10f0000010f1d, 0x10f2700010f28, 0x10f3000010f51, 0x10fb000010fc5, 0x10fe000010ff7, 0x1100000011047, 0x1106600011070, 0x1107f000110bb, 0x110d0000110e9, 0x110f0000110fa, 0x1110000011135, 0x1113600011140, 0x1114400011148, 0x1115000011174, 0x1117600011177, 0x11180000111c5, 0x111c9000111cd, 0x111ce000111db, 0x111dc000111dd, 0x1120000011212, 0x1121300011238, 0x1123e0001123f, 0x1128000011287, 0x1128800011289, 0x1128a0001128e, 0x1128f0001129e, 0x1129f000112a9, 0x112b0000112eb, 0x112f0000112fa, 0x1130000011304, 0x113050001130d, 0x1130f00011311, 0x1131300011329, 0x1132a00011331, 0x1133200011334, 0x113350001133a, 0x1133b00011345, 0x1134700011349, 0x1134b0001134e, 0x1135000011351, 0x1135700011358, 0x1135d00011364, 0x113660001136d, 0x1137000011375, 0x114000001144b, 0x114500001145a, 0x1145e00011462, 0x11480000114c6, 0x114c7000114c8, 0x114d0000114da, 0x11580000115b6, 0x115b8000115c1, 0x115d8000115de, 0x1160000011641, 0x1164400011645, 0x116500001165a, 0x11680000116b9, 0x116c0000116ca, 0x117000001171b, 0x1171d0001172c, 0x117300001173a, 0x118000001183b, 0x118c0000118ea, 0x118ff00011907, 0x119090001190a, 0x1190c00011914, 0x1191500011917, 0x1191800011936, 0x1193700011939, 0x1193b00011944, 0x119500001195a, 0x119a0000119a8, 0x119aa000119d8, 0x119da000119e2, 0x119e3000119e5, 0x11a0000011a3f, 0x11a4700011a48, 0x11a5000011a9a, 0x11a9d00011a9e, 0x11ac000011af9, 0x11c0000011c09, 0x11c0a00011c37, 0x11c3800011c41, 0x11c5000011c5a, 0x11c7200011c90, 0x11c9200011ca8, 0x11ca900011cb7, 0x11d0000011d07, 0x11d0800011d0a, 0x11d0b00011d37, 0x11d3a00011d3b, 0x11d3c00011d3e, 0x11d3f00011d48, 0x11d5000011d5a, 0x11d6000011d66, 0x11d6700011d69, 0x11d6a00011d8f, 0x11d9000011d92, 0x11d9300011d99, 0x11da000011daa, 0x11ee000011ef7, 0x11fb000011fb1, 0x120000001239a, 0x1248000012544, 0x130000001342f, 0x1440000014647, 0x1680000016a39, 0x16a4000016a5f, 0x16a6000016a6a, 0x16ad000016aee, 0x16af000016af5, 0x16b0000016b37, 0x16b4000016b44, 0x16b5000016b5a, 0x16b6300016b78, 0x16b7d00016b90, 0x16e6000016e80, 0x16f0000016f4b, 0x16f4f00016f88, 0x16f8f00016fa0, 0x16fe000016fe2, 0x16fe300016fe5, 0x16ff000016ff2, 0x17000000187f8, 0x1880000018cd6, 0x18d0000018d09, 0x1b0000001b11f, 0x1b1500001b153, 0x1b1640001b168, 0x1b1700001b2fc, 0x1bc000001bc6b, 0x1bc700001bc7d, 0x1bc800001bc89, 0x1bc900001bc9a, 0x1bc9d0001bc9f, 0x1da000001da37, 0x1da3b0001da6d, 0x1da750001da76, 0x1da840001da85, 0x1da9b0001daa0, 0x1daa10001dab0, 0x1e0000001e007, 0x1e0080001e019, 0x1e01b0001e022, 0x1e0230001e025, 0x1e0260001e02b, 0x1e1000001e12d, 0x1e1300001e13e, 0x1e1400001e14a, 0x1e14e0001e14f, 0x1e2c00001e2fa, 0x1e8000001e8c5, 0x1e8d00001e8d7, 0x1e9220001e94c, 0x1e9500001e95a, 0x1fbf00001fbfa, 0x200000002a6de, 0x2a7000002b735, 0x2b7400002b81e, 0x2b8200002cea2, 0x2ceb00002ebe1, 0x300000003134b, ), 'CONTEXTJ': ( 0x200c0000200e, ), 'CONTEXTO': ( 0xb7000000b8, 0x37500000376, 0x5f3000005f5, 0x6600000066a, 0x6f0000006fa, 0x30fb000030fc, ), } PKH]-hh3python3.10/site-packages/pip/_vendor/idna/compat.pynu[from .core import * from .codec import * from typing import Any, Union def ToASCII(label): # type: (str) -> bytes return encode(label) def ToUnicode(label): # type: (Union[bytes, bytearray]) -> str return decode(label) def nameprep(s): # type: (Any) -> None raise NotImplementedError('IDNA 2008 does not utilise nameprep protocol') PKH]TA:221python3.10/site-packages/pip/_vendor/idna/core.pynu[from . import idnadata import bisect import unicodedata import re from typing import Union, Optional from .intranges import intranges_contain _virama_combining_class = 9 _alabel_prefix = b'xn--' _unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]') class IDNAError(UnicodeError): """ Base exception for all IDNA-encoding related problems """ pass class IDNABidiError(IDNAError): """ Exception when bidirectional requirements are not satisfied """ pass class InvalidCodepoint(IDNAError): """ Exception when a disallowed or unallocated codepoint is used """ pass class InvalidCodepointContext(IDNAError): """ Exception when the codepoint is not valid in the context it is used """ pass def _combining_class(cp): # type: (int) -> int v = unicodedata.combining(chr(cp)) if v == 0: if not unicodedata.name(chr(cp)): raise ValueError('Unknown character in unicodedata') return v def _is_script(cp, script): # type: (str, str) -> bool return intranges_contain(ord(cp), idnadata.scripts[script]) def _punycode(s): # type: (str) -> bytes return s.encode('punycode') def _unot(s): # type: (int) -> str return 'U+{:04X}'.format(s) def valid_label_length(label): # type: (Union[bytes, str]) -> bool if len(label) > 63: return False return True def valid_string_length(label, trailing_dot): # type: (Union[bytes, str], bool) -> bool if len(label) > (254 if trailing_dot else 253): return False return True def check_bidi(label, check_ltr=False): # type: (str, bool) -> bool # Bidi rules should only be applied if string contains RTL characters bidi_label = False for (idx, cp) in enumerate(label, 1): direction = unicodedata.bidirectional(cp) if direction == '': # String likely comes from a newer version of Unicode raise IDNABidiError('Unknown directionality in label {} at position {}'.format(repr(label), idx)) if direction in ['R', 'AL', 'AN']: bidi_label = True if not bidi_label and not check_ltr: return True # Bidi rule 1 direction = unicodedata.bidirectional(label[0]) if direction in ['R', 'AL']: rtl = True elif direction == 'L': rtl = False else: raise IDNABidiError('First codepoint in label {} must be directionality L, R or AL'.format(repr(label))) valid_ending = False number_type = None # type: Optional[str] for (idx, cp) in enumerate(label, 1): direction = unicodedata.bidirectional(cp) if rtl: # Bidi rule 2 if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: raise IDNABidiError('Invalid direction for codepoint at position {} in a right-to-left label'.format(idx)) # Bidi rule 3 if direction in ['R', 'AL', 'EN', 'AN']: valid_ending = True elif direction != 'NSM': valid_ending = False # Bidi rule 4 if direction in ['AN', 'EN']: if not number_type: number_type = direction else: if number_type != direction: raise IDNABidiError('Can not mix numeral types in a right-to-left label') else: # Bidi rule 5 if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: raise IDNABidiError('Invalid direction for codepoint at position {} in a left-to-right label'.format(idx)) # Bidi rule 6 if direction in ['L', 'EN']: valid_ending = True elif direction != 'NSM': valid_ending = False if not valid_ending: raise IDNABidiError('Label ends with illegal codepoint directionality') return True def check_initial_combiner(label): # type: (str) -> bool if unicodedata.category(label[0])[0] == 'M': raise IDNAError('Label begins with an illegal combining character') return True def check_hyphen_ok(label): # type: (str) -> bool if label[2:4] == '--': raise IDNAError('Label has disallowed hyphens in 3rd and 4th position') if label[0] == '-' or label[-1] == '-': raise IDNAError('Label must not start or end with a hyphen') return True def check_nfc(label): # type: (str) -> None if unicodedata.normalize('NFC', label) != label: raise IDNAError('Label must be in Normalization Form C') def valid_contextj(label, pos): # type: (str, int) -> bool cp_value = ord(label[pos]) if cp_value == 0x200c: if pos > 0: if _combining_class(ord(label[pos - 1])) == _virama_combining_class: return True ok = False for i in range(pos-1, -1, -1): joining_type = idnadata.joining_types.get(ord(label[i])) if joining_type == ord('T'): continue if joining_type in [ord('L'), ord('D')]: ok = True break if not ok: return False ok = False for i in range(pos+1, len(label)): joining_type = idnadata.joining_types.get(ord(label[i])) if joining_type == ord('T'): continue if joining_type in [ord('R'), ord('D')]: ok = True break return ok if cp_value == 0x200d: if pos > 0: if _combining_class(ord(label[pos - 1])) == _virama_combining_class: return True return False else: return False def valid_contexto(label, pos, exception=False): # type: (str, int, bool) -> bool cp_value = ord(label[pos]) if cp_value == 0x00b7: if 0 < pos < len(label)-1: if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c: return True return False elif cp_value == 0x0375: if pos < len(label)-1 and len(label) > 1: return _is_script(label[pos + 1], 'Greek') return False elif cp_value == 0x05f3 or cp_value == 0x05f4: if pos > 0: return _is_script(label[pos - 1], 'Hebrew') return False elif cp_value == 0x30fb: for cp in label: if cp == '\u30fb': continue if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): return True return False elif 0x660 <= cp_value <= 0x669: for cp in label: if 0x6f0 <= ord(cp) <= 0x06f9: return False return True elif 0x6f0 <= cp_value <= 0x6f9: for cp in label: if 0x660 <= ord(cp) <= 0x0669: return False return True return False def check_label(label): # type: (Union[str, bytes, bytearray]) -> None if isinstance(label, (bytes, bytearray)): label = label.decode('utf-8') if len(label) == 0: raise IDNAError('Empty Label') check_nfc(label) check_hyphen_ok(label) check_initial_combiner(label) for (pos, cp) in enumerate(label): cp_value = ord(cp) if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']): continue elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): try: if not valid_contextj(label, pos): raise InvalidCodepointContext('Joiner {} not allowed at position {} in {}'.format( _unot(cp_value), pos+1, repr(label))) except ValueError: raise IDNAError('Unknown codepoint adjacent to joiner {} at position {} in {}'.format( _unot(cp_value), pos+1, repr(label))) elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']): if not valid_contexto(label, pos): raise InvalidCodepointContext('Codepoint {} not allowed at position {} in {}'.format(_unot(cp_value), pos+1, repr(label))) else: raise InvalidCodepoint('Codepoint {} at position {} of {} not allowed'.format(_unot(cp_value), pos+1, repr(label))) check_bidi(label) def alabel(label): # type: (str) -> bytes try: label_bytes = label.encode('ascii') ulabel(label_bytes) if not valid_label_length(label_bytes): raise IDNAError('Label too long') return label_bytes except UnicodeEncodeError: pass if not label: raise IDNAError('No Input') label = str(label) check_label(label) label_bytes = _punycode(label) label_bytes = _alabel_prefix + label_bytes if not valid_label_length(label_bytes): raise IDNAError('Label too long') return label_bytes def ulabel(label): # type: (Union[str, bytes, bytearray]) -> str if not isinstance(label, (bytes, bytearray)): try: label_bytes = label.encode('ascii') except UnicodeEncodeError: check_label(label) return label else: label_bytes = label label_bytes = label_bytes.lower() if label_bytes.startswith(_alabel_prefix): label_bytes = label_bytes[len(_alabel_prefix):] if not label_bytes: raise IDNAError('Malformed A-label, no Punycode eligible content found') if label_bytes.decode('ascii')[-1] == '-': raise IDNAError('A-label must not end with a hyphen') else: check_label(label_bytes) return label_bytes.decode('ascii') label = label_bytes.decode('punycode') check_label(label) return label def uts46_remap(domain, std3_rules=True, transitional=False): # type: (str, bool, bool) -> str """Re-map the characters in the string according to UTS46 processing.""" from .uts46data import uts46data output = '' for pos, char in enumerate(domain): code_point = ord(char) try: uts46row = uts46data[code_point if code_point < 256 else bisect.bisect_left(uts46data, (code_point, 'Z')) - 1] status = uts46row[1] replacement = None # type: Optional[str] if len(uts46row) == 3: replacement = uts46row[2] # type: ignore if (status == 'V' or (status == 'D' and not transitional) or (status == '3' and not std3_rules and replacement is None)): output += char elif replacement is not None and (status == 'M' or (status == '3' and not std3_rules) or (status == 'D' and transitional)): output += replacement elif status != 'I': raise IndexError() except IndexError: raise InvalidCodepoint( 'Codepoint {} not allowed at position {} in {}'.format( _unot(code_point), pos + 1, repr(domain))) return unicodedata.normalize('NFC', output) def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): # type: (Union[str, bytes, bytearray], bool, bool, bool, bool) -> bytes if isinstance(s, (bytes, bytearray)): s = s.decode('ascii') if uts46: s = uts46_remap(s, std3_rules, transitional) trailing_dot = False result = [] if strict: labels = s.split('.') else: labels = _unicode_dots_re.split(s) if not labels or labels == ['']: raise IDNAError('Empty domain') if labels[-1] == '': del labels[-1] trailing_dot = True for label in labels: s = alabel(label) if s: result.append(s) else: raise IDNAError('Empty label') if trailing_dot: result.append(b'') s = b'.'.join(result) if not valid_string_length(s, trailing_dot): raise IDNAError('Domain too long') return s def decode(s, strict=False, uts46=False, std3_rules=False): # type: (Union[str, bytes, bytearray], bool, bool, bool) -> str if isinstance(s, (bytes, bytearray)): s = s.decode('ascii') if uts46: s = uts46_remap(s, std3_rules, False) trailing_dot = False result = [] if not strict: labels = _unicode_dots_re.split(s) else: labels = s.split('.') if not labels or labels == ['']: raise IDNAError('Empty domain') if not labels[-1]: del labels[-1] trailing_dot = True for label in labels: s = ulabel(label) if s: result.append(s) else: raise IDNAError('Empty label') if trailing_dot: result.append('') return '.'.join(result) PKH]xQQ5python3.10/site-packages/pip/_vendor/idna/__init__.pynu[from .package_data import __version__ from .core import ( IDNABidiError, IDNAError, InvalidCodepoint, InvalidCodepointContext, alabel, check_bidi, check_hyphen_ok, check_initial_combiner, check_label, check_nfc, decode, encode, ulabel, uts46_remap, valid_contextj, valid_contexto, valid_label_length, valid_string_length, ) from .intranges import intranges_contain __all__ = [ "IDNABidiError", "IDNAError", "InvalidCodepoint", "InvalidCodepointContext", "alabel", "check_bidi", "check_hyphen_ok", "check_initial_combiner", "check_label", "check_nfc", "decode", "encode", "intranges_contain", "ulabel", "uts46_remap", "valid_contextj", "valid_contexto", "valid_label_length", "valid_string_length", ] PKH]C9python3.10/site-packages/pip/_vendor/idna/package_data.pynu[__version__ = '3.2' PKH]ecq} } 2python3.10/site-packages/pip/_vendor/idna/codec.pynu[from .core import encode, decode, alabel, ulabel, IDNAError import codecs import re from typing import Tuple, Optional _unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]') class Codec(codecs.Codec): def encode(self, data, errors='strict'): # type: (str, str) -> Tuple[bytes, int] if errors != 'strict': raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) if not data: return b"", 0 return encode(data), len(data) def decode(self, data, errors='strict'): # type: (bytes, str) -> Tuple[str, int] if errors != 'strict': raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) if not data: return '', 0 return decode(data), len(data) class IncrementalEncoder(codecs.BufferedIncrementalEncoder): def _buffer_encode(self, data, errors, final): # type: ignore # type: (str, str, bool) -> Tuple[str, int] if errors != 'strict': raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) if not data: return "", 0 labels = _unicode_dots_re.split(data) trailing_dot = '' if labels: if not labels[-1]: trailing_dot = '.' del labels[-1] elif not final: # Keep potentially unfinished label until the next call del labels[-1] if labels: trailing_dot = '.' result = [] size = 0 for label in labels: result.append(alabel(label)) if size: size += 1 size += len(label) # Join with U+002E result_str = '.'.join(result) + trailing_dot # type: ignore size += len(trailing_dot) return result_str, size class IncrementalDecoder(codecs.BufferedIncrementalDecoder): def _buffer_decode(self, data, errors, final): # type: ignore # type: (str, str, bool) -> Tuple[str, int] if errors != 'strict': raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) if not data: return ('', 0) labels = _unicode_dots_re.split(data) trailing_dot = '' if labels: if not labels[-1]: trailing_dot = '.' del labels[-1] elif not final: # Keep potentially unfinished label until the next call del labels[-1] if labels: trailing_dot = '.' result = [] size = 0 for label in labels: result.append(ulabel(label)) if size: size += 1 size += len(label) result_str = '.'.join(result) + trailing_dot size += len(trailing_dot) return (result_str, size) class StreamWriter(Codec, codecs.StreamWriter): pass class StreamReader(Codec, codecs.StreamReader): pass def getregentry(): # type: () -> codecs.CodecInfo # Compatibility as a search_function for codecs.register() return codecs.CodecInfo( name='idna', encode=Codec().encode, # type: ignore decode=Codec().decode, # type: ignore incrementalencoder=IncrementalEncoder, incrementaldecoder=IncrementalDecoder, streamwriter=StreamWriter, streamreader=StreamReader, ) PKH]OxkkDpython3.10/site-packages/pip/_vendor/__pycache__/six.cpython-310.pycnu[o ai@sdZddlmZddlZddlZddlZddlZddlZdZdZ ej ddkZ ej ddkZ ej dddkZ e rJefZefZefZeZeZejZn=efZeefZeejfZeZeZejd reed Zn"Gd d d eZ ze!e Wn e"yed ZYnwed Z[ e rddl#m$Z$ndZ$ddZ%ddZ&GdddeZ'Gddde'Z(Gdddej)Z*Gddde'Z+GdddeZ,e,e-Z.Gddde*Z/ge+ddd d!e+d"d#d$d%d"e+d&d#d#d'd&e+d(d)d$d*d(e+d+d)d,e+d-d#d$d.d-e+d/d0d0d1d/e+d2d0d0d/d2e+d3d4d5e+d6d)d$d7d6e+d8d)e r#d9nd:d;e+dd?d@dAe+d!d!d e+dBdBdCe+dDdDdCe+dEdEdCe+d7d)d$d7d6e+dFd#d$dGdFe+dHd#d#dIdHe(d$d)e(dJdKe(dLdCej dMkrydNndCe(dOdPe(dQdRdSe(dTdUdVe(dWdXej dYkrdWndZe(d[d\d]e(d^d_d`e(dadbdce(dddedfe(dgdhdie(djdkdle(dmdndoe(dpdqdre(dsdtdue(dvdwdxe(dydydze(d{d{dze(d|d|dze(d}d}d~e(dde(dde(dde(dZddZe(dde(ddde(ddde(ddde(ddde(ddde(ddde(ddde(ddde(ddde(ddde(ddde(ddde(ddde(ddde(de-dde(de-dde(de-de-de(ddde(ddde(dddZ0ejdkre0e(ddÃg7Z0e0D]Z1e2e/e1j3e1e4e1e(re.5e1de1j3q[1e0e/_0e/e-dZ6e.5e6dơGddȄde*Z7e+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+dAdde+ddde+ddde+ddde+dddddփe+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+dddgZ8e8D] Z1e2e7e1j3e1qO[1e8e7_0e.5e7e-dddGddde*Z9e+ddde+ddde+dddgZ:e:D] Z1e2e9e1j3e1q[1e:e9_0e.5e9e-dddGddde*Z;ge+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+ddde+d dde+d dde+d dde+d dde+d dde+ddde+ddde+ddde+dddZe>D] Z1e2e=e1j3e1q[1e>e=_0e.5e=e-dddGdd d e*Z?e+d!ddgZ@e@D] Z1e2e?e1j3e1q[1e@e?_0e.5e?e-d"d#d$Gd%d&d&ej)ZAe.5eAe-dd'd(d)ZBd*d+ZCe r^d,ZDd-ZEd.ZFd/ZGd0ZHd1ZInd2ZDd3ZEd4ZFd5ZGd6ZHd7ZIzeJZKWneLyd8d9ZKYnweKZJzeMZMWneLyd:d;ZMYnwe rd<d=ZNejOZPd>d?ZQeZRnd@d=ZNdAdBZPdCd?ZQGdDdEdEeZReMZMe%eNdFeSeDZTeSeEZUeSeFZVeSeGZWeSeHZXeSeIZYe r"dGdHZZdIdJZ[dKdLZ\dMdNZ]e^dOZ_e^dPZ`e^dQZan*dRdHZZdSdJZ[dTdLZ\dUdNZ]e^dVZ_e^dWZ`e^dXZae%eZdYe%e[dZe%e\d[e%e]d\e rd]d^Zbd_d`ZcedZeddlfZfefgdajhZi[fejdZkejlZmenZoddlpZpepjqZqepjrZr[pdbZsej dcdckrddZtdeZudfZvnBdgZtdhZudiZvn8djd^Zbdkd`ZceeZeedZidldmZkdndoZmewejxeyZoddlqZqeqjqZqZrdpZsddZtdeZudfZve%ebdqe%ecdrdsdbZzdtdgZ{dudhZ|dvdiZ}e r&e~e6jdwZddxdyZn ddzd{Zed|ej ddd}krDed~nddZe~e6jddZedur]ddZej dddMkroeZddZe%edej dddkrejejfddZejje_ejejfddZejje_nejZddZddZdddZdddZdddZddZgZe-Zeddurge_ejreejD]\ZZeej-dkrej3e-kreje=nq[[eje.dS(z6Utilities for writing code that runs on Python 2 and 3)absolute_importNz'Benjamin Peterson z1.16.0)rjavaic@eZdZddZdS)XcCsdS)Nlselfr r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/six.py__len__>z X.__len__N)__name__ __module__ __qualname__r r r r r r< rl)spec_from_loadercCs ||_dS)z Add documentation to a function.N)__doc__)funcdocr r r _add_docPs rcCst|tj|S)z7Import module, returning the module after the last dot.) __import__sysmodulesnamer r r _import_moduleUs rc@seZdZddZddZdS) _LazyDescrcCs ||_dSNrr rr r r __init__] z_LazyDescr.__init__cCs@|}t||j|z t|j|jW|StyY|Swr)_resolvesetattrrdelattr __class__AttributeError)r objtpresultr r r __get__`s z_LazyDescr.__get__N)rrrr!r+r r r r r[s rcs.eZdZdfdd ZddZddZZS) MovedModuleNcs4tt||tr|dur|}||_dS||_dSr)superr,r!PY3mod)r roldnewr&r r r!ns   zMovedModule.__init__cCs t|jSr)rr/r r r r r#wr"zMovedModule._resolvecCs"|}t||}t||||Sr)r#getattrr$)r attr_modulevaluer r r __getattr__zs  zMovedModule.__getattr__r)rrrr!r#r7 __classcell__r r r2r r,ls r,cs(eZdZfddZddZgZZS) _LazyModulecstt|||jj|_dSr)r-r9r!r&rr r2r r r!sz_LazyModule.__init__cCs ddg}|dd|jD7}|S)NrrcSsg|]}|jqSr r).0r4r r r sz'_LazyModule.__dir__..)_moved_attributes)r attrsr r r __dir__sz_LazyModule.__dir__)rrrr!r>r<r8r r r2r r9s  r9cs&eZdZdfdd ZddZZS)MovedAttributeNcsftt||tr%|dur|}||_|dur |dur|}n|}||_dS||_|dur.|}||_dSr)r-r?r!r.r/r4)r rold_modnew_modold_attrnew_attrr2r r r!s  zMovedAttribute.__init__cCst|j}t||jSr)rr/r3r4r moduler r r r#s  zMovedAttribute._resolveNN)rrrr!r#r8r r r2r r?sr?c@speZdZdZddZddZddZdd d Zdd d Zd dZ ddZ ddZ ddZ e Z ddZddZdS)_SixMetaPathImporterz A meta path importer to import six.moves and its submodules. This class implements a PEP302 finder and loader. It should be compatible with Python 2.5 and all existing versions of Python3 cCs||_i|_dSr)r known_modules)r six_module_namer r r r!s z_SixMetaPathImporter.__init__cGs"|D] }||j|jd|<qdSN.rHr)r r/ fullnamesfullnamer r r _add_modulesz _SixMetaPathImporter._add_modulecCs|j|jd|SrJrLr rNr r r _get_modulez _SixMetaPathImporter._get_moduleNcCs||jvr|SdSr)rH)r rNpathr r r find_modules z _SixMetaPathImporter.find_modulecCs||jvr t||SdSr)rHr)r rNrStargetr r r find_specs  z_SixMetaPathImporter.find_speccCs(z|j|WStytd|w)Nz!This loader does not know module )rHKeyError ImportErrorrPr r r __get_modules    z!_SixMetaPathImporter.__get_modulecCsRztj|WStyYnw||}t|tr|}n||_|tj|<|Sr)rrrW _SixMetaPathImporter__get_module isinstancer,r# __loader__)r rNr/r r r load_modules      z _SixMetaPathImporter.load_modulecCst||dS)z Return true, if the named module is a package. We need this method to get correct spec objects with Python 3.4 (see PEP451) __path__)hasattrrZrPr r r is_packagesz_SixMetaPathImporter.is_packagecCs||dS)z;Return None Required, if is_package is implementedN)rZrPr r r get_codes z_SixMetaPathImporter.get_codecCs ||jSr)r]r)r specr r r create_module z"_SixMetaPathImporter.create_modulecCsdSrr rDr r r exec_modulerz _SixMetaPathImporter.exec_moduler)rrrrr!rOrQrTrVrZr]r`ra get_sourcercrer r r r rGs    rGc@seZdZdZgZdS) _MovedItemszLazy loading of moved objectsN)rrrrr^r r r r rgsrg cStringIOioStringIOfilter itertoolsbuiltinsifilter filterfalse ifilterfalseinput __builtin__ raw_inputinternrmapimapgetcwdosZgetcwdugetcwdb getoutputcommands subprocessrangexrange reload_module importlibimpreloadreduce functools shlex_quoteZpipesshlexquoteUserDict collectionsUserList UserStringzipizip zip_longest izip_longest configparser ConfigParsercollections_abc)rrzcollections.abccopyregcopy_regdbm_gnugdbmzdbm.gnudbm_ndbmdbmzdbm.ndbm _dummy_thread dummy_thread)r _threadhttp_cookiejar cookielibzhttp.cookiejar http_cookiesCookiez http.cookies html_entitieshtmlentitydefsz html.entities html_parser HTMLParserz html.parser http_clienthttplibz http.clientemail_mime_basezemail.MIMEBasezemail.mime.baseemail_mime_imagezemail.MIMEImagezemail.mime.imageemail_mime_multipartzemail.MIMEMultipartzemail.mime.multipartemail_mime_nonmultipartzemail.MIMENonMultipartzemail.mime.nonmultipartemail_mime_textzemail.MIMETextzemail.mime.textBaseHTTPServerz http.server CGIHTTPServerSimpleHTTPServercPicklepicklequeueQueuereprlibrepr socketserver SocketServerthreadtkinterTkintertkinter_dialogDialogztkinter.dialogtkinter_filedialog FileDialogztkinter.filedialogtkinter_scrolledtext ScrolledTextztkinter.scrolledtexttkinter_simpledialog SimpleDialogztkinter.simpledialog tkinter_tixTixz tkinter.tix tkinter_ttkttkz tkinter.ttktkinter_constants Tkconstantsztkinter.constants tkinter_dndTkdndz tkinter.dndtkinter_colorchoosertkColorChooserztkinter.colorchoosertkinter_commondialogtkCommonDialogztkinter.commondialogtkinter_tkfiledialog tkFileDialog tkinter_fonttkFontz tkinter.fonttkinter_messagebox tkMessageBoxztkinter.messageboxtkinter_tksimpledialogtkSimpleDialog urllib_parsez.moves.urllib_parsez urllib.parse urllib_errorz.moves.urllib_errorz urllib.errorurllibz .moves.urlliburllib_robotparser robotparserzurllib.robotparser xmlrpc_client xmlrpclibz xmlrpc.client xmlrpc_serverSimpleXMLRPCServerz xmlrpc.serverwin32winreg_winregzmoves.z.movesmovesc@eZdZdZdS)Module_six_moves_urllib_parsez7Lazy loading of moved objects in six.moves.urllib_parseNrrrrr r r r rTr ParseResulturlparse SplitResultparse_qs parse_qsl urldefragurljoinurlsplit urlunparse urlunsplit quote_plusunquote unquote_plusunquote_to_bytes urlencode splitquerysplittag splituser splitvalue uses_fragment uses_netloc uses_params uses_query uses_relativemoves.urllib_parsezmoves.urllib.parsec@r)Module_six_moves_urllib_errorz7Lazy loading of moved objects in six.moves.urllib_errorNrr r r r r~rrURLErrorurllib2 HTTPErrorContentTooShortErrorz.moves.urllib.errormoves.urllib_errorzmoves.urllib.errorc@r)Module_six_moves_urllib_requestz9Lazy loading of moved objects in six.moves.urllib_requestNrr r r r rrrurlopenzurllib.requestinstall_opener build_opener pathname2url url2pathname getproxiesRequestOpenerDirectorHTTPDefaultErrorHandlerHTTPRedirectHandlerHTTPCookieProcessor ProxyHandler BaseHandlerHTTPPasswordMgrHTTPPasswordMgrWithDefaultRealmAbstractBasicAuthHandlerHTTPBasicAuthHandlerProxyBasicAuthHandlerAbstractDigestAuthHandlerHTTPDigestAuthHandlerProxyDigestAuthHandler HTTPHandler HTTPSHandler FileHandler FTPHandlerCacheFTPHandlerUnknownHandlerHTTPErrorProcessor urlretrieve urlcleanup URLopenerFancyURLopener proxy_bypassparse_http_listparse_keqv_listz.moves.urllib.requestmoves.urllib_requestzmoves.urllib.requestc@r) Module_six_moves_urllib_responsez:Lazy loading of moved objects in six.moves.urllib_responseNrr r r r r+rr+addbasezurllib.response addclosehookaddinfo addinfourlz.moves.urllib.responsemoves.urllib_responsezmoves.urllib.responsec@r)#Module_six_moves_urllib_robotparserz=Lazy loading of moved objects in six.moves.urllib_robotparserNrr r r r r1rr1RobotFileParserz.moves.urllib.robotparsermoves.urllib_robotparserzmoves.urllib.robotparserc@sNeZdZdZgZedZedZedZ edZ edZ ddZ d S) Module_six_moves_urllibzICreate a six.moves.urllib namespace that resembles the Python 3 namespacerrr*r0r3cCsgdS)N)parseerrorrequestresponserr r r r r r>zModule_six_moves_urllib.__dir__N) rrrrr^ _importerrQr5r6r7r8rr>r r r r r4s      r4z moves.urllibcCstt|j|dS)zAdd an item to six.moves.N)r$rgr)mover r r add_movesr<c CsNztt|WdSty&ztj|=WYdSty%td|fww)zRemove item from six.moves.zno such move, %rN)r%rgr'r__dict__rWrr r r remove_moves  r>__func____self__ __closure____code__ __defaults__ __globals__im_funcZim_selfZ func_closure func_codeZ func_defaultsZ func_globalscCs|Sr)next)itr r r advance_iterator#r9rIcCstddt|jDS)Ncss|]}d|jvVqdS)__call__N)r=)r:klassr r r ,szcallable..)anytype__mro__)r(r r r callable+srPcC|Srr unboundr r r get_unbound_function0rrTcCrQrr rclsr r r create_unbound_method5rrWcCs|jSr)rErRr r r rT:scCst|||jSr)types MethodTyper&)rr(r r r create_bound_method=rZcCst|d|Sr)rXrYrUr r r rW@c@r)IteratorcCst||Sr)rN__next__r r r r rGEr\z Iterator.nextN)rrrrGr r r r r]Crr]z3Get the function out of a possibly unbound functioncKt|jdi|SNr )iterkeysdkwr r r iterkeysVrRrfcKr_r`)ravaluesrcr r r itervaluesYrRrhcKr_r`)raitemsrcr r r iteritems\rRrjcKr_r`)ralistsrcr r r iterlists_rRrlrbrgricK|jdi|Sr`)rfrcr r r rfhr[cKrmr`)rhrcr r r rhkr[cKrmr`)rjrcr r r rjnr[cKrmr`)rlrcr r r rlqr[viewkeys viewvalues viewitemsz1Return an iterator over the keys of a dictionary.z3Return an iterator over the values of a dictionary.z?Return an iterator over the (key, value) pairs of a dictionary.zBReturn an iterator over the (key, [values]) pairs of a dictionary.cCs |dS)Nzlatin-1)encodesr r r br"rtcCrQrr rrr r r urruz>BassertCountEqualZassertRaisesRegexpZassertRegexpMatchesZassertNotRegexpMatchesassertRaisesRegex assertRegexassertNotRegexcCrQrr rrr r r rtrcCst|dddS)Nz\\z\\\\unicode_escape)unicodereplacerrr r r ruscCs t|dS)Nrord)bsr r r byte2intrdrcCs t||Srr~)bufir r r indexbytesrdrZassertItemsEqualz Byte literalz Text literalcOt|t|i|Sr)r3_assertCountEqualr argskwargsr r r rvrRcOrr)r3_assertRaisesRegexrr r r rxrRcOrr)r3 _assertRegexrr r r ryrRcOrr)r3_assertNotRegexrr r r rzrRexeccCs2z|dur|}|j|ur|||d}d}wr) __traceback__with_traceback)r)r6tbr r r reraises  rcCsB|durtd}|j}|dur|j}~n|dur|}tddS)zExecute code in a namespace.Nrwzexec _code_ in _globs_, _locs_)r _getframe f_globalsf_localsr)Z_code_Z_globs_Z_locs_framer r r exec_s  rzedef reraise(tp, value, tb=None): try: raise tp, value, tb finally: tb = None )rzrdef raise_from(value, from_value): try: raise value from from_value finally: value = None cCs|rr )r6 from_valuer r r raise_fromrrprintc s*|dtjdur dSfdd}d}|dd}|dur0t|tr'd}n t|ts0td|d d}|durKt|trBd}n t|tsKtd |rQtd |sa|D] }t|tr`d}nqU|rltd }td }nd }d }|durv|}|dur||}t|D]\} }| r||||q||dS)z4The new-style print function for Python 2.4 and 2.5.fileNcsdt|ts t|}ttr+t|tr+jdur+tdd}|dur$d}|j|}|dS)Nerrorsstrict) r[ basestringstrrr|encodingr3rqwrite)datarfpr r rs    zprint_..writeFsepTzsep must be None or a stringendzend must be None or a stringz$invalid keyword arguments to print()  )poprstdoutr[r|r TypeError enumerate) rrrZ want_unicoderrargnewlinespacerr rr print_sN           rcOsH|dtj}|dd}t|i||r |dur"|dSdSdS)NrflushF)getrrr_printr)rrrrr r r r/s    zReraise an exception.c Csd|D]}zt||}Wn tyYqwt|||q|D]}t||t||iq||_|Sr)r3r'r$update __wrapped__)wrapperwrappedassignedupdatedr4r6r r r _update_wrapper>s rcCstjt|||dS)Nrrr)rpartialrrr r r wrapsNsrcs&Gfdddt}t|ddiS)z%Create a base class with a metaclass.cs,eZdZfddZefddZdS)z!with_metaclass..metaclasscs>tjdddkrt}|ur|d<n}|||S)Nr)r__orig_bases__)r version_inforX resolve_bases)rVr this_basesrdresolved_basesbasesmetar r __new___s  z)with_metaclass..metaclass.__new__cs |Sr) __prepare__)rVrrrr r rjs z-with_metaclass..metaclass.__prepare__N)rrrr classmethodrr rr r metaclass]s rtemporary_classr )rNr)rrrr rr with_metaclassXsrcsfdd}|S)z6Class decorator for creating a class with a metaclass.cs||j}|d}|dur t|tr|g}|D]}||q|dd|ddt|dr6|j|d<|j|j |S)N __slots__r= __weakref__r) r=copyrr[rrr_rr __bases__)rV orig_varsslots slots_varrr r rrs        zadd_metaclass..wrapperr )rrr rr add_metaclassps  rutf-8rcCs4t|tr|St|tr|||Stdt|)zCoerce **s** to six.binary_type. For Python 2: - `unicode` -> encoded to `str` - `str` -> `str` For Python 3: - `str` -> encoded to `bytes` - `bytes` -> `bytes` not expecting type '%s')r[ binary_type text_typerqrrNrsrrr r r ensure_binarys   rcCsft|tur|Strt|tr|||Str"t|tr"|||St|ttfs1t dt||S)zCoerce *s* to `str`. For Python 2: - `unicode` -> encoded to `str` - `str` -> `str` For Python 3: - `str` -> `str` - `bytes` -> decoded to `str` r) rNrPY2r[rrqr.rdecoderrr r r ensure_strs   rcCs4t|tr |||St|tr|Stdt|)zCoerce *s* to six.text_type. For Python 2: - `unicode` -> `unicode` - `str` -> `unicode` For Python 3: - `str` -> `str` - `bytes` -> decoded to `str` r)r[rrrrrNrr r r ensure_texts  rcCs2trd|jvrtd|j|j|_dd|_|S)a A class decorator that defines __unicode__ and __str__ methods under Python 2. Under Python 3 it does nothing. To support Python 2 and 3 with a single code base, define a __str__ method returning text and apply this decorator to the class. __str__zY@python_2_unicode_compatible cannot be applied to %s because it doesn't define __str__().cSs|dS)Nr) __unicode__rqr r r r sz-python_2_unicode_compatible..)rr= ValueErrorrrr)rKr r r python_2_unicode_compatibles  r__spec__rrF)rr)r __future__rrrloperatorrrX __author__ __version__rrr.PY34r string_typesint integer_typesrN class_typesrbytesrmaxsizeMAXSIZErlongZ ClassTyper|platform startswithobjectrlen OverflowErrorimportlib.utilrrrrr, ModuleTyper9r?rGrr:rgr<r4r$rr[rOrr_urllib_parse_moved_attributesr_urllib_error_moved_attributesr _urllib_request_moved_attributesr+!_urllib_response_moved_attributesr1$_urllib_robotparser_moved_attributesr4r<r> _meth_func _meth_self _func_closure _func_code_func_defaults _func_globalsrGrI NameErrorrPrTrYrZrWr] attrgetterget_method_functionget_method_selfget_function_closureget_function_codeget_function_defaultsget_function_globalsrfrhrjrl methodcallerrnrorprtruchrunichrstructStructpackint2byte itemgetterrgetitemrra iterbytesrirjBytesIOrrrrrrvrrvrxryrzr3rmrrrrrWRAPPER_ASSIGNMENTSWRAPPER_UPDATESrupdate_wrapperrrrrrrrr^ __package__globalsrrsubmodule_search_locations meta_pathrrimporterappendr r r r s      I                   ! " # $ % & ' ( )*+, -. / 0 1 2 3 4 5 679 ; < =>@AB C D E H                                                               ! " #%                                                  5        PKH]ˎ Ipython3.10/site-packages/pip/_vendor/__pycache__/__init__.cpython-310.pycnu[o aid@s dZddlmZddlZddlZddlZdZej ej e Z ddZ ereeje dejejdd<e de d e d e d e d e d e de de de de de de de de de de de de de de de de de de d e d!e d"e d#e d$e d%e d&e d'e d(e d)e d*e d+e d,e d-e d.e d/e d0e d1e d2e d3e d4e d5e d6e d7e d8e d9dSdS):z pip._vendor is for vendoring dependencies of pip to prevent needing pip to depend on something external. Files inside of pip._vendor should be considered immutable and should only be updated to versions from upstream. )absolute_importNFcCsvdt|}z t|ttddWn tyYdSwtj|tj|<|dd\}}t tj||tj|dS)Nz{0}.{1}r)level.) format__name__ __import__globalslocals ImportErrorsysmodulesrsplitsetattr) modulename vendored_namebaseheadr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/__init__.pyvendoreds    rz*.whl cachecontrolcertificoloramadistlibdistrohtml5libsixz six.moveszsix.moves.urllibzsix.moves.urllib.parse packagingzpackaging.versionzpackaging.specifierspep517 pkg_resources platformdirsprogressrequestszrequests.exceptionszrequests.packageszrequests.packages.urllib3z&requests.packages.urllib3._collectionsz$requests.packages.urllib3.connectionz(requests.packages.urllib3.connectionpoolz!requests.packages.urllib3.contribz*requests.packages.urllib3.contrib.ntlmpoolz+requests.packages.urllib3.contrib.pyopensslz$requests.packages.urllib3.exceptionsz requests.packages.urllib3.fieldsz"requests.packages.urllib3.filepostz"requests.packages.urllib3.packagesz/requests.packages.urllib3.packages.ordered_dictz&requests.packages.urllib3.packages.sixz5requests.packages.urllib3.packages.ssl_match_hostnamezErequests.packages.urllib3.packages.ssl_match_hostname._implementationz%requests.packages.urllib3.poolmanagerz!requests.packages.urllib3.requestz"requests.packages.urllib3.responsezrequests.packages.urllib3.utilz)requests.packages.urllib3.util.connectionz&requests.packages.urllib3.util.requestz'requests.packages.urllib3.util.responsez$requests.packages.urllib3.util.retryz#requests.packages.urllib3.util.ssl_z&requests.packages.urllib3.util.timeoutz"requests.packages.urllib3.util.url resolvelibtenacitytomliurllib3)__doc__ __future__rglobos.pathosr DEBUNDLEDpathabspathdirname__file__ WHEEL_DIRrjoinrrrrsz $ PKH]줄Gpython3.10/site-packages/pip/_vendor/__pycache__/distro.cpython-310.pycnu[o ai@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z dZ ejd d Zejd d ZdZddiZddddddZ ddiZ!e"dZ#e"dZ$dddedddfZ%dKddZ&dd Z'dLd!d"Z(dMd#d$Z)dLd%d&Z*dLd'd(Z+dLd)d*Z,dLd+d,Z-d-d.Z.d/d0Z/dMd1d2Z0d3d4Z1d5d6Z2d7d8Z3d9d:Z4d;d<Z5d=d>Z6d?d@Z7dAdBZ8zddCl9m:Z:Wne;yGdDdEdEe<Z:YnwGdFdGdGe<Z=e=Z>dHdIZ?e@dJkre?dSdS)Na The ``distro`` package (``distro`` stands for Linux Distribution) provides information about the Linux distribution it runs on, such as a reliable machine-readable distro ID, or version information. It is the recommended replacement for Python's original :py:func:`platform.linux_distribution` function, but it provides much more functionality. An alternative implementation became necessary because Python 3.5 deprecated this function, and Python 3.8 removed it altogether. Its predecessor function :py:func:`platform.dist` was already deprecated since Python 2.6 and removed in Python 3.8. Still, there are many cases in which access to OS distribution information is needed. See `Python issue 1322 `_ for more information. Nz1.6.0F) AnyCallableDictIterableOptionalSequenceTextIOTupleType TypedDictUnion VersionDictmajorminor build_numberInfoDictidversion version_partslikecodenameZ UNIXCONFDIRz/etcZ UNIXUSRLIBDIRz/usr/libz os-releaseoloraclerhel)enterpriseenterpriseasenterpriseenterpriseserverredhatenterpriseworkstationredhatenterpriseserverredhatenterprisecomputenoderedhatzA(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)z(\w+)[-_](release|version)$debian_versionz lsb-releasez oem-releasezsystem-releasez plesk-releaseziredmail-releaseTcCstjdtddt|S)aG .. deprecated:: 1.6.0 :func:`distro.linux_distribution()` is deprecated. It should only be used as a compatibility shim with Python's :py:func:`platform.linux_distribution()`. Please use :func:`distro.id`, :func:`distro.version` and :func:`distro.name` instead. Return information about the current OS distribution as a tuple ``(id_name, version, codename)`` with items as follows: * ``id_name``: If *full_distribution_name* is false, the result of :func:`distro.id`. Otherwise, the result of :func:`distro.name`. * ``version``: The result of :func:`distro.version`. * ``codename``: The result of :func:`distro.codename`. The interface of this function is compatible with the original :py:func:`platform.linux_distribution` function, supporting a subset of its parameters. The data it returns may not exactly be the same, because it uses more data sources than the original function, and that may lead to different data if the OS distribution is not consistent across multiple data sources it provides (there are indeed such distributions ...). Another reason for differences is the fact that the :func:`distro.id` method normalizes the distro ID string to a reliable machine-readable value for a number of popular OS distributions. zdistro.linux_distribution() is deprecated. It should only be used as a compatibility shim with Python's platform.linux_distribution(). Please use distro.id(), distro.version() and distro.name() instead.) stacklevel)warningswarnDeprecationWarning_distrolinux_distribution)full_distribution_namer+/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distro.pyr)s ! r)cCtS)aD Return the distro ID of the current distribution, as a machine-readable string. For a number of OS distributions, the returned distro ID value is *reliable*, in the sense that it is documented and that it does not change across releases of the distribution. This package maintains the following reliable distro ID values: ============== ========================================= Distro ID Distribution ============== ========================================= "ubuntu" Ubuntu "debian" Debian "rhel" RedHat Enterprise Linux "centos" CentOS "fedora" Fedora "sles" SUSE Linux Enterprise Server "opensuse" openSUSE "amazon" Amazon Linux "arch" Arch Linux "cloudlinux" CloudLinux OS "exherbo" Exherbo Linux "gentoo" GenToo Linux "ibm_powerkvm" IBM PowerKVM "kvmibm" KVM for IBM z Systems "linuxmint" Linux Mint "mageia" Mageia "mandriva" Mandriva Linux "parallels" Parallels "pidora" Pidora "raspbian" Raspbian "oracle" Oracle Linux (and Oracle Enterprise Linux) "scientific" Scientific Linux "slackware" Slackware "xenserver" XenServer "openbsd" OpenBSD "netbsd" NetBSD "freebsd" FreeBSD "midnightbsd" MidnightBSD ============== ========================================= If you have a need to get distros for reliable IDs added into this set, or if you find that the :func:`distro.id` function returns a different distro ID for one of the listed distros, please create an issue in the `distro issue tracker`_. **Lookup hierarchy and transformations:** First, the ID is obtained from the following sources, in the specified order. The first available and non-empty value is used: * the value of the "ID" attribute of the os-release file, * the value of the "Distributor ID" attribute returned by the lsb_release command, * the first part of the file name of the distro release file, The so determined ID value then passes the following transformations, before it is returned by this method: * it is translated to lower case, * blanks (which should not be there anyway) are translated to underscores, * a normalization of the ID is performed, based upon `normalization tables`_. The purpose of this normalization is to ensure that the ID is as reliable as possible, even across incompatible changes in the OS distributions. A common reason for an incompatible change is the addition of an os-release file, or the addition of the lsb_release command, with ID values that differ from what was previously determined from the distro release file name. )r(rr+r+r+r,rsMrcC t|S)ak Return the name of the current OS distribution, as a human-readable string. If *pretty* is false, the name is returned without version or codename. (e.g. "CentOS Linux") If *pretty* is true, the version and codename are appended. (e.g. "CentOS Linux 7.1.1503 (Core)") **Lookup hierarchy:** The name is obtained from the following sources, in the specified order. The first available and non-empty value is used: * If *pretty* is false: - the value of the "NAME" attribute of the os-release file, - the value of the "Distributor ID" attribute returned by the lsb_release command, - the value of the "" field of the distro release file. * If *pretty* is true: - the value of the "PRETTY_NAME" attribute of the os-release file, - the value of the "Description" attribute returned by the lsb_release command, - the value of the "" field of the distro release file, appended with the value of the pretty version ("" and "" fields) of the distro release file, if available. )r(nameprettyr+r+r,r/s %r/cC t||S)av Return the version of the current OS distribution, as a human-readable string. If *pretty* is false, the version is returned without codename (e.g. "7.0"). If *pretty* is true, the codename in parenthesis is appended, if the codename is non-empty (e.g. "7.0 (Maipo)"). Some distributions provide version numbers with different precisions in the different sources of distribution information. Examining the different sources in a fixed priority order does not always yield the most precise version (e.g. for Debian 8.2, or CentOS 7.1). The *best* parameter can be used to control the approach for the returned version: If *best* is false, the first non-empty version number in priority order of the examined sources is returned. If *best* is true, the most precise version number out of all examined sources is returned. **Lookup hierarchy:** In all cases, the version number is obtained from the following sources. If *best* is false, this order represents the priority order: * the value of the "VERSION_ID" attribute of the os-release file, * the value of the "Release" attribute returned by the lsb_release command, * the version number parsed from the "" field of the first line of the distro release file, * the version number parsed from the "PRETTY_NAME" attribute of the os-release file, if it follows the format of the distro release files. * the version number parsed from the "Description" attribute returned by the lsb_release command, if it follows the format of the distro release files. )r(rr1bestr+r+r,r+ *rcCr.)a Return the version of the current OS distribution as a tuple ``(major, minor, build_number)`` with items as follows: * ``major``: The result of :func:`distro.major_version`. * ``minor``: The result of :func:`distro.minor_version`. * ``build_number``: The result of :func:`distro.build_number`. For a description of the *best* parameter, see the :func:`distro.version` method. )r(rr4r+r+r,rX rcCr.)a5 Return the major version of the current OS distribution, as a string, if provided. Otherwise, the empty string is returned. The major version is the first part of the dot-separated version string. For a description of the *best* parameter, see the :func:`distro.version` method. )r( major_versionr6r+r+r,r8j r8cCr.)a6 Return the minor version of the current OS distribution, as a string, if provided. Otherwise, the empty string is returned. The minor version is the second part of the dot-separated version string. For a description of the *best* parameter, see the :func:`distro.version` method. )r( minor_versionr6r+r+r,r:xr9r:cCr.)a3 Return the build number of the current OS distribution, as a string, if provided. Otherwise, the empty string is returned. The build number is the third part of the dot-separated version string. For a description of the *best* parameter, see the :func:`distro.version` method. )r(rr6r+r+r,rr9rcCr-)a Return a space-separated list of distro IDs of distributions that are closely related to the current OS distribution in regards to packaging and programming interfaces, for example distributions the current distribution is a derivative from. **Lookup hierarchy:** This information item is only provided by the os-release file. For details, see the description of the "ID_LIKE" attribute in the `os-release man page `_. )r(rr+r+r+r,rsrcCr-)a Return the codename for the release of the current OS distribution, as a string. If the distribution does not have a codename, an empty string is returned. Note that the returned codename is not always really a codename. For example, openSUSE returns "x86_64". This function does not handle such cases in any special way and just returns the string it finds, if any. **Lookup hierarchy:** * the codename within the "VERSION" attribute of the os-release file, if provided, * the value of the "Codename" attribute returned by the lsb_release command, * the value of the "" field of the distro release file. )r(rr+r+r+r,rsrcCr2)a Return certain machine-readable information items about the current OS distribution in a dictionary, as shown in the following example: .. sourcecode:: python { 'id': 'rhel', 'version': '7.0', 'version_parts': { 'major': '7', 'minor': '0', 'build_number': '' }, 'like': 'fedora', 'codename': 'Maipo' } The dictionary structure and keys are always the same, regardless of which information items are available in the underlying data sources. The values for the various keys are as follows: * ``id``: The result of :func:`distro.id`. * ``version``: The result of :func:`distro.version`. * ``version_parts -> major``: The result of :func:`distro.major_version`. * ``version_parts -> minor``: The result of :func:`distro.minor_version`. * ``version_parts -> build_number``: The result of :func:`distro.build_number`. * ``like``: The result of :func:`distro.like`. * ``codename``: The result of :func:`distro.codename`. For a description of the *pretty* and *best* parameters, see the :func:`distro.version` method. )r(infor3r+r+r,r;r5r;cCr-)z Return a dictionary containing key-value pairs for the information items from the os-release file data source of the current OS distribution. See `os-release file`_ for details about these information items. )r(os_release_infor+r+r+r,r<r<cCr-)z Return a dictionary containing key-value pairs for the information items from the lsb_release command data source of the current OS distribution. See `lsb_release command output`_ for details about these information items. )r(lsb_release_infor+r+r+r,r>s r>cCr-)z Return a dictionary containing key-value pairs for the information items from the distro release file data source of the current OS distribution. See `distro release file`_ for details about these information items. )r(distro_release_infor+r+r+r,r?r=r?cCr-)z Return a dictionary containing key-value pairs for the information items from the distro release file data source of the current OS distribution. )r( uname_infor+r+r+r,r@sr@cCr.)a Return a single named information item from the os-release file data source of the current OS distribution. Parameters: * ``attribute`` (string): Key of the information item. Returns: * (string): Value of the information item, if the item exists. The empty string, if the item does not exist. See `os-release file`_ for details about these information items. )r(os_release_attr attributer+r+r,rA rAcCr.)a Return a single named information item from the lsb_release command output data source of the current OS distribution. Parameters: * ``attribute`` (string): Key of the information item. Returns: * (string): Value of the information item, if the item exists. The empty string, if the item does not exist. See `lsb_release command output`_ for details about these information items. )r(lsb_release_attrrBr+r+r,rE+s rEcCr.)a Return a single named information item from the distro release file data source of the current OS distribution. Parameters: * ``attribute`` (string): Key of the information item. Returns: * (string): Value of the information item, if the item exists. The empty string, if the item does not exist. See `distro release file`_ for details about these information items. )r(distro_release_attrrBr+r+r,rF@rDrFcCr.)aZ Return a single named information item from the distro release file data source of the current OS distribution. Parameters: * ``attribute`` (string): Key of the information item. Returns: * (string): Value of the information item, if the item exists. The empty string, if the item does not exist. )r( uname_attrrBr+r+r,rGTr7rG)cached_propertyc@s eZdZdZddZddZdS)rHzA version of @property which caches the value. On access, it calls the underlying function and sets the value in `__dict__` so future accesses will not re-call the property. cCs|j|_||_dS)N)__name___fname_f)selffr+r+r,__init__ps zcached_property.__init__cCs2|dus Jd|j||}|j|j<|S)Nzcall {} on an instance)formatrJrK__dict__)rLobjownerretr+r+r,__get__uszcached_property.__get__N)rI __module__ __qualname____doc__rNrTr+r+r+r,rHjs rHc@sHeZdZdZ     dDddZddZdEd d Zd d ZdFddZdGddZ dFddZ dFddZ dFddZ dFddZ ddZddZdGddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zed0d1Zed2d3Zed4d5Zed6d7Zed8d9Zed:d;Z edd?Z"d@dAZ#edBdCZ$dS)HLinuxDistributiona  Provides information about a OS distribution. This package creates a private module-global instance of this class with default initialization arguments, that is used by the `consolidated accessor functions`_ and `single source accessor functions`_. By using default initialization arguments, that module-global instance returns data about the current OS distribution (i.e. the distro this package runs on). Normally, it is not necessary to create additional instances of this class. However, in situations where control is needed over the exact data sources that are used, instances of this class can be created with a specific distro release file, or a specific os-release file, or without invoking the lsb_release command. TNcCs||_|r tj|dnt|_|rtj|dnt|_|r!||_n#tj|jt }tj|jt }tj |s=tj |sA||_n||_|pGd|_ ||_ ||_ dS)a The initialization method of this class gathers information from the available data sources, and stores that in private instance attributes. Subsequent access to the information items uses these private instance attributes, so that the data sources are read only once. Parameters: * ``include_lsb`` (bool): Controls whether the `lsb_release command output`_ is included as a data source. If the lsb_release command is not available in the program execution path, the data source for the lsb_release command will be empty. * ``os_release_file`` (string): The path name of the `os-release file`_ that is to be used as a data source. An empty string (the default) will cause the default path name to be used (see `os-release file`_ for details). If the specified or defaulted os-release file does not exist, the data source for the os-release file will be empty. * ``distro_release_file`` (string): The path name of the `distro release file`_ that is to be used as a data source. An empty string (the default) will cause a default search algorithm to be used (see `distro release file`_ for details). If the specified distro release file does not exist, or if no default distro release file can be found, the data source for the distro release file will be empty. * ``include_uname`` (bool): Controls whether uname command output is included as a data source. If the uname command is not available in the program execution path the data source for the uname command will be empty. * ``root_dir`` (string): The absolute path to the root directory to use to find distro-related information files. Public instance attributes: * ``os_release_file`` (string): The path name of the `os-release file`_ that is actually used as a data source. The empty string if no distro release file is used as a data source. * ``distro_release_file`` (string): The path name of the `distro release file`_ that is actually used as a data source. The empty string if no distro release file is used as a data source. * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter. This controls whether the lsb information will be loaded. * ``include_uname`` (bool): The result of the ``include_uname`` parameter. This controls whether the uname information will be loaded. Raises: * :py:exc:`IOError`: Some I/O issue with an os-release file or distro release file. * :py:exc:`subprocess.CalledProcessError`: The lsb_release command had some issue (other than not being available in the program execution path). * :py:exc:`UnicodeError`: A data source has unexpected characters or uses an unexpected encoding. etczusr/librYN)root_dirospathjoin _UNIXCONFDIRetc_dir_UNIXUSRLIBDIR usr_lib_diros_release_file_OS_RELEASE_BASENAMEisfiledistro_release_file include_lsb include_uname)rLrgrcrfrhr[etc_dir_os_release_fileusr_lib_os_release_filer+r+r,rNs$O  zLinuxDistribution.__init__cCs dj|dS)zReturn repr of all infoaeLinuxDistribution(os_release_file={self.os_release_file!r}, distro_release_file={self.distro_release_file!r}, include_lsb={self.include_lsb!r}, include_uname={self.include_uname!r}, _os_release_info={self._os_release_info!r}, _lsb_release_info={self._lsb_release_info!r}, _distro_release_info={self._distro_release_info!r}, _uname_info={self._uname_info!r})rL)rOrkr+r+r,__repr__szLinuxDistribution.__repr__cCs"|r|n|||fS)z Return information about the OS distribution that is compatible with Python's :func:`platform.linux_distribution`, supporting a subset of its parameters. For details, see :func:`distro.linux_distribution`. )r/rrr)rLr*r+r+r,r)s z$LinuxDistribution.linux_distributioncCsldd}|d}|r||tS|d}|r||tS|d}|r(||tS|d}|r4||tSdS)zoReturn the distro ID of the OS distribution, as a string. For details, see :func:`distro.id`. cSs|dd}|||S)N _)lowerreplaceget) distro_idtabler+r+r, normalizes z'LinuxDistribution.id..normalizerdistributor_idrY)rANORMALIZED_OS_IDrENORMALIZED_LSB_IDrFNORMALIZED_DISTRO_IDrG)rLrtrrr+r+r,rs        zLinuxDistribution.idFcCs||dp|dp|dp|d}|r:|dp|d}|s:|dp+|d}|jdd}|r:|d|}|p=dS) zu Return the name of the OS distribution, as a string. For details, see :func:`distro.name`. r/ru pretty_name descriptionTr0rmrY)rArErFrGr)rLr1r/rr+r+r,r/4s"   zLinuxDistribution.namec Cs|d|d|d||ddd||ddd|dg}d}|rB|D]}|d|dks>|dkr@|}q.n |D] }|dkrN|}nqD|r_|r_|r_d||}|S)z{ Return the version of the OS distribution, as a string. For details, see :func:`distro.version`. version_idreleaseryrYrz.z {0} ({1})) rArErF_parse_distro_release_contentrqrGcountrrO)rLr1r4versionsrvr+r+r,rLs6 zLinuxDistribution.versioncCsL|j|d}|r$td}||}|r$|\}}}||pd|p"dfSdS)z Return the version of the OS distribution, as a tuple of version numbers. For details, see :func:`distro.version_parts`. r6z(\d+)\.?(\d+)?\.?(\d+)?rY)rYrYrY)rrecompilematchgroups)rLr4 version_str version_regexmatchesrrrr+r+r,rqs   zLinuxDistribution.version_partscC||dS)z Return the major version number of the current distribution. For details, see :func:`distro.major_version`. rrrLr4r+r+r,r8zLinuxDistribution.major_versioncCr)z Return the minor version number of the current distribution. For details, see :func:`distro.minor_version`. rrr+r+r,r:rzLinuxDistribution.minor_versioncCr)z} Return the build number of the current distribution. For details, see :func:`distro.build_number`. r#rrr+r+r,rrzLinuxDistribution.build_numbercCs|dpdS)z Return the IDs of distributions that are like the OS distribution. For details, see :func:`distro.like`. id_likerY)rArkr+r+r,rrzLinuxDistribution.likecCs8z|jdWSty|dp|dpdYSw)zp Return the codename of the OS distribution. For details, see :func:`distro.codename`. rrY)_os_release_infoKeyErrorrErFrkr+r+r,rs   zLinuxDistribution.codenamec CsBt||||t||||||d||dS)z Return certain machine-readable information about the OS distribution. For details, see :func:`distro.info`. rr)dictrrr8r:rrr)rLr1r4r+r+r,r;s zLinuxDistribution.infocC|jS)z Return a dictionary containing key-value pairs for the information items from the os-release file data source of the OS distribution. For details, see :func:`distro.os_release_info`. )rrkr+r+r,r<z!LinuxDistribution.os_release_infocCr)z Return a dictionary containing key-value pairs for the information items from the lsb_release command data source of the OS distribution. For details, see :func:`distro.lsb_release_info`. )_lsb_release_inforkr+r+r,r> z"LinuxDistribution.lsb_release_infocCr)z Return a dictionary containing key-value pairs for the information items from the distro release file data source of the OS distribution. For details, see :func:`distro.distro_release_info`. )_distro_release_inforkr+r+r,r?rz%LinuxDistribution.distro_release_infocCr)z Return a dictionary containing key-value pairs for the information items from the uname command data source of the OS distribution. For details, see :func:`distro.uname_info`. ) _uname_inforkr+r+r,r@rzLinuxDistribution.uname_infocC|j|dS)z Return a single named information item from the os-release file data source of the OS distribution. For details, see :func:`distro.os_release_attr`. rY)rrqrLrCr+r+r,rAz!LinuxDistribution.os_release_attrcCr)z Return a single named information item from the lsb_release command output data source of the OS distribution. For details, see :func:`distro.lsb_release_attr`. rY)rrqrr+r+r,rErz"LinuxDistribution.lsb_release_attrcCr)z Return a single named information item from the distro release file data source of the OS distribution. For details, see :func:`distro.distro_release_attr`. rY)rrqrr+r+r,rF rz%LinuxDistribution.distro_release_attrcCr)z Return a single named information item from the uname command output data source of the OS distribution. For details, see :func:`distro.uname_attr`. rY)rrqrr+r+r,rGrzLinuxDistribution.uname_attrcCsFtj|jr!t|j }||WdS1swYiS)z Get the information items from the specified os-release file. Returns: A dictionary containing all information items. N)r\r]rercopen_parse_os_release_content)rL release_filer+r+r,rs   z"LinuxDistribution._os_release_infoc Csi}tj|dd}d|_tjddkr t|jtr |jd|_t|}|D]}d|vr;| dd\}}||| <q& q&d|vrI|d|d <|Sd |vrU|d |d <|Sd |vryt d |d }|ry| }|d }|d}|}||d <|S)aD Parse the lines of an os-release file. Parameters: * lines: Iterable through the lines in the os-release file. Each line must be a unicode string or a UTF-8 encoded byte string. Returns: A dictionary containing all information items. T)posixrr#z iso-8859-1=rversion_codenamerubuntu_codenamerz(\(\D+\))|,(\s+)?\D+z(),)shlexwhitespace_splitsys version_info isinstance wordcharsbytesdecodelistsplitrorsearchgroupstrip) linespropslexertokenstokenkrrrr+r+r,r,s4      z+LinuxDistribution._parse_os_release_contentc Cs|jsiSttjd)}z d}tj||d}Wnttjfy,iYWdSwWdn1s7wY|| }| |S)z Get the information items from the lsb_release command output. Returns: A dictionary containing all information items. wb) lsb_releasez-astderrN) rgrr\devnull subprocess check_outputOSErrorCalledProcessError_to_str splitlines_parse_lsb_release_contentrLrcmdstdoutcontentr+r+r,rns  z#LinuxDistribution._lsb_release_infocCsXi}|D]%}|ddd}t|dkrq|\}}||dd|iq|S)aM Parse the output of the lsb_release command. Parameters: * lines: Iterable through the lines of the lsb_release output. Each line must be a unicode string or a UTF-8 encoded byte string. Returns: A dictionary containing all information items.  :rr#rmrn)rrlenupdaterpro)rrlinekvrrr+r+r,rs  z,LinuxDistribution._parse_lsb_release_contentc Csttjd&}z d}tj||d}Wnty$iYWdSwWdn1s/wY||}||S)Nr)unamez-rsr) rr\rrrrrr_parse_uname_contentrr+r+r,rs  zLinuxDistribution._uname_infocCsTi}td|d}|r(|\}}|dkriS||d<||d<||d<|S)Nz^([^\s]+)\s+([\d\.]+)rLinuxrr/r|)rrrrro)rrrr/rr+r+r,rs  z&LinuxDistribution._parse_uname_contentcCsVt}|dkr dn|}tjddkrt|tr||S|St|tr)||S|S)Nasciizutf-8r)rgetfilesystemencodingrrrrunicodeencode)textencodingr+r+r,rs   zLinuxDistribution._to_strcCs|jr2||j}tj|j}t|}d|vr'd|dvr'd|d<|S|r0|d|d<|Sz t |j }| Wn t yKgd}Ynw|D]9}|t vrUqNt|}|rtj|j |}||}d|vr||_|d|d<d|dvrd|d<|SqNiS)z Get the information items from the specified distro release file. Returns: A dictionary containing all information items. r/ cloudlinuxrr)z SuSE-releasez arch-releasez base-releasezcentos-releasezfedora-releasezgentoo-releasezmageia-releasezmandrake-releasezmandriva-releasezmandrivalinux-releasezmanjaro-releasezoracle-releasezredhat-releasez sl-releasezslackware-version)rf_parse_distro_release_filer\r]basename _DISTRO_RELEASE_BASENAME_PATTERNrrorlistdirr`sortr _DISTRO_RELEASE_IGNORE_BASENAMESr^)rL distro_inforr basenamesfilepathr+r+r,rs>        z&LinuxDistribution._distro_release_infoc CsZzt|}||WdWS1swYWdSttfy,iYSw)z Parse a distro release file. Parameters: * filepath: Path name of the distro release file. Returns: A dictionary containing all information items. N)rr~readlinerIOError)rLrfpr+r+r,rs  (z,LinuxDistribution._parse_distro_release_filecCst|ddd}i}|r@|dddd|d<|dr-|dddd|d<|dr>|dddd|d<|S|rH||d<|S) a Parse a line from a distro release file. Parameters: * line: Line from the distro release file. Must be a unicode string or a UTF-8 encoded byte string. Returns: A dictionary containing all information items. Nrr/r#r{rr)(_DISTRO_RELEASE_CONTENT_REVERSED_PATTERNrrr)rrrr+r+r,r~%s    z/LinuxDistribution._parse_distro_release_content)TrYrYTNTFFF)%rIrUrVrWrNrlr)rr/rrr8r:rrrr;r<r>r?r@rArErFrGrHr staticmethodrrrrrrrrr~r+r+r+r,rX|s^ j    %             A      DrXcCstt}|tj|ttjt j dd}|j ddddd|j dd t d d d | }|jr=td d |jd}nt}|jrQ|tj|ddddS|d|jdd|jdd}|d||}|d|dS)NzOS distro info tool)rzz--jsonz-jz!Output in machine readable format store_true)helpactionz --root-dirz-rr[z5Path to the root filesystem directory (defaults to /))typedestrF)rgrhr[T)indent sort_keyszName: %sr0z Version: %sz Codename: %s)logging getLoggerrIsetLevelDEBUG addHandler StreamHandlerrrargparseArgumentParser add_argumentstr parse_argsr[rXr(jsonr;dumpsr/rr)loggerparserargsdistdistribution_versiondistribution_codenamer+r+r,mainCs6     r__main__rrr)ArWrrrr\rrrrr% __version__typingrrrrrrrr r r r rr renvironrqr_rardrvrwrxrrrrr)rr/rrr8r:rrrr;r<r>r?r@rArErFrG functoolsrH ImportErrorobjectrXr(rrIr+r+r+r,s    + P ( -    -     I& PKH]4UJpython3.10/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-310.pycnu[o ai+ @s dZdZdZdZddlZddlmZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlmZddlmZddlZdd lmZdd lmZzdd lmZWneyidd lmZYnwzdd lmZWneydd lmZYnwzddlm Z ddlm!Z!m"Z"Wneyddl m Z ddl m!Z!m"Z"Ynwzddl m#Z$Wneyzddl%m#Z$Wn eydZ$YnwYnwzddlm&Z&WneyGdddZ&Ynwe&Z'de'_de'_(e&Z)de)_de)_*de)_+de)_,de)_-de)_.dde/e)De)_0ddZ1e1e)_2gdZ3e4e j5ddZ6e6ddkZ7e7rGe j8Z9e:Z;ee:Z?e@eAeBeCeDe4eEeFeGeHeIg ZJn,e jKZ9eLZMddZ?gZJddlNZNd OD]ZPz eJQeReNePWqZeSyrYqZweTd!d"eMd#DZUd$d%ZVejWejXZYd&ZZeZd'Z[eYeZZ\eZmd?d@ZndAdBZodCdDZpdEdFZqdGdHZr dDdJdKZsGdLdMdMehZtGdNdOdOetZuGdPdQdQetZvGdRdSdSevZwGdTdUdUevZxGdVdWdWevZyGdXdYdYeyZzeyZ{eyet_|GdZd[d[evZ}Gd\d]d]eyZ~Gd^d_d_e}ZGd`dadaevZGdbdcdcevZGdddedeeZGdfdgdgeZGdhdidievZGdjdkdkevZGdldmdmevZGdndodoevZGdpdqdqevZGdrdsdseZGdtdudueZGdvdwdweZGdxdydyeZGdzd{d{eZGd|d}d}eZGd~ddeZGdddetZGdddeZGdddeZGdddeZGdddeZGdddetZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdddehZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdddehZddZdEddZdFddZddZddZddZddZdGddZddZdHddZdd„ZddĄZewdšZedơZedǡZedȡZedɡZee]ddIdˍdd̈́Zed΃dd̈́ZedЃdd̈́ZeeBeBedd#dˍBZeeedӃeZeydԃedՃd֡eeeeBdסdZddڄZdd܄ZddބZddZddZedd̈́Z edd̈́Z ededfddZddZddZddZehe_ːdIddZe&Zehe_ehe_ededfddZeZ eedddZeedddZeeddeddBdZee{deԠdZdddeԠfddZ֐dHddZedZedZeeeYe\dd\ZZeeݐdOdZedd ^eޠߡd d Zd d ZeedddZ eddZ eddZeddZ eeddeBdZ eZ eddZ eeee`ddeedeydedZeeeԠeBd)ddZ Gdd d ZGd!d"d"ehZGd#d$d$ehZGd%d&d&eZejjjejjjejjjej_e7r4eed'ejeed(ejeed)ejeed*ejeed+ejeed,ejeejd-ejjeejd.ejjeejd/ejjeed0ejeed1ejeed2ejGd3d4d4Zed5kre~d6Ze~d7ZeeYe\d8Zeed9dd:ešZeeed;Zd<eBZeed9dd:ešZeeed=Zed>ed;eed=Z e  d?ej  d@ej  d@ej  dAddlZejeĐejej dBdSdS(Ja pyparsing module - Classes and methods to define and execute parsing grammars ============================================================================= The pyparsing module is an alternative approach to creating and executing simple grammars, vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you don't need to learn a new syntax for defining grammars or matching expressions - the parsing module provides a library of classes that you use to construct the grammar directly in Python. Here is a program to parse "Hello, World!" (or any greeting of the form ``", !"``), built up using :class:`Word`, :class:`Literal`, and :class:`And` elements (the :class:`'+'` operators create :class:`And` expressions, and the strings are auto-converted to :class:`Literal` expressions):: from pip._vendor.pyparsing import Word, alphas # define grammar of a greeting greet = Word(alphas) + "," + Word(alphas) + "!" hello = "Hello, World!" print (hello, "->", greet.parseString(hello)) The program outputs the following:: Hello, World! -> ['Hello', ',', 'World', '!'] The Python representation of the grammar is quite readable, owing to the self-explanatory class names, and the use of '+', '|' and '^' operators. The :class:`ParseResults` object returned from :class:`ParserElement.parseString` can be accessed as a nested list, a dictionary, or an object with named attributes. The pyparsing module handles some of the problems that are typically vexing when writing text parsers: - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) - quoted strings - embedded comments Getting Started - ----------------- Visit the classes :class:`ParserElement` and :class:`ParseResults` to see the base classes that most other pyparsing classes inherit from. Use the docstrings for examples of how to: - construct literal match expressions from :class:`Literal` and :class:`CaselessLiteral` classes - construct character word-group expressions using the :class:`Word` class - see how to create repetitive expressions using :class:`ZeroOrMore` and :class:`OneOrMore` classes - use :class:`'+'`, :class:`'|'`, :class:`'^'`, and :class:`'&'` operators to combine simple expressions into more complex ones - associate names with your parsed results using :class:`ParserElement.setResultsName` - access the parsed data, which is returned as a :class:`ParseResults` object - find some helpful expression short-cuts like :class:`delimitedList` and :class:`oneOf` - find more useful common expressions in the :class:`pyparsing_common` namespace class z2.4.7z30 Mar 2020 00:43 UTCz*Paul McGuire N)ref)datetime) itemgetter)wraps)contextmanager) filterfalse) ifilterfalse)RLock)Iterable)MutableMappingMapping) OrderedDict)SimpleNamespacec@s eZdZdS)rN)__name__ __module__ __qualname__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pyparsing.pyr raA A cross-version compatibility configuration for pyparsing features that will be released in a future version. By setting values in this configuration to True, those features can be enabled in prior versions for compatibility development and testing. - collect_all_And_tokens - flag to enable fix for Issue #63 that fixes erroneous grouping of results names when an And expression is nested within an Or or MatchFirst; set to True to enable bugfix released in pyparsing 2.3.0, or False to preserve pre-2.3.0 handling of named results Ta Diagnostic configuration (all default to False) - warn_multiple_tokens_in_named_alternation - flag to enable warnings when a results name is defined on a MatchFirst or Or expression with one or more And subexpressions (only warns if __compat__.collect_all_And_tokens is False) - warn_ungrouped_named_tokens_in_collection - flag to enable warnings when a results name is defined on a containing expression with ungrouped subexpressions that also have results names - warn_name_set_on_empty_Forward - flag to enable warnings whan a Forward is defined with a results name, but has no contents defined - warn_on_multiple_string_args_to_oneof - flag to enable warnings whan oneOf is incorrectly called with multiple str arguments - enable_debug_on_named_expressions - flag to auto-enable debug on all subsequent calls to ParserElement.setName() FcCs$g|]}|ds|dr|qS)Zenable_Zwarn_ startswith).0nmrrr $rcCsdt_dt_dt_dt_dSNT)__diag__)warn_multiple_tokens_in_named_alternation)warn_ungrouped_named_tokens_in_collectionwarn_name_set_on_empty_Forward%warn_on_multiple_string_args_to_oneofrrrr_enable_all_warningss r!)t __version____versionTime__ __author__ __compat__rAndCaselessKeywordCaselessLiteral CharsNotInCombineDictEachEmpty FollowedByForward GoToColumnGroupKeywordLineEnd LineStartLiteral PrecededBy MatchFirstNoMatchNotAny OneOrMoreOnlyOnceOptionalOrParseBaseExceptionParseElementEnhanceParseExceptionParseExpressionParseFatalException ParseResultsParseSyntaxException ParserElement QuotedStringRecursiveGrammarExceptionRegexSkipTo StringEnd StringStartSuppressTokenTokenConverterWhiteWordWordEnd WordStart ZeroOrMoreChar alphanumsalphas alphas8bit anyCloseTag anyOpenTag cStyleCommentcolcommaSeparatedListcommonHTMLEntity countedArraycppStyleCommentdblQuotedStringdblSlashComment delimitedListdictOfdowncaseTokensemptyhexnums htmlCommentjavaStyleCommentlinelineEnd lineStartlineno makeHTMLTags makeXMLTagsmatchOnlyAtColmatchPreviousExprmatchPreviousLiteral nestedExprnullDebugActionnumsoneOfopAssocoperatorPrecedence printablespunc8bitpythonStyleComment quotedString removeQuotesreplaceHTMLEntity replaceWith restOfLinesglQuotedStringsrange stringEnd stringStarttraceParseAction unicodeString upcaseTokens withAttribute indentedBlockoriginalTextForungroup infixNotation locatedExpr withClass CloseMatchtokenMappyparsing_commonpyparsing_unicode unicode_setconditionAsParseActionrecCs`t|tr|Szt|WSty/t|td}td}|dd| |YSw)aDrop-in replacement for str(obj) that tries to be Unicode friendly. It first tries str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It then < returns the unicode object | encodes it with the default encoding | ... >. xmlcharrefreplacez&#\d+;cSs$dtt|dddddS)Nz\ur)hexinttrrrrz_ustr..) isinstanceunicodestrUnicodeEncodeErrorencodesysgetdefaultencodingrHsetParseActiontransformString)objretZ xmlcharrefrrr_ustrs   rz6sum len sorted reversed list tuple set any all min maxccs|]}|VqdSNr)ryrrr srcCs:d}dddD}t||D] \}}|||}q|S)z/Escape &, <, >, ", ', etc. in a string of data.z&><"'css|] }d|dVqdS)&;Nr)rsrrrrz_xml_escape..zamp gt lt quot apos)splitzipreplace)data from_symbols to_symbolsfrom_to_rrr _xml_escapes r 0123456789Z ABCDEFabcdef\ccs|] }|tjvr|VqdSr)string whitespacercrrrrcs@|dur|nd|r tntttfdd}|S)Nzfailed user-defined conditioncs t|||s||dSr)boolrlrexc_typefnmsgrrpa%s z"conditionAsParseAction..pa)rBr@ _trim_arityr)rmessagefatalrrrrr s  rc@sPeZdZdZdddZeddZdd Zd d Zd d Z dddZ ddZ dS)r>z7base exception class for all parsing runtime exceptionsrNcCs>||_|dur||_d|_n||_||_||_|||f|_dSNr)locrpstr parserElementargs)selfrrrelemrrr__init__0szParseBaseException.__init__cCs||j|j|j|jS)z internal factory method to simplify creating one type of ParseException from another - avoids having __init__ signature conflicts among subclasses )rrrr)clsperrr_from_exception;sz"ParseBaseException._from_exceptioncCsJ|dkr t|j|jS|dvrt|j|jS|dkr!t|j|jSt|)zsupported attributes by name are: - lineno - returns the line number of the exception text - col - returns the column number of the exception text - line - returns the line containing the exception text rl)r[columnri)rlrrr[riAttributeError)ranamerrr __getattr__CszParseBaseException.__getattr__cCs^|jr |jt|jkrd}nd|j|j|jddd}nd}d|j||j|j|jfS)Nz, found end of textz , found %rrz\\\rz%%s%s (at char %d), (line:%d, col:%d))rrlenrrrlr)rfoundstrrrr__str__Rs$zParseBaseException.__str__cCt|Srrrrrr__repr__\zParseBaseException.__repr__>!,s    r>c@seZdZdZedddZdS)r@a: Exception thrown when parse expressions don't match class; supported attributes by name are: - lineno - returns the line number of the exception text - col - returns the column number of the exception text - line - returns the line containing the exception text Example:: try: Word(nums).setName("integer").parseString("ABC") except ParseException as pe: print(pe) print("column: {}".format(pe.col)) prints:: Expected integer (at char 0), (line:1, col:1) column: 1 c Csfddl}|dur t}g}t|tr%||j|d|jdd|dt |j ||dkr|j |j |d}t }t|| dD]d\}}|d}|jdd} t| tr|jjd vrdqI| |vriqI|| t | } |d | j| j | n&| durt | } |d | j| j n|j} | jd vrqI|d | j|d8}|snqId|S)ap Method to take an exception and translate the Python internal traceback into a list of the pyparsing expressions that caused the exception to be raised. Parameters: - exc - exception raised during parsing (need not be a ParseException, in support of Python exceptions that might be raised in a parse action) - depth (default=16) - number of levels back in the stack trace to list expression and function names; if None, the full stack trace names will be listed; if 0, only the failing input line, marker, and exception string will be shown Returns a multi-line string listing the ParserElements and/or function names in the exception's stack trace. Note: the diagnostic output will include string representations of the expressions that failed to parse. These representations will be more helpful if you use `setName` to give identifiable names to your expressions. Otherwise they will use the default string forms, which may be cryptic to read. explain() is only supported under Python 3. rN r^z{0}: {1})contextr) parseImpl _parseNoCachez {0}.{1} - {2}z{0}.{1})wrapperzz{0} )inspectrgetrecursionlimitrr>appendrir[formatrrgetinnerframes __traceback__set enumeratef_localsgetrEf_codeco_nameaddrr) excdepthrrcallersseenifffrmf_self self_typecoderrrexplainsN         zParseException.explainN)r)rrrr staticmethodrrrrrr@ksr@c@eZdZdZdS)rBznuser-throwable exception thrown when inconsistent parse content is found; stops all parsing immediatelyNrrrrrrrrrBsrBc@r)rDzjust like :class:`ParseFatalException`, but thrown internally when an :class:`ErrorStop` ('-' operator) indicates that parsing is to stop immediately because an unbacktrackable syntax error has been found. NrrrrrrDsrDc@ eZdZdZddZddZdS)rGziexception thrown by :class:`ParserElement.validate` if the grammar could be improperly recursive cCs ||_dSrparseElementTracerparseElementListrrrr z"RecursiveGrammarException.__init__cCs d|jS)NzRecursiveGrammarException: %srrrrrrrz!RecursiveGrammarException.__str__N)rrrrrrrrrrrGs rGc@s,eZdZddZddZddZddZd S) _ParseResultsWithOffsetcCs||f|_dSrtup)rp1p2rrrrz _ParseResultsWithOffset.__init__cCs |j|Srrrr rrr __getitem__rz#_ParseResultsWithOffset.__getitem__cCst|jdSNr)reprrrrrrrr!z _ParseResultsWithOffset.__repr__cCs|jd|f|_dSr$rr"rrr setOffsetrz!_ParseResultsWithOffset.setOffsetN)rrrrr#rr&rrrrrs  rc@seZdZdZd]ddZddddefddZdd Zefd d Zd d Z ddZ ddZ ddZ e Z ddZddZddZddZddZerPeZ eZ eZneZ eZ eZ ddZd d!Zd"d#Zd$d%Zd&d'Zd^d(d)Zd*d+Zd,d-Zd.d/Zd0d1Z d2d3Z!d4d5Z"d6d7Z#d8d9Z$d:d;Z%d`` - see :class:`ParserElement.setResultsName`) Example:: integer = Word(nums) date_str = (integer.setResultsName("year") + '/' + integer.setResultsName("month") + '/' + integer.setResultsName("day")) # equivalent form: # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") # parseString returns a ParseResults object result = date_str.parseString("1999/12/31") def test(s, fn=repr): print("%s -> %s" % (s, fn(eval(s)))) test("list(result)") test("result[0]") test("result['month']") test("result.day") test("'month' in result") test("'minutes' in result") test("result.dump()", str) prints:: list(result) -> ['1999', '/', '12', '/', '31'] result[0] -> '1999' result['month'] -> '12' result.day -> '31' 'month' in result -> True 'minutes' in result -> False result.dump() -> ['1999', '/', '12', '/', '31'] - day: 31 - month: 12 - year: 1999 NTcCs"t||r|St|}d|_|Sr)robject__new___ParseResults__doinit)rtoklistnameasListmodalretobjrrrr(!s  zParseResults.__new__c Csd|jr;d|_d|_d|_i|_||_||_|durg}||tr(|dd|_n||tr3t||_n|g|_t |_ |dur|r|sHd|j|<||t rQt |}||_||t dttfre|ddgfvs||trm|g}|r||trtt|jd||<n tt|dd||<|||_dSz |d||<WdStttfy|||<YdSwdSdSdS)NFrr)r)_ParseResults__name_ParseResults__parent_ParseResults__accumNames_ParseResults__asList_ParseResults__modallist_ParseResults__toklist_generatorTypedict_ParseResults__tokdictrrr basestringrCrKeyError TypeError IndexError)rr*r+r,r-rrrrr*sH      "  zParseResults.__init__cCsLt|ttfr |j|S||jvr|j|ddStdd|j|DS)NrrcSsg|]}|dqSrrrvrrrrXz,ParseResults.__getitem__..)rrslicer5r1r8rCr"rrrr#Qs   zParseResults.__getitem__cCs||tr|j|t|g|j|<|d}n"||ttfr'||j|<|}n|j|tt|dg|j|<|}||trFt||_ dSdSr$) rr8rr4rrAr5rCwkrefr0)rkr?rsubrrr __setitem__Zs   " zParseResults.__setitem__c Cst|ttfrXt|j}|j|=t|tr$|dkr||7}t||d}tt||}||j D]\}}|D]}t |D]\}\}} t || | |k||<qBq.r^rrrr _itervalueszParseResults._itervaluescr_)Nc3s|] }||fVqdSrrr`rrrrrz*ParseResults._iteritems..rbrrrr _iteritemsrdzParseResults._iteritemscC t|S)zVReturns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).)r4r\rrrrkeys zParseResults.keyscCrf)zXReturns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).)r4 itervaluesrrrrvaluesrhzParseResults.valuescCrf)zfReturns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).)r4 iteritemsrrrrrJrhzParseResults.itemscCrS)zSince keys() returns an iterator, this method is helpful in bypassing code that looks for the existence of any defined results names.)rr8rrrrhaskeyss zParseResults.haskeyscOs|sdg}|D]\}}|dkr|d|f}q td|t|dts1t|dks1|d|vr>|d}||}||=|S|d}|S)a Removes and returns item at specified index (default= ``last``). Supports both ``list`` and ``dict`` semantics for ``pop()``. If passed no argument or an integer argument, it will use ``list`` semantics and pop tokens from the list of parsed tokens. If passed a non-integer argument (most likely a string), it will use ``dict`` semantics and pop the corresponding value from any defined results names. A second default return value argument is supported, just as in ``dict.pop()``. Example:: def remove_first(tokens): tokens.pop(0) print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] label = Word(alphas) patt = label("LABEL") + OneOrMore(Word(nums)) print(patt.parseString("AAB 123 321").dump()) # Use pop() in a parse action to remove named result (note that corresponding value is not # removed from list form of results) def remove_LABEL(tokens): tokens.pop("LABEL") return tokens patt.addParseAction(remove_LABEL) print(patt.parseString("AAB 123 321").dump()) prints:: ['AAB', '123', '321'] - LABEL: AAB ['AAB', '123', '321'] rdefaultrz-pop() got an unexpected keyword argument '%s'r)rJr;rrr)rrkwargsrCr?indexr defaultvaluerrrpops%   zParseResults.popcCs||vr||S|S)a[ Returns named result matching the given key, or if there is no such name, then returns the given ``defaultValue`` or ``None`` if no ``defaultValue`` is specified. Similar to ``dict.get()``. Example:: integer = Word(nums) date_str = integer("year") + '/' + integer("month") + '/' + integer("day") result = date_str.parseString("1999/12/31") print(result.get("year")) # -> '1999' print(result.get("hour", "not specified")) # -> 'not specified' print(result.get("hour")) # -> None r)rkey defaultValuerrrrszParseResults.getcCsR|j|||jD]\}}t|D]\}\}}t||||k||<qq dS)a Inserts new element at location index in the list of parsed tokens. Similar to ``list.insert()``. Example:: print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] # use a parse action to insert the parse location in the front of the parsed results def insert_locn(locn, tokens): tokens.insert(0, locn) print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] N)r5insertr8rJrr)rroinsStrr+rMrCrOrPrrrrt s zParseResults.insertcCs|j|dS)a Add single element to end of ParseResults list of elements. Example:: print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] # use a parse action to compute the sum of the parsed integers, and add it to the end def append_sum(tokens): tokens.append(sum(map(int, tokens))) print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] N)r5r)ritemrrrr  zParseResults.appendcCs(t|tr ||dS|j|dS)a  Add sequence of elements to end of ParseResults list of elements. Example:: patt = OneOrMore(Word(alphas)) # use a parse action to append the reverse of the matched strings, to make a palindrome def make_palindrome(tokens): tokens.extend(reversed([t[::-1] for t in tokens])) return ''.join(tokens) print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' N)rrC__iadd__r5extend)ritemseqrrrry/s zParseResults.extendcCs|jdd=|jdS)z7 Clear all elements and results names. N)r5r8clearrrrrr{Bs zParseResults.clearcCs z||WStyYdSwr)r:rr+rrrrIs   zParseResults.__getattr__cCs|}||7}|Srcopy)rotherrrrr__add__OszParseResults.__add__cs|jr5t|jfdd|j}fdd|D}|D]\}}|||<t|dtr4t||d_q|j|j7_|j |j|S)Ncs|dkrS|Sr$r)a)offsetrrrWr@z'ParseResults.__iadd__..c s4g|]\}}|D]}|t|d|dfqqSrr)rrrCvlistr?) addoffsetrrrYs  z)ParseResults.__iadd__..r) r8rr5rJrrCrBr0r1update)rr otheritemsotherdictitemsrCr?r)rrrrxTs     zParseResults.__iadd__cCs"t|tr |dkr |S||Sr$)rrr~rrrrr__radd__dszParseResults.__radd__cCsdt|jt|jfS)Nz(%s, %s))r%r5r8rrrrrlzParseResults.__repr__cCsdddd|jDdS)N[, css*|]}t|tr t|nt|VqdSr)rrCrr%rr rrrrps(z'ParseResults.__str__..])rr5rrrrroszParseResults.__str__rcCsLg}|jD]}|r|r||t|tr||7}q|t|q|Sr)r5rrrC _asStringListr)rsepoutrvrrrrrs   zParseResults._asStringListcCsdd|jDS)ax Returns the parse results as a nested list of matching tokens, all converted to strings. Example:: patt = OneOrMore(Word(alphas)) result = patt.parseString("sldkj lsdkj sldkj") # even though the result prints in string-like form, it is actually a pyparsing ParseResults print(type(result), result) # -> ['sldkj', 'lsdkj', 'sldkj'] # Use asList() to create an actual list result_list = result.asList() print(type(result_list), result_list) # -> ['sldkj', 'lsdkj', 'sldkj'] cSs"g|] }t|tr |n|qSr)rrCr,)rresrrrrs"z'ParseResults.asList..rUrrrrr,}szParseResults.asListcs6tr|j}n|j}fddtfdd|DS)a Returns the named parse results as a nested dictionary. Example:: integer = Word(nums) date_str = integer("year") + '/' + integer("month") + '/' + integer("day") result = date_str.parseString('12/31/1999') print(type(result), repr(result)) # -> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) result_dict = result.asDict() print(type(result_dict), repr(result_dict)) # -> {'day': '1999', 'year': '12', 'month': '31'} # even though a ParseResults supports dict-like access, sometime you just need to have a dict import json print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} cs0t|tr|r |Sfdd|DS|S)Ncsg|]}|qSrrr>toItemrrrr@z7ParseResults.asDict..toItem..)rrCrlasDictrrrrrs z#ParseResults.asDict..toItemc3s |] \}}||fVqdSrrrrCr?rrrrz&ParseResults.asDict..)PY_3rJrkr7)ritem_fnrrrrs   zParseResults.asDictcCs<t|j}t|j|_|j|_|j|j|j|_|S)zG Returns a new copy of a :class:`ParseResults` object. ) rCr5r7r8rJr0r1rr/rrrrrr~s zParseResults.copyFc CsFd}g}tdd|jD}|d}|sd}d}d}d} |dur%|} n|jr+|j} | s3|r1dSd} |||d| d g7}t|jD]S\} } t| trp| |vr`|| || |oY|du||g7}qA|| d|oi|du||g7}qAd} | |vrz|| } | s|rqAd} t t | } |||d| d | d | d g 7}qA|||d | d g7}d |S) z (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names. rcss*|]\}}|D] }|d|fVqqdSrNrrrrrrs  z%ParseResults.asXML.. rNITEM<>.z %s%s- %s: rr)rfull include_list_depthcs|]}t|tVqdSr)rrC)rvvrrrrSz %s%s[%d]: %s%s%s) rrr,rlsortedrJrrCdumpr%anyrr) rrrrrrNLrJrCr?r rrrrr)sR           zParseResults.dumpcOs tj|g|Ri|dS)a# Pretty-printer for parsed results as a list, using the `pprint `_ module. Accepts additional positional or keyword args as defined for `pprint.pprint `_ . Example:: ident = Word(alphas, alphanums) num = Word(nums) func = Forward() term = ident | num | Group('(' + func + ')') func <<= ident + Group(Optional(delimitedList(term))) result = func.parseString("fna a,b,(fnb c,d,200),100") result.pprint(width=40) prints:: ['fna', ['a', 'b', ['(', 'fnb', ['c', 'd', '200'], ')'], '100']] N)pprintr,rrrnrrrrjs zParseResults.pprintcCs.|j|j|jdur|pd|j|jffSr)r5r8r~r0r1r/rrrr __getstate__szParseResults.__getstate__cCsP|d|_|d\|_}}|_i|_|j||dur#t||_dSd|_dSrF)r5r8r/r1rrBr0)rstater inAccumNamesrrr __setstate__s   zParseResults.__setstate__cCs|j|j|j|jfSr)r5r/r2r3rrrr__getnewargs__rzParseResults.__getnewargs__cCstt|t|Sr)rrr4rgrrrrrrzParseResults.__dir__cCsrdd}|g}|D]\}}t|tr||j||d7}q |||g|||d7}q |dur7||g|d}|S)z Helper classmethod to construct a ParseResults from a dict, preserving the name-value relations as results names. If an optional 'name' argument is given, a nested ParseResults will be returned cSsBzt|Wn tyYdSwtrt|ttf St|t SNF)rX Exceptionrrrbytesr9rrrr is_iterables   z+ParseResults.from_dict..is_iterabler+)r+r,N)rJrr from_dict)rrr+rrrCr?rrrrs  zParseResults.from_dict)NNTTrr)NFrT)rTTr)6rrrrr(rrr#rErQrRrTrV __nonzero__rYr[r^rcrerrgrjrJr\rirkrlrqrrtrryr{rrrxrrrrr,rr~rrrrrrrrrrrrrrrrCsx * '   7  $ = (A rCcCsF|}d|krt|krnn ||ddkrdS||dd|S)aReturns current column within a string, counting newlines as line separators. The first column is number 1. Note: the default parsing behavior is to expand tabs in the input string before starting the parsing process. See :class:`ParserElement.parseString` for more information on parsing strings containing ```` s, and suggested methods to maintain a consistent view of the parsed string, the parse location, and line and column positions within the parsed string. rrr)rrfind)rstrgrrrrr[s Br[cCs|dd|dS)aReturns current line number within a string, counting newlines as line separators. The first line is number 1. Note - the default parsing behavior is to expand tabs in the input string before starting the parsing process. See :class:`ParserElement.parseString` for more information on parsing strings containing ```` s, and suggested methods to maintain a consistent view of the parsed string, the parse location, and line and column positions within the parsed string. rrr)count)rrrrrrls rlcCsB|dd|}|d|}|dkr||d|S||ddS)zfReturns the line of text containing loc within a string, counting newlines as line separators. rrrN)rfind)rrlastCRnextCRrrrris  ricCs8tdt|dt|dt||t||fdS)NzMatch z at loc z(%d,%d))printrrlr[)instringrexprrrr_defaultStartDebugActions8rcCs$tdt|dt|dS)NzMatched z -> )rrrr,)rstartlocendlocrtoksrrr_defaultSuccessDebugActions$rcCstdt|dS)NzException raised:)rr)rrrrrrr_defaultExceptionDebugActionrrcGdS)zG'Do-nothing' debug action, to suppress debugging output during parsing.Nr)rrrrrssrsrcstvr fddSdgdgtdddkr#ddd}dd d ntj}tjd }|dd d }|d|d|ffdd}d}z tdtdj}Wn tybt}Ynw||_|S)Ncs|Srrr)funcrrrz_trim_arity..rFr)rcSs8tdkrdnd}tj| |dd|}|ddgS)N)rrrrlimitr)system_version traceback extract_stack)rr frame_summaryrrrr sz"_trim_arity..extract_stackcSs$tj||d}|d}|ddgS)Nrrr)r extract_tb)tbrframesrrrrrsz_trim_arity..extract_tbrrrcs z|dd}dd<|WSty`drz#td}|dddddks4Wz~WntyAYnwz~WwtyNYwwdkr_dd7<Yqw)NrrTrrr)r;rexc_info NameError)rrrr foundArityrrmaxargspa_call_line_synthrrr!s8     z_trim_arity..wrapperzr __class__r=) singleArgBuiltinsrrrrgetattrrrr)rrr LINE_DIFF this_liner func_namerrrrs.      rc@seZdZdZdZdZeddZeddZe dd Z dd d Z d d Z ddZ dddZdddZdddZddZddZddZddZdd Zd!d"Zdd#d$Zd%d&Zdd'd(Zd)d*Zd+d,ZGd-d.d.eZed/ur{Gd0d1d1eZnGd2d1d1eZiZ e!Z"d3d3gZ#dd4d5Z$eZ%ed6d7Z&dZ'edd9d:Z(dd;d<Z)e*dfd=d>Z+d?d@Z,e*fdAdBZ-e*dfdCdDZ.dEdFZ/dGdHZ0dIdJZ1dKdLZ2dMdNZ3dOdPZ4dQdRZ5dSdTZ6dUdVZ7dWdXZ8dYdZZ9d[d\Z:d]d^Z;d_d`ZdedfZ?dgdhZ@didjZAdkdlZBdmdnZCdodpZDddqdrZEdsdtZFdudvZGdwdxZHdydzZIdd{d|ZJdd}d~ZKddZLddZMddZNddZOddZPdddZQ / /dddZRd/S)rEz)Abstract base level parser element class.z FcC |t_dS)a Overrides the default whitespace chars Example:: # default whitespace chars are space, and newline OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] # change to just treat newline as significant ParserElement.setDefaultWhitespaceChars(" \t") OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] N)rEDEFAULT_WHITE_CHARScharsrrrsetDefaultWhitespaceCharsLs z'ParserElement.setDefaultWhitespaceCharscCr)ah Set class to be used for inclusion of string literals into a parser. Example:: # default literal class used is Literal integer = Word(nums) date_str = integer("year") + '/' + integer("month") + '/' + integer("day") date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] # change to Suppress ParserElement.inlineLiteralsUsing(Suppress) date_str = integer("year") + '/' + integer("month") + '/' + integer("day") date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] N)rE_literalStringClassrrrrinlineLiteralsUsing\s z!ParserElement.inlineLiteralsUsingcCs|jr |j}|js|Sr)tb_next)rrrrr_trim_tracebackrszParserElement._trim_tracebackcCst|_d|_d|_d|_||_d|_ttj |_ d|_ d|_ d|_ t|_d|_d|_d|_d|_d|_d|_d|_d|_d|_dS)NTFrNNN)r4 parseAction failActionstrRepr resultsName saveAsListskipWhitespacerrEr whiteCharscopyDefaultWhiteCharsmayReturnEmptykeepTabs ignoreExprsdebug streamlined mayIndexErrorerrmsg modalResults debugActionsr callPreparse callDuringTry)rsavelistrrrrxs(  zParserElement.__init__cCs<t|}|jdd|_|jdd|_|jrtj|_|S)a/ Make a copy of this :class:`ParserElement`. Useful for defining different parse actions for the same parsing pattern, using copies of the original parse element. Example:: integer = Word(nums).setParseAction(lambda toks: int(toks[0])) integerK = integer.copy().addParseAction(lambda toks: toks[0] * 1024) + Suppress("K") integerM = integer.copy().addParseAction(lambda toks: toks[0] * 1024 * 1024) + Suppress("M") print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) prints:: [5120, 100, 655360, 268435456] Equivalent form of ``expr.copy()`` is just ``expr()``:: integerM = integer().addParseAction(lambda toks: toks[0] * 1024 * 1024) + Suppress("M") N)r~rr r rErr )rcpyrrrr~s zParserElement.copycCs$||_d|j|_tjr||S)a_ Define name for this expression, makes debugging and exception messages clearer. Example:: Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) Expected )r+rr!enable_debug_on_named_expressionssetDebugr|rrrsetNames  zParserElement.setNamecCs |||S)aO Define name for referencing matching tokens as a nested attribute of the returned parse results. NOTE: this returns a *copy* of the original :class:`ParserElement` object; this is so that the client can define a basic element, such as an integer, and reference it in multiple places with different names. You can also set results names using the abbreviated syntax, ``expr("name")`` in place of ``expr.setResultsName("name")`` - see :class:`__call__`. Example:: date_str = (integer.setResultsName("year") + '/' + integer.setResultsName("month") + '/' + integer.setResultsName("day")) # equivalent form: date_str = integer("year") + '/' + integer("month") + '/' + integer("day") )_setResultsNamerr+listAllMatchesrrrsetResultsNames zParserElement.setResultsNamecCs4|}|dr|dd}d}||_| |_|S)N*rT)r~endswithrr)rr+rnewselfrrrrs  zParserElement._setResultsNameTcsB|r|jdfdd }|_||_|St|jdr|jj|_|S)zMethod to invoke the Python pdb debugger when this element is about to be parsed. Set ``breakFlag`` to True to enable, False to disable. Tcsddl}|||||Sr$)pdb set_trace)rr doActions callPreParser# _parseMethodrrbreakersz'ParserElement.setBreak..breaker_originalParseMethodNTT)_parser*r])r breakFlagr)rr'rsetBreaks zParserElement.setBreakcOsXt|dgkr g|_|Stdd|Dstdtttt||_|dd|_|S)a Define one or more actions to perform when successfully matching parse element definition. Parse action fn is a callable method with 0-3 arguments, called as ``fn(s, loc, toks)`` , ``fn(loc, toks)`` , ``fn(toks)`` , or just ``fn()`` , where: - s = the original string being parsed (see note below) - loc = the location of the matching substring - toks = a list of the matched tokens, packaged as a :class:`ParseResults` object If the functions in fns modify the tokens, they can return them as the return value from fn, and the modified list of tokens will replace the original. Otherwise, fn does not need to return any value. If None is passed as the parse action, all previously added parse actions for this expression are cleared. Optional keyword arguments: - callDuringTry = (default= ``False``) indicate if parse action should be run during lookaheads and alternate testing Note: the default parsing behavior is to expand tabs in the input string before starting the parsing process. See :class:`parseString for more information on parsing strings containing ```` s, and suggested methods to maintain a consistent view of the parsed string, the parse location, and line and column positions within the parsed string. Example:: integer = Word(nums) date_str = integer + '/' + integer + '/' + integer date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] # use parse action to convert to ints at parse time integer = Word(nums).setParseAction(lambda toks: int(toks[0])) date_str = integer + '/' + integer + '/' + integer # note that integer fields are now ints, not strings date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] Ncs|]}t|VqdSr)callable)rrrrrrraz/ParserElement.setParseAction..zparse actions must be callablerF)r4rallr;maprrrrfnsrnrrrrs(zParserElement.setParseActioncOs4|jtttt|7_|jp|dd|_|S)z Add one or more parse actions to expression's list of parse actions. See :class:`setParseAction`. See examples in :class:`copy`. rF)rr4r2rrrr3rrraddParseActionszParserElement.addParseActionc OsF|D]}|jt||d|dddq|jp|dd|_|S)aAdd a boolean predicate function to expression's list of parse actions. See :class:`setParseAction` for function call signatures. Unlike ``setParseAction``, functions passed to ``addCondition`` need to return boolean success/fail of the condition. Optional keyword arguments: - message = define a custom message to be used in the raised exception - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException Example:: integer = Word(nums).setParseAction(lambda toks: int(toks[0])) year_int = integer.copy() year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") date_str = year_int + '/' + integer + '/' + integer result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) rrF)rrr)rrrrr)rr4rnrrrr addCondition)s   zParserElement.addConditioncCs ||_|S)aDefine action to perform if parsing fails at this expression. Fail acton fn is a callable function that takes the arguments ``fn(s, loc, expr, err)`` where: - s = string being parsed - loc = location where expression match was attempted and failed - expr = the parse expression that failed - err = the exception thrown The function returns no value. It may throw :class:`ParseFatalException` if it is desired to stop parsing immediately.)rrrrrr setFailActionBs zParserElement.setFailActionc CsJd}|r#d}|jD]}z |||\}}d}q ty Yq w|s|SNTF)r r,r@)rrr exprsFoundedummyrrr_skipIgnorablesOs   zParserElement._skipIgnorablescCsZ|jr |||}|jr+|j}t|}||kr+|||vr+|d7}||kr+|||vs|SNr)r r=rr r)rrrwtinstrlenrrrpreParse\s zParserElement.preParsecCs|gfSrrrrrr%rrrrhrzParserElement.parseImplcCs|Srrrrr tokenlistrrr postParsekzParserElement.postParsec Cs@d\}}}|j}|s |jr|j|r|j||||zA|r(|jr(|||} n|} | } |js5| t|krRz ||| |\}} WntyQt |t||j |w||| |\}} Wnft y} z|j|rs|j||| || |jr~||| || d} ~ ww|r|jr|||} n|} | } |js| t|krz ||| |\}} Wntyt |t||j |w||| |\}} | ||| } t | |j|j|jd} |jr|s|jr|rEzD|jD]>}z||| | } Wnty}z t d}||_|d}~ww| dur$| | ur$t | |j|jot| t tf|jd} qWnat yD} z|j|r?|j||| || d} ~ ww|jD]?}z||| | } Wntyh}z t d}||_|d}~ww| dur| | urt | |j|jot| t tf|jd} qH|r|j|r|j||| ||| || fS)N)rrr)r,r-z exception raised in parse action)rrrrrArrrr<r@rrrErCrrrrr __cause__rr4)rrrr%r&TRYMATCHFAIL debuggingpreloc tokensStarttokenserr retTokensrparse_action_excrrrrros            zParserElement._parseNoCachecCs6z |j||dddWStyt|||j|w)NFr%r)r,rBr@rrrrrrrtryParses  zParserElement.tryParsec Cs,z |||WdSttfyYdSw)NFT)rTr@r<rSrrr canParseNexts zParserElement.canParseNextc@eZdZddZdS)zParserElement._UnboundedCachecs~it|_fdd}fdd}fdd}fdd}t|||_t|||_t|||_t|||_dS) Nc |Srrrrrcache not_in_cacherrr z3ParserElement._UnboundedCache.__init__..getcs ||<dSrrrrrrOr[rrrr]z3ParserElement._UnboundedCache.__init__..setc dSrr{rr_rrr{r]z5ParserElement._UnboundedCache.__init__..clearctSrrrr_rr cache_lenrz9ParserElement._UnboundedCache.__init__..cache_len)r'r\types MethodTyperrr{rT)rrrr{rdrrZrrs    z&ParserElement._UnboundedCache.__init__Nrrrrrrrr_UnboundedCache rhNc@rV)ParserElement._FifoCachecst|_tfdd}fdd}fdd}fdd}t|||_t|||_t|||_t|||_dS) NcrWrrXrYrZrrrr].ParserElement._FifoCache.__init__..getcsJ||<tkr#zdWn tyYnwtks dSdSr)rpopitemr:r^)r[sizerrrs  .ParserElement._FifoCache.__init__..setcr`rrarr_rrr{r]0ParserElement._FifoCache.__init__..clearcrbrrcrr_rrrdr4ParserElement._FifoCache.__init__..cache_len) r'r\ _OrderedDictrerfrrr{rTrrmrrr{rdr)r[r\rmrrs   !ParserElement._FifoCache.__init__Nrgrrrr _FifoCacherirtc@rV)rjcst|_itgfdd}fdd}fdd}fdd}t|||_t|||_t|||_t|||_ dS) NcrWrrXrYrZrrrr]rkcs>||<tkrdtks |dSr)rrqpopleftrr^)r[key_fiformrrrs   rncsdSrrar)r[rvrrr{s rocrbrrcrr_rrrdrrp) r'r\ collectionsdequererfrrr{rTrrr)r[rvr\rmrr s   rsNrgrrrrrtrirc Csd\}}|||||f}tjqtj}||} | |jur^tj|d7<z |||||} WntyF} z ||| j | j d} ~ ww||| d| d f| WdStj|d7<t | t rn| | d| d fWdS1swYdS)Nrrr)rEpackrat_cache_lock packrat_cacherr\packrat_cache_statsrr>rrrr~rr) rrrr%r&HITMISSlookupr[rOrrrr _parseCache+s,   $zParserElement._parseCachecCs(tjdgttjtjdd<dSr$)rErzr{rr{rrrr resetCacheDs zParserElement.resetCachecCs<tjsdt_|durtt_nt|t_tjt_dSdS)aEnables "packrat" parsing, which adds memoizing to the parsing logic. Repeated parse attempts at the same string location (which happens often in many complex grammars) can immediately return a cached value, instead of re-executing parsing/validating code. Memoizing is done of both valid results and parsing exceptions. Parameters: - cache_size_limit - (default= ``128``) - if an integer value is provided will limit the size of the packrat cache; if None is passed, then the cache size will be unbounded; if 0 is passed, the cache will be effectively disabled. This speedup may break existing programs that use parse actions that have side-effects. For this reason, packrat parsing is disabled when you first import pyparsing. To activate the packrat feature, your program must call the class method :class:`ParserElement.enablePackrat`. For best results, call ``enablePackrat()`` immediately after importing pyparsing. Example:: from pip._vendor import pyparsing pyparsing.ParserElement.enablePackrat() TN)rE_packratEnabledrhrzrtrr,)cache_size_limitrrr enablePackratJs   zParserElement.enablePackratc Cst|js ||jD]}|q|js|}z"||d\}}|r<|||}t t }|||W|SW|St y_}ztj rJt |dddurY||j|_|d}~ww)a Execute the parse expression with the given string. This is the main interface to the client code, once the complete expression has been built. Returns the parsed data as a :class:`ParseResults` object, which may be accessed as a list, or as a dict or object with attributes if the given parser includes results names. If you want the grammar to require that the entire input string be successfully parsed, then set ``parseAll`` to True (equivalent to ending the grammar with ``StringEnd()``). Note: ``parseString`` implicitly calls ``expandtabs()`` on the input string, in order to report proper column numbers in parse actions. If the input string contains tabs and the grammar uses parse actions that use the ``loc`` argument to index into the string being parsed, you can ensure you have a consistent view of the input string by: - calling ``parseWithTabs`` on your grammar before calling ``parseString`` (see :class:`parseWithTabs`) - define your parse action using the full ``(s, loc, toks)`` signature, and reference the input string using the parse action's ``s`` argument - explictly expand the tabs in your input string before calling ``parseString`` Example:: Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text rrN)rErr streamliner r  expandtabsr,rAr-rJr>verbose_stacktracerrr)rrparseAllr;rrNserrrr parseStringms0!      zParserElement.parseStringc csb|js||jD]}|q |jst|}t|}d}|j}|j}t d} zb||kr| |krz|||} ||| dd\} } Wn t yS| d}Yn)w| |krx| d7} | | | fV|ru|||} | |krp| }n |d7}n| }n| d}||kr| |ks6WdSWdSWdSWdSt y}zt j rt|dddur||j|_|d}~ww)aq Scan the input string for expression matches. Each match will return the matching tokens, start location, and end location. May be called with optional ``maxMatches`` argument, to clip scanning after 'n' matches are found. If ``overlap`` is specified, then overlapping matches will be reported. Note that the start and end locations are reported relative to the string being parsed. See :class:`parseString` for more information on parsing strings with embedded tabs. Example:: source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" print(source) for tokens, start, end in Word(alphas).scanString(source): print(' '*start + '^'*(end-start)) print(' '*start + tokens[0]) prints:: sldjf123lsdjjkf345sldkjf879lkjsfd987 ^^^^^ sldjf ^^^^^^^ lsdjjkf ^^^^^^ sldkjf ^^^^^^ lkjsfd rFr&rrN)rrr r rrrrAr,rErr@r>rrrr)rr maxMatchesoverlapr;r@r preparseFnparseFnmatchesrLnextLocrNnextlocrrrr scanStringsP         (zParserElement.scanStringc Csg}d}d|_zN||D]-\}}}|||||r8t|tr)||7}nt|tr3||7}n|||}q |||ddd|D}dtt t |WSt yv}zt j rat|dddurp||j|_|d}~ww)a[ Extension to :class:`scanString`, to modify matching text with modified tokens that may be returned from a parse action. To use ``transformString``, define a grammar and attach a parse action to it that modifies the returned token list. Invoking ``transformString()`` on a target string will then scan for matches, and replace the matched text patterns according to the logic in the parse action. ``transformString()`` returns the resulting transformed string. Example:: wd = Word(alphas) wd.setParseAction(lambda toks: toks[0].title()) print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) prints:: Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. rTNcSsg|]}|r|qSrrrorrrrr@z1ParserElement.transformString..rr)r rrrrCr,r4rr2r_flattenr>rErrrr)rrrlastErrr;rrrrrs0    zParserElement.transformStringc Cs`ztdd|||DWSty/}ztjrt|dddur)||j|_|d}~ww)a Another extension to :class:`scanString`, simplifying the access to the tokens found to match the given parse expression. May be called with optional ``maxMatches`` argument, to clip searching after 'n' matches are found. Example:: # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters cap_word = Word(alphas.upper(), alphas.lower()) print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) # the sum() builtin can be used to merge results into a single ParseResults object print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) prints:: [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] cSsg|]\}}}|qSrr)rrrr;rrrr7z.ParserElement.searchString..rN)rCrr>rErrrr)rrrrrrr searchString!szParserElement.searchStringc csVd}d}|j||dD]\}}}|||V|r|dV|}q ||dVdS)aR Generator method to split a string using the given expression as a separator. May be called with optional ``maxsplit`` argument, to limit the number of splits; and the optional ``includeSeparators`` argument (default= ``False``), if the separating matching text should be included in the split results. Example:: punc = oneOf(list(".,;:/-!?")) print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) prints:: ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] r)rN)r) rrmaxsplitincludeSeparatorssplitslastrrr;rrrrAs zParserElement.splitcCsV|turt|St|tr||}t|ts%tjdt|t dddSt ||gS)a[ Implementation of + operator - returns :class:`And`. Adding strings to a ParserElement converts them to :class:`Literal`s by default. Example:: greet = Word(alphas) + "," + Word(alphas) + "!" hello = "Hello, World!" print (hello, "->", greet.parseString(hello)) prints:: Hello, World! -> ['Hello', ',', 'World', '!'] ``...`` may be used as a parse expression as a short form of :class:`SkipTo`. Literal('start') + ... + Literal('end') is equivalent to: Literal('start') + SkipTo('end')("_skipped*") + Literal('end') Note that the skipped text is returned with '_skipped' as a results name, and to support having multiple skips in the same parser, the value returned is a list of all skipped text. 4Cannot combine element of type %s with ParserElementr stacklevelN) Ellipsis _PendingSkiprr9rrEwarningswarnr SyntaxWarningr&rrrrrZs    zParserElement.__add__cCsZ|tur t|d|St|tr||}t|ts)tjdt|t dddS||S)z` Implementation of + operator when left operand is not a :class:`ParserElement` _skipped*rrrN) rrIrr9rrErrrrrrrrrs   zParserElement.__radd__cCsJt|tr ||}t|tstjdt|tdddS|t |S)zT Implementation of - operator, returns :class:`And` with error stop rrrN) rr9rrErrrrr& _ErrorStoprrrr__sub__s   zParserElement.__sub__cCsBt|tr ||}t|tstjdt|tdddS||S)z` Implementation of - operator when left operand is not a :class:`ParserElement` rrrNrr9rrErrrrrrrr__rsub__   zParserElement.__rsub__cs|turd}nt|tr#|ddtfkr#d|ddddd}t|tr.|d}}nyt|trtdd |D}|d dd}|ddurPd|df}t|dtr{|ddur{|ddkrgtS|ddkrqtS|dtSt|dtrt|dtr|\}}||8}ntd t|dt|dtd t||dkrtd |dkrtd||krdkrtd|rfdd|r|dkr܈|}|St g||}|S|}|S|dkr}|St g|}|S)a Implementation of * operator, allows use of ``expr * 3`` in place of ``expr + expr + expr``. Expressions may also me multiplied by a 2-integer tuple, similar to ``{min, max}`` multipliers in regular expressions. Tuples may also include ``None`` as in: - ``expr*(n, None)`` or ``expr*(n, )`` is equivalent to ``expr*n + ZeroOrMore(expr)`` (read as "at least n instances of ``expr``") - ``expr*(None, n)`` is equivalent to ``expr*(0, n)`` (read as "0 to n instances of ``expr``") - ``expr*(None, None)`` is equivalent to ``ZeroOrMore(expr)`` - ``expr*(1, None)`` is equivalent to ``OneOrMore(expr)`` Note that ``expr*(None, n)`` does not raise an exception if more than n exprs exist in the input stream; that is, ``expr*(None, n)`` does not enforce a maximum number of expr occurrences. If this behavior is desired, then write ``expr*(None, n) + ~expr`` )rNNrr=rrrcss |] }|tur |ndVqdSr)rrrrrrrz(ParserElement.__mul__..NNz8cannot multiply 'ParserElement' and ('%s', '%s') objectsz0cannot multiply 'ParserElement' and '%s' objectsz/cannot multiply ParserElement by negative valuez@second tuple value must be greater or equal to first tuple valuez,cannot multiply ParserElement by 0 or (0, 0)cs$|dkrt|dStSr>)r<nmakeOptionalListrrrrsz/ParserElement.__mul__..makeOptionalList) rrtuplerrSr:r;r ValueErrorr&)rr minElements optElementsrrrr__mul__sX          zParserElement.__mul__cCs ||Sr)rrrrr__rmul__rzParserElement.__rmul__cCsZ|tur t|ddSt|tr||}t|ts'tjdt|t dddSt ||gS)zL Implementation of | operator - returns :class:`MatchFirst` T) must_skiprrrN) rrrr9rrErrrrr7rrrr__or__s     zParserElement.__or__cCsBt|tr ||}t|tstjdt|tdddS||BS)z` Implementation of | operator when left operand is not a :class:`ParserElement` rrrNrrrrr__ror__ rzParserElement.__ror__cCFt|tr ||}t|tstjdt|tdddSt||gS)zD Implementation of ^ operator - returns :class:`Or` rrrN) rr9rrErrrrr=rrrr__xor__     zParserElement.__xor__cCsBt|tr ||}t|tstjdt|tdddS||AS)z` Implementation of ^ operator when left operand is not a :class:`ParserElement` rrrNrrrrr__rxor__ rzParserElement.__rxor__cCr)zF Implementation of & operator - returns :class:`Each` rrrN) rr9rrErrrrr,rrrr__and__' rzParserElement.__and__cCsBt|tr ||}t|tstjdt|tdddS||@S)z` Implementation of & operator when left operand is not a :class:`ParserElement` rrrNrrrrr__rand__3 rzParserElement.__rand__cCr)zH Implementation of ~ operator - returns :class:`NotAny` )r9rrrr __invert__? szParserElement.__invert__cCstd|jj)Nz%r object is not iterable)r;rrrrrrrYE szParserElement.__iter__c Cszt|tr |f}t|Wn ty||f}Ynwt|dkr``s to spaces before parsing the input string. Must be called before ``parseString`` when the input grammar contains elements that match ```` characters. T)r rrrr parseWithTabs rzParserElement.parseWithTabscCsNt|tr t|}t|tr||jvr|j||S|jt||S)a Define expression to be ignored (e.g., comments) while doing pattern matching; may be called repeatedly, to define multiple comment or other ignorable patterns. Example:: patt = OneOrMore(Word(alphas)) patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] patt.ignore(cStyleComment) patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] )rr9rLr rr~rrrrignore s    zParserElement.ignorecCs"|pt|pt|p tf|_d|_|S)zT Enable display of debugging messages while doing pattern matching. T)rrrrr)r startAction successActionexceptionActionrrrsetDebugActions s zParserElement.setDebugActionscCs |r |ttt|Sd|_|S)a Enable display of debugging messages while doing pattern matching. Set ``flag`` to True to enable, False to disable. Example:: wd = Word(alphas).setName("alphaword") integer = Word(nums).setName("numword") term = wd | integer # turn on debugging for wd wd.setDebug() OneOrMore(term).parseString("abc 123 xyz 890") prints:: Match alphaword at loc 0(1,1) Matched alphaword -> ['abc'] Match alphaword at loc 3(1,4) Exception raised:Expected alphaword (at char 4), (line:1, col:5) Match alphaword at loc 7(1,8) Matched alphaword -> ['xyz'] Match alphaword at loc 11(1,12) Exception raised:Expected alphaword (at char 12), (line:1, col:13) Match alphaword at loc 15(1,16) Exception raised:Expected alphaword (at char 15), (line:1, col:16) The output shown is that produced by the default debug actions - custom debug actions can be specified using :class:`setDebugActions`. Prior to attempting to match the ``wd`` expression, the debugging message ``"Match at loc (,)"`` is shown. Then if the parse succeeds, a ``"Matched"`` message is shown, or an ``"Exception raised"`` message is shown. Also note the use of :class:`setName` to assign a human-readable name to the expression, which makes debugging and exception messages easier to understand - for instance, the default name created for the :class:`Word` expression without calling ``setName`` is ``"W:(ABCD...)"``. F)rrrrr)rflagrrrr s %zParserElement.setDebugcC|jSrrrrrrr zParserElement.__str__cCrrrrrrrr rzParserElement.__repr__cCsd|_d|_|Sr)rrrrrrr szParserElement.streamlinecCsdSrrrrrrcheckRecursion rFzParserElement.checkRecursioncCs|gdS)zj Check defined expressions for valid structure, check for infinite recursive definitions. N)r)r validateTracerrrvalidate szParserElement.validatec Csz|}Wn"ty(t|d }|}Wdn1s!wYYnwz|||WStyQ}ztjr<t|dddurK||j |_ |d}~ww)z Execute the parse expression on the given file or filename. If a filename is specified (instead of a file object), the entire file is opened, read, and closed before parsing. rNr) readropenrr>rErrrr)rfile_or_filenamer file_contentsfrrrr parseFile s$    zParserElement.parseFilecCs>||urdSt|tr||St|trt|t|kSdSr9)rr9rrEvarsrrrr__eq__ s   zParserElement.__eq__cC ||k Srrrrrr__ne__$ rzParserElement.__ne__cCrr)idrrrr__hash__' rzParserElement.__hash__cC||kSrrrrrr__req__* rzParserElement.__req__cCrrrrrrr__rne__- rzParserElement.__rne__cCs.z |jt||dWdStyYdSw)a Method for quick testing of a parser against a test string. Good for simple inline microtests of sub expressions while building up larger parser. Parameters: - testString - to test against this expression for a match - parseAll - (default= ``True``) - flag to pass to :class:`parseString` when running tests Example:: expr = Word(nums) assert expr.matches("100") rTF)rrr>)r testStringrrrrr0 s  zParserElement.matches#c  Cst|trtttj|}t|trt|}|dur!t j }|j } g} g} d} td t dt} d}|D]/}|durG||dsK| rQ|sQ| |q:|sTq:| r]dd| nd|g}g} z| ||}|j||d}Wnuty}zIt|trd nd}d|vr|t|j||d t|j|d d |n |d |jd ||d t|| o|} |}WYd}~nd}~wty}z|dt|| o|} |}WYd}~nld}~ww| o| } |durHz)|||}|durt|tr ||n|t|n||Wn3tyG}z||j|d|d|jt |j|WYd}~nd}~ww||j|d|rc|r\|d| d|| ||fq:| | fS)as Execute the parse expression on a series of test strings, showing each test, the parsed results or where the parse failed. Quick and easy way to run a parse expression against a list of sample strings. Parameters: - tests - a list of separate test strings, or a multiline string of test strings - parseAll - (default= ``True``) - flag to pass to :class:`parseString` when running tests - comment - (default= ``'#'``) - expression for indicating embedded comments in the test string; pass None to disable comment filtering - fullDump - (default= ``True``) - dump results as list followed by results names in nested outline; if False, only dump nested list - printResults - (default= ``True``) prints test output to stdout - failureTests - (default= ``False``) indicates if these tests are expected to fail parsing - postParse - (default= ``None``) optional callback for successful parse results; called as `fn(test_string, parse_results)` and returns a string to be added to the test output - file - (default=``None``) optional file-like object to which test output will be written; if None, will default to ``sys.stdout`` Returns: a (success, results) tuple, where success indicates that all tests succeeded (or failed if ``failureTests`` is True), and the results contain a list of lines of each test's output Example:: number_expr = pyparsing_common.number.copy() result = number_expr.runTests(''' # unsigned integer 100 # negative integer -100 # float with scientific notation 6.02e23 # integer with scientific notation 1e-12 ''') print("Success" if result[0] else "Failed!") result = number_expr.runTests(''' # stray character 100Z # missing leading digit before '.' -.100 # too many '.' 3.14.159 ''', failureTests=True) print("Success" if result[0] else "Failed!") prints:: # unsigned integer 100 [100] # negative integer -100 [-100] # float with scientific notation 6.02e23 [6.02e+23] # integer with scientific notation 1e-12 [1e-12] Success # stray character 100Z ^ FAIL: Expected end of text (at char 3), (line:1, col:4) # missing leading digit before '.' -.100 ^ FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) # too many '.' 3.14.159 ^ FAIL: Expected end of text (at char 4), (line:1, col:5) Success Each test string must be on a single line. If you want to test a string that spans multiple lines, create a test like this:: expr.runTest(r"this is a test\n of strings that spans \n 3 lines") (Note that this is a raw string literal, you must include the leading 'r'.) NT\nruFrrz(FATAL)rrrzFAIL: zFAIL-EXCEPTION: )rz{0} failed: {1}: {2})!rr9r4r2rrrstrip splitlinesr5rstdoutwriter5r~rr{rrrrlstriprr>rBrirr[rrCrrrr)rtestsrcommentfullDump printResults failureTestsrEfileprint_ allResultscommentssuccessrBOMrrresultrrrpp_valuer;rrrrunTestsD sz `   $     ( zParserElement.runTestsFTr+)rr)TrTTFNN)Srrrrrrrrrrrrr~rrrr.rr5r6r8r=rArrErrTrUr'rhrqrtrzr ryr{rr,rrrr_MAX_INTrrrrrrrrrrrrrrrrrrYr#rrrrrrrrrrrrrrrrrrrrrrrrrrEGs       1    W    ":J 0 &  J      $    +    rEcs6eZdZd fdd ZddZddZdd ZZS) rFcs>tt|t|tdd|_|j|_||_||_ dS)Nr-...) superrrrr-rrr+anchorr)rrrrrrr s  z_PendingSkip.__init__cs\t|dd}jr'dd}fdd}j||||B|Sj||S)NrrcSs0|jr |jdgkr|d=|dddSdS)Nrr_skipped)rr,rqrrrrr sz'_PendingSkip.__add__..must_skipcs@|jdddgkr|d}dtjd|d<dSdS)Nrrrz missing .show_skip)rIrrrr5)rrskipperrrrrrr s  z_PendingSkip.__add__cCrr)rrrrrr rz_PendingSkip.__repr__cGstd)NzBuse of `...` expression without following SkipTo target expression)rrrrrrr rz_PendingSkip.parseImplr)rrrrrrr __classcell__rrrrr s rc eZdZdZfddZZS)rMzYAbstract :class:`ParserElement` subclass, for defining atomic matching patterns. cstt|jdddSNFr)rrMrrrrrr rdzToken.__init__rrrrrrrrrrrM srMcr)r-z'An empty token, will always match. cs$tt|d|_d|_d|_dS)Nr-TF)rr-rr+r rrrrrr s zEmpty.__init__r rrrrr- sr-c*eZdZdZfddZdddZZS)r8z#A token that will never match. cs*tt|d|_d|_d|_d|_dS)Nr8TFzUnmatchable token)rr8rr+r rrrrrrr s  zNoMatch.__init__TcCst|||j|r)r@rrBrrrr$ zNoMatch.parseImplrrrrrrrrrrrrr8 s r8cr )r5aToken to exactly match a specified string. Example:: Literal('blah').parseString('blah') # -> ['blah'] Literal('blah').parseString('blahfooblah') # -> ['blah'] Literal('blah').parseString('bla') # -> Exception: Expected "blah" For case-insensitive matching, use :class:`CaselessLiteral`. For keyword matching (force word break before and after the matched string), use :class:`Keyword` or :class:`CaselessKeyword`. cstt|||_t||_z|d|_Wnty*tj dt ddt |_ Ynwdt |j|_d|j|_d|_d|_|jdkrOt|turQt|_ dSdSdS) Nrz2null string passed to Literal; use Empty() insteadrr"%s"rFr)rr5rmatchrmatchLenfirstMatchCharr<rrrr-rrr+rr rr_SingleCharLiteralr matchStringrrrr6 s$     zLiteral.__init__TcCs<|||jkr||j|r||j|jfSt|||j|r)rrrrr@rrBrrrrJ zLiteral.parseImplrrrrrrr5( s r5c@eZdZdddZdS)rTcCs,|||jkr|d|jfSt|||j|r>)rrr@rrBrrrrP sz_SingleCharLiteral.parseImplNrrrrrrrrrrO rcsLeZdZdZedZdfdd Zddd Zfd d Ze d d Z Z S)r2aToken to exactly match a specified string as a keyword, that is, it must be immediately followed by a non-keyword character. Compare with :class:`Literal`: - ``Literal("if")`` will match the leading ``'if'`` in ``'ifAndOnlyIf'``. - ``Keyword("if")`` will not; it will only match the leading ``'if'`` in ``'if x=1'``, or ``'if(y==2)'`` Accepts two optional constructor arguments in addition to the keyword string: - ``identChars`` is a string of characters that would be valid identifier characters, defaulting to all alphanumerics + "_" and "$" - ``caseless`` allows case-insensitive matching, default is ``False``. Example:: Keyword("start").parseString("start") # -> ['start'] Keyword("start").parseString("starting") # -> Exception For case-insensitive matching, use :class:`CaselessKeyword`. _$NFcstt||durtj}||_t||_z|d|_Wnty.t j dt ddYnwd|j|_ d|j |_ d|_d|_||_|rO||_|}t||_dS)Nrz2null string passed to Keyword; use Empty() insteadrrrrF)rr2rDEFAULT_KEYWORD_CHARSrrrrr<rrrr+rr rcaselessupper caselessmatchr identChars)rrrrrrrrs s*      zKeyword.__init__TcCs|jr>||||j|jkr=|t||jks&|||j|jvr=|dks5||d|jvr=||j|jfSn;|||jkry|jdksQ||j|ry|t||jksd|||j|jvry|dksq||d|jvry||j|jfSt |||j |rF) rrrrrrrrrr@rrBrrrr szKeyword.parseImplcstt|}tj|_|Sr)rr2r~rr)rrrrrr~ sz Keyword.copycCr)z,Overrides the default Keyword chars N)r2rrrrrsetDefaultKeywordChars s zKeyword.setDefaultKeywordCharsrr) rrrrrUrrrr~rr rrrrrr2X s  r2cr )r(afToken to match a specified string, ignoring case of letters. Note: the matched results will always be in the case of the given match string, NOT the case of the input text. Example:: OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] (Contrast with example for :class:`CaselessKeyword`.) cs6tt||||_d|j|_d|j|_dS)Nz'%s'r)rr(rr returnStringr+rrrrrr s zCaselessLiteral.__init__TcCs<||||j|jkr||j|jfSt|||j|r)rrrr!r@rrBrrrr rzCaselessLiteral.parseImplrrrrrrr( s r(c"eZdZdZdfdd ZZS)r'z Caseless version of :class:`Keyword`. Example:: OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] (Contrast with example for :class:`CaselessLiteral`.) Ncstt|j||dddS)NTr)rr'r)rrrrrrr szCaselessKeyword.__init__rr rrrrr' s r'cs,eZdZdZdfdd Zd ddZZS) raA variation on :class:`Literal` which matches "close" matches, that is, strings with at most 'n' mismatching characters. :class:`CloseMatch` takes parameters: - ``match_string`` - string to be matched - ``maxMismatches`` - (``default=1``) maximum number of mismatches allowed to count as a match The results from a successful parse will contain the matched text from the input string and the following named results: - ``mismatches`` - a list of the positions within the match_string where mismatches were found - ``original`` - the original match_string used to compare against the input string If ``mismatches`` is an empty list, then the match was an exact match. Example:: patt = CloseMatch("ATCATCGAATGGA") patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) # exact match patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) # close match allowing up to 2 mismatches patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) rcsBtt|||_||_||_d|j|jf|_d|_d|_dS)Nz&Expected %r (with up to %d mismatches)F) rrrr+ match_string maxMismatchesrrr )rr$r%rrrr s zCloseMatch.__init__TcCs|}t|}|t|j}||krY|j}d}g} |j} tt||||D]\}} | \} } | | kr?| |t| | kr?nq&|d}t|||g}||d<| |d<||fSt|||j|)Nrroriginal mismatches) rr$r%rrrrCr@r)rrrr%startr@maxlocr$match_stringlocr'r%s_msrcmatresultsrrrr s*  zCloseMatch.parseImpl)rrrrrrrr s  rcs8eZdZdZd fdd Zdd d Zfd d ZZS)rPaX Token for matching words composed of allowed character sets. Defined with string containing all allowed initial characters, an optional string containing allowed body characters (if omitted, defaults to the initial character set), and an optional minimum, maximum, and/or exact length. The default value for ``min`` is 1 (a minimum value < 1 is not valid); the default values for ``max`` and ``exact`` are 0, meaning no maximum or exact length restriction. An optional ``excludeChars`` parameter can list characters that might be found in the input ``bodyChars`` string; useful to define a word of all printables except for one or two characters, for instance. :class:`srange` is useful for defining custom character set strings for defining ``Word`` expressions, using range notation from regular expression character sets. A common mistake is to use :class:`Word` to match a specific literal string, as in ``Word("Address")``. Remember that :class:`Word` uses the string argument to define *sets* of matchable characters. This expression would match "Add", "AAA", "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. To match an exact literal string, use :class:`Literal` or :class:`Keyword`. pyparsing includes helper strings for building Words: - :class:`alphas` - :class:`nums` - :class:`alphanums` - :class:`hexnums` - :class:`alphas8bit` (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) - :class:`punc8bit` (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) - :class:`printables` (any non-whitespace character) Example:: # a word composed of digits integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) # a word with a leading capital, and zero or more lowercase capital_word = Word(alphas.upper(), alphas.lower()) # hostnames are alphanumeric, with leading alpha, and '-' hostname = Word(alphas, alphanums + '-') # roman numeral (not a strict parser, accepts invalid mix of characters) roman = Word("IVXLCDM") # any string of non-whitespace characters, except for ',' csv_value = Word(printables, excludeChars=",") NrrFcstt|r'tdfdd|D}|r'dfdd|D}||_t||_|r:||_t||_n||_t||_|dk|_ |dkrOt d||_ |dkrZ||_ nt |_ |dkrg||_ ||_ t||_d|j|_d |_||_d |j|jvr|dkr|dkr|dkr|j|jkrd t|j|_n#t|jdkrd t|jt|jf|_n d t|jt|jf|_|jrd|jd|_z t|j|_Wn tyd|_YdSw|jj|_t|_dSdSdSdSdS)Nrc3|] }|vr|VqdSrrr excludeCharsrrrH rz Word.__init__..c3r/rrrr0rrrJ rrrzZcannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permittedrFrz[%s]+z%s[%s]*z [%s][%s]*z\b)rrPrrr initCharsOrig initChars bodyCharsOrig bodyChars maxSpecifiedrminLenmaxLenrrr+rr asKeyword_escapeRegexRangeCharsreStringrrescapecompilerrre_match _WordRegexr)rr3r5minmaxexactr9r1rr0rrD s^      (       z Word.__init__Tc Cs|||jvrt|||j||}|d7}t|}|j}||j}t||}||kr>|||vr>|d7}||kr>|||vs0d}|||jkrJd}n+|jrZ||krZ|||vrZd}n|j ru|dkri||d|vss||kru|||vrud}|rt|||j|||||fS)NrFTr) r3r@rrr5r8r@r7r6r9) rrrr%r(r@ bodycharsr)throwExceptionrrrr} s.  zWord.parseImplcsxztt|WStyYnw|jdur9dd}|j|jkr1d||j||jf|_|jSd||j|_|jS)NcSs t|dkr|dddS|S)Nrrcrrrr charsAsStr s z Word.__str__..charsAsStrz W:(%s, %s)zW:(%s))rrPrrrr2r4)rrGrrrr s   z Word.__str__)NrrrFNrrrrrrrrrrrrrrP s 4 9rPc@r)r?TcCs4|||}|st|||j||}||fSr)r>r@rendgroup)rrrr%rrrrr s  z_WordRegex.parseImplNrrrrrrr? rr?cs"eZdZdZdfdd ZZS)rTzA short-cut class for defining ``Word(characters, exact=1)``, when defining a match of any single character in a string of characters. FNcsZtt|j|d||ddtd|j|_|rd|j|_t|j|_|jj |_ dS)Nr)rBr9r1[%s]rz\b%s\b) rrTrr:rr3r;rr=rr>)rcharsetr9r1rrrr s  z Char.__init__)FNr rrrrrT srTcsTeZdZdZdfdd ZdddZdd d Zdd d Zfd dZddZ Z S)rHahToken for matching strings that match a given regular expression. Defined with string specifying the regular expression in a form recognized by the stdlib Python `re module `_. If the given regex contains named groups (defined using ``(?P...)``), these will be preserved as named parse results. If instead of the Python stdlib re module you wish to use a different RE module (such as the `regex` module), you can replace it by either building your Regex object with a compiled RE that was compiled using regex: Example:: realnum = Regex(r"[+-]?\d+\.\d*") date = Regex(r'(?P\d{4})-(?P\d\d?)-(?P\d\d?)') # ref: https://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression roman = Regex(r"M{0,4}(CM|CD|D?{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") # use regex module instead of stdlib re module to construct a Regex using # a compiled regular expression import regex parser = pp.Regex(regex.compile(r'[0-9]')) rFcstt|t|tr?|stjdtdd||_||_ zt |j|j |_ |j|_ Wn/t jy>tjd|tddwt|drWt|drW||_ |j|_|_ ||_ ntd|j j|_t||_d|j|_d |_|d d u|_||_||_|jr|j|_|jr|j|_d Sd S) aThe parameters ``pattern`` and ``flags`` are passed to the ``re.compile()`` function as-is. See the Python `re module `_ module for an explanation of the acceptable patterns and flags. z0null string passed to Regex; use Empty() insteadrr$invalid pattern (%s) passed to RegexpatternrzCRegex may only be constructed with a string or a compiled RE objectrFrN)rrHrrr9rrrrNflagsrr=r; sre_constantserrorr]r;rr>rr+rrr  asGroupListasMatchparseImplAsGroupListrparseImplAsMatch)rrNrOrRrSrrrr sD       zRegex.__init__Tc Csb|||}|st|||j||}t|}|}|r-|D]\}}|||<q$||fSr)r>r@rrIrCrJ groupdictrJ) rrrr%rrdrCr?rrrr s   zRegex.parseImplcCs8|||}|st|||j||}|}||fSr)r>r@rrIgroupsrrrr%rrrrrrT s zRegex.parseImplAsGroupListcCs4|||}|st|||j||}|}||fSr)r>r@rrIrYrrrrU! s zRegex.parseImplAsMatchcsDztt|WStyYnw|jdurdt|j|_|jS)NzRe:(%s))rrHrrrr%rNrrrrr* s  z Regex.__str__csljrtjdtddtjr tr tjdtddtjr*fdd}nfdd}|S)a Return Regex with an attached parse action to transform the parsed result as if called using `re.sub(expr, repl, string) `_. Example:: make_html = Regex(r"(\w+):(.*?):").sub(r"<\1>\2") print(make_html.transformString("h1:main title:")) # prints "

main title

" z-cannot use sub() with Regex(asGroupList=True)rrz9cannot use sub() with a callable with Regex(asMatch=True)cs|dSr$)expandrN)replrrrK r!zRegex.sub..pacsj|dSr$)rrDr[r\rrrrN s)rRrrr SyntaxErrorrSr0r5)rr\rrr]rrD5 s  z Regex.sub)rFFr) rrrrrrrTrUrrDrrrrrrH s -  rHcs<eZdZdZ  d fdd Zd ddZfd d ZZS) rFa& Token for matching strings that are delimited by quoting characters. Defined with the following parameters: - quoteChar - string of one or more characters defining the quote delimiting string - escChar - character to escape quotes, typically backslash (default= ``None``) - escQuote - special quote sequence to escape an embedded quote string (such as SQL's ``""`` to escape an embedded ``"``) (default= ``None``) - multiline - boolean indicating whether quotes can span multiple lines (default= ``False``) - unquoteResults - boolean indicating whether the matched text should be unquoted (default= ``True``) - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default= ``None`` => same as quoteChar) - convertWhitespaceEscapes - convert escaped whitespace (``'\t'``, ``'\n'``, etc.) to actual whitespace (default= ``True``) Example:: qs = QuotedString('"') print(qs.searchString('lsjdf "This is the quote" sldjf')) complex_qs = QuotedString('{{', endQuoteChar='}}') print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) sql_qs = QuotedString('"', escQuote='""') print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) prints:: [['This is the quote']] [['This is the "quote"']] [['This is the quote with "embedded" quotes']] NFTc sHtt|}|stjdtddt|dur|}n|}|s0tjdtddt|_t |_ |d_ |_ t |_ |_|_|_|_|rttjtjB_dtjtj d|durnt|podf_nd_dtjtj d|durt|pdf_t j d krjd d fd d tt j d ddDd7_|rÈjdt|7_|rڈjdt|7_tjd_jdtj 7_ztjj_j_jj_Wnt j!ytjdjtddwt"_#dj#_$d_%d_&dS)Nz$quoteChar cannot be the empty stringrrz'endQuoteChar cannot be the empty stringrz %s(?:[^%s%s]rz%s(?:[^%s\n\r%s]rz|(?:z)|(?:c3s6|]}dtjd|tj|fVqdS)z%s[^%s]N)rr< endQuoteCharr:rrrrr s  z(QuotedString.__init__..r)z|(?:%s)z|(?:%s.)z(.)z)*%srMrFT)'rrFrrrrrr^ quoteCharr quoteCharLenfirstQuoteCharr_endQuoteCharLenescCharescQuoteunquoteResultsconvertWhitespaceEscapesr MULTILINEDOTALLrOr<r:rNrrGescCharReplacePatternr=r;rr>rPrQrr+rrr )rrarerf multilinergr_rhrrrry sv            zQuotedString.__init__c Cs|||jkr |||pd}|st|||j||}|}|jre||j|j }t |t red|vrO|j rOddddd}| D] \}}| ||}qD|jrZt|jd|}|jre| |j|j}||fS)Nr r  )\trz\fz\rz\g<1>)rcr>r@rrIrJrgrbrdrr9rhrJrrerrDrkrfr_) rrrr%rrws_mapwslitwscharrrrr s* zQuotedString.parseImplcsFztt|WStyYnw|jdur d|j|jf|_|jS)Nz.quoted string, starting with %s ending with %s)rrFrrrrar_rrrrr s  zQuotedString.__str__)NNFTNTrrHrrrrrFR s& A#rFcs8eZdZdZd fdd Zd ddZfd d ZZS) r)aToken for matching words composed of characters *not* in a given set (will include whitespace in matched characters if not listed in the provided exclusion set - see example). Defined with string containing all disallowed characters, and an optional minimum, maximum, and/or exact length. The default value for ``min`` is 1 (a minimum value < 1 is not valid); the default values for ``max`` and ``exact`` are 0, meaning no maximum or exact length restriction. Example:: # define a comma-separated-value as anything that is not a ',' csv_value = CharsNotIn(',') print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) prints:: ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] rrcstt|d|_||_|dkrtd||_|dkr ||_nt|_|dkr-||_||_t ||_ d|j |_ |jdk|_ d|_ dS)NFrzfcannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permittedrr)rr)rrnotCharsrr7r8rrr+rr r)rrtr@rArBrrrr s     zCharsNotIn.__init__TcCs|||jvrt|||j||}|d7}|j}t||jt|}||kr:|||vr:|d7}||kr:|||vs,|||jkrIt|||j|||||fSr>)rtr@rr@r8rr7)rrrr%r(notcharsmaxlenrrrrszCharsNotIn.parseImplcshztt|WStyYnw|jdur1t|jdkr+d|jdd|_|jSd|j|_|jS)NrEz !W:(%s...)z!W:(%s))rr)rrrrrtrrrrr&s   zCharsNotIn.__str__)rrrrrHrrrrr) s  r)cseZdZdZidddddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*Zd3fd.d/ Zd4d1d2ZZS)5rOaSpecial matching class for matching whitespace. Normally, whitespace is ignored by pyparsing grammars. This class is included when some whitespace structures are significant. Define with a string containing the whitespace characters to be matched; default is ``" \t\r\n"``. Also takes optional ``min``, ``max``, and ``exact`` arguments, as defined for the :class:`Word` class. rzrmzrzrozrnz zu zu᠎zu z u z u z u z u zu zu zu zu zz z zzzz)u u u​u u u  rrcstt|_dfddjDdddjD_d_dj_ |_ |dkr:|_ nt _ |dkrI|_ |_ dSdS)Nrc3s|] }|jvr|VqdSr) matchWhiterrrrrYrz!White.__init__..css|]}tj|VqdSr)rO whiteStrsrrrrr[rTrr) rrOrryrrr r+r rr7r8r)rwsr@rArBrrrrVs   zWhite.__init__TcCs|||jvrt|||j||}|d7}||j}t|t|}||kr;|||jvr;|d7}||kr;|||jvs,|||jkrJt|||j|||||fSr>)ryr@rr8r@rr7)rrrr%r(r)rrrrjs zWhite.parseImpl)rxrrrr)rrrrrzrrrrrrrrO4s\     rOceZdZfddZZS)_PositionTokencs(tt||jj|_d|_d|_dSr9)rr}rrrr+r rrrrrr{  z_PositionToken.__init__rrrrrrrrrr}zr}cs2eZdZdZfddZddZd ddZZS) r0zaToken to advance to a specific column of input text; useful for tabular report scraping. cstt|||_dSr)rr0rr[)rcolnorrrr zGoToColumn.__init__cCs~t|||jkr=t|}|jr|||}||kr=||r=t|||jkr=|d7}||kr=||r=t|||jks'|Sr>)r[rr r=isspace)rrrr@rrrrAs $$zGoToColumn.preParseTcCsDt||}||jkrt||d|||j|}|||}||fS)NzText not in expected columnr[r@)rrrr%thiscolnewlocrrrrrs   zGoToColumn.parseImplr)rrrrrrArrrrrrr0s   r0cr )r4aMatches if current position is at the beginning of a line within the parse string Example:: test = '''\ AAA this line AAA and this line AAA but not this one B AAA and definitely not this one ''' for t in (LineStart() + 'AAA' + restOfLine).searchString(test): print(t) prints:: ['AAA', ' this line'] ['AAA', ' and this line'] ctt|d|_dS)NzExpected start of line)rr4rrrrrrrrzLineStart.__init__TcCs&t||dkr |gfSt|||j|r>)r[r@rrBrrrrszLineStart.parseImplrrrrrrr4 r4cr )r3zTMatches if current position is at the end of a line within the parse string cs,tt||tjddd|_dS)NrrzExpected end of line)rr3rrrErrrrrrrrs zLineEnd.__init__TcCs\|t|kr||dkr|ddfSt|||j||t|kr&|dgfSt|||j|)Nrrrr@rrBrrrrs     zLineEnd.parseImplrrrrrrr3s r3cr )rKzLMatches if current position is at the beginning of the parse string cr)NzExpected start of text)rrKrrrrrrrrzStringStart.__init__TcCs0|dkr|||dkrt|||j||gfSr$)rAr@rrBrrrrszStringStart.parseImplrrrrrrrKs rKcr )rJzBMatches if current position is at the end of the parse string cr)NzExpected end of text)rrJrrrrrrrrzStringEnd.__init__TcCsX|t|krt|||j||t|kr|dgfS|t|kr$|gfSt|||j|r>rrBrrrrs    zStringEnd.parseImplrrrrrrrJs rJc.eZdZdZeffdd ZdddZZS)rRayMatches if the current position is at the beginning of a Word, and is not preceded by any character in a given set of ``wordChars`` (default= ``printables``). To emulate the ```` behavior of regular expressions, use ``WordStart(alphanums)``. ``WordStart`` will also match at the beginning of the string being parsed, or at the beginning of a line. cs"tt|t||_d|_dS)NzNot at the start of a word)rrRrr wordCharsrrrrrrrs  zWordStart.__init__TcCs@|dkr||d|jvs|||jvrt|||j||gfSrF)rr@rrBrrrrs zWordStart.parseImplrrrrrrxrrrrrrrrRsrRcr)rQa_Matches if the current position is at the end of a Word, and is not followed by any character in a given set of ``wordChars`` (default= ``printables``). To emulate the ```` behavior of regular expressions, use ``WordEnd(alphanums)``. ``WordEnd`` will also match at the end of the string being parsed, or at the end of a line. cs(tt|t||_d|_d|_dS)NFzNot at the end of a word)rrQrrrrrrrrrr r~zWordEnd.__init__TcCsPt|}|dkr$||kr$|||jvs||d|jvr$t|||j||gfSrF)rrr@r)rrrr%r@rrrrs zWordEnd.parseImplrrrrrrrQsrQcszeZdZdZdfdd ZddZddZfd d Zfd d Zfd dZ dddZ fddZ dfdd Z Z S)rAz]Abstract subclass of ParserElement, for combining and post-processing parsed tokens. Fcstt|t|trt|}t|tr|g_n@t|t r(|g_n6t|t rIt|}t dd|DrCfdd|D}t|_nzt|_Wn t y]|g_Ynwd_ dS)Ncsrr)rr9)rrrrrr*rz+ParseExpression.__init__..c3s(|]}t|tr|n|VqdSr)rr9rrr;rrrr+&F)rrArrr6r4r9rexprsrEr rr;rrrrrrrrs$         zParseExpression.__init__cCs|j|d|_|Sr)rrrrrrrr4s zParseExpression.appendcCs0d|_dd|jD|_|jD]}|q|S)zExtends ``leaveWhitespace`` defined in base class, and also invokes ``leaveWhitespace`` on all contained expressions.FcSg|]}|qSrr}rrrrr=r@z3ParseExpression.leaveWhitespace..)rrr)rr;rrrr9s   zParseExpression.leaveWhitespacecstt|tr"||jvr tt|||jD] }||jdq|Stt|||jD] }||jdq-|SrZ)rrLr rrArr)rrr;rrrrB    zParseExpression.ignorecsLztt|WStyYnw|jdur#d|jjt|jf|_|jSNz%s:(%s)) rrArrrrrrrrrrrrNs  zParseExpression.__str__cs tt||jD]}|q t|jdkr|jd}t||jrO|jsO|jdurO|j sO|jdd|jdg|_d|_ |j |j O_ |j |j O_ |jd}t||jr|js|jdur|j s|jdd|jdd|_d|_ |j |j O_ |j |j O_ dt ||_|S)Nrrrrr)rrArrrrrrrrrr rrr)rr;rrrrrXs8        zParseExpression.streamlineNcCsB|dur|ngdd|g}|jD]}||q|gdSr)rrr)rrtmpr;rrrrzs  zParseExpression.validatecs$tt|}dd|jD|_|S)NcSrrr}rrrrrr@z(ParseExpression.copy..)rrAr~rrrrrr~szParseExpression.copycsVtjr"|jD]}t|tr!|jr!tjdd|t |j |jddqt t | ||S)N]{0}: setting results name {1!r} on {2} expression collides with {3!r} on contained expressionrrr)rrrrrErrrrrrrrArrr+rr;rrrrs zParseExpression._setResultsNamerr)rrrrrrrrrrrr~rrrrrrrAs " rAcs`eZdZdZGdddeZdfdd ZfddZdd d Zd d Z d dZ ddZ Z S)r&a Requires all given :class:`ParseExpression` s to be found in the given order. Expressions may be separated by whitespace. May be constructed using the ``'+'`` operator. May also be constructed using the ``'-'`` operator, which will suppress backtracking. Example:: integer = Word(nums) name_expr = OneOrMore(Word(alphas)) expr = And([integer("id"), name_expr("name"), integer("age")]) # more easily written as: expr = integer("id") + name_expr("name") + integer("age") cr|)zAnd._ErrorStopcs*ttj|j|i|d|_|dS)N-)rr&rrr+rrrrrrs zAnd._ErrorStop.__init__rrrrrrrrTcst|}|rFt|vrFg}t|D]/\}}|tur:|t|dkr6t||djd}|t|dqtd||q||dd<t t | ||t dd|jD|_ ||jdj|jdj|_d|_dS) Nrrrz0cannot construct And with sequence ending in ...cs|]}|jVqdSrr rrrrrzAnd.__init__..rT)r4rrrr-rrrIrrr&rr1r rr rr)rrrrr r skipto_argrrrrs     z And.__init__cs|jrStdd|jddDrSt|jddD]/\}}|dur#qt|trI|jrIt|jdtrI|jd|j|d|jd<d|j|d<qdd|jD|_tt|t dd|jD|_ |S)Ncss0|]}t|to|jot|jdtVqdSrN)rrArrrrrrrs(z!And.streamline..rrcSsg|]}|dur|qSrrrrrrrz"And.streamline..csrrrrrrrrr) rrrrrArrr&rr1r )rr r;rrrrs&  zAnd.streamlinec Cs|jdj|||dd\}}d}|jddD]W}t|tjr"d}q|r[z ||||\}}Wn4ty7tyJ}zd|_t|d}~wt yZt|t ||j |w||||\}}|sj| rn||7}q||fS)NrFrrT) rr,rr&rrDr>rrr<rrrl) rrrr% resultlist errorStopr; exprtokensrrrrrs.     z And.parseImplcCt|tr ||}||Srrr9rrrrrrrx   z And.__iadd__cCs8|dd|g}|jD] }|||jsdSq dSr)rrr rrsubRecCheckListr;rrrrs  zAnd.checkRecursioncC@t|dr|jS|jdurdddd|jDd|_|jS)Nr+{rcsr/rrrrrrrrazAnd.__str__..}r]r+rrrrrrrr   z And.__str__r) rrrrr-rrrrrxrrrrrrrr&s  r&c^eZdZdZdfdd ZfddZddd Zd d Zd d ZddZ dfdd Z Z S)r=aRequires that at least one :class:`ParseExpression` is found. If two expressions match, the expression that matches the longest string will be used. May be constructed using the ``'^'`` operator. Example:: # construct Or using '^' operator number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) print(number.searchString("123 3.1416 789")) prints:: [['123'], ['3.1416'], ['789']] Fc<tt||||jrtdd|jD|_dSd|_dS)NcsrrrrrrrrrzOr.__init__..T)rr=rrrr rrrrr z Or.__init__c.tt|tjrtdd|jD|_|S)Ncsrrrrrrrrrz Or.streamline..)rr=rr%collect_all_And_tokensrrrrrrrrz Or.streamlineTc Csd}d}g}|jD]M}z|||}Wn;ty2} zd| _| j|kr(| }| j}WYd} ~ q d} ~ wtyNt||krLt|t||j|}t|}Yq w|||fq |r|j t ddd|sq|dd} | |||Sd} |D]M\} } | | dkr| Sz | |||\}}Wnty} zd| _| j|kr| }| j}WYd} ~ qud} ~ ww|| kr||fS|| dkr||f} qu| dkr| S|dur|j|_ |t||d|)NrrT)rrrIrr no defined alternatives to match) rrTr@rrr<rrrsortrr,r)rrrr% maxExcLoc maxExceptionrr;loc2rO best_exprlongestloc1expr1rrrrrs`          z Or.parseImplcCrrrrrrr__ixor__[rz Or.__ixor__cCr)Nr+rz ^ csr/rrrrrrrerazOr.__str__..rrrrrrr`rz Or.__str__cC,|dd|g}|jD]}||q dSrrrrrrrri  zOr.checkRecursioncPtjstjrtdd|jDrtjdd|t |j ddt t | ||S)Ncsrrrr&rrrrrqrz%Or._setResultsName..{0}: setting results name {1!r} on {2} expression may only return a single token for an And alternative, in future will return the full list of tokensrrr)r%rrrrrrrrrrrr=rrrrrrn zOr._setResultsNamerr) rrrrrrrrrrrrrrrrr=s  = r=cr)r7aRequires that at least one :class:`ParseExpression` is found. If two expressions match, the first one listed is the one that will match. May be constructed using the ``'|'`` operator. Example:: # construct MatchFirst using '|' operator # watch the order of expressions to match number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] # put more selective expression first number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] Fcr)Ncsrrrrrrrrrz&MatchFirst.__init__..T)rr7rrrr rrrrrrzMatchFirst.__init__cr)Ncsrrrrrrrrrz(MatchFirst.streamline..)rr7rr%rrrrrrrrrrzMatchFirst.streamlineTc Csd}d}|jD]F}z ||||}|WSty1}z|j|kr'|}|j}WYd}~qd}~wtyMt||krKt|t||j|}t|}Yqw|durX|j|_|t||d|)Nrr)rr,r@rr<rrr) rrrr%rrr;rrOrrrrs*     zMatchFirst.parseImplcCrrrrrrr__ior__rzMatchFirst.__ior__cCr)Nr+r | csr/rrrrrrrraz%MatchFirst.__str__..rrrrrrrrzMatchFirst.__str__cCrrrrrrrrrzMatchFirst.checkRecursioncr)Ncsrrrrrrrrrz-MatchFirst._setResultsName..rrrr)r%rrrrrrrrrrrr7rrrrrrrzMatchFirst._setResultsNamerr) rrrrrrrrrrrrrrrrr7{s   r7csHeZdZdZd fdd ZfddZd ddZd d Zd d ZZ S)r,asRequires all given :class:`ParseExpression` s to be found, but in any order. Expressions may be separated by whitespace. May be constructed using the ``'&'`` operator. Example:: color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") integer = Word(nums) shape_attr = "shape:" + shape_type("shape") posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") color_attr = "color:" + color("color") size_attr = "size:" + integer("size") # use Each (using operator '&') to accept attributes in any order # (shape and posn are required, color and size are optional) shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) shape_spec.runTests(''' shape: SQUARE color: BLACK posn: 100, 120 shape: CIRCLE size: 50 color: BLUE posn: 50,80 color:GREEN size:20 shape:TRIANGLE posn:20,40 ''' ) prints:: shape: SQUARE color: BLACK posn: 100, 120 ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] - color: BLACK - posn: ['100', ',', '120'] - x: 100 - y: 120 - shape: SQUARE shape: CIRCLE size: 50 color: BLUE posn: 50,80 ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] - color: BLUE - posn: ['50', ',', '80'] - x: 50 - y: 80 - shape: CIRCLE - size: 50 color: GREEN size: 20 shape: TRIANGLE posn: 20,40 ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] - color: GREEN - posn: ['20', ',', '40'] - x: 20 - y: 40 - shape: TRIANGLE - size: 20 Tcs>tt|||tdd|jD|_d|_d|_d|_dS)Ncsrrrrrrrr rz Each.__init__..T) rr,rr1rr rinitExprGroupsrrrrrr s  z Each.__init__cs(tt|tdd|jD|_|S)Ncsrrrrrrrrrz"Each.streamline..)rr,rr1rr rrrrrszEach.streamlinec s|jrItdd|jD|_dd|jD}dd|jD}|||_dd|jD|_dd|jD|_dd|jD|_|j|j7_d |_|}|jdd}|jddg}d } | r||j|j} g} | D]8} z| ||}Wnt y| | Yqmw| |j t | | | |vr| | qm| vr | qmt| t| krd } | s_|rd d d|D} t ||d | |fdd|jD7}g}|D]} | |||\}}| |qt|tg}||fS)Ncss(|]}t|trt|j|fVqdSr)rr<rrrrrrrrz!Each.parseImpl..cSg|] }t|tr|jqSrrr<rrrrrrz"Each.parseImpl..cSs$g|]}|jrt|ttfs|qSr)r rr<rHrrrrrrcSrr)rrSrrrrrrrcSrr)rr:rrrrrrrcSs g|] }t|tttfs|qSr)rr<rSr:rrrrrs FTrcsr/rrrrrrr9raz*Missing one or more required elements (%s)cs$g|]}t|tr|jvr|qSrrrtmpOptrrr=r)rr7ropt1map optionalsmultioptionals multirequiredrequiredrTr@rrrremoverrr,sumrC)rrrr%opt1opt2tmpLoctmpReqd matchOrder keepMatchingtmpExprsfailedr;missingrr. finalResultsrrrrsV     zEach.parseImplcCr)Nr+rz & csr/rrrrrrrLrazEach.__str__..rrrrrrrGrz Each.__str__cCrrrrrrrrPrzEach.checkRecursionr) rrrrrrrrrrrrrrr,s8  1 r,csjeZdZdZdfdd ZdddZdd Zfd d Zfd d ZddZ dddZ fddZ Z S)r?zfAbstract subclass of :class:`ParserElement`, for combining and post-processing parsed tokens. Fcstt||t|tr t|jtr||}n|t|}||_ d|_ |durM|j |_ |j |_ | |j|j|_|j|_|j|_|j|jdSdSr)rr?rrr9 issubclassrrMr5rrrr rr rrrr ryrrrrrrrZs     zParseElementEnhance.__init__TcCs.|jdur|jj|||ddStd||j|)NFrr)rr,r@rrBrrrrls zParseElementEnhance.parseImplcCs*d|_|j|_|jdur|j|Sr)rrr~rrrrrrrs    z#ParseElementEnhance.leaveWhitespacecstt|tr"||jvr tt|||jdur |j|jd|Stt|||jdur8|j|jd|SrZ)rrLr rr?rrrrrrryrzParseElementEnhance.ignorecs&tt||jdur|j|Sr)rr?rrrrrrrs  zParseElementEnhance.streamlinecCsF||vr t||g|dd|g}|jdur!|j|dSdSr)rGrr)rrrrrrrs  z"ParseElementEnhance.checkRecursionNcCsB|durg}|dd|g}|jdur|j||gdSrrrrrrrrrrrs   zParseElementEnhance.validatecsVztt|WStyYnw|jdur(|jdur(d|jjt|jf|_|jSr) rr?rrrrrrrrrrrrs zParseElementEnhance.__str__rrr) rrrrrrrrrrrrrrrrrr?Vs    r?cr )r.abLookahead matching of the given parse expression. ``FollowedBy`` does *not* advance the parsing position within the input string, it only verifies that the specified parse expression matches at the current position. ``FollowedBy`` always returns a null token list. If any results names are defined in the lookahead expression, those *will* be returned for access by name. Example:: # use FollowedBy to match a label only if it is followed by a ':' data_word = Word(alphas) label = data_word + FollowedBy(':') attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() prints:: [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] ctt||d|_dSr)rr.rr rrrrrr zFollowedBy.__init__TcCs(|jj|||d\}}|dd=||fS)NrR)rr,)rrrr%_rrrrrs zFollowedBy.parseImplrrrrrrr.rr.cs,eZdZdZd fdd Zd ddZZS) r6apLookbehind matching of the given parse expression. ``PrecededBy`` does not advance the parsing position within the input string, it only verifies that the specified parse expression matches prior to the current position. ``PrecededBy`` always returns a null token list, but if a results name is defined on the given expression, it is returned. Parameters: - expr - expression that must match prior to the current parse location - retreat - (default= ``None``) - (int) maximum number of characters to lookbehind prior to the current parse location If the lookbehind expression is a string, Literal, Keyword, or a Word or CharsNotIn with a specified exact or maximum length, then the retreat parameter is not required. Otherwise, retreat must be specified to give a maximum number of characters to look back from the current parse position for a lookbehind match. Example:: # VB-style variable names with type prefixes int_var = PrecededBy("#") + pyparsing_common.identifier str_var = PrecededBy("$") + pyparsing_common.identifier Ncstt||||_d|_d|_d|_t|t r%t |}d|_n+t|t t fr3|j }d|_nt|ttfrF|jtkrF|j}d|_n t|trPd}d|_||_dt ||_d|_|jdddS)NTFrznot preceded by cSs|tddSr)rQrArrrrrz%PrecededBy.__init__..)rr6rrrr rrBrrrr5r2rrPr)r8rr}retreatrrrr)rrrrrrrs*  zPrecededBy.__init__rTc Cs|jr!||jkrt|||j||j}|j||\}}||fS|jt}|td||j|}t|||j} tdt ||jddD])} z||t || \}}Wnt yk} z| } WYd} ~ qGd} ~ ww||fS| rF) rBrr@rrr,rJrArGr@rr>) rrrr%r(rr test_exprinstring_slice last_exprrpberrrrs&   zPrecededBy.parseImplr)rTrrrrrr6sr6cs2eZdZdZfddZd ddZddZZS) r9aLookahead to disallow matching with the given parse expression. ``NotAny`` does *not* advance the parsing position within the input string, it only verifies that the specified parse expression does *not* match at the current position. Also, ``NotAny`` does *not* skip over leading whitespace. ``NotAny`` always returns a null token list. May be constructed using the '~' operator. Example:: AND, OR, NOT = map(CaselessKeyword, "AND OR NOT".split()) # take care not to mistake keywords for identifiers ident = ~(AND | OR | NOT) + Word(alphas) boolean_term = Optional(NOT) + ident # very crude boolean expression - to support parenthesis groups and # operation hierarchy, use infixNotation boolean_expr = boolean_term + ZeroOrMore((AND | OR) + boolean_term) # integers that are followed by "." are actually floats integer = Word(nums) + ~Char(".") cs0tt||d|_d|_dt|j|_dS)NFTzFound unwanted token, )rr9rrr rrrrrrrr*szNotAny.__init__TcCs&|j||rt|||j||gfSr)rrUr@rrBrrrr1szNotAny.parseImplcC4t|dr|jS|jdurdt|jd|_|jS)Nr+z~{rr]r+rrrrrrrr6  zNotAny.__str__rrHrrrrr9s   r9cs>eZdZd fdd ZddZd ddZdfd d ZZS)_MultipleMatchNcs<tt||d|_|}t|tr||}||dSr)rrrrrr9rstopOn)rrrenderrrrr@s   z_MultipleMatch.__init__cCs2t|tr ||}|dur||_|Sd|_|Sr)rr9r not_ender)rrrrrrHs  z_MultipleMatch.stopOnTc Cs|jj}|j}|jdu}|r|jj}|r|||||||dd\}}z*|j } |r1|||| r9|||} n|} ||| |\}} | sI| rM|| 7}q*ttfy[Y||fSwNFr) rr,r=rrTr rlr@r<) rrrr%self_expr_parseself_skip_ignorables check_ender try_not_enderrNhasIgnoreExprsrL tmptokensrrrrNs0       z_MultipleMatch.parseImplFcsftjr*|jgt|jdgD]}t|tr)|jr)tjd d|t |j |jddqt t |||S)Nrrrrr)rrrrrrErrrrrrrrrrrrrrksz_MultipleMatch._setResultsNamerrr)rrrrrrrrrrrrr?s  rc@seZdZdZddZdS)r:ajRepetition of one or more of the given expression. Parameters: - expr - expression that must match one or more times - stopOn - (default= ``None``) - expression for a terminating sentinel (only required if the sentinel would ordinarily match the repetition expression) Example:: data_word = Word(alphas) label = data_word + FollowedBy(':') attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) text = "shape: SQUARE posn: upper left color: BLACK" OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] # use stopOn attribute for OneOrMore to avoid reading label string as part of the data attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] # could also be written as (attr_expr * (1,)).parseString(text).pprint() cCr)Nr+rz}...rrrrrrrzOneOrMore.__str__N)rrrrrrrrrr:ys r:cs8eZdZdZd fdd Zd fdd Zdd ZZS) rSakOptional repetition of zero or more of the given expression. Parameters: - expr - expression that must match zero or more times - stopOn - (default= ``None``) - expression for a terminating sentinel (only required if the sentinel would ordinarily match the repetition expression) Example: similar to :class:`OneOrMore` Ncstt|j||dd|_dS)NrT)rrSrr )rrrrrrrs zZeroOrMore.__init__Tc s6z tt||||WSttfy|gfYSwr)rrSrr@r<rBrrrrs  zZeroOrMore.parseImplcCr)Nr+r]...rrrrrrrzZeroOrMore.__str__rrrHrrrrrSs  rSc@s eZdZddZeZddZdS) _NullTokencCrrrrrrrrVrFz_NullToken.__bool__cCrrrrrrrrrFz_NullToken.__str__N)rrrrVrrrrrrrs rcs<eZdZdZeZeffdd Zd ddZddZZ S) r<aGOptional matching of the given expression. Parameters: - expr - expression that must match zero or more times - default (optional) - value to be returned if the optional expression is not found. Example:: # US postal code can be a 5-digit zip, plus optional 4-digit qualifier zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) zip.runTests(''' # traditional ZIP code 12345 # ZIP+4 form 12101-0001 # invalid ZIP 98765- ''') prints:: # traditional ZIP code 12345 ['12345'] # ZIP+4 form 12101-0001 ['12101-0001'] # invalid ZIP 98765- ^ FAIL: Expected end of text (at char 5), (line:1, col:6) cs.tt|j|dd|jj|_||_d|_dS)NFr T)rr<rrrrsr )rrrmrrrrs  zOptional.__init__Tc Csz|jj|||dd\}}W||fSttfyH|j|jur7|jjr2t|jg}|j||jj<n|jg}ng}Y||fSY||fSY||fSwr)rr,r@r<rs_Optional__optionalNotMatchedrrC)rrrr%rNrrrrs     zOptional.parseImplcCr)Nr+rrrrrrrrrzOptional.__str__r) rrrrrrrrrrrrrrr<s $ r<cs,eZdZdZd fdd Zd ddZZS) rIa Token for skipping over all undefined text until the matched expression is found. Parameters: - expr - target expression marking the end of the data to be skipped - include - (default= ``False``) if True, the target expression is also parsed (the skipped text and target expression are returned as a 2-element list). - ignore - (default= ``None``) used to define grammars (typically quoted strings and comments) that might contain false matches to the target expression - failOn - (default= ``None``) define expressions that are not allowed to be included in the skipped test; if found before the target expression is found, the SkipTo is not a match Example:: report = ''' Outstanding Issues Report - 1 Jan 2000 # | Severity | Description | Days Open -----+----------+-------------------------------------------+----------- 101 | Critical | Intermittent system crash | 6 94 | Cosmetic | Spelling error on Login ('log|n') | 14 79 | Minor | System slow when running too many reports | 47 ''' integer = Word(nums) SEP = Suppress('|') # use SkipTo to simply match everything up until the next SEP # - ignore quoted strings, so that a '|' character inside a quoted string does not match # - parse action will call token.strip() for each matched token, i.e., the description body string_data = SkipTo(SEP, ignore=quotedString) string_data.setParseAction(tokenMap(str.strip)) ticket_expr = (integer("issue_num") + SEP + string_data("sev") + SEP + string_data("desc") + SEP + integer("days_open")) for tkt in ticket_expr.searchString(report): print tkt.dump() prints:: ['101', 'Critical', 'Intermittent system crash', '6'] - days_open: 6 - desc: Intermittent system crash - issue_num: 101 - sev: Critical ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] - days_open: 14 - desc: Spelling error on Login ('log|n') - issue_num: 94 - sev: Cosmetic ['79', 'Minor', 'System slow when running too many reports', '47'] - days_open: 47 - desc: System slow when running too many reports - issue_num: 79 - sev: Minor FNcs`tt||||_d|_d|_||_d|_t|t r#| ||_ n||_ dt |j |_dS)NTFzNo match found for )rrIr ignoreExprr r includeMatchrrr9rfailOnrrr)rrincluderrrrrr@s zSkipTo.__init__Tc Cs$|}t|}|j}|jj}|jdur|jjnd}|jdur!|jjnd} |} | |kri|dur3||| r3n>| durJ z| || } Wn tyHYnwq8z ||| dddWntt fyc| d7} Ynwn | |ks)t|||j || }|||} t | } |j r||||dd\}} | | 7} || fS)NrF)r%r&r) rrr,rrUrrTr>r@r<rrCr)rrrr%rr@r expr_parseself_failOn_canParseNextself_ignoreExpr_tryParsetmplocskiptext skipresultr-rrrrMsD    zSkipTo.parseImpl)FNNrrrrrrrIs9 rIcsneZdZdZdfdd ZddZddZd d Zd d Zdd dZ ddZ fddZ dfdd Z Z S)r/a_Forward declaration of an expression to be defined later - used for recursive grammars, such as algebraic infix notation. When the expression is known, it is assigned to the ``Forward`` variable using the '<<' operator. Note: take care when assigning to ``Forward`` not to overlook precedence of operators. Specifically, '|' has a lower precedence than '<<', so that:: fwdExpr << a | b | c will actually be evaluated as:: (fwdExpr << a) | b | c thereby leaving b and c out as parseable alternatives. It is recommended that you explicitly group the values inserted into the ``Forward``:: fwdExpr << (a | b | c) Converting to use the '<<=' operator instead will avoid this problem. See :class:`ParseResults.pprint` for an example of a recursive parser created using ``Forward``. Ncstt|j|dddSr )rr/rrrrrrrzForward.__init__cCsjt|tr ||}||_d|_|jj|_|jj|_||jj|jj |_ |jj |_ |j |jj |Sr) rr9rrrrr rr rrr ryrrrr __lshift__s      zForward.__lshift__cCs||>Srrrrrr __ilshift__rzForward.__ilshift__cCrrrrrrrrszForward.leaveWhitespacecCs$|jsd|_|jdur|j|Sr)rrrrrrrrs   zForward.streamlinecCsJ|durg}||vr|dd|g}|jdur|j||gdSrrrrrrrs  zForward.validatecCst|dr|jS|jdur|jSd|_d}z+|jdur%t|jdd}nd}W|jjd||_|jSW|jjd||_|jS|jjd||_w)Nr+z: ...riNonez: )r]r+rrrrr)r retStringrrrrs   zForward.__str__cs*|jdur tt|St}||K}|Sr)rrr/r~rrrrr~s z Forward.copyFcs@tjr|jdurtjdd|t|jddtt | ||S)NzR{0}: setting results name {0!r} on {1} expression that has no contained expressionrrr) rrrrrrrrrr/rrrrrrs zForward._setResultsNamerr)rrrrrrrrrrrr~rrrrrrr/|s   r/cr")rNzW Abstract subclass of :class:`ParseExpression`, for converting parsed results. Fcrr)rrNrrrrrrrrzTokenConverter.__init__rr rrrrrNsrNcs6eZdZdZd fdd ZfddZdd ZZS) r*aConverter to concatenate all matching tokens to a single string. By default, the matching patterns must also be contiguous in the input string; this can be disabled by specifying ``'adjacent=False'`` in the constructor. Example:: real = Word(nums) + '.' + Word(nums) print(real.parseString('3.1416')) # -> ['3', '.', '1416'] # will also erroneously match the following print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] real = Combine(Word(nums) + '.' + Word(nums)) print(real.parseString('3.1416')) # -> ['3.1416'] # no match when there are internal spaces print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) rTcs8tt|||r|||_d|_||_d|_dSr)rr*rradjacentr joinStringr)rrr r rrrrs zCombine.__init__cs*|jr t|||Stt|||Sr)r rErrr*rrrrr s  zCombine.ignorecCsL|}|dd=|td||jg|jd7}|jr$|r$|gS|S)Nr)r-)r~rCrrr rrrl)rrrrDretToksrrrrEs  "zCombine.postParse)rT)rrrrrrrErrrrrr*s  r*c(eZdZdZfddZddZZS)r1aConverter to return the matched tokens as a list - useful for returning tokens of :class:`ZeroOrMore` and :class:`OneOrMore` expressions. Example:: ident = Word(alphas) num = Word(nums) term = ident | num func = ident + Optional(delimitedList(term)) print(func.parseString("fn a, b, 100")) # -> ['fn', 'a', 'b', '100'] func = ident + Group(Optional(delimitedList(term))) print(func.parseString("fn a, b, 100")) # -> ['fn', ['a', 'b', '100']] crr)rr1rrrrrrr*rzGroup.__init__cCs|gSrrrCrrrrE.rzGroup.postParserrrrrrErrrrrr1s r1cr)r+a?Converter to return a repetitive expression as a list, but also as a dictionary. Each element can also be referenced using the first token in the expression as its key. Useful for tabular report scraping when the first column can be used as a item key. Example:: data_word = Word(alphas) label = data_word + FollowedBy(':') attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) text = "shape: SQUARE posn: upper left color: light blue texture: burlap" attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) # print attributes as plain groups print(OneOrMore(attr_expr).parseString(text).dump()) # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names result = Dict(OneOrMore(Group(attr_expr))).parseString(text) print(result.dump()) # access named fields as dict entries, or output as dict print(result['shape']) print(result.asDict()) prints:: ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] - color: light blue - posn: upper left - shape: SQUARE - texture: burlap SQUARE {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} See more examples at :class:`ParseResults` of accessing fields by results name. crr)rr+rrrrrrrXrz Dict.__init__cCst|D]h\}}t|dkrq|d}t|tr t|d}t|dkr.td|||<qt|dkrEt|dtsEt|d|||<q|}|d=t|dks[t|trc| rct||||<qt|d|||<q|j rs|gS|S)Nrrrr) rrrrrrrrCr~rlr)rrrrDr tokikey dictvaluerrrrE\s$   zDict.postParserrrrrr+1s &r+c@r)rLa[Converter for ignoring the results of a parsed expression. Example:: source = "a, b, c,d" wd = Word(alphas) wd_list1 = wd + ZeroOrMore(',' + wd) print(wd_list1.parseString(source)) # often, delimiters that are useful during parsing are just in the # way afterward - use Suppress to keep them out of the parsed output wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) print(wd_list2.parseString(source)) prints:: ['a', ',', 'b', ',', 'c', ',', 'd'] ['a', 'b', 'c', 'd'] (See also :class:`delimitedList`.) cCsgSrrrCrrrrErFzSuppress.postParsecCs|SrrrrrrrrFzSuppress.suppressN)rrrrrErrrrrrLus rLc@s(eZdZdZddZddZddZdS) r;zDWrapper for parse actions, to ensure they are only called once. cCst||_d|_dSr)rr0called)r methodCallrrrrs  zOnlyOnce.__init__cCs*|js||||}d|_|St||d)NTr)rr0r@)rrrrr.rrrrs  zOnlyOnce.__call__cCs d|_dSr)rrrrrresetrzOnlyOnce.resetN)rrrrrrrrrrrr;s  r;cs8tfdd}zj|_W|StyY|Sw)aqDecorator for debugging parse actions. When the parse action is called, this decorator will print ``">> entering method-name(line:, , )"``. When the parse action completes, the decorator will print ``"<<"`` followed by the returned value, or any exception that the parse action raised. Example:: wd = Word(alphas) @traceParseAction def remove_duplicate_chars(tokens): return ''.join(sorted(set(''.join(tokens)))) wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) print(wds.parseString("slkdjs sld sldd sdlf sdljf")) prints:: >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) <>entering %s(line: '%s', %d, %r) z<.z)rrr)rrrrrrs   r,cCs\t|dt|dt|d}|r!t|t|||S|tt|||S)aHelper to define a delimited list of expressions - the delimiter defaults to ','. By default, the list elements and delimiters can have intervening whitespace, and comments, but this can be overridden by passing ``combine=True`` in the constructor. If ``combine`` is set to ``True``, the matching tokens are returned as a single token string, with the delimiters included; otherwise, the matching tokens are returned as a list of tokens, with the delimiters suppressed. Example:: delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc'] delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] z [rr)rr*rSrrL)rdelimcombinedlNamerrrrbs$rbcsjtfdd}|durttdd}n|}|d|j|dd|d td S) a>Helper to define a counted list of expressions. This helper defines a pattern of the form:: integer expr expr expr... where the leading integer tells how many expr expressions follow. The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. If ``intExpr`` is specified, it should be a pyparsing expression that produces an integer value. Example:: countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] # in this parser, the leading integer value is given in binary, # '10' indicating that 2 values are in the array binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] cs.|d}|rttg|ptt>gSr$)r1r&re)rrrr arrayExprrrrcountFieldParseActions"z+countedArray..countFieldParseActionNcSs t|dSr$)rrrrrrrzcountedArray..arrayLenTrz(len) r)r/rPrtrr~rr5r)rintExprr"rr rr^s r^cCs6g}|D]}t|tr|t|q||q|Sr)rr4ryrr)Lrr rrrr s   rcs6tfdd}|j|dddt|S)a4Helper to define an expression that is indirectly defined from the tokens matched in a previous expression, that is, it looks for a 'repeat' of a previous expression. For example:: first = Word(nums) second = matchPreviousLiteral(first) matchExpr = first + ":" + second will match ``"1:1"``, but not ``"1:2"``. Because this matches a previous literal, will also match the leading ``"1:1"`` in ``"1:10"``. If this is not desired, use :class:`matchPreviousExpr`. Do *not* use with packrat parsing enabled. csT|r#t|dkr|d>dSt|}tdd|D>dSt>dS)Nrrcsr/r)r5rttrrrr*razDmatchPreviousLiteral..copyTokenToRepeater..)rrr,r&r-)rrrtflatreprrcopyTokenToRepeater#s   z1matchPreviousLiteral..copyTokenToRepeaterTr$(prev) )r/r5rr)rr,rr*rrqs   rqcsFt|}|Kfdd}|j|dddt|S)aTHelper to define an expression that is indirectly defined from the tokens matched in a previous expression, that is, it looks for a 'repeat' of a previous expression. For example:: first = Word(nums) second = matchPreviousExpr(first) matchExpr = first + ":" + second will match ``"1:1"``, but not ``"1:2"``. Because this matches by expressions, will *not* match the leading ``"1:1"`` in ``"1:10"``; the expressions are evaluated first, and then compared, so ``"1"`` is compared with ``"10"``. Do *not* use with packrat parsing enabled. cs*t|fdd}j|dddS)Ncs$t|}|krtddddS)Nrr)rr,r@)rrr theseTokens matchTokensrrmustMatchTheseTokensEs  zLmatchPreviousExpr..copyTokenToRepeater..mustMatchTheseTokensTr$)rr,r)rrrr1r*r/rr,Cs  z.matchPreviousExpr..copyTokenToRepeaterTr$r-)r/r~r5rr)re2r,rr*rrp1s rpcCs:dD] }||t|}q|dd}|dd}t|S)Nz\^-[]rrrmrp)r_bslashr)rrrrrr:Ns   r:c st|tr tjddd|rdd}dd}|rtntndd}dd}|r)tntg}t|tr7|}nt|t rAt |}ntjd t dd|sNt S|sd }|t |d kr||}t||d d D]&\} } || |rz||| d =n||| r||| d =||| nqh|d 7}|t |d ksZ|s|s|rz3t |t d |krtdd dd|Dd|WStddd|Dd|WStytjdt ddYnwtfdd|Dd|S)aHelper to quickly define a set of alternative Literals, and makes sure to do longest-first testing when there is a conflict, regardless of the input order, but returns a :class:`MatchFirst` for best performance. Parameters: - strs - a string of space-delimited literals, or a collection of string literals - caseless - (default= ``False``) - treat all literals as caseless - useRegex - (default= ``True``) - as an optimization, will generate a Regex object; otherwise, will generate a :class:`MatchFirst` object (if ``caseless=True`` or ``asKeyword=True``, or if creating a :class:`Regex` raises an exception) - asKeyword - (default=``False``) - enforce Keyword-style matching on the generated expressions Example:: comp_oper = oneOf("< = > <= >= !=") var = Word(alphas) number = Word(nums) term = var | number comparison_expr = term + comp_oper + term print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) prints:: [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] z_More than one string argument passed to oneOf, pass choices as a list or space-delimited stringrrcSs||kSr)rrbrrrr{rzoneOf..cSs||Sr)rrr4rrrr|scSrrrr4rrrrrcSs ||Srrr4rrrrs z6Invalid argument to oneOf, expected string or iterablerrNrrKcsr/r)r:rsymrrrrrazoneOf..r|css|]}t|VqdSr)rr<r6rrrrrz7Exception creating Regex for oneOf, building MatchFirstc3|]}|VqdSrrr6parseElementClassrrrra)rr9rrr'r(r2r5rr r4rr8rrrtrrHrrr7) strsruseRegexr9isequalmaskssymbolsr currNrrr:rruVs^          *&  "rucCsttt||S)aHelper to easily and clearly define a dictionary by specifying the respective patterns for the key and value. Takes care of defining the :class:`Dict`, :class:`ZeroOrMore`, and :class:`Group` tokens in the proper order. The key pattern can include delimiting markers or punctuation, as long as they are suppressed, thereby leaving the significant key text. The value pattern can include named results, so that the :class:`Dict` results can include named token fields. Example:: text = "shape: SQUARE posn: upper left color: light blue texture: burlap" attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) print(OneOrMore(attr_expr).parseString(text).dump()) attr_label = label attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) # similar to Dict, but simpler call format result = dictOf(attr_label, attr_value).parseString(text) print(result.dump()) print(result['shape']) print(result.shape) # object attribute access works too print(result.asDict()) prints:: [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] - color: light blue - posn: upper left - shape: SQUARE - texture: burlap SQUARE SQUARE {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} )r+r:r1)rrrOrrrrcs%rccCs^tdd}|}d|_|d||d}|r dd}ndd}|||j|_|S) aHelper to return the original, untokenized text for a given expression. Useful to restore the parsed fields of an HTML start tag into the raw tag text itself, or to revert separate tokens with intervening whitespace back to the original matching input text. By default, returns astring containing the original parsed text. If the optional ``asString`` argument is passed as ``False``, then the return value is a :class:`ParseResults` containing any results names that were originally matched, and a single token containing the original matched text from the input string. So if the expression passed to :class:`originalTextFor` contains expressions with defined results names, you must set ``asString`` to ``False`` if you want to preserve those results name values. Example:: src = "this is test bold text normal text " for tag in ("b", "i"): opener, closer = makeHTMLTags(tag) patt = originalTextFor(opener + SkipTo(closer) + closer) print(patt.searchString(src)[0]) prints:: [' bold text '] ['text'] cS|Srr)rrrrrrrz!originalTextFor..F_original_start _original_endcSs||j|jSr)rDrErrrrrrcSs&||d|dg|dd<dS)NrDrE)rqrrrr extractTexts&z$originalTextFor..extractText)r-rr~rr )rasString locMarker endlocMarker matchExprrFrrrrs  rcCst|ddS)zkHelper to undo pyparsing's default grouping of And expressions, even if all but one are non-empty. cSs|dSr$rrrrrrrzungroup..)rNr5)rrrrrsrcCs4tdd}t|d|d|dS)aHelper to decorate a returned token with its starting and ending locations in the input string. This helper adds the following results names: - locn_start = location where matched expression begins - locn_end = location where matched expression ends - value = the actual parsed results Be careful if the input text contains ```` characters, you may want to call :class:`ParserElement.parseWithTabs` Example:: wd = Word(alphas) for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): print(match) prints:: [[0, 'ljsdf', 5]] [[8, 'lksdjjf', 15]] [[18, 'lkkjj', 23]] cSrBrrrrrrrrCzlocatedExpr.. locn_startrOlocn_end)r-rr1r~r)rlocatorrrrrs$rrerkrjrrz\[]-*.$+^?()~ rBcCs |ddSrFrrrrrr(rrz\\0?[xX][0-9a-fA-F]+cCstt|dddS)Nrz\0xr)unichrrrrrrrr)rz \\0[0-7]+cCstt|ddddS)Nrr)rOrrrrrr*sz\]rrrnegatebodyrcs@ddzdfddt|jDWStyYdSw)aHelper to easily define string ranges for use in Word construction. Borrows syntax from regexp '[]' string range definitions:: srange("[0-9]") -> "0123456789" srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" The input string must be enclosed in []'s, and the returned string is the expanded character set joined into a single string. The values enclosed in the []'s may be: - a single character - an escaped character with a leading backslash (such as ``\-`` or ``\]``) - an escaped hex character with a leading ``'\x'`` (``\x21``, which is a ``'!'`` character) (``\0x##`` is also supported for backwards compatibility) - an escaped octal character with a leading ``'\0'`` (``\041``, which is a ``'!'`` character) - a range of any of the above, separated by a dash (``'a-z'``, etc.) - any combination of the above (``'aeiouy'``, ``'a-zA-Z0-9_$'``, etc.) cSs<t|ts|Sdddtt|dt|ddDS)Nrcsr/rrOrrrrrIraz+srange....rr)rrCrrGord)prrrrIs<zsrange..rc3r9rr)rpart _expandedrrrKrazsrange..)r_reBracketExprrrRrrFrrWrr/s " rcfdd}|S)zoHelper method for defining parse actions that require matching at a specific column in the input text. cs"t||krt||ddS)Nzmatched token not at column %dr)rlocnrrrr verifyColSsz!matchOnlyAtCol..verifyColr)rr\rrrroOs rocs fddS)aHelper method for common parse actions that simply return a literal value. Especially useful when used with :class:`transformString` (). Example:: num = Word(nums).setParseAction(lambda toks: int(toks[0])) na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) term = na | num OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] csgSrrrreplStrrrrezreplaceWith..rr]rr]rr~Xs r~cCs|dddS)aHelper parse action for removing quotation marks from parsed quoted strings. Example:: # by default, quotation marks are included in parsed results quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] # use removeQuotes to strip quotation marks from parsed results quotedString.setParseAction(removeQuotes) quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] rrrrrrrrr|grwr|csLfdd}z tdtdj}Wn ty t}Ynw||_|S)aLHelper to define a parse action by mapping a function to all elements of a ParseResults list. If any additional args are passed, they are forwarded to the given function as additional arguments after the token, as in ``hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))``, which will convert the parsed data to an integer using base 16. Example (compare the last to example in :class:`ParserElement.transformString`:: hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) hex_ints.runTests(''' 00 11 22 aa FF 0a 0d 1a ''') upperword = Word(alphas).setParseAction(tokenMap(str.upper)) OneOrMore(upperword).runTests(''' my kingdom for a horse ''') wd = Word(alphas).setParseAction(tokenMap(str.title)) OneOrMore(wd).setParseAction(' '.join).runTests(''' now is the winter of our discontent made glorious summer by this sun of york ''') prints:: 00 11 22 aa FF 0a 0d 1a [0, 17, 34, 170, 255, 10, 13, 26] my kingdom for a horse ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] now is the winter of our discontent made glorious summer by this sun of york ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] csfdd|DS)Ncsg|] }|gRqSrr)rtoknrrrrrrz(tokenMap..pa..rrrarrrrztokenMap..parr)rrrr)rrrrrrarrvs$   rcC t|SrrrrrrrrrcCrbrrlowerrrrrrrrrcs~t|tr|t|| d}n|jtttd}|rGt t }||dt t t |td|tddgdd d d |}n6t t ttd d B}||dt t t | tttd|tddgdd d d |}ttd|d dd}|d|fdd |ddddd}|_|_t||_||fS)zRInternal helper to construct opening and closing tag expressions, given a tag namer#z_-:tag=/FrmrecS |ddkSNrrhrrrrrrrz_makeTags..rr0cSrjrkrrrrrrrr)r z<%s>c s*|dddd|S)Nr(r:r)rErrtitlerr~rresnamerrrs*rIrrlrz)rr9r2r+rPrVrUr`r~rr|r+rSr1rLr<r{rxrdr*_Lrr5rrrmrrfrItag_body)tagStrxml suppress_LT suppress_GT tagAttrName tagAttrValueopenTagcloseTagrrnr _makeTagssH , rzcC t|dS)aKHelper to construct opening and closing tag expressions for HTML, given a tag name. Matches tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. Example:: text = 'More info at the pyparsing wiki page' # makeHTMLTags returns pyparsing expressions for the opening and # closing tags as a 2-tuple a, a_end = makeHTMLTags("A") link_expr = a + SkipTo(a_end)("link_text") + a_end for link in link_expr.searchString(text): # attributes in the tag (like "href" shown here) are # also accessible as named results print(link.link_text, '->', link.href) prints:: pyparsing -> https://github.com/pyparsing/pyparsing/wiki Frzrrrrrrms rmcCr{)zHelper to construct opening and closing tag expressions for XML, given a tag name. Matches tags only in the given upper/lower case. Example: similar to :class:`makeHTMLTags` Tr|r}rrrrns rncs8|r |ddn|ddDfdd}|S)a7Helper to create a validating parse action to be used with start tags created with :class:`makeXMLTags` or :class:`makeHTMLTags`. Use ``withAttribute`` to qualify a starting tag with a required attribute value, to avoid false matches on common tags such as ```` or ``
``. Call ``withAttribute`` with a series of attribute names and values. Specify the list of filter attributes names and values as: - keyword arguments, as in ``(align="right")``, or - as an explicit dict with ``**`` operator, when an attribute name is also a Python reserved word, as in ``**{"class":"Customer", "align":"right"}`` - a list of name-value tuples, as in ``(("ns1:class", "Customer"), ("ns2:align", "right"))`` For attribute names with a namespace prefix, you must use the second form. Attribute names are matched insensitive to upper/lower case. If just testing for ``class`` (with or without a namespace), use :class:`withClass`. To verify that the attribute exists, but without specifying a value, pass ``withAttribute.ANY_VALUE`` as the value. Example:: html = '''
Some text
1 4 0 1 0
1,3 2,3 1,1
this has no type
''' div,div_end = makeHTMLTags("div") # only match div tag having a type attribute with value "grid" div_grid = div().setParseAction(withAttribute(type="grid")) grid_expr = div_grid + SkipTo(div | div_end)("body") for grid_header in grid_expr.searchString(html): print(grid_header.body) # construct a match with any div tag having a type attribute, regardless of the value div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) div_expr = div_any_type + SkipTo(div | div_end)("body") for div_header in div_expr.searchString(html): print(div_header.body) prints:: 1 4 0 1 0 1 4 0 1 0 1,3 2,3 1,1 NcSsg|]\}}||fqSrrrrrrr/rz!withAttribute..csZD](\}}||vrt||d||tjkr*|||kr*t||d||||fqdS)Nzno matching attribute z+attribute '%s' has value '%s', must be '%s')r@r ANY_VALUE)rrrNattrName attrValueattrsrrr0s  zwithAttribute..pa)rJ)rattrDictrrrrrs 8 rcCs"|rd|nd}tdi||iS)aSimplified version of :class:`withAttribute` when matching on a div class - made difficult because ``class`` is a reserved word in Python. Example:: html = '''
Some text
1 4 0 1 0
1,3 2,3 1,1
this <div> has no class
''' div,div_end = makeHTMLTags("div") div_grid = div().setParseAction(withClass("grid")) grid_expr = div_grid + SkipTo(div | div_end)("body") for grid_header in grid_expr.searchString(html): print(grid_header.body) div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) div_expr = div_any_type + SkipTo(div | div_end)("body") for div_header in div_expr.searchString(html): print(div_header.body) prints:: 1 4 0 1 0 1 4 0 1 0 1,3 2,3 1,1 z%s:classclassNr)r) classname namespace classattrrrrr:s#r(r`cCsGdddt}t}||||B}t|D]0\}}|ddd\} } } } | dkr0d| nd| } | dkrJ| dusBt| d krFtd | \}}t| }| tjkr| d krh||| t|t | }n| d kr| dur||| |t|t | |}n|||t|t |}n| dkr||||||t|t ||||}nvtd | tj kr#| d krt | t st | } || j |t| |}nQ| d kr| dur||| |t|t | |}n5|||t|t |}n&| dkr||||||t|||||}ntd td | r=t | ttfr8|j| n|| ||| |BK}|}q||K}|S)al Helper method for constructing grammars of expressions made up of operators working in a precedence hierarchy. Operators may be unary or binary, left- or right-associative. Parse actions can also be attached to operator expressions. The generated parser will also recognize the use of parentheses to override operator precedences (see example below). Note: if you define a deep operator list, you may see performance issues when using infixNotation. See :class:`ParserElement.enablePackrat` for a mechanism to potentially improve your parser performance. Parameters: - baseExpr - expression representing the most basic element for the nested - opList - list of tuples, one for each operator precedence level in the expression grammar; each tuple is of the form ``(opExpr, numTerms, rightLeftAssoc, parseAction)``, where: - opExpr is the pyparsing expression for the operator; may also be a string, which will be converted to a Literal; if numTerms is 3, opExpr is a tuple of two expressions, for the two operators separating the 3 terms - numTerms is the number of terms for this operator (must be 1, 2, or 3) - rightLeftAssoc is the indicator whether the operator is right or left associative, using the pyparsing-defined constants ``opAssoc.RIGHT`` and ``opAssoc.LEFT``. - parseAction is the parse action to be associated with expressions matching this operator expression (the parse action tuple member may be omitted); if the parse action is passed a tuple or list of functions, this is equivalent to calling ``setParseAction(*fn)`` (:class:`ParserElement.setParseAction`) - lpar - expression for matching left-parentheses (default= ``Suppress('(')``) - rpar - expression for matching right-parentheses (default= ``Suppress(')')``) Example:: # simple example of four-function arithmetic with ints and # variable names integer = pyparsing_common.signed_integer varname = pyparsing_common.identifier arith_expr = infixNotation(integer | varname, [ ('-', 1, opAssoc.RIGHT), (oneOf('* /'), 2, opAssoc.LEFT), (oneOf('+ -'), 2, opAssoc.LEFT), ]) arith_expr.runTests(''' 5+3*6 (5+3)*6 -2--11 ''', fullDump=False) prints:: 5+3*6 [[5, '+', [3, '*', 6]]] (5+3)*6 [[[5, '+', 3], '*', 6]] -2--11 [[['-', 2], '-', ['-', 11]]] c@r)zinfixNotation.._FBTcSs|j|||gfSr)rrTrBrrrrsz$infixNotation.._FB.parseImplNrrrrrr_FBrrrNrErz%s termz %s%s termrz@if numterms=3, opExpr must be a tuple or list of two expressionsrz6operator must be unary (1), binary (2), or ternary (3)z2operator must indicate right or left associativity)r.r/rrrrrvLEFTr1r:RIGHTrr<rrr4r)baseExpropListlparrparrrlastExprr operDefopExprarityrightLeftAssocrtermNameopExpr1opExpr2thisExprrJrrrrds`H  &   &   rz4"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*"z string enclosed in double quotesz4'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*'z string enclosed in single quotesz*quotedString using single or double quotesuzunicode string literalcCs||krtd|durt|trt|trt|dkrQt|dkrQ|dur>tt|t||tjdd dd}nTt t||tj dd}nA|durstt|t |t |ttjdd dd}nttt |t |ttjdd d d}ntd t }|dur|tt|t||B|Bt|K}n|tt|t||Bt|K}|d ||f|S) a Helper method for defining nested lists enclosed in opening and closing delimiters ("(" and ")" are the default). Parameters: - opener - opening character for a nested list (default= ``"("``); can also be a pyparsing expression - closer - closing character for a nested list (default= ``")"``); can also be a pyparsing expression - content - expression for items within the nested lists (default= ``None``) - ignoreExpr - expression for ignoring opening and closing delimiters (default= :class:`quotedString`) If an expression is not provided for the content argument, the nested expression will capture all whitespace-delimited content between delimiters as a list of separate values. Use the ``ignoreExpr`` argument to define expressions that may contain opening or closing characters that should not be treated as opening or closing characters for nesting, such as quotedString or a comment expression. Specify multiple expressions using an :class:`Or` or :class:`MatchFirst`. The default is :class:`quotedString`, but if no expressions are to be ignored, then pass ``None`` for this argument. Example:: data_type = oneOf("void int short long char float double") decl_data_type = Combine(data_type + Optional(Word('*'))) ident = Word(alphas+'_', alphanums+'_') number = pyparsing_common.number arg = Group(decl_data_type + ident) LPAR, RPAR = map(Suppress, "()") code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) c_function = (decl_data_type("type") + ident("name") + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + code_body("body")) c_function.ignore(cStyleComment) source_code = ''' int is_odd(int x) { return (x%2); } int dec_to_hex(char hchar) { if (hchar >= '0' && hchar <= '9') { return (ord(hchar)-ord('0')); } else { return (10+ord(hchar)-ord('A')); } } ''' for func in c_function.searchString(source_code): print("%(name)s (%(type)s) args: %(args)s" % func) prints:: is_odd (int) args: [['int', 'x']] dec_to_hex (int) args: [['char', 'hchar']] z.opening and closing strings cannot be the sameNrrNcS |dSr$rrrrrr;rznestedExpr..cSrr$rrrrrr@rcSrr$rrrrrrGrcSrr$rrrrrrLrzOopening and closing arguments must be strings if no content expression is givenznested %s%s expression)rrr9rr*r:r)rErrrer~r5r/r1rLrSr)openerclosercontentrrrrrrrs`A        *$rrc s&ddfddfdd}fdd}fdd }ttd td }tt|d }t|d }t|d} |rftt ||t|t|t |td | } ntt |t|t|t |td | } | fdd| t t| dS)aHelper method for defining space-delimited indentation blocks, such as those used to define block statements in Python source code. Parameters: - blockStatementExpr - expression defining syntax of statement that is repeated within the indented block - indentStack - list created by caller to manage indentation stack (multiple statementWithIndentedBlock expressions within a single grammar should share a common indentStack) - indent - boolean indicating whether block must be indented beyond the current level; set to False for block of left-most statements (default= ``True``) A valid block must contain at least one ``blockStatement``. Example:: data = ''' def A(z): A1 B = 100 G = A2 A2 A3 B def BB(a,b,c): BB1 def BBA(): bba1 bba2 bba3 C D def spam(x,y): def eggs(z): pass ''' indentStack = [1] stmt = Forward() identifier = Word(alphas, alphanums) funcDecl = ("def" + identifier + Group("(" + Optional(delimitedList(identifier)) + ")") + ":") func_body = indentedBlock(stmt, indentStack) funcDef = Group(funcDecl + func_body) rvalue = Forward() funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") rvalue << (funcCall | identifier | Word(nums)) assignment = Group(identifier + "=" + rvalue) stmt << (funcDef | assignment | identifier) module_body = OneOrMore(stmt) parseTree = module_body.parseString(data) parseTree.pprint() prints:: [['def', 'A', ['(', 'z', ')'], ':', [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], 'B', ['def', 'BB', ['(', 'a', 'b', 'c', ')'], ':', [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], 'C', 'D', ['def', 'spam', ['(', 'x', 'y', ')'], ':', [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] Ncsdd<dSrrr) backup_stack indentStackrr reset_stackr z"indentedBlock..reset_stackcsN|t|krdSt||}|dkr%|dkrt||dt||ddS)Nrzillegal nestingznot a peer entry)rr[r@rrrcurColrrrcheckPeerIndents     z&indentedBlock..checkPeerIndentcs0t||}|dkr|dSt||d)Nrznot a subentry)r[rr@rrrrcheckSubIndents   z%indentedBlock..checkSubIndentcsN|t|krdSt||}r|vst||d|dkr%dSdS)Nznot an unindentr)rr[r@rqrrrr checkUnindents     z$indentedBlock..checkUnindentz rINDENTrUNINDENTcsSrr)rr5rrW)rrrrr_zindentedBlock..zindented block) r:r3rrrJr-rrr1r<r8rr3) blockStatementExprrrrrrrrPEERUNDENTsmExprr)rrrrrWs2 Q    rz#[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]z[\0xa1-\0xbf\0xd7\0xf7]z_:zany tagzgt lt amp nbsp quot aposz><& "'z &(?Pr8z);zcommon HTML entitycCs t|jS)zRHelper parser action to replace common HTML entities with their special characters)_htmlEntityMaprentityrrrrr}rhr}z/\*(?:[^*]|\*(?!/))*z*/zC style commentzz HTML commentz.*z rest of linez//(?:\\\n|[^\n])*z // commentzC++ style commentz#.*zPython style commentr0 commaItemrir\c@seZdZdZeeZ eeZ e e  d eZ e e d eedZ ed d eZ e ede e dZ ed d eeeed eB d Z eeed  d eZ ed d eZ eeBeBZ ed d eZ e eded dZ ed dZ ed dZ!e!de!d dZ"ee!de!ddee!de!d dZ#e#$dd d e  d!Z%e&e"e%Be#B d" d"Z' ed# d$Z( e)d=d&d'Z*e)d>d)d*Z+ed+ d,Z, ed- d.Z- ed/ d0Z. e/e0BZ1e)d1d2Z2e&e3e4d3e5e e6d3d4ee7d5 d6Z8e9ee:;e8Bd7d8 d9Z< e)ed:d Z= e)ed;d Z>d`, :class:`reals`, :class:`scientific notation`) - common :class:`programming identifiers` - network addresses (:class:`MAC`, :class:`IPv4`, :class:`IPv6`) - ISO8601 :class:`dates` and :class:`datetime` - :class:`UUID` - :class:`comma-separated list` Parse actions: - :class:`convertToInteger` - :class:`convertToFloat` - :class:`convertToDate` - :class:`convertToDatetime` - :class:`stripHTMLTags` - :class:`upcaseTokens` - :class:`downcaseTokens` Example:: pyparsing_common.number.runTests(''' # any int or real number, returned as the appropriate type 100 -100 +100 3.14159 6.02e23 1e-12 ''') pyparsing_common.fnumber.runTests(''' # any int or real number, returned as float 100 -100 +100 3.14159 6.02e23 1e-12 ''') pyparsing_common.hex_integer.runTests(''' # hex numbers 100 FF ''') pyparsing_common.fraction.runTests(''' # fractions 1/2 -3/4 ''') pyparsing_common.mixed_integer.runTests(''' # mixed fractions 1 1/2 -3/4 1-3/4 ''') import uuid pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) pyparsing_common.uuid.runTests(''' # uuid 12345678-1234-5678-1234-567812345678 ''') prints:: # any int or real number, returned as the appropriate type 100 [100] -100 [-100] +100 [100] 3.14159 [3.14159] 6.02e23 [6.02e+23] 1e-12 [1e-12] # any int or real number, returned as float 100 [100.0] -100 [-100.0] +100 [100.0] 3.14159 [3.14159] 6.02e23 [6.02e+23] 1e-12 [1e-12] # hex numbers 100 [256] FF [255] # fractions 1/2 [0.5] -3/4 [-0.75] # mixed fractions 1 [1] 1/2 [0.5] -3/4 [-0.75] 1-3/4 [1.75] # uuid 12345678-1234-5678-1234-567812345678 [UUID('12345678-1234-5678-1234-567812345678')] integerz hex integerrz[+-]?\d+zsigned integerrhfractioncCs|d|dS)Nrrrrrrrrrzpyparsing_common.rz"fraction or mixed integer-fractionz[+-]?(?:\d+\.\d*|\.\d+)z real numberz@[+-]?(?:\d+(?:[eE][+-]?\d+)|(?:\d+\.\d*|\.\d+)(?:[eE][+-]?\d+)?)z$real number with scientific notationz[+-]?\d+\.?\d*([eE][+-]?\d+)?fnumberr identifierzK(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}z IPv4 addressz[0-9a-fA-F]{1,4} hex_integerrlzfull IPv6 address)rrz::zshort IPv6 addresscCstdd|DdkS)Ncss |] }tj|rdVqdSr)r _ipv6_partrr'rrrrrz,pyparsing_common...rP)rrrrrrrz::ffff:zmixed IPv6 addressz IPv6 addressz:[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}z MAC address%Y-%m-%dcrZ)a Helper to create a parse action for converting parsed date string to Python datetime.date Params - - fmt - format to be passed to datetime.strptime (default= ``"%Y-%m-%d"``) Example:: date_expr = pyparsing_common.iso8601_date.copy() date_expr.setParseAction(pyparsing_common.convertToDate()) print(date_expr.parseString("1999-12-31")) prints:: [datetime.date(1999, 12, 31)] c s@z t|dWSty}zt||t|d}~wwr$)rstrptimedaterr@rrrrvefmtrrcvt_fns z.pyparsing_common.convertToDate..cvt_fnrrrrrr convertToDate zpyparsing_common.convertToDate%Y-%m-%dT%H:%M:%S.%fcrZ)aHelper to create a parse action for converting parsed datetime string to Python datetime.datetime Params - - fmt - format to be passed to datetime.strptime (default= ``"%Y-%m-%dT%H:%M:%S.%f"``) Example:: dt_expr = pyparsing_common.iso8601_datetime.copy() dt_expr.setParseAction(pyparsing_common.convertToDatetime()) print(dt_expr.parseString("1999-12-31T23:59:59.999")) prints:: [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] c s<z t|dWSty}zt||t|d}~wwr$)rrrr@rrrrrrs z2pyparsing_common.convertToDatetime..cvt_fnrrrrrconvertToDatetimerz"pyparsing_common.convertToDatetimez7(?P\d{4})(?:-(?P\d\d)(?:-(?P\d\d))?)?z ISO8601 datez(?P\d{4})-(?P\d\d)-(?P\d\d)[T ](?P\d\d):(?P\d\d)(:(?P\d\d(\.\d*)?)?)?(?PZ|[+-]\d\d:?\d\d)?zISO8601 datetimez2[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}UUIDcCstj|dS)aParse action to remove HTML tags from web page HTML source Example:: # strip HTML links from normal text text = 'More info at the
pyparsing wiki page' td, td_end = makeHTMLTags("TD") table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end print(table_text.parseString(text).body) Prints:: More info at the pyparsing wiki page r)r_html_stripperr)rrrNrrr stripHTMLTagsszpyparsing_common.stripHTMLTagsrr0rrrrizcomma separated listcCrbrrcrrrrr#rcCrbrrdrrrrr&rN)r)r)?rrrrrrconvertToIntegerfloatconvertToFloatrPrtrrrrfrrHsigned_integerrr5r<r mixed_integerrrealsci_realrnumberrrVrUr ipv4_addressr_full_ipv6_address_short_ipv6_addressr6_mixed_ipv6_addressr* ipv6_address mac_addressrrr iso8601_dateiso8601_datetimeuuidrYrXrrr:r5r3rxrO _commasepitemrbr{r~comma_separated_listrrdrrrrrs""         rc@seZdZddZddZdS)_lazyclasspropertycCs||_|j|_|j|_dSr)rrrr7rrrr+s z_lazyclassproperty.__init__csldurt|tdrtfddjddDr i_|jj}|jvr1|j|<j|S)N_internc3s"|] }jt|dguVqdS)rN)rr)r superclassrrrr3sz-_lazyclassproperty.__get__..r)rr]r__mro__rrr)rrrattrnamerrr__get__0s   z_lazyclassproperty.__get__N)rrrrrrrrrr*s rc@sPeZdZdZgZeddZeddZeddZ edd Z ed d Z d S) ra A set of Unicode characters, for language-specific strings for ``alphas``, ``nums``, ``alphanums``, and ``printables``. A unicode_set is defined by a list of ranges in the Unicode character set, in a class attribute ``_ranges``, such as:: _ranges = [(0x0020, 0x007e), (0x00a0, 0x00ff),] A unicode set can also be defined using multiple inheritance of other unicode sets:: class CJK(Chinese, Japanese, Korean): pass cCsZg}|jD]}|tur n|jD]}|t|d|ddqqddtt|DS)NrrrcSsg|]}t|qSrrSrrrrrTr@z5unicode_set._get_chars_for_ranges..)rr_rangesryrGrr)rrccrrrrr_get_chars_for_rangesLs  z!unicode_set._get_chars_for_rangescCdttj|S)z+all non-whitespace characters in this ranger)rrrrrrrrrrxVzunicode_set.printablescCr)z'all alphabetic characters in this ranger)rfilterrisalpharrrrrrV[rzunicode_set.alphascCr)z*all numeric digit characters in this ranger)rrrisdigitrrrrrrt`rzunicode_set.numscCs |j|jS)z)all alphanumeric characters in this range)rVrtrrrrrUes zunicode_set.alphanumsN) rrrrrrrrrxrVrtrUrrrrr<s     rc@seZdZdZdejfgZGdddeZGdddeZ GdddeZ Gd d d eZ Gd d d eZ Gd ddeZ GdddeZGdddeZGddde eeZGdddeZGdddeZGdddeZGdddeZdS)rzF A namespace class for defining common language unicode_sets. c@eZdZdZddgZdS)zpyparsing_unicode.Latin1z/Unicode set for Latin-1 Unicode Character Range)r~)NrrrrrrrrrLatin1q rc@eZdZdZdgZdS)zpyparsing_unicode.LatinAz/Unicode set for Latin-A Unicode Character Range)iNrrrrrLatinAu rc@r)zpyparsing_unicode.LatinBz/Unicode set for Latin-B Unicode Character Range)iiONrrrrrLatinByrrc@eZdZdZgdZdS)zpyparsing_unicode.Greekz.Unicode set for Greek Unicode Character Ranges))ipi)ii)ii)i iE)iHiM)iPiW)iY)i[)i])i_i})ii)ii)ii)ii)ii)ii)iiNrrrrrGreek}rrc@r)zpyparsing_unicode.Cyrillicz0Unicode set for Cyrillic Unicode Character Range)iiNrrrrrCyrillicrrc@r)zpyparsing_unicode.Chinesez/Unicode set for Chinese Unicode Character Range)Nii0i?0NrrrrrChineserrc@sDeZdZdZgZGdddeZGdddeZGdddeZdS) zpyparsing_unicode.Japanesez`Unicode set for Japanese Unicode Character Range, combining Kanji, Hiragana, and Katakana rangesc@r)z pyparsing_unicode.Japanese.Kanjiz-Unicode set for Kanji Unicode Character Range)rirNrrrrrKanjirrc@r)z#pyparsing_unicode.Japanese.Hiraganaz0Unicode set for Hiragana Unicode Character Range)i@0i0NrrrrrHiraganarrc@r)z#pyparsing_unicode.Japanese.Katakanaz1Unicode set for Katakana Unicode Character Range)i0i0NrrrrrKatakanarrN) rrrrrrrrrrrrrJapaneses rc@r)zpyparsing_unicode.Koreanz.Unicode set for Korean Unicode Character Range))ii)ii)i01i1)i`i)iirNrrrrrKoreanrrc@r)zpyparsing_unicode.CJKzTUnicode set for combined Chinese, Japanese, and Korean (CJK) Unicode Character RangeNrrrrrCJKsrc@r)zpyparsing_unicode.Thaiz,Unicode set for Thai Unicode Character Range)ii:)i?i[NrrrrrThairrc@r)zpyparsing_unicode.Arabicz.Unicode set for Arabic Unicode Character Range))ii)ii)iiNrrrrrArabicrrc@r)zpyparsing_unicode.Hebrewz.Unicode set for Hebrew Unicode Character Range)iiNrrrrrHebrewrrc@r)zpyparsing_unicode.Devanagariz2Unicode set for Devanagari Unicode Character Range)i i )iiNrrrrr Devanagarirr N)rrrrr maxunicoderrrrrrrrrrrrrrr rrrrrks  ruالعربيةu中文uкириллицаuΕλληνικάuעִברִיתu 日本語u漢字u カタカナu ひらがなu 한국어u ไทยuदेवनागरीc@s,eZdZdZGdddZGdddZdS)pyparsing_testzB namespace class for classes useful in writing unit tests c@s8eZdZdZddZddZddZdd Zd d Zd S) z&pyparsing_test.reset_pyparsing_contextax Context manager to be used when writing unit tests that modify pyparsing config values: - packrat parsing - default whitespace characters. - default keyword characters - literal string auto-conversion class - __diag__ settings Example: with reset_pyparsing_context(): # test that literals used to construct a grammar are automatically suppressed ParserElement.inlineLiteralsUsing(Suppress) term = Word(alphas) | Word(nums) group = Group('(' + term[...] + ')') # assert that the '()' characters are not included in the parsed tokens self.assertParseAndCheckLisst(group, "(abc 123 def)", ['abc', '123', 'def']) # after exiting context manager, literals are converted to Literal expressions again cCs i|_dSr) _save_contextrrrrrrz/pyparsing_test.reset_pyparsing_context.__init__cCsftj|jd<tj|jd<tj|jd<tj|jd<tj|jd<ddtj D|jd<d t j i|jd <|S) Ndefault_whitespacedefault_keyword_charsliteral_string_classpackrat_enabled packrat_parsecSsi|]}|tt|qSr)rr)rr+rrr s z?pyparsing_test.reset_pyparsing_context.save..rrr%) rErr r2rrrr,r _all_namesr%rrrrrsaves      z+pyparsing_test.reset_pyparsing_context.savecCstj|jdkrt|jd|jdt_t|jd|jdD] \}}tt ||q%|jdt_ |jdt_ |jdt _ dS)Nr rrrrrr%)rErr rr2rrrJsetattrrrr,r%r)rr+rOrrrrestores   z.pyparsing_test.reset_pyparsing_context.restorecC|Sr)rrrrr __enter__ rz0pyparsing_test.reset_pyparsing_context.__enter__cGrr)rrrrr__exit__rz/pyparsing_test.reset_pyparsing_context.__exit__N) rrrrrrrrrrrrrreset_pyparsing_contexts rc@sReZdZdZ dddZ dddZ ddd Z dd d Zee dfd d Z dS)z&pyparsing_test.TestParseResultsAssertszk A mixin class to add parse results assertion methods to normal unittest.TestCase classes. NcCs@|dur|j|||d|dur|j|||ddSdS)z Unit test assertion to compare a ParseResults object with an optional expected_list, and compare any defined results names with an optional expected_dict. Nr) assertEqualr,r)rr expected_list expected_dictrrrrassertParseResultsEqualss z?pyparsing_test.TestParseResultsAsserts.assertParseResultsEqualsTcC2|j|dd}|rt||j|||ddS)z Convenience wrapper assert to test a parser element and input string, and assert that the resulting ParseResults.asList() is equal to the expected_list. Tr)rrNrrrr)rr test_stringrrverboserrrrassertParseAndCheckList! z>pyparsing_test.TestParseResultsAsserts.assertParseAndCheckListcCr )z Convenience wrapper assert to test a parser element and input string, and assert that the resulting ParseResults.asDict() is equal to the expected_dict. Tr)rrNr!)rrr"rrr#rrrrassertParseAndCheckDict-r%z>pyparsing_test.TestParseResultsAsserts.assertParseAndCheckDictc Cs|\}}|durddt||D}|D]k\}}} tdd| Dd} tdd| Dd} | durR|j| | p7|dt|trB|Wdn1sLwYqtdd| Dd} td d| Dd} | | fd krx|j|| | | pt|d qtd |q|j||dur|nd ddS)aP Unit test assertion to evaluate output of ParserElement.runTests(). If a list of list-dict tuples is given as the expected_parse_results argument, then these are zipped with the report tuples returned by runTests and evaluated using assertParseResultsEquals. Finally, asserts that the overall runTests() success value is True. :param run_tests_report: tuple(bool, [tuple(str, ParseResults or Exception)]) returned from runTests :param expected_parse_results (optional): [tuple(str, list, dict, Exception)] NcSs"g|] \}}|d|d|fqSrr)rrptexpectedrrrrHszOpyparsing_test.TestParseResultsAsserts.assertRunTestResults..cs|] }t|tr|VqdSr)rrrexprrrrQrzNpyparsing_test.TestParseResultsAsserts.assertRunTestResults..css(|]}t|trt|tr|VqdSr)rrrrr*rrrrTs )expected_exceptionrcsr)r)rr4r*rrrrcrcsr)r)rr7r*rrrrfrr)rrrzno validation for {!r}zfailed runTestsr) rr assertRaisesrrrrr assertTrue)rrun_tests_reportexpected_parse_resultsrrun_test_successrun_test_resultsmergedr"rr(fail_msgr,rrrrrassertRunTestResults9sR    z;pyparsing_test.TestParseResultsAsserts.assertRunTestResultsccs<|j||d dVWddS1swYdS)Nr)r-)rrrrrrassertRaisesParseExceptionxs"zApyparsing_test.TestParseResultsAsserts.assertRaisesParseExceptionrrr) rrrrrr$r&r5rr@r6rrrrTestParseResultsAssertss    ?r7N)rrrrrr7rrrrr sCr __main__selectfromrr)rcolumnsr ZtablescommandaK # '*' as column list and dotted table name select * from SYS.XYZZY # caseless match on "SELECT", and casts back to "select" SELECT * from XYZZY, ABC # list of column names, and mixed case SELECT keyword Select AA,BB,CC from Sys.dual # multiple tables Select A, B, C from Sys.dual, Table2 # invalid SELECT keyword - should fail Xelect A, B, C from Sys.dual # incomplete command - should fail Select # invalid column name - should fail Select ^^^ frox Sys.dual z] 100 -100 +100 3.14159 6.02e23 1e-12 z 100 FF z6 12345678-1234-5678-1234-567812345678 r)r)rFr)FTFrr(rr"r#r$rweakrefrrBr~rrrrPrwrrreroperatorr itertools functoolsr contextlibrr ImportErrorr_threadr threadingcollections.abcr r r r rqZ ordereddictrr%rrrrrr rrrr!enable_all_warnings__all__r version_inforrmaxsizerrr9chrrOrrrrrreversedr4rrr1r@rArZmaxintxrangerG __builtin__rfnamerrrrr6rascii_uppercaseascii_lowercaserVrtrfrUr3r printablerxrrr>r@rBrDrGr'rrCregisterr[rlrirrrrsrrErrMr-r8r5rrprr2r(r'rrPr?rTrHrFr)rOr}r0r4r3rKrJrRrQrAr&r=r7r,r?r.r6r9rr:rSrr<rIr/rNr*r1r+rLr;rrbr^rrqrpr:rurcrrrrrerkrjrrr _escapedPunc_escapedHexChar_escapedOctChar _singleChar _charRangerrYrror~r|rrrdrzrmrnrr~rrvrrrrwr`rr{rrrrrWryrYrXr7rrrgr]r}rZrgrrrar_rhrzrrr\rrrrrrrrrrrrrrrrrr r rZ selectTokenZ fromTokenidentZ columnNameZcolumnNameListZ columnSpecZ tableNameZ tableNameListZ simpleSQLrrrrrrrrrrstH                   ?]   H   D+! 'N E   KFym{VO#K,:#Dvj-D 0 $  W '*     0   0  %E &  h ~  (    "./J6  ,  PKH]rs?python3.10/site-packages/pip/_vendor/chardet/sbcharsetprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Universal charset detector code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 2001 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # Shy Shalom - original C code # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from collections import namedtuple from .charsetprober import CharSetProber from .enums import CharacterCategory, ProbingState, SequenceLikelihood SingleByteCharSetModel = namedtuple('SingleByteCharSetModel', ['charset_name', 'language', 'char_to_order_map', 'language_model', 'typical_positive_ratio', 'keep_ascii_letters', 'alphabet']) class SingleByteCharSetProber(CharSetProber): SAMPLE_SIZE = 64 SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2 POSITIVE_SHORTCUT_THRESHOLD = 0.95 NEGATIVE_SHORTCUT_THRESHOLD = 0.05 def __init__(self, model, reversed=False, name_prober=None): super(SingleByteCharSetProber, self).__init__() self._model = model # TRUE if we need to reverse every pair in the model lookup self._reversed = reversed # Optional auxiliary prober for name decision self._name_prober = name_prober self._last_order = None self._seq_counters = None self._total_seqs = None self._total_char = None self._freq_char = None self.reset() def reset(self): super(SingleByteCharSetProber, self).reset() # char order of last character self._last_order = 255 self._seq_counters = [0] * SequenceLikelihood.get_num_categories() self._total_seqs = 0 self._total_char = 0 # characters that fall in our sampling range self._freq_char = 0 @property def charset_name(self): if self._name_prober: return self._name_prober.charset_name else: return self._model.charset_name @property def language(self): if self._name_prober: return self._name_prober.language else: return self._model.language def feed(self, byte_str): # TODO: Make filter_international_words keep things in self.alphabet if not self._model.keep_ascii_letters: byte_str = self.filter_international_words(byte_str) if not byte_str: return self.state char_to_order_map = self._model.char_to_order_map language_model = self._model.language_model for char in byte_str: order = char_to_order_map.get(char, CharacterCategory.UNDEFINED) # XXX: This was SYMBOL_CAT_ORDER before, with a value of 250, but # CharacterCategory.SYMBOL is actually 253, so we use CONTROL # to make it closer to the original intent. The only difference # is whether or not we count digits and control characters for # _total_char purposes. if order < CharacterCategory.CONTROL: self._total_char += 1 # TODO: Follow uchardet's lead and discount confidence for frequent # control characters. # See https://github.com/BYVoid/uchardet/commit/55b4f23971db61 if order < self.SAMPLE_SIZE: self._freq_char += 1 if self._last_order < self.SAMPLE_SIZE: self._total_seqs += 1 if not self._reversed: lm_cat = language_model[self._last_order][order] else: lm_cat = language_model[order][self._last_order] self._seq_counters[lm_cat] += 1 self._last_order = order charset_name = self._model.charset_name if self.state == ProbingState.DETECTING: if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD: confidence = self.get_confidence() if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: self.logger.debug('%s confidence = %s, we have a winner', charset_name, confidence) self._state = ProbingState.FOUND_IT elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: self.logger.debug('%s confidence = %s, below negative ' 'shortcut threshhold %s', charset_name, confidence, self.NEGATIVE_SHORTCUT_THRESHOLD) self._state = ProbingState.NOT_ME return self.state def get_confidence(self): r = 0.01 if self._total_seqs > 0: r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) / self._total_seqs / self._model.typical_positive_ratio) r = r * self._freq_char / self._total_char if r >= 1.0: r = 0.99 return r PKH]Njƃ00Apython3.10/site-packages/pip/_vendor/chardet/universaldetector.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Universal charset detector code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 2001 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # Shy Shalom - original C code # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### """ Module containing the UniversalDetector detector class, which is the primary class a user of ``chardet`` should use. :author: Mark Pilgrim (initial port to Python) :author: Shy Shalom (original C code) :author: Dan Blanchard (major refactoring for 3.0) :author: Ian Cordasco """ import codecs import logging import re from .charsetgroupprober import CharSetGroupProber from .enums import InputState, LanguageFilter, ProbingState from .escprober import EscCharSetProber from .latin1prober import Latin1Prober from .mbcsgroupprober import MBCSGroupProber from .sbcsgroupprober import SBCSGroupProber class UniversalDetector(object): """ The ``UniversalDetector`` class underlies the ``chardet.detect`` function and coordinates all of the different charset probers. To get a ``dict`` containing an encoding and its confidence, you can simply run: .. code:: u = UniversalDetector() u.feed(some_bytes) u.close() detected = u.result """ MINIMUM_THRESHOLD = 0.20 HIGH_BYTE_DETECTOR = re.compile(b'[\x80-\xFF]') ESC_DETECTOR = re.compile(b'(\033|~{)') WIN_BYTE_DETECTOR = re.compile(b'[\x80-\x9F]') ISO_WIN_MAP = {'iso-8859-1': 'Windows-1252', 'iso-8859-2': 'Windows-1250', 'iso-8859-5': 'Windows-1251', 'iso-8859-6': 'Windows-1256', 'iso-8859-7': 'Windows-1253', 'iso-8859-8': 'Windows-1255', 'iso-8859-9': 'Windows-1254', 'iso-8859-13': 'Windows-1257'} def __init__(self, lang_filter=LanguageFilter.ALL): self._esc_charset_prober = None self._charset_probers = [] self.result = None self.done = None self._got_data = None self._input_state = None self._last_char = None self.lang_filter = lang_filter self.logger = logging.getLogger(__name__) self._has_win_bytes = None self.reset() def reset(self): """ Reset the UniversalDetector and all of its probers back to their initial states. This is called by ``__init__``, so you only need to call this directly in between analyses of different documents. """ self.result = {'encoding': None, 'confidence': 0.0, 'language': None} self.done = False self._got_data = False self._has_win_bytes = False self._input_state = InputState.PURE_ASCII self._last_char = b'' if self._esc_charset_prober: self._esc_charset_prober.reset() for prober in self._charset_probers: prober.reset() def feed(self, byte_str): """ Takes a chunk of a document and feeds it through all of the relevant charset probers. After calling ``feed``, you can check the value of the ``done`` attribute to see if you need to continue feeding the ``UniversalDetector`` more data, or if it has made a prediction (in the ``result`` attribute). .. note:: You should always call ``close`` when you're done feeding in your document if ``done`` is not already ``True``. """ if self.done: return if not len(byte_str): return if not isinstance(byte_str, bytearray): byte_str = bytearray(byte_str) # First check for known BOMs, since these are guaranteed to be correct if not self._got_data: # If the data starts with BOM, we know it is UTF if byte_str.startswith(codecs.BOM_UTF8): # EF BB BF UTF-8 with BOM self.result = {'encoding': "UTF-8-SIG", 'confidence': 1.0, 'language': ''} elif byte_str.startswith((codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE)): # FF FE 00 00 UTF-32, little-endian BOM # 00 00 FE FF UTF-32, big-endian BOM self.result = {'encoding': "UTF-32", 'confidence': 1.0, 'language': ''} elif byte_str.startswith(b'\xFE\xFF\x00\x00'): # FE FF 00 00 UCS-4, unusual octet order BOM (3412) self.result = {'encoding': "X-ISO-10646-UCS-4-3412", 'confidence': 1.0, 'language': ''} elif byte_str.startswith(b'\x00\x00\xFF\xFE'): # 00 00 FF FE UCS-4, unusual octet order BOM (2143) self.result = {'encoding': "X-ISO-10646-UCS-4-2143", 'confidence': 1.0, 'language': ''} elif byte_str.startswith((codecs.BOM_LE, codecs.BOM_BE)): # FF FE UTF-16, little endian BOM # FE FF UTF-16, big endian BOM self.result = {'encoding': "UTF-16", 'confidence': 1.0, 'language': ''} self._got_data = True if self.result['encoding'] is not None: self.done = True return # If none of those matched and we've only see ASCII so far, check # for high bytes and escape sequences if self._input_state == InputState.PURE_ASCII: if self.HIGH_BYTE_DETECTOR.search(byte_str): self._input_state = InputState.HIGH_BYTE elif self._input_state == InputState.PURE_ASCII and \ self.ESC_DETECTOR.search(self._last_char + byte_str): self._input_state = InputState.ESC_ASCII self._last_char = byte_str[-1:] # If we've seen escape sequences, use the EscCharSetProber, which # uses a simple state machine to check for known escape sequences in # HZ and ISO-2022 encodings, since those are the only encodings that # use such sequences. if self._input_state == InputState.ESC_ASCII: if not self._esc_charset_prober: self._esc_charset_prober = EscCharSetProber(self.lang_filter) if self._esc_charset_prober.feed(byte_str) == ProbingState.FOUND_IT: self.result = {'encoding': self._esc_charset_prober.charset_name, 'confidence': self._esc_charset_prober.get_confidence(), 'language': self._esc_charset_prober.language} self.done = True # If we've seen high bytes (i.e., those with values greater than 127), # we need to do more complicated checks using all our multi-byte and # single-byte probers that are left. The single-byte probers # use character bigram distributions to determine the encoding, whereas # the multi-byte probers use a combination of character unigram and # bigram distributions. elif self._input_state == InputState.HIGH_BYTE: if not self._charset_probers: self._charset_probers = [MBCSGroupProber(self.lang_filter)] # If we're checking non-CJK encodings, use single-byte prober if self.lang_filter & LanguageFilter.NON_CJK: self._charset_probers.append(SBCSGroupProber()) self._charset_probers.append(Latin1Prober()) for prober in self._charset_probers: if prober.feed(byte_str) == ProbingState.FOUND_IT: self.result = {'encoding': prober.charset_name, 'confidence': prober.get_confidence(), 'language': prober.language} self.done = True break if self.WIN_BYTE_DETECTOR.search(byte_str): self._has_win_bytes = True def close(self): """ Stop analyzing the current document and come up with a final prediction. :returns: The ``result`` attribute, a ``dict`` with the keys `encoding`, `confidence`, and `language`. """ # Don't bother with checks if we're already done if self.done: return self.result self.done = True if not self._got_data: self.logger.debug('no data received!') # Default to ASCII if it is all we've seen so far elif self._input_state == InputState.PURE_ASCII: self.result = {'encoding': 'ascii', 'confidence': 1.0, 'language': ''} # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD elif self._input_state == InputState.HIGH_BYTE: prober_confidence = None max_prober_confidence = 0.0 max_prober = None for prober in self._charset_probers: if not prober: continue prober_confidence = prober.get_confidence() if prober_confidence > max_prober_confidence: max_prober_confidence = prober_confidence max_prober = prober if max_prober and (max_prober_confidence > self.MINIMUM_THRESHOLD): charset_name = max_prober.charset_name lower_charset_name = max_prober.charset_name.lower() confidence = max_prober.get_confidence() # Use Windows encoding name instead of ISO-8859 if we saw any # extra Windows-specific bytes if lower_charset_name.startswith('iso-8859'): if self._has_win_bytes: charset_name = self.ISO_WIN_MAP.get(lower_charset_name, charset_name) self.result = {'encoding': charset_name, 'confidence': confidence, 'language': max_prober.language} # Log all prober confidences if none met MINIMUM_THRESHOLD if self.logger.getEffectiveLevel() <= logging.DEBUG: if self.result['encoding'] is None: self.logger.debug('no probers hit minimum threshold') for group_prober in self._charset_probers: if not group_prober: continue if isinstance(group_prober, CharSetGroupProber): for prober in group_prober.probers: self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, prober.get_confidence()) else: self.logger.debug('%s %s confidence = %s', group_prober.charset_name, group_prober.language, group_prober.get_confidence()) return self.result PKH]/Ppython3.10/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-310.pycnu[o ai@sdZdZedZdS)z This module exists only to simplify retrieving the version number of chardet from within setup.py and from chardet subpackages. :author: Dan Blanchard (dan.blanchard@gmail.com) z4.0.0.N)__doc__ __version__splitVERSIONrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/version.pysPKH]TޜTpython3.10/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-310.pycnu[o ai?@sDddlmZddlmZddlmZddlmZGdddeZdS))EUCKRDistributionAnalysis)CodingStateMachine)MultiByteCharSetProber)CP949_SM_MODELcs4eZdZfddZeddZeddZZS) CP949Probercs,tt|tt|_t|_|dS)N) superr__init__rr coding_smrdistribution_analyzerresetself __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/cp949prober.pyr#s  zCP949Prober.__init__cCdS)NCP949rr rrr charset_name+zCP949Prober.charset_namecCr)NKoreanrr rrrlanguage/rzCP949Prober.language)__name__ __module__ __qualname__rpropertyrr __classcell__rrrrr"s   rN) chardistributionrcodingstatemachinermbcharsetproberrmbcssmrrrrrrs    PKH]NƃYpython3.10/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-310.pycnu[o aiV@s|ddlmZididdddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-d#d.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'ddd#d(dd)dd*dd+dd,dd-dd.dd/ddd#d0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'ddd#d(dd)dd*dd+dd,dd-dd.dd/ddd#d0dd1dd2d#d3dd4ddddddddd#ddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/ddd#d0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'dddd(d#d)dd*dd+dd,dd-dd.dd/ddd#d0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2d#d3dd4dddddddddddddd5 d iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/ddd#d0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'dddd(dd)dd*d#d+dd,dd-dd.dd/ddd#d0dd1dd2dd3dd4ddddddddd#ddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'ddd#d(dd)dd*d#d+dd,dd-dd.dd/ddd#d0dd1dd2dd3dd4d#ddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/d#ddd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/ddd#d0dd1d#d2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/ddd#d0dd1dd2dd3dd4dddddddddddddd5 ididdddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'ddd#d(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3d#d4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'ddd#d(dd)dd*dd+dd,dd-dd.dd/ddd#d0dd1dd2dd3dd4ddddddddd#ddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3d#d4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3d#d4dddddddddddddd5 d!iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 d"iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 d#iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$d#d%d#id&d#d'd#dd#d(d#d)d#d*d#d+d#d,d#d-d#d.d#d/d#ddd0d#d1d#d2d#d3d#d4d#dd#d#d#d#d#ddddd#d#d5 d$iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'ddd#d(dd)dd*d#d+dd,dd-d#d.dd/d#dd#d0dd1d#d2d#d3dd4d#dddddd#dd#dddd#d5 d%iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'd#dd#d(dd)d#d*d#d+dd,d#d-d#d.dd/d#dd#d0d#d1d#d2d#d3d#d4d#ddddd#ddd#d#ddd#d5 id&iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'd#dd#d(dd)dd*d#d+dd,dd-d#d.dd/d#dd#d0dd1d#d2dd3dd4d#ddddddddddddd5 d'iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%d#id&dd'ddd#d(dd)dd*d#d+dd,d#d-d#d.dd/d#dd#d0dd1d#d2d#d3d#d4d#ddd#ddddd#d#ddd#d5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$d#d%d#id&d#d'd#dd#d(d#d)d#d*dd+d#d,d#d-d#d.d#d/d#dd#d0d#d1d#d2d#d3d#d4ddd#d#d#d#d#dddddd#d5 d(iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'd#dd#d(dd)dd*d#d+dd,dd-dd.dd/d#ddd0dd1dd2dd3dd4d#ddddddddddddd5 d)iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$d#d%d#id&d#d'd#dd#d(dd)dd*d#d+dd,d#d-d#d.d#d/d#dd#d0dd1d#d2dd3dd4d#dddddddd#dddd#d5 d*iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$d#d%d#id&d#d'd#dd#d(d#d)d#d*d#d+d#d,d#d-d#d.d#d/d#dd#d0d#d1d#d2d#d3d#d4ddd#d#d#d#d#ddddd#d#d5 d+iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'd#ddd(dd)dd*dd+dd,dd-dd.dd/d#ddd0dd1dd2d#d3d#d4ddddd#ddddddddd5 d,iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%d#id&dd'ddd#d(dd)dd*d#d+dd,dd-d#d.dd/d#dd#d0dd1d#d2d#d3d#d4d#ddddddddddddd5 d-iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&d#d'ddd#d(d#d)dd*d#d+dd,d#d-d#d.dd/d#dd#d0dd1dd2d#d3dd4d#dddd#dddd#d#dd#d#d5 d.iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'ddd#d(dd)dd*d#d+dd,dd-d#d.dd/d#dd#d0dd1dd2d#d3dd4d#dddddddd#dddd#d5 d/iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&d#d'd#dd#d(dd)dd*d#d+dd,d#d-dd.dd/d#dd#d0dd1dd2d#d3d#d4d#ddd#d#dddd#d#dd#d#d5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$d#d%d#id&d#d'd#dd#d(d#d)d#d*d#d+d#d,d#d-d#d.d#d/d#dd#d0d#d1d#d2d#d3d#d4ddd#dd#d#d#ddddd#d#d5 d0iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'ddd#d(dd)dd*d#d+dd,dd-d#d.dd/d#dd#d0dd1d#d2dd3dd4d#dddddddd#dddd#d5 d1iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%d#id&d#d'd#dd#d(d#d)dd*d#d+dd,d#d-dd.d#d/d#dd#d0dd1dd2d#d3d#d4d#dd#ddd#ddd#d#ddd#d5 d2iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%d#id&dd'd#dd#d(dd)dd*d#d+dd,d#d-d#d.d#d/d#dd#d0d#d1d#d2d#d3d#d4d#dd#dd#dddd#d#dd#d#d5 d3iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%d#id&dd'ddd#d(dd)dd*d#d+dd,d#d-d#d.dd/d#dd#d0dd1d#d2d#d3dd4d#dddddddd#d#ddd#d5 d4iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$d#d%d#id&d#d'd#dd#d(d#d)d#d*dd+dd,d#d-d#d.d#d/d#ddd0d#d1d#d2d#d3d#d4ddd#dd#d#d#ddddd#dd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'ddd#d(dd)dd*d#d+dd,dd-dd.dd/ddd#d0dd1dd2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%d#id&dd'dddd(dd)dd*d#d+dd,dd-dd.dd/d#dd#d0dd1d#d2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'ddd#d(dd)dd*d#d+dd,dd-dd.dd/ddd#d0dd1dd2dd3dd4d#dddddddd#ddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'ddd#d(dd)dd*d#d+dd,d#d-dd.dd/d#ddd0dd1dd2dd3d#d4d#ddddddddd#dddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'ddd#d(dd)dd*d#d+dd,d#d-d#d.dd/d#dd#d0dd1dd2dd3dd4d#ddddddddd#dddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#d#d$dd%did&dd'ddd#d(dd)dd*d#d+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$d#d%d#id&dd'ddd#d(dd)dd*dd+d#d,d#d-d#d.d#d/d#ddd0d#d1d#d2d#d3d#d4ddd#dd#d#dddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'ddd#d(dd)d#d*dd+dd,d#d-dd.d#d/d#ddd0dd1dd2d#d3dd4dddddd#dddddd#d#d5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd'dddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2dd3d#d4dddddddddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$d#d%did&dd'd#ddd(dd)dd*dd+dd,dd-dd.dd/dddd0dd1dd2d#d3d#d4ddddddd#ddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%d#id&dd'd#dd#d(d#d)d#d*dd+dd,d#d-d#d.d#d/d#ddd0dd1dd2d#d3d#d4ddd#dddd#ddddddd5 d5 Zidd6dd6dd6d#d6d*d6d/d6d3d6d2d6d-d6d1d6d%d7d,d6d.d6d'd7d4d6d0d6d8d6id9d6d:d6d&d6d)d6d$d6d;d6d+d6d(d6dd6d?d6d@d6dAd6dd6ddBddBiddBddBd dBddBddBdCdBddBddBd dBd"dBddBddBddBd dBddDddDddDid dDddDddDdEdDddDd dDddDddBd!dBd dBddBddBddBdFdBdGdHdIdJdKdLidMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]dYd^d_d`d[dadbdcdddedfdgdhdidjdkdlidmdndodpdqdrdsdtdudvdwdxdydBdzdBd{dBd|dBd}dBd~dBddSddddIddddGidddd]ddddFdddddd^ddUddddOddKdddd`ddWddddddaiddddddddddBddBddBddBddBdddddddddddddd dd idd dd dd dddddddHddJddLddNddPddRddTddVddXddZdd\did_ddbdQddddfddhd djd!dld"dnd#dpd$drd%dtd&dvd'dxddd(dd)dd*dd+idd,dd-dd.dd/dddd0dddddd“ddÓddēddœddƓddǓddȓddɓdd˓idd͓ddϓddѓddӓddԓddՓdd֓ddדddؓddٓddړddۓddܓddݓddޓddߓddiddddddddddddddddddddddddddddddddddidddddddd1dd2dd3dd4ddCdd=dd?dd;dd<dd@ddEdd:dd9ddAidd>dd8ddddMdddddddddddddddddddddDddBdd7dDd6d6iZeddeeddddZidd6dd6dd6d#d6d*d6d/d6d3d6d2d6d-d6d1d6d%d7d,d6d.d6d'd7d4d6d0d6d8d6id9d6d:d6d&d6d)d6d$d6d;d6d+d6d(d6dd6d?d6d@d6dAd6dd6ddBddBiddBddBd dBddBddBdCdBddBddBd dBd"dBddBddBddBd dBddDddDddDid dDddDddDdEdDddDd dDddDddBd!dBd dBddBddBddBdFdBdGdHdIdJdKdLidMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]dYd^d_d`d[dadbdcdddedfdgdhdidjdkdlidmdndodpdqdrdsdtdudvdwdxdydBdzdBd{dBd|dBd}dBd~dBddSddddIddddGidddd]ddddFdddddd^ddUddddOddKdddd`ddWddddddaiddddddddddBddBddBddBddBdddddd“ddÓddēddœddƓddǓiddȓddɓdd˓dd͓ddϓddѓdHdӓdJdԓdLdՓdNd֓dPdדdRdؓdTdٓdVdړdXdۓdZdܓd\dݓid_dޓdbdߓddddfddhddjddlddnddpddrddtddvddxdddddddddiddddddddddddddddddddddddddddddMddddidddΐddАdddDddBdddddddddddddd dd dd dd dd ddiddddddddddddddddddddddddddddddQddddidd dd!dd"dd#dd$dd%dd&dd'dddd(dd)dd*dd+dd,dd-dd.dd/idddd0dd1dd2dd3dd4ddCdd=dd?dd;dd<dd@ddEdd:dDd9dBdAd7d>d6d8iZeddeeddddZidd6dd6dd6d#d6d*d6d/d6d3d6d2d6d-d6d1d6d%d7d,d6d.d6d'd7d4d6d0d6d8d6id9d6d:d6d&d6d)d6d$d6d;d6d+d6d(d6dd6d?d6d@d6dAd6dd6ddBddBiddBddBd dBddBddBdCdBddBddBd dBd"dBddBddBddBd dBddDddDddDid dDddDddDdEdDddDd dDddDddBd!dBd dBddBddBddBdFdBdGdHdIdJdKdLidMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]dYd^d_d`d[dadbdcdddedfdgdhdidjdkdlidmdndodpdqdrdsdtdudvdwdxdydBdzdBd{dBd|dBd}dBd~dBddSddddIddddGidddd]ddddFdddddd^ddUddddOddKdddd`ddWddddddaiddddddddddBddBddBddBddBdddddd“ddÓddMddēddœddƓiddǓddȓddɓdd˓dd͓ddϓdHdѓdJdӓdLdԓdNdՓdPd֓dRdדdTdؓdVdٓdXdړdZdۓd\dܓid_dݓdbdޓdddߓdfd>dhd!djdEdldQdnd#dpddrd$dtddvd?dxddd'ddddddiddCdddd&dddddddddddddddddd=dddd*dd ddddidddddd+dd dddddddddddddddd,dd ddddddddidddddddddd-dddd.dddd/dddddddd0ddddddddidddd8dddd"dd1dddd2dddd3dddd4dddd(dd dd%dddd9idddddddd:dddd)dd dd<ddddAdd dd@dddd;dDddBdd7dDd6d6iZed deeddddZidd6dd6dd6d#d6d*d6d/d6d3d6d2d6d-d6d1d6d%d7d,d6d.d6d'd7d4d6d0d6d8d6id9d6d:d6d&d6d)d6d$d6d;d6d+d6d(d6dd6d?d6d@d6dAd6dd6ddBddBiddBddBd dBddBddBdCdBddBddBd dBd"dBddBddBddBd dBddDddDddDid dDddDddDdEdDddDd dDddDddBd!dBd dBddBddBddBdFdBdGdHdIdJdKdLidMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]dYd^d_d`d[dadbdcdddedfdgdhdidjdkdlidmdndodpdqdrdsdtdudvdwdxdydBdzdBd{dBd|dBd}dBd~dBddSddddIddddGidddd]ddddFdddddd^ddUddddOddKdddd`ddWddddddaiddddddddddBddBddBddBddBdddddd“ddÓddēddœddƓddǓiddȓddɓdd˓dd͓ddϓddѓdHdӓdJdԓdLdՓdNd֓dPdדdRdؓdTdٓdVdړdXdۓdZdܓd\dݓid_dޓdbdߓddddfddhddjddlddnddpddrddtdMdvddxdddddddddiddddddddddddddddddddddddddddddddddidddΐddАdddDddBdd>dd#dd$dd?dd'ddddCdd&dd=dd*dd+dd,idd-dd.dd/dddd0dd8dd1dd2dd3dd4dd(dd%dd9dd:dd)dd<ddAidd@dd;ddEdd!dddddddddddddddddd dd dd ddddidddddddd"dddddddddd dddddddd dddDd dBdd7dd6dQiZ ed de eddddZ idd6dd6dd6d#d6d*d6d/d6d3d6d2d6d-d6d1d6d%d7d,d6d.d6d'd7d4d6d0d6d8d6id9d6d:d6d&d6d)d6d$d6d;d6d+d6d(d6dd6d?d6d@d6dAd6dd6ddBddBiddBddBd dBddBddBdCdBddBddBd dBd"dBddBddBddBd dBddDddDddDid dDddDddDdEdDddDd dDddDddBd!dBd dBddBddBddBdFdBdGdHdIdJdKdLidMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]dYd^d_d`d[dadbdcdddedfdgdhdidjdkdlidmdndodpdqdrdsdtdudvdwdxdydBdzdBd{dBd|dBd}dBd~dBddSddddIddddGidddd]ddddFdddddd^ddUddddOddKdddd`ddWddddddaiddddddddddBddBddBddBddBdddddddddddddd dd idd dd dd dddddddHddJddLddNddPddRddTddVddXddZdd\did_ddbdQddddfddhd djd!dld"dnddpddrd“dtdÓdvdēdxdœddƓddǓddȓddɓidd˓dd͓ddϓddѓddӓddԓddՓdd֓ddדddؓddٓddړddۓddܓddݓddޓddߓiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddDddMdd8dd#dd$dd%dd&dd'dddd(dd)dd*dd+dd,dd-dd.dd/idddd0dd1dd2dd3dd4ddCdd=dd?dd;dd<dd@ddEdd:dDd9dBdAd7d>d6d6iZ ed de eddddZ idd6dd6dd6d#d6d*d6d/d6d3d6d2d6d-d6d1d6d%d7d,d6d.d6d'd7d4d6d0d6d8d6id9d6d:d6d&d6d)d6d$d6d;d6d+d6d(d6dd6d?d6d@d6dAd6dd6ddBddBiddBddBd dBddBddBdCdBddBddBd dBd"dBddBddBddBd dBddDddDddDid dDddDddDdEdDddDd dDddDddBd!dBd dBddBddBddBdFdBdGdHdIdJdKdLidMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]dYd^d_d`d[dadbdcdddedfdgdhdidjdkdlidmdndodpdqdrdsdtdudvdwdxdydBdzdBd{dBd|dBd}dBd~dBddSddddIddddGidddd]ddddFdddddd^ddUddddOddKdddd`ddWddddddaiddddddddddBddBddBddBddBdddddd“ddÓddēddœddƓddǓiddȓddɓdd˓dd͓ddϓddѓdHdӓdJdԓdLdՓdNd֓dPdדdRdؓdTdٓdVdړdXdۓdZdܓd\dݓid_dޓdbdߓddddfddhddjddlddnddpddrddtddvddxdddddddddidddddddddddddddddddddddddd dd dd dd dd iddddddddddddddddddddddddddddddddQddidddd dd!dd"dd#dd$dd%dd&dd'dddd(dd)dd*dd+dd,dd-dd.idd/dddd0dd1dd2dd3dd4ddCdd=dd?dd;dd<dd@ddEdd:dd9ddAidd>dd8ddddMdddddddddddddddddddddDddBdd7dDd6d6iZ ed de eddddZd S()SingleByteCharSetModel%,!.)083*<$1&"#- (457:29?>=/;+     ) '6rAr>r=r9r:r7r@r8r;r?r6r<@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~IBM866RussianglP@?FuЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё) charset_namelanguagechar_to_order_maplanguage_modeltypical_positive_ratiokeep_ascii_lettersalphabetz windows-1251IBM855zKOI8-R MacCyrillicz ISO-8859-5N)#pip._vendor.chardet.sbcharsetproberrRUSSIAN_LANG_MODELIBM866_RUSSIAN_CHAR_TO_ORDERIBM866_RUSSIAN_MODEL"WINDOWS_1251_RUSSIAN_CHAR_TO_ORDERWINDOWS_1251_RUSSIAN_MODELIBM855_RUSSIAN_CHAR_TO_ORDERIBM855_RUSSIAN_MODELKOI8_R_RUSSIAN_CHAR_TO_ORDERKOI8_R_RUSSIAN_MODEL!MACCYRILLIC_RUSSIAN_CHAR_TO_ORDERMACCYRILLIC_RUSSIAN_MODEL ISO_8859_5_RUSSIAN_CHAR_TO_ORDERISO_8859_5_RUSSIAN_MODELrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/langrussianmodel.pysh       !"#$%&'()*+,-./01234B      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234E      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234H      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234K      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234N      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Q      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234T      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234W      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Z      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234]      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234`      !"#$%&'()*+,-./01234"      !"#$%&'()*+,-./01234c      !"#$%&'()*+,-./01234%      !"#$%&'()*+,-./01234f      !"#$%&'()*+,-./01234(      !"#$%&'()*+,-./01234i      !"#$%&'()*+,-./01234+      !"#$%&'()*+,-./01234l      !"#$%&'()*+,-./01234.      !"#$%&'()*+,-./01234o      !"#$%&'()*+,-./012341      !"#$%&'()*+,-./01234r      !"#$%&'()*+,-./012344      !"#$%&'()*+,-./01234u      !"#$%&'()*+,-./012347      !"#$%&'()*+,-./01234x      !"#$%&'()*+,-./01234:      !"#$%&'()*+,-./01234{      !"#$%&'()*+,-./01234=      !"#$%&'()*+,-./01234~      !"#$%&'()*+,-./01234@      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234C      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234F      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234I      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234L      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234)      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~PKH]SXpython3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-310.pycnu[o aiU @s0ddlmZddlmZmZGdddeZdS)) CharSetProber) ProbingState MachineStatecsVeZdZdZdfdd ZfddZeddZed d Zd d Z d dZ Z S)MultiByteCharSetProberz MultiByteCharSetProber Ncs,tt|j|dd|_d|_ddg|_dS)N) lang_filter)superr__init__distribution_analyzer coding_sm _last_char)selfr __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/mbcharsetprober.pyr 'szMultiByteCharSetProber.__init__cs<tt||jr|j|jr|jddg|_dS)Nr)rrresetr r r r rrrr-s   zMultiByteCharSetProber.resetcCtNNotImplementedErrorrrrr charset_name5z#MultiByteCharSetProber.charset_namecCrrrrrrrlanguage9rzMultiByteCharSetProber.languagecCstt|D]X}|j||}|tjkr&|jd|j|j |t j |_ n9|tj kr1t j|_ n.|tjkr^|j}|dkrO|d|jd<|j|j|q|j||d|d|q|d|jd<|jt jkr||jr|||jkr|t j|_ |jS)Nz!%s %s prober hit error at byte %srr)rangelenr next_staterERRORloggerdebugrrrNOT_ME_stateITS_MEFOUND_ITSTARTget_current_charlenr r feedstate DETECTINGgot_enough_dataget_confidenceSHORTCUT_THRESHOLD)r byte_stri coding_statechar_lenrrrr(=s4       zMultiByteCharSetProber.feedcCs |jSr)r r,rrrrr,Zs z%MultiByteCharSetProber.get_confidencer) __name__ __module__ __qualname____doc__r rpropertyrrr(r, __classcell__rrrrr"s   rN) charsetproberrenumsrrrrrrrs PKH]˯JJSpython3.10/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-310.pycnu[o aiP@sdZdZdZdS)g?i(iiii< iTii iQii i iii<iw ii9 i iiiiZ iiiqi i i iW iyiiieioiiv ii i iiii iLiBi iQ iiiQiiiEiifiiiiiiiidi( iyiii,i i i iE iei iWiRiii| iR ii i i iX i ijiEii i+iPiiiii;iim iiliiii iieiHiiiii^ iki6ii" Fi i i i i^ i i iii?i`iui$i1i ii i iUi i1 iiigiliii iiGii2iiq i i iPiiL iiiiiy ii i iMiikii4 iiiiii i i@ i`ii5iiN ii7i3iiniiuiGi&ibihi0i iM iNii i iY i ii ii &i iQi i7i^ihiiiJ iiPiiiiriiiiiiiT i-iGi,iui i ii$iii<iBii$i>iiix iLiWiiini iiTiiZii i i{ iii i ii i?i 0ibi;DiiiiCiSiiUi> i|igi ii i iKi iiii% i5 iiiiil iihi iii?i iUiii ii*i< i i ii i iii ii i! iX iii iiQ igiiii iiri ii iqii iiz ii i3i iii i i]iciziii7 ii_ii iCii&iaiHi| ili ii=iiiIiPi ii~ i8i`i iw i i iTii i iiii iiiii[iq ii igi|iCi ii iN iIiii5 i i(ii/iHiK i iiii9iiIiii|iii i iWii iii^~iiii i i= iXii3i iIiii iiii3iriioi ii i{iiiiC!iHi iifi= ii1[i i| iDii%iitii i ii ii.iiyiiTiii9 i i i#iiJiniiii ii>iBi"iiiai iiMiKi iW i i i i! ir iFi+ i i i iix HiJiiii2KiiR i$ii9i it ii ii iiiiiiiii%i~i i` iiii'iviii ii|i'i iin i*ii iiFii%i)i~ii iiiJi&ii i!iD iiwii[i ii i i i' i ikiii i i iiiiiih Bi_i i?iigihii'iiiiiiiiiiii5i] ii iiiiiii1 ii)ia iiiii; iii_iiQi/iu i i iji[ii}ii iii iiiiQi^ i iGiizi iiiViOii ii ii imiui i6ii i-i$i iiRii} i ipir i] i iDi iiiiiiiiiiii1iniiiitiYiG i i i/ i|ti0i iiiii\i i iivii iiciiii i~iAi"ii" i!i8Ci8 ii iji i1iili>i ii] i i i~iLi(iiiKidviDiiii%i iii i, i2ii iiij -i.i imiKi iioi i;i ii idi@iai iM i1 iLi@i2 iiwiitiQi i/ii ii~iiiii i/ii i_ i#i OiiOiGiiki[iOioii- i ii i!i i iIiiii{iri i.ihi i iT iii'iL aii i@ii iii iT i/ iiiii iiMiii il iii i{i8i#i iii9iiSiRi wiiZii0 iEigig ii iLiiipiiiSi iiiii i@iiI iLi; iOiqiii) i i:iFii5iJidiA ii i) iEiLYiiii im i ii i iiic iiRii!iiii i(iii]Iii i iieiiii iii`ii iii ii[iiC i(iPi,i i}iO i' iLi\ i i i iiiiZiiisi'i iUiiiiiN iii i iiMiiiiii iiiiigi'iii ii Pi0 is iiiip i iniiii i\i iii i!ihimi(i& i iCiiBi)i5 iiiiii ii>iii i i{iNiiiiEi3Ji#iicii ii$ i5iixi i]iiiki iiiiP ii iiiriiL i izidiii#i iii[ iSiihiiGiiiii iU+i iyiwi"iiVi2 i&izi i iiJ iP i iiii% iZi$ io iT iKi1 i ii`iVi ii id i iii+i iiAii iiii$ii i_i3i\ iiiibi ifiiii iAiniixiFi iOi[ii(i ii i#i7i2 ixiif i i i!i6i{ iiYiii+iiiii iiii i iKiei i i iTi$iiiih ii iRiii"i iZi i_ ii@iiai iii3 i iki)ijiii ieii iA i^ii iW iiihi: iz i) ii| iii ii i8 iji iii3i i iziipiyi i i2 ioiD i=i.ii9 iaifii*i_ii i*ii i i ii i- ii i}ii i ii* i ititi6 qiiiiiii iSi iii!i)iiyi ii ij ii iiViIiiig iiiLii iipiDii i ii%ii iM iiii$i i iiE i"iU iie i i|i iQiii ii ii i1 iiii$i i]i4i&iiiziii`iiwi iiii i)i% i&iiii*iii8i2i> iSi iii1i#i ii ii#i i iiii iF iii, i> i+i i iiZ 3iqi i$ii iVi i;iiiNimiKiWiii5i i Ri4i iIiiDiiii i i i iiii%iKi|iii iii9iin iii i-i3 i2 ipii? ii~iiiiiiCii[ii iii i3 i> iili i`ix iiii i# iiii0iii iL i iiQiiRii?i(imii` ii3iiii& i ii isiDii0 ib ifi@ i iii ii=i i i<iii ii6iiis iii iSiii i8iZ iii ii iii i ii iiiiNi i i iLi iJ iii ibiig iii[ iiiiii~ ii i iiifiiiii i i` i4i= iiiili? iici ii iiii iiiiiiiiwiii i%ii id i^i+iii iZiF iI iit i /i iiiyi* isi&i+iii) iii iii i i ie iiiQi] ii i_i7 ii0ciuiiiLiki iiii#iiiiiii?iii ini i iii iii iHiiYiiu ii i iiJii_ i_i&iiii iiiZi%i isiiSii i iViiiiii1i'iiFi\i i|i iWiii|iSWi i* i iRiliPi#i i i-iq ii i ii4iiiiiia iiiii@ i iXiii%iii8 i3i,ii} iiidixi ii# ii6i i i.iiiAi iir i i iR idiii+ iiii i{i{iHi i iiiiiici i i iii,iiI iici ii iii=i iJi. i,i>iiiiLiei]ii iC iiii*i; i ii iipi iiiRii9 i i ii iii?i:i i i iQi'isiiwi[i ii-i i)iiMiiiii]}i6i@i iiUiiii/iiis i iiik i? ii, i= i1iMi iii/iS id iio i6 ikiui iiiW{iixiWii iiiix i^ ii[ i+ 7i:iiU iii!iii i.iHiTiiYiii ii@i"iCisi i i iG bii7i~i. iUi iqi iiii{iiiYi/i iiiAi ii*i:i8i'i i ii iiA i_i0iiiiiiiiKi i iit i* iii iiii i i iiDiiii>iiivii i i'iViii iiikii i\iiii!i i*iU iiiiiizii\if iii i iii iiii i iiB iii iii{i=i i&i iiV i i"i! i i iii i( i=ii i ii9i ii4iaii-iQ i ii imiiiiiCiii7i}iqiDi4iuii iiiv iiiF iiu ia iiH ioi i iliKiA iii izi4 i i! iH ii i5 iijii`ii iB i:iOiai i#iiidii(i i& ii^imig iE iio ii(iG i$i@i iIiiiAi i`Xii7ii/ii$ii iihiiii iUi"iTiiiimii!iiiiii iiMi iii 2iqii9iii iiii/iii pi@iX iijii i^ ibi i iniiviiioioiiviii0ii9ii$ iifiS izi iiDi{iiXii iVi3 iYi ii iAiiiiiqiU i i: ii2iji ii i{ ii iFi i i ii iiiciiiR i;ik hii i iiY iOixiziZi<iv ii i i iiIiii4 iMiiiiib iiii ii iiCii iiiO ii8iii i.i]i iVic i iii iH iiTiii ii> i ii i3ii,iiifiiiiliTiWiHi.i'i>ipiiii"ii iJii i ivi2iii ixi i2iigi i4iii i iii{ iz i i i iii iiiiii?iii iJiiii i i8iE ij \ii8i8 ii iii`ii>ibiSiii i iii0i iiiEi iidiiii1iiin@ii iiTii iiQiCii iK i;ikiiiiii_i\ ieiiwiiiiiMii. iriaiii i ii iiiigii i' i iii i Tiii4ioii iXiyiixii i i iU ^i: iiii ii"i#iii ii iiiiNiUiiip i" i-i i ii:ii ii iiii iiW i iG iLii iGiw oiii iMir ii iiQ iiI iN%i iXiii i7 i iaii ii i' iiihi i}iNiyi?itii iD iiii liiii iie iJisi2i*iyiiiiii iiqi ii5i}is i$iiii5 iBiii# idisi} ii~iiib iiO i/ ]iii i]i2iifi7iiiOi iRii# i i[iEii if iS i idiFiiiC iV i>ii iiBii i i1i6imii iiiip i ii i i<izi i| iXiiisie i]iii i iiOi i+i iiiiii:i iAii ii ii( i imi4iP i inii ioioiiimiiyii8i i<iii<ic iC iii&iwi i i$i i9i&ii i)i`iiiiiiGibiEii:iQio iF i iii i iFi|i;i iii3i4 i%i:i iciipi6 i\iCii0i9 ii iiii~ iii"ih iiii i)ii i iii* ii i i i%ii iiii i.iii9i iii iii ii"i! ii, i ig iJ igiF iiii ii;ii iZiEi^iA iiili5ii ii4i' iiiki ii i2ii ii iXi7ii i{iiBixi=ei(i iii'iiiiiiiiii iD iiikii iii-i, i iei7 i ii iiini} ip i7ijii ii9ii iii0iPi iiiiiO i i i iUi iii< iii iJiitiNii)i i.ii*i iAir i] i)iiiiiGii_ ipik iii i% i ii ii>ibi_i^?ii:iYiDi%ii iiiiiYii i iiiiil Aii i i iDiBi i ii i@ i(iv iiigi i i}iviiii iiiii iiiiiiii i-i~iiy i%i i _i iiiiijiMi iiGi+i iii iiii3 i;i Gi)ii iii i ii ii i ii,iIi iii iXiAi\iiiP ivii iVii=i i i6 i<iiX i i i ii8 i- iY iiiii iiciiii9i i- iuii ii iR i i ii6ii iih i}i i? iw i ii ia i( i i1ii ii>iii i ii]i iXiriPi0 i,ii+ ijii`iiiii. iii ii& iWiB iii|i7 Uii iWiiYii iiw i iii iiiiiuiibiiq iiibiii =i$ iiNiJiiiUiiii iiiiKi,iii4iri{i iiHiipi5iii=i i iEi9ii;i <ii5i iii ii\iiipiiiiriNiii^iiiiiK ii i*ii{ i+ i ii*i8iiii iiii ij ii@il 6ii2i8ii iiii'iiiiB iiii\iiiS iV ii~iiiii i iiVi iz i i^i i iii_ i} iG iqiI i ii8itihiS ii}iRi i9Sin iPiiB iiisiiXi}ifiiii iiiiiin iIi^iTiixiiriii_ibiiOiPiQiRiSN)!GB2312_TYPICAL_DISTRIBUTION_RATIOGB2312_TABLE_SIZEGB2312_CHAR_TO_FREQ_ORDERrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/gb2312freq.pys)PKH]aj2 2 Xpython3.10/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-310.pycnu[o ai@sNddlmZddlmZddlmZmZmZedgdZGdddeZ d S) ) namedtuple) CharSetProber)CharacterCategory ProbingStateSequenceLikelihoodSingleByteCharSetModel) charset_namelanguagechar_to_order_maplanguage_modeltypical_positive_ratiokeep_ascii_lettersalphabetcsbeZdZdZdZdZdZdfdd Zfd d Ze d d Z e d dZ ddZ ddZ ZS)SingleByteCharSetProber@igffffff?g?FNcsJtt|||_||_||_d|_d|_d|_d|_ d|_ | dSN) superr__init___model _reversed _name_prober _last_order _seq_counters _total_seqs _total_char _freq_charreset)selfmodelreversed name_prober __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/sbcharsetprober.pyr3s z SingleByteCharSetProber.__init__cs:tt|d|_dgt|_d|_d|_d|_ dS)Nr) rrrrrget_num_categoriesrrrrrr"r$r%rAs  zSingleByteCharSetProber.resetcC|jr|jjS|jjSr)rr rr(r$r$r%r Kz$SingleByteCharSetProber.charset_namecCr)r)rr rr(r$r$r%r Rr*z SingleByteCharSetProber.languagec CsF|jjs ||}|s|jS|jj}|jj}|D]L}||tj}|tj kr-|j d7_ ||j kra|j d7_ |j |j kra|jd7_|jsQ||j |}n|||j }|j|d7<||_ q|jj}|jtjkr|j|jkr|}||jkr|jd||tj|_|jS||jkr|jd|||jtj|_|jS)Nrz$%s confidence = %s, we have a winnerz9%s confidence = %s, below negative shortcut threshhold %s)rrfilter_international_wordsstater r getr UNDEFINEDCONTROLr SAMPLE_SIZErrrrrr r DETECTINGSB_ENOUGH_REL_THRESHOLDget_confidencePOSITIVE_SHORTCUT_THRESHOLDloggerdebugFOUND_IT_stateNEGATIVE_SHORTCUT_THRESHOLDNOT_ME) rbyte_strr r charorderlm_catr confidencer$r$r%feedYsJ        zSingleByteCharSetProber.feedcCsLd}|jdkr$d|jtj|j|jj}||j|j}|dkr$d}|S)Ng{Gz?rg?gGz?)rrrPOSITIVErr rr)rrr$r$r%r3s z&SingleByteCharSetProber.get_confidence)FN)__name__ __module__ __qualname__r0r2r4r9rrpropertyr r r@r3 __classcell__r$r$r"r%r-s   0rN) collectionsr charsetproberrenumsrrrrrr$r$r$r%s   PKH]YxxUpython3.10/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-310.pycnu[o ai@s^ddlmZddlmZdZdZdZdZdZdZ dZ dZ d Z d Z geeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee eeeeeee ee ee eeeeeeeeeeee ee ee e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee e e e e e e e e e e e e e e e e e e e e e e ee e e e e e e e e e e e e e e e e e e e e e e e e e e e e e e ee e e e e e e e RZd ZGd d d eZdS)) CharSetProber) ProbingState)@rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrcsLeZdZfddZddZeddZeddZd d Zd d Z Z S) Latin1Probercs&tt|d|_d|_|dS)N)superr __init___last_char_class _freq_counterresetself __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/latin1prober.pyras zLatin1Prober.__init__cCs t|_dgt|_t|dS)Nr)OTHr FREQ_CAT_NUMrrrrrrrrgs zLatin1Prober.resetcCdS)Nz ISO-8859-1rrrrr charset_namelzLatin1Prober.charset_namecCr)NrrrrrlanguageprzLatin1Prober.languagecCsd||}|D]'}t|}t|jt|}|dkr"tj|_|j S|j|d7<||_q|j S)Nrr) filter_with_english_lettersLatin1_CharToClassLatin1ClassModelr CLASS_NUMrNOT_ME_staterstate)rbyte_strc char_classfreqrrrfeedts  zLatin1Prober.feedcCs\|jtjkrdSt|j}|dkrd}n|jd|jdd|}|dkr(d}|d}|S)Ng{Gz?grrg4@g\(\?)r%rr#sumr)rtotal confidencerrrget_confidences  zLatin1Prober.get_confidence) __name__ __module__ __qualname__rrpropertyrrr*r. __classcell__rrrrr `s   r N) charsetproberrenumsrrUDFrASCASSACVACOASVASOr"r r!r rrrrs                                                  ' PKH]phSpython3.10/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-310.pycnu[o ai@sDddlmZddlmZddlmZddlmZGdddeZdS))MultiByteCharSetProber)CodingStateMachine)Big5DistributionAnalysis) BIG5_SM_MODELcs4eZdZfddZeddZeddZZS) Big5Probercs,tt|tt|_t|_|dS)N) superr__init__rr coding_smrdistribution_analyzerresetself __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/big5prober.pyr#s  zBig5Prober.__init__cCdS)NBig5rr rrr charset_name)zBig5Prober.charset_namecCr)NChineserr rrrlanguage-rzBig5Prober.language)__name__ __module__ __qualname__rpropertyrr __classcell__rrrrr"s   rN) mbcharsetproberrcodingstatemachinerchardistributionrmbcssmrrrrrrs    PKH]zӦUpython3.10/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-310.pycnu[o ai@sDddlmZddlmZddlmZddlmZGdddeZdS))MultiByteCharSetProber)CodingStateMachine)GB2312DistributionAnalysis)GB2312_SM_MODELcs4eZdZfddZeddZeddZZS) GB2312Probercs,tt|tt|_t|_|dS)N) superr__init__rr coding_smrdistribution_analyzerresetself __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/gb2312prober.pyr"s  zGB2312Prober.__init__cCdS)NGB2312rr rrr charset_name(zGB2312Prober.charset_namecCr)NChineserr rrrlanguage,rzGB2312Prober.language)__name__ __module__ __qualname__rpropertyrr __classcell__rrrrr!s   rN) mbcharsetproberrcodingstatemachinerchardistributionrmbcssmrrrrrrs    PKH]!ɝTpython3.10/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-310.pycnu[o ai@sDddlmZddlmZddlmZddlmZGdddeZdS))MultiByteCharSetProber)CodingStateMachine)EUCKRDistributionAnalysis)EUCKR_SM_MODELcs4eZdZfddZeddZeddZZS) EUCKRProbercs,tt|tt|_t|_|dS)N) superr__init__rr coding_smrdistribution_analyzerresetself __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/euckrprober.pyr#s  zEUCKRProber.__init__cCdS)NzEUC-KRrr rrr charset_name)zEUCKRProber.charset_namecCr)NKoreanrr rrrlanguage-rzEUCKRProber.language)__name__ __module__ __qualname__rpropertyrr __classcell__rrrrr"s   rN) mbcharsetproberrcodingstatemachinerchardistributionrmbcssmrrrrrrs    PKH] J/J/Rpython3.10/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-310.pycnu[o ai4@sdZdZdZdS)g@0 (0 xitiiiiHiaiiii+iWiuihii]iiiiiiiiiiiviwiiiimiFi!ipii iiiiiixi/iiiiiiii9iiitii-iyiKiiiiiiOiiniiiiiii0i<i4{iiiiiiiiiriiiiiiiiiiiiXiXiiiiYiii&iiPiiiiiiii^iiiiiii9iiiiiiiQii"itiiii]i{i7iii{ii;iiuiizi/ii|iiii7iii.iiiiiiiiiiiiii{iiii#i|i}ii~iiti8ii_i i i i i i!iiii_iiiiiii*iiuii`i"iii|iiiiiiiaiiiiiii?iiRi!i i/iii!i"i=iii#ii$i%i&i'i(i)i,ii'ibi$i*ii+ii-ii,iiiiii&iUiii#iii-i.'iiifi/isii0iiiiii ii9ie[i1iiiiZiii:iiii2i3iiGiiiyi4iiii5i6i7i,wiiisi8ii9i:iii~i;ii<i;i}i=i>i?ioi)iii@iiAiBiii2iYiCiDii<iEiFiGiHiIi%iJiKiLiMiNiOi`i>iPii=iQiiRiiSiTi;iiiii iUiiViWiXi4iYiiZi[ii\i]ii^iii_"iPiii`i;ii~iHiaivizi?iiiibiii<iciddieific0iidiigiyiiihiisi0iji=ikiiliiii<ibiiUi iiiiIiminioiipiqirisitiuiiii6iviwii*i]ixiyiiiziZi-:ibi i{i|i&i'iii5iiii>i}i~iwiigiiii6ii%ii(iviiiwiiiEiiiiiiiiiifiVii7iiiiiBiNii[ii'iiiiiiiSiiiiiieiiixiiiiiiiiiiiiiiiiiiiii?iiiiiqiifii(i)iii~ii\iiiiii)iiiiiiiiiii$iiiiiliiii~iiiCiiii@iiiii2iiKiiziViiiQirifiiii ihi+i3ii1i iiigi(iiiiziiiiiiiiiiiiiiiiiAi<ijiiiMigii2iiiiiiiiiiVihiiiJiii0ibiiiiiiiYiiiai!*iiiiKiDi8iiRiiBi@iiiiiiiiyiiiiiiXi:iii#iiiiiiGiiikiii=iii!iiiJi=iii}iiijiiiiiiiiiiiiiEiiiiijiO4iiiiiiiii ivi]iiCiiiiiiiioiiii iiiliciAiiiiiiiiiTiiikiiii3i*iqii>iiiiiii+iiiii;ipiixiiii iiiii ii i ii i iiiliiiiii)iimi8iiiDiiiii iiiiiii7iLBiiiDiiiiiitiiii i!i i"i#i$i%iRi&i'i(i)i*i+i,i,i-i.mii i^i/iciiEiiiiaimi0iEi1i2i3iiii4iTiiii5iiiii6i7iiniiioi8i9iFiiii:iGi;i<i=i>i?i@iAiBiCiDiEi$iFiGiii%iiipiHiIiJiKiLiiiiiiiiMiNiOiPiQiRiiSi/iTiiUiiiiViIiHiiiiiWiiXiqiYiZi[i\iiriisi]i^i_i` iviLiai.iibiFi>iijicZiiiBi6ii`idieii|iifiii5igiihiiiHijiiikiilii1iminioipiqiriCisitiuiviwiixiyizi{iii|i}i~iiiiiiiiOiiiiiiiiiiiiiEiiiqiiiIii\ii-iiiSiii iieiiiliiMQiPiii^ii i-iFiiiiiiiiiiiiiiiiiii i.iitiiiiiJiiiiiiiigiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiuiiii9i iiii ii$iiiii5i%ikLiiiiiiiiiiAiiiiiiiiiRiuiiiiii)iii:iiiiii"i$iviiciZiiiii*iWiiKiiLi+iiiiiii iBii?iiiiiiiiMi[i5iiiiniiiiCii'iiiiiiiii iiii iiiiiiiFiTi/iiii8iuiiiiKii(iMiiiiiiiiiiiiTi?iiiiiiei i(iiiiii%i0iOii i8i i i i i iii i i i#i iVi iiPi  MiWii ii ii|i i Siiiiiii i iii i i i i i ii i 9Diiii 3iii i i i{i iii i i ii iiiii! ikiiiiNiYii" i# i$ i% i& i' i( i]i) i* i+ i, i- i. ii/ ii>iri1 iiii\ii2 ii3 iii4 i5 i6 iwi7 ii8 ii3iiii9 i: iL i; i< iiiiiii iiii= iiJi> i? i@ iiA iB iC iD iiE iiiF iG iH iI iiiiiiiJ iK iiiL iM iN iiIiO iP iiQ iR iS iiT iiU iV iW iX iiY iZ i[ i\ i] iii^ i_ i` ia iiib ic id ie iiif ig iUiixi ih iiii ij iii4i&iii!iiiSiyi iii"i ii#ik iil im in iiipiQii.io iUiOiip iiq ir is ixit iiu iv iw iii$ix iiy ii`iz i{ i| i} i~ i i i i i i i iCiiii%iyiiioi ii i i i i i ii i i i iii iii i i@iii iGi iiii2iiii i i i iNi i iiiii i i i i ri iiziniiiPi i#i i&iQi iimi iciii i'i iwi i i(ili@iiii)ii*i i i i ii i i i iii iii i i iHii i ii iii i i ii i iri iiAi iiii }i,iii:iiii iiIi iNii1i iWiiiiii i+i i 1iibii iqi i,i iieii_iidi i i i i i ii2iiii i i i i ii ii i ii-i iii i i i i i ii i i i i i ii ii i i7i ii ii i i i i i i iiiiii,iGiiii ii^i i i.i igii ii i i iii iiii_ii i i iihihii{i i|iii3i i i iii i i \iiiii i i i i i i i i i i iiii iji iiii4ii i i i i i ii i i i i6idi/i i iiioi iiRii &i kniziii ii iXiidiiSii}i i}iii~iiiii i! iNi" iiiiii# iisi$ i% i& fiDii1i' iii( i@i) ^ii* ii+ i, i- i. i/ iJi+i0 i1 i2 iiTii3 i4 i5 i6 i7 iAi.iiii8 i9 ii"i: i; ii< i= i> iii0i? ii@ iiA iB iiC iD iE iF iG iii_i[iH iI iii`iaiJ iiiiiK iL iM iN iO iiiiiiiP iQ iR N) EUCKR_TYPICAL_DISTRIBUTION_RATIOEUCKR_TABLE_SIZEEUCKR_CHAR_TO_FREQ_ORDERrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/euckrfreq.pys(PKH]tzSpython3.10/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-310.pycnu[o ai @sHddlmZddlmZmZddlmZddlmZGdddeZ dS)) CharSetProber) ProbingState MachineState)CodingStateMachine) UTF8_SM_MODELcsTeZdZdZfddZfddZeddZedd Zd d Z d d Z Z S) UTF8Proberg?cs*tt|tt|_d|_|dS)N)superr__init__rr coding_sm _num_mb_charsresetself __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/utf8prober.pyr &s  zUTF8Prober.__init__cs"tt||jd|_dS)N)rrr r r r rrrr ,s  zUTF8Prober.resetcCdS)Nzutf-8rr rrr charset_name1zUTF8Prober.charset_namecCr)Nrr rrrlanguage5rzUTF8Prober.languagecCs|D]1}|j|}|tjkrtj|_n|tjkr tj|_n|tj kr3|j dkr3|j d7_ q|j tj krE||jkrEtj|_|j S)Nr)r next_staterERRORrNOT_ME_stateITS_MEFOUND_ITSTARTget_current_charlenr state DETECTINGget_confidenceSHORTCUT_THRESHOLD)rbyte_strc coding_staterrrfeed9s      zUTF8Prober.feedcCs*d}|jdkr||j|j9}d|S|S)NgGz?g?)r ONE_CHAR_PROB)runlikerrrr$Ls  zUTF8Prober.get_confidence) __name__ __module__ __qualname__r+r r propertyrrr)r$ __classcell__rrrrr#s    rN) charsetproberrenumsrrcodingstatemachinermbcssmrrrrrrs   PKH]mg [python3.10/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-310.pycnu[o ai@s(ddlZddlmZGdddeZdS)N) MachineStatec@sDeZdZdZddZddZddZdd Zd d Ze d d Z dS)CodingStateMachinea A state machine to verify a byte sequence for a particular encoding. For each byte the detector receives, it will feed that byte to every active state machine available, one byte at a time. The state machine changes its state based on its previous state and the byte it receives. There are 3 states in a state machine that are of interest to an auto-detector: START state: This is the state to start with, or a legal byte sequence (i.e. a valid code point) for character has been identified. ME state: This indicates that the state machine identified a byte sequence that is specific to the charset it is designed for and that there is no other possible encoding which can contain this byte sequence. This will to lead to an immediate positive answer for the detector. ERROR state: This indicates the state machine identified an illegal byte sequence for that encoding. This will lead to an immediate negative answer for this encoding. Detector will exclude this encoding from consideration from here on. cCs0||_d|_d|_d|_tt|_|dS)Nr) _model_curr_byte_pos_curr_char_len _curr_statelogging getLogger__name__loggerreset)selfsmr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/codingstatemachine.py__init__7s   zCodingStateMachine.__init__cCs tj|_dSN)rSTARTrrrrrr ?s zCodingStateMachine.resetcCsh|jd|}|jtjkrd|_|jd||_|j|jd|}|jd||_|jd7_|jS)N class_tablerchar_len_table class_factor state_tabler)rrrrrr)rc byte_class curr_staterrr next_stateBs zCodingStateMachine.next_statecCs|jSr)rrrrrget_current_charlenPsz&CodingStateMachine.get_current_charlencC |jdS)Nnamerrrrrget_coding_state_machineSs z+CodingStateMachine.get_coding_state_machinecCr)Nlanguager!rrrrr#Vs zCodingStateMachine.languageN) r __module__ __qualname____doc__rr rrr"propertyr#rrrrr!sr)r enumsrobjectrrrrrs PKH]5 =C C Npython3.10/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-310.pycnu[o ai}@shdZGdddeZGdddeZGdddeZGdddeZGd d d eZGd d d eZd S)zr All of the Enums that are used throughout the chardet package. :author: Dan Blanchard (dan.blanchard@gmail.com) c@eZdZdZdZdZdZdS) InputStatezS This enum represents the different states a universal detector can be in. N)__name__ __module__ __qualname____doc__ PURE_ASCII ESC_ASCII HIGH_BYTEr r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/enums.pyr rc@s<eZdZdZdZdZdZdZdZdZ eeBZ e eBeBZ dS) LanguageFilterzj This enum represents the different language filters we can apply to a ``UniversalDetector``. rrN) rrrr CHINESE_SIMPLIFIEDCHINESE_TRADITIONALJAPANESEKOREANNON_CJKALLCHINESECJKr r r rrsrc@r) ProbingStatezG This enum represents the different states a prober can be in. rrrN)rrrr DETECTINGFOUND_ITNOT_MEr r r rr rrc@r) MachineStatezN This enum represents the different states a state machine can be in. rrrN)rrrr STARTERRORITS_MEr r r rr!)rr!c@s,eZdZdZdZdZdZdZeddZ dS) SequenceLikelihoodzX This enum represents the likelihood of a character following the previous one. rrrcCsdS)z::returns: The number of likelihood categories in the enum.rr )clsr r rget_num_categories;sz%SequenceLikelihood.get_num_categoriesN) rrrr NEGATIVEUNLIKELYLIKELYPOSITIVE classmethodr(r r r rr%2sr%c@s$eZdZdZdZdZdZdZdZdS)CharacterCategoryz This enum represents the different categories language models for ``SingleByteCharsetProber`` put characters into. Anything less than CONTROL is considered a letter. N) rrrr UNDEFINED LINE_BREAKSYMBOLDIGITCONTROLr r r rr.Asr.N)r objectrrrr!r%r.r r r rs   PKH]*F8[python3.10/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-310.pycnu[o ai@s,ddlmZddlmZGdddeZdS)) ProbingState) CharSetProbercsReZdZdfdd ZfddZeddZedd Zd d Zd d Z Z S)CharSetGroupProberNcs(tt|j|dd|_g|_d|_dS)N) lang_filter)superr__init__ _active_numprobers_best_guess_prober)selfr __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/charsetgroupprober.pyr!s zCharSetGroupProber.__init__csJtt|d|_|jD]}|r|d|_|jd7_q d|_dS)NrTr)rrresetr r activer )r proberr rrr's  zCharSetGroupProber.resetcC |js ||js dS|jjSN)r get_confidence charset_namer rrrr1 zCharSetGroupProber.charset_namecCrr)r rlanguagerrrrr9rzCharSetGroupProber.languagecCs|jD]?}|sq|js q||}|sq|tjkr%||_tj|_|jS|tjkrBd|_|j d8_ |j dkrBtj|_|jSq|jS)NFrr) r rfeedrFOUND_ITr _statestateNOT_MEr )r byte_strrrrrrrAs(       zCharSetGroupProber.feedcCs|j}|tjkr dS|tjkrdSd}d|_|jD])}|sq|js*|jd|j q| }|jd|j |j |||krB|}||_q|jsHdS|S)NgGz?g{Gz?gz %s not activez%s %s confidence = %s) rrrrr r rloggerdebugrrr)r r best_confrconfrrrrVs,   z!CharSetGroupProber.get_confidencer) __name__ __module__ __qualname__rrpropertyrrrr __classcell__rrr rr s   rN)enumsr charsetproberrrrrrrs  PKH] Tpython3.10/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-310.pycnu[o ai@s`ddlmZmZddlmZddlmZddlmZddl m Z ddl m Z GdddeZ d S) ) ProbingState MachineState)MultiByteCharSetProber)CodingStateMachine)EUCJPDistributionAnalysis)EUCJPContextAnalysis)EUCJP_SM_MODELcsPeZdZfddZfddZeddZeddZd d Zd d Z Z S) EUCJPProbercs4tt|tt|_t|_t|_ | dSN) superr __init__rr coding_smrdistribution_analyzerrcontext_analyzerresetself __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/eucjpprober.pyr %s   zEUCJPProber.__init__cstt||jdSr )r r rrrrrrr,szEUCJPProber.resetcCdS)NzEUC-JPrrrrr charset_name0zEUCJPProber.charset_namecCr)NJapaneserrrrrlanguage4rzEUCJPProber.languagecCs,tt|D]o}|j||}|tjkr&|jd|j|j |t j |_ nP|tj kr1t j|_ nE|tjkru|j}|dkrW|d|jd<|j|j||j|j|q|j||d|d||j||d|d|q|d|jd<|jt jkr|jr||jkrt j|_ |jS)Nz!%s %s prober hit error at byte %sr)rangelenr next_staterERRORloggerdebugrrrNOT_ME_stateITS_MEFOUND_ITSTARTget_current_charlen _last_charrfeedrstate DETECTINGgot_enough_dataget_confidenceSHORTCUT_THRESHOLD)rbyte_stri coding_statechar_lenrrrr+8s<       zEUCJPProber.feedcCs|j}|j}t||Sr )rr/rmax)r context_conf distrib_confrrrr/Ys   zEUCJPProber.get_confidence) __name__ __module__ __qualname__r rpropertyrrr+r/ __classcell__rrrrr $s    !r N)enumsrrmbcharsetproberrcodingstatemachinerchardistributionrjpcntxrmbcssmrr rrrrs     PKH]ٗQpython3.10/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-310.pycnu[o ai @sDddlmZddlmZddlmZmZgdZddZddZ d S) )UniversalDetector) InputState) __version__VERSION)rdetect detect_allrrcCsFt|tst|tstdt|t|}t}|||S)z Detect the encoding of the given byte string. :param byte_str: The byte sequence to examine. :type byte_str: ``bytes`` or ``bytearray`` 3Expected object of type bytes or bytearray, got: {}) isinstance bytearraybytes TypeErrorformattyperfeedclose)byte_strdetectorr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/__init__.pyrs    rcCst|tst|tstdt|t|}t}||||j t j krig}|j D],}| |jkrZ|j}|j}|drN|jrN|j||}||| |jdq.t|dkrit|dddS|jgS)z Detect all the possible encodings of the given byte string. :param byte_str: The byte sequence to examine. :type byte_str: ``bytes`` or ``bytearray`` rziso-8859)encoding confidencelanguagecSs |d S)Nrr)resultrrrQs zdetect_all..)key)r r r r r rrrr _input_stater HIGH_BYTE_charset_probersget_confidenceMINIMUM_THRESHOLD charset_namelower startswith_has_win_bytes ISO_WIN_MAPgetappendrlensortedr)rrresultsproberr!lower_charset_namerrrr-s:         rN) universaldetectorrenumsrversionrr__all__rrrrrrs   PKH]*%[d Npython3.10/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-310.pycnu[o ai)@sddlmZdZgejejdejejejejejejejejejejejejejejejejejejejdejdejdejdddejdejdddejdejdejejejejejejejRZdZedeedd d Zd Z gejdejejejejejejejejejejejejejejejejejejejejejejejejejejejejdejejejejejejejejejddejejejejejejejejejejejejejejejejejejejejejejRZ d Z e d e e dd d Z dZ gejdejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejdejejejdejejejejejdejejejejejejejejejejejejejejejejejejejejejejejejejejejejRZdZe deeddd ZdZgejdejejejejejejejejejejejejejejejejejejejdejejejejejejdejejejejejejejejejejejRZdZedeeddd ZdS)) MachineState(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)rrrrrrz HZ-GB-2312Chinese) class_table class_factor state_tablechar_len_tablenamelanguage(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr) rrrrrrrrr z ISO-2022-CN(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr) rrrrrrrrrr z ISO-2022-JPJapanese(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrz ISO-2022-KRKoreanN)enumsrHZ_CLSSTARTERRORITS_MEHZ_STHZ_CHAR_LEN_TABLE HZ_SM_MODEL ISO2022CN_CLS ISO2022CN_STISO2022CN_CHAR_LEN_TABLEISO2022CN_SM_MODEL ISO2022JP_CLS ISO2022JP_STISO2022JP_CHAR_LEN_TABLEISO2022JP_SM_MODEL ISO2022KR_CLS ISO2022KR_STISO2022KR_CHAR_LEN_TABLEISO2022KR_SM_MODELr*r*/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/escsm.pys # # #         # PKH]MڒVjVjQpython3.10/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-310.pycnu[o aiz@sdZdZdZdS)g?(i ii Riiaii ni!i iL,iBi iiiii{ i] iii ijiii.iNiii:iii?iii=iNKikiq iii i i ib iii ioi2 iiii ici8iiiiiii{|i "i i @i\ii iiiiiiFii| iQHiiPivi iiiiDi^ iiiFi} iEi iOi0isii4<2i i&iMiii~ iiGii[ iii?ii iaiiK i*iigi Zi i:i iiKi i iiiii`iliii i i qii~ii i ii iiiciuii*iii i i~imiiieiGi^iini UiCiiCiiiiiii jioi/iiiPi7 i[ii i? iiiioSi(ii ip]ii6iji i@ iiiiii8+i3 i[ii\iiiii] iA ii i1iiHi i idii+i i2iiii iOiL iiifi1iiiiiii3i9li,i iiiiiii ieiz iQiMi&i Xiiiii iikipiMii %i iiii'i ii\ i i7Jii!iiiiiNiiB iPi_ iqi iii i i ii i iIii8 ii ii{ i i iimiiifiiixii iii ii iigii iiiiii&ii'iiiii.i iiiM iiii$#iiDihiAi iiriiiUiGiiii i iQiSiiiidi 0FiiiC iiiii iiJii iUiiN i iii<ii i:iA i ii i i9ii}ii iiiWiPi ii)iDiiii4 i i i)iiir iisiiitii9 iiiis i*iiiiiii] iiiii iD iji( i iii iiui5iYiji iliiuiii iii` i i=i iiiiiii5ii!iiiTiE ixiiiei iiO iPii| i6iAi i/iki i iili!i iiBii`ii i iAii iiii ivi i iiwiiiMi iiiiiia iii i} iixi,}ii iB iiiiiiiiiF ikimi ii ii ii iibii) i^ iP i i,ii ii7i5 i~ iyi|i iziiii iC i{iiiiiiiiii1bii i iiit ii ii_ iiiii i i ib iii5Diilii|i[i* ii ii%iG i^ iiliii ii` iii ipiincigimiii'i2iii{ii ii iiiD iifi ii|i: iiii i i i i ii inii ii;iiIiYi}ii iXi"ii iiiiiii-iiliiiiiiiiiEii~ii>i]ii,iiiiviLiBii&iii iiiiGiiiiBii i+ iii iiiii i iaiiii ia ii}iE iiDii=ii0i ii i6 iiiivi!iiiiii9iHiiiii iFiiiiii"iiH iii i ioiiiRi*ii.iiiiiiI 3ii, ii*iSiiiXiii/iibipii iiiiiiRii ii7 ii2ii iiiiiii_ iib ii iiii iiiiiii` Oii i i`i7i i iiiiiiia iiiiiiigiii ii i_ii~iiiii iaii ib iiiii ii i;i i-i iiQ iiiqiiii`ii#i#iiiiiri isiiiiditi iic ii ikiwi ii iiiiiiigi iQiiUi i iiiCiSiic iii5iiiBii_i iciNiiYiiii iLidi i i iKi i8 iaiGiii i iiisi6i iti; Niii i i4ii:ii\iqiiii.iii iui iiii i i iriii i iic iiii@iii ii ii ii/i9 ii iiiiiii i< id iiii8iviiCiii iimii iiiiiiZiiiwi {iiii$iiiMid i0irii iigiiViiiii: iZiii{i$ie i0iii$i i i ii5ii[iviiiciiViR i$i; iiif iii idiiiWie iii iii i iiJ iiiiiuii ii ii i iK ii2iiL i i.iii2ii iiiii%i iii i iiiiiii i ixi iM ii}iiiTiiiid i iiiii`iiiii i3iii;i iiiiyiYiLiii i iiiiU\iiiiiiViN iii iii ii"ixi%ii;i= i iii2iEii!iii^ii"iwi i#iiii ii$i<iQiiiri%ii]ii&ii< i'i i3i6iBii i(iii ii i iig i i i)i i i*i+i! iii:ii7ii^ii iii(i i,i+i i ixi-ii/ihi= i.iiiiVi ii hii i/iiii<iii;i0iiii i i1izi i ii5i6i i_)i2i3ii4iyi" ii ii^i5i i i?i%i+if i i6i_iWiii i7i> ii ig i# iu i8i ii9ih iF iiVi{i iO iiIwi~i i^iii:iiiiiiii i;iei1iiiiiiiii i i iiP i<i=ii>i i(i`iRi? iYiiIi ii i7i i i?iii i@iioiqiYiniiiliiii ii ii iEiPiVii! i iiiiiniiAii|i ii iBiiiiii- i iOi i iCiiDiWiTiTiiii i}iEii&i i iiiiii iii~iG i iii$ iWiiiioii iFiiGiii" iii# iiiDi-iQ iiHiei i iiIi iiiJizi iiKiiiLii$ i iiiiiH iiiiiiMi:i iiiNiiI i iiiHiiiiiOiii iPiQiiikiRiR i ii i i ii iiiiiiSiTiii i% iiiiii& iS iUi iiS iiCiiiiVi~ii!iXiiiiii,iiiiiOii|iiiiPiie iiii i i iiiiiiiiT iiiiWiiiiXiiYiiRi iviii ii i=i iiZiiU iii[i iiiV i% i\iii]iii^i8iT i. i' i_iiviiiiiwitii`iaibi> iii"i{i i iiciidi9iiiii[i9iiidih i ieiii iJ i!iiifiii iiiTigiii i%iWiMihiiiiiiiiiiiii( ij iiyi7imiijiki i? iW i"iii Biili|i i) izii iii iiiiiminiuiv iwii i* iiioipiiqi7i.irii i iii iifii i isi& iyi ii i iiiii i i>iiii iYi iitiiui/ i+ i ivi ii i@ iwii i ii3iiii, ixi i6i9i i ii6i ii! iiiyiiQi:ici iii- oiiiFiX i i iifi iizi iii iii{i/ii' i ibiii`iiiiui iviiiii i i iiii i0iEiSii8i[i|i}iGii ii!i~iiiFiU ii ii iieisiii iw iiii" i iai iZi&iiiii i iiiiAiii iiii iiiiiiiii ioii ii i i ii iiA i iJi0i ix i ii iiY iiiiii i i iiZ i8ioiiiQiiiii iaQiiipi;iiPiibiiiii i ii iiii iii iiiiiiiii]iiiii iiiii'iii. i i iiiii iLiiiiii ii/ iiiiiB i0 i[ ii8iiiii iii/i3iiiii iiii0i iniiiiiiii i iiiiiiiii4iiii<i ii iiiYi iiiC iiii iiiii}i1ii iiiiKi i0 iFiiii ii#ii\iiifi >i iii iiiiii i iiiiijiiiiii-ipi9i@ i6iyiiii i i1 iiiiiiiViiiii4iii iKi1 ii iD i iiiiii#iiii i2 iiii iZiHipiiigiii i iqri iiiii i iK iV i i\ i,i ii iiii]iiiui iiiiiiiiiZiii iiiiijiii0ihihiii ii iE iii iii iiiiiiiiiii iiii2 iiiiiiMiiwiii iy i?iiii itimi( i ii+iiiiiiiii i ii i iii iiL iii) i ii iiif ii iiiiiiiRi"iA i3 i ii-i1ii$i i(ii] i i# ii$ i iiii i* iiii i ii i i=ik ii!ii iiii i ii _iiiii^ i2ii iiii9iii iiii4 i iii ibiiii ii ii5ii iii"i i iiiii4iIi ii#ii iiiiiij iiii$ik i ii ii\i igiiEi5 iiiiiiiii iii6 iiii ii%iii ii i[i iiiiii i&eiii iiioi iil i i}iiiizii+ iii iiiini-ii i'iiii iiii(iii iiiiiiii ii iiiBiiiqiiii<ii*iji)i"i*ii>i)i7 ii+iiiiiiizii,iiiiiM i)iriii-i i iiiiiTipiii#i#iiiiiiii iiii i ii iiSii.i8 iiiiiz i9 i=iiiim iiSiiiiiixiii/iiiqiii3ii5ii: i i ii iiiiii i; i i0i1iiiiiin ii_ ii]i i iniiiii i% iiiii i` iiiiiziTisi2i3 ii i{ i5ii ig iiikiiiii iii3i4ii iici iii i iiiai:i1i iii!Aihi io i i6i"ii il -ii ia i5ii ii i ii#i! ii$ii ii4 ifii i%i& i iN ri iiWiiiiii i' ii$iii< i iNiiiW ikiiO iiiiiiiX i, ii6i&itiiP ii i7i i i i- ijii i iiC[ip ii i'i8i ib iim i i ii{i(i i ii i9i i i i:i i i^iiiiB i;iiiiii ii ii ii)i<i=i ii ii>iiiii =iiiiiiiiiiin iiHiDi i?iiUiWi i= ii:ii iNi iKiEi@i4ic i ii> iiQ i iAiiihiii i i( i]iiiiBi*iiiliiCiDiiEih iiiiiiXiiiii+iiii+iJiiiUii iimi iEiiiiFiiGi ki inii id iiiiiiiF i!i iiri@iiHi"iCiGiii ii^i ii 8iti) i;i i? i!iioiIi i"i#i#i$iiJi i%i i&iriKi'i5 i(i)iio i@ i}iA ii,ii*i41i+ii i i ii" ii,ii iC iiuiriD i-i i-i iLivi{ii| iMi.i.iNiY i6 iii i/i0i/i ii1i$ii2i%iGiRiB i i_iiiC ii iD ii3iiiii ii i. ii i4i@iwii5ii6i7iii ii&i0ii8i i&i i* i+ iG iOiui# i i1iPiRiiQii ii)iii=i9iili iiiiE iSiiki i\i iii iyi:i i;i<iF i%i=iiRiii>idi'i, i?iei$ ii2i3i- ii i4ii(iSi@iAiBii.iTiiOi i iiiii i&i iii i<i iiiiCiiDi iiUiip iG ie i i i ii iEi;iViFi'iGi)i ii} iHi*iiWiiiIiiTii i iiiiii iiJi. igi~iUiij i iiiXiii8ii*i iiiKi~ iii iLiiH i iii% i+if iii iitiiMiNiii ii ii iiik iYiiYiii*i/ iiOiR iZiH ii#iI i i iii5iS i]iE i[i\i isiI i+iPiQi,i i iRiiSiTii,iiUi]iVi iiLi-i!i iT i\4iWi iiXiYiZii[i>iwiiiii+i^iiJ ii_i$ii\iiiili.i]i`ii^i_iq i%ii`iaiiii i6ig iU ibicidiai iq ixi iei ibiyi ifihigihiii'iii iii ijir ii i0 i i=iibi|iiiii i iih iki iliii iaiicimiii ini iiui iidieiis iK i/ioi7ii& i iJ i8ipiqii ij ifii igi iii(ii`irisi i iii<iFik ifiiii]iiiIiti>iiuiivii iii i0ii-iiwiL ii iiiiiGiaii it i ii iSiKixiiyiziiiV iiOii1 i i{i i iiF iyii9iZ i|i}i~iFi iii i i:iiiii2 iiiipii;iG iii ihiiiii7 iiiiiqiiiM iiiiiii iii iii i(i8 iiN i ii3 i iiO i<iiiiTiiW i iiiii(iiii1iiiiiiiiu iZii i iciijiP ipiii iiii iv iiijii iiii iQ iK i ii i' iiiiii9 iii i izii i iiikiiiii ii2i iiliii>i=iCi'iii>i iiZiiii imini iibiii i iqi?ii ii ii i"ii i?i i}iiioi@i>iiAi i1ii)iiii?i i iiiixi ii ii i3i i ihii il iiii)ii ipii'iiii4ii i i iiiiAi_i iBiiL ii iPiqii iiriiiiiX iicisi! iiiiHii iw iiiiCiDitiiiiiiix i ii i/ iiii5i i4 iuiir iii_ii/i i<ii~i7iy im iii^i5 in ibi itiiil iiii6ii i7iiiiiiiviiii i8i: ii ii0 i i1 iiwiIiiiii i( iiiBi ii4isi iiiii i iii?iCiixi iEiHi iiFiyiziGiiiii{iiii|ii; i}i9imiH i~iiz iiis i iiM iiii iiim iiiIiiiio iiiiiiii_iiii i2 i3 iHii*iii iiii< iiii:ii ii iiAii iiR iiiii i ii" ii iiiiii ii iii iiiQi i iY iiiiiiii{iKii i[i iJiiiN iiS iiiiiI iiiT i@ii iii i i@iiRiii it iiiiJiIii iiii iU iimiiii{ i ii i i;iV iii iii<iii idiiiiXiii9iii6 iiiUiiii iiLi!i= ii) ii i i iii i ii ii=i$i(iviii&iicii iii i ii>iiii{i"iiiii#iiiiiW ii iiii ii$i i%iiiiii&i^iii[ i ii'iiiiiiii(i iii2i\ iJi ip ipin iiu iq i)ii iO i> ii i*iX iii i+ii i,i iii iiiiiKii i iIi-iii!iiiiii.iDiiiJisi# iii ii7 iiii/iwii|iiiiii"i4 i| i,iiiii iiiiiiiii?iY iP i0ii1iZ iZ i ii i ii i#i@i2ii|iiziiiiiAi'ii? ii ii8 ii yiiLiVi i3i i i i$iiiiMii%ii i i i i i.ii4iNiii ii i i iiii i5i9 i%iiiiKiQ iixi6i7iiBi i iOiv i[ iii&ii ii iiiXii* ii\ iPi i iNi+ iw iiiiiWiCi ii iQiDi i?i] iiii^ io iR i i iEii iiFi i'iiXiiGiiS i iiT iRii8ixi ikiSiiTiii ii iiDii9i!iiiii(iiLi"i#i$i%i_ ii&iJi:iUii}i i)ii i;i<i iEi+i'i iiHi=iVi*iHiyi, i+iWi3i>i ii?i(iIi,i-i` iqiia i iii ii)i*iXi i+iiOiYi,i-ii.ii/i ii0i.iiii1i iJir i2i3i$ i i4ii5i6i7i iib i iii} i ifiiKii i i i i8iZi9ii: ii ic ii:ii i;is iJ i@ii it i; i i/i<id ii iiiU ii0iie i=iif iu iMiiiii i>i i[iiAiLiiii?i i i i i@iAiv iBiCi\iijii[ i ig iDiEiiiFi iBiiGi iiHii(iiMiCih iiIiNiJi iKiLiiiMii1i2iNiidiOidiV iDi`ii#i5 iPi]iQiEini i iii^iRi_iFiSip ii iiTiUii i iVii i iiGiiiieiHiOi iiPi`iWiw ij iXi ii3i iaiiIiYiJix i7iiii- i i4ik iibiZi-iii. icii[i iri;i iKi5iLiXii i iii\i]iii6i% i^i_iii~i`il iy iaizi~ iiibi?iici7idi iiieiiz iiiMifigi/ ihi|ii@idiiiiiNiiii8ifiiijikiiOiPiiilimi@ini9i ioi i iii< isii\ iQi.iRiNi@i iipiiSi{ iqiiAii iiiiTi iiii:iiiri isi@ iW i;itiui iviwixiyi| iiiiizi i i3iQiiimiiAi{i|ii ii}iOiRi iigiii~iZi iiiiii i\im ii} ii<iX ii ii i iiii iiY iiii0 iiii i=i iiiiLiiiiihiiiiii>i>ii/i?iUiiiiiiei)ix tiifiSii iy i in i i iiTi i@ii i iiiiiii ii iziUigiiViio iii6 ip itiiiiii iAiiJiVihiZ i iiWiiiiN)BIG5_TYPICAL_DISTRIBUTION_RATIOBIG5_TABLE_SIZEBIG5_CHAR_TO_FREQ_ORDERrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/big5freq.pys*PKH]τgsIsIOpython3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-310.pycnu[o aic@s ddlmZdZejejejdejejejejejejejejejejejejejejejejejejejejfZdZedeeddZdZ gejejdejejejd dejd ejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejRZ d Z e d e e d dZ dZ gdd ddejejejejejejejejejejejejejejejejejejejejejejejejejejdejdejejejejejejejRZdZe d eeddZdZejejdejejejejejejejejejejejejejfZdZed eeddZdZgejejejdddd ejejejejejejejejejejejejejejejejejejejejejejejejejdejejejejejejejejejejejejejejejRZdZedeeddZdZgejejejejejejdejejejejejejejejejejejejejejejejejd ejejejejejejejejejdejejejejejejejejejejejejejRZdZedeeddZdZejejejdejejejejejejejejejejejejejejejejejejejejfZdZed eeddZ dZ!gdddejd dejejejejejejejejejejejejd d d d ejejd d d d d ejd d d d d d dddejddd d ejd d d d d d d ejejejejRZ"d Z#e!d e"e#d!dZ$dZ%gd d dd d dejejejejejejejejejejejejdddejejejdddejdejd d dd dddddejdddejejejdddddejdejejejRZ&d"Z'e%d e&e'd#dZ(d$Z)gejejejejejejd%d d&d'ddd dd dejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejejddddejejejejejejejejejejejejejdddejejejejejejejejejejejejddddejejejejejejejejejejejejejejddejejejejejejejejejejejejd&d&d&d&ejejejejejejejejejejejejejejejd&ejejejejejejejejejejejejd%d%d%d%ejejejejejejejejejejejejejejejd%ejejejejejejejejejejejejd%d%d%ejejejejejejejejejejejejejejejejejejejejejejejejejejejRZ*d(Z+e)d)e*e+d*dZ,d+S),) MachineState(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)rrrrrBig5) class_table class_factor state_tablechar_len_tablename(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr) rrrrrrrrrr CP949(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)rrrrrrzEUC-JP(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)rrrrzEUC-KR(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)rrrrrrrrzx-euc-tw(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)rrrrrrrGB2312(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)rrrrrr Shift_JIS(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)rrrrrrzUTF-16BE)rrrrrrzUTF-16LE(rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr rrrrrr rrrrrrr)rrrrrrrrrrrrrrrrzUTF-8N)-enumsrBIG5_CLSERRORSTARTITS_MEBIG5_STBIG5_CHAR_LEN_TABLE BIG5_SM_MODEL CP949_CLSCP949_STCP949_CHAR_LEN_TABLECP949_SM_MODEL EUCJP_CLSEUCJP_STEUCJP_CHAR_LEN_TABLEEUCJP_SM_MODEL EUCKR_CLSEUCKR_STEUCKR_CHAR_LEN_TABLEEUCKR_SM_MODEL EUCTW_CLSEUCTW_STEUCTW_CHAR_LEN_TABLEEUCTW_SM_MODEL GB2312_CLS GB2312_STGB2312_CHAR_LEN_TABLEGB2312_SM_MODELSJIS_CLSSJIS_STSJIS_CHAR_LEN_TABLE SJIS_SM_MODEL UCS2BE_CLS UCS2BE_STUCS2BE_CHAR_LEN_TABLEUCS2BE_SM_MODEL UCS2LE_CLS UCS2LE_STUCS2LE_CHAR_LEN_TABLEUCS2LE_SM_MODELUTF8_CLSUTF8_STUTF8_CHAR_LEN_TABLE UTF8_SM_MODELrHrH/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/mbcssm.pys $   #$ # #&  # # #                                         PKH]daXpython3.10/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-310.pycnu[o ai@sddlmZddlmZddlmZmZddlmZm Z ddl m Z ddl m Z mZmZmZmZmZddlmZddlmZdd lmZGd d d eZd S) )CharSetGroupProber) HebrewProber)ISO_8859_5_BULGARIAN_MODELWINDOWS_1251_BULGARIAN_MODEL)ISO_8859_7_GREEK_MODELWINDOWS_1253_GREEK_MODEL)WINDOWS_1255_HEBREW_MODEL)IBM855_RUSSIAN_MODELIBM866_RUSSIAN_MODELISO_8859_5_RUSSIAN_MODELKOI8_R_RUSSIAN_MODELMACCYRILLIC_RUSSIAN_MODELWINDOWS_1251_RUSSIAN_MODEL)TIS_620_THAI_MODEL)ISO_8859_9_TURKISH_MODEL)SingleByteCharSetProbercseZdZfddZZS)SBCSGroupProbercstt|t}ttd|}ttd|}|||tttttt tt tt tt tt tttttttttt|||g|_|dS)NFT)superr__init__rrrset_model_probersrr r r r r rrrrrrprobersreset)self hebrew_proberlogical_hebrew_probervisual_hebrew_prober __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/sbcsgroupprober.pyr/s8 zSBCSGroupProber.__init__)__name__ __module__ __qualname__r __classcell__rrrrr.srN)charsetgroupproberr hebrewproberrlangbulgarianmodelrrlanggreekmodelrrlanghebrewmodelrlangrussianmodelr r r r r r langthaimodelrlangturkishmodelrsbcharsetproberrrrrrrs       PKH]ZU^^[python3.10/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-310.pycnu[o ai˜@sbddlmZididdddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 didddddddddd)ddd d)d d)d dd d)d ddddddd)dddd)ddidd)dd)dd)dd)dddd)dddddddddd)ddd dd!dddd"d)d#d)id$d)d%d)d&dd'dd(d)d)dd*d)d+d)d,d&d-d)d.d&d/dd0d)d1d)d2d)d3d)d4dd)dddddddddddd5 didddddd)dd)ddddd d)d dd dd d)d ddddddddddd)dd)idddddd)dd)dddd)dddddddddddd)d dd!ddd&d"dd#did$dd%dd&d&d'dd(dd)d)d*dd+dd,d)d-dd.dd/d&d0dd1d)d2dd3dd4d)ddddddd&ddd)ddd5 didddddd)ddddddd dd d)d dd dd d)ddddddddddddidddd)dd)dddddd)ddddddddddddd dd!d)dd&d"dd#did$dd%dd&d&d'dd(d)d)d&d*dd+dd,d)d-dd.d)d/d)d0dd1d)d2d)d3d)d4ddddd)ddd)dddddd5 didddddd)ddddddd dd d)d dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd)d"dd#did$dd%dd&d&d'dd(dd)d)d*dd+dd,d)d-dd.dd/d)d0dd1d)d2dd3dd4d)ddddddd)dddddd5 d idddddd)dddd)ddd d)d d)d d)d dd d)dddddddddddd)idd)dddd)ddddddddddddddddddd dd!ddd&d"dd#d)id$dd%dd&d&d'd&d(dd)d&d*dd+dd,dd-dd.d)d/d&d0dd1d)d2dd3dd4d)ddddddd)dd)dddd5 d idddddddddd)ddd dd dd dd dd ddddd)dd)dddd)dd)idddd)dd)dd)dddd)dddd)ddddddddd dd!dddd"dd#d)id$dd%d)d&dd'dd(dd)dd*dd+d)d,d)d-d)d.d)d/dd0dd1d)d2d)d3dd4dddddddddddddd5 d iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd)d"dd#did$dd%dd&d)d'dd(dd)d)d*dd+dd,dd-dd.dd/d)d0dd1dd2dd3dd4dddddddddddddd5 d idddddd)ddddddd dd dd dd dd ddddddddddd)ddiddddddddddddddddddddddddd dd!ddd&d"dd#d)id$dd%d)d&d)d'dd(dd)dd*dd+dd,d)d-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddddd dd d)d dd d)d ddddd)dd)dd)dd)ddidddd)dd)dd)ddddddddddddddddd dd!d)ddd"dd#d&id$d)d%dd&dd'dd(d&d)dd*dd+dd,d)d-d)d.d)d/dd0dd1d)d2d)d3d)d4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/d)d0dd1dd2dd3dd4dddddddddddddd5 didddddd)ddddddd dd dd dd dd d)dddddddddd)dd)idd)dddd)ddddddddddddddddddd dd!ddd&d"dd#did$dd%dd&d)d'dd(dd)d)d*dd+dd,d)d-dd.d)d/d&d0dd1d&d2dd3dd4d)ddddddd)dd)dddd5 didddddd)dddddd)d dd d)d dd dd d)dddddddddddd)iddddddddddddddddddddddddd dd!ddd)d"dd#did$dd%dd&d&d'dd(dd)d)d*dd+dd,dd-dd.dd/d)d0dd1dd2dd3dd4d)ddddddddd)dddd5 didddddd)dddd)ddd dd dd dd dd d)dddddddddddd)idddddd)ddddddddddddddddddd dd!ddd&d"dd#did$dd%dd&d&d'dd(dd)d&d*dd+dd,d)d-dd.d)d/d&d0dd1dd2dd3dd4d)ddddddd)dd)dddd5 didddddd)dd)ddddd d)d d)d dd dd d)dddd)dddddddd)idddddd)dd)ddddddddddddddddd dd!ddd&d"dd#did$dd%dd&d&d'dd(dd)d&d*dd+dd,dd-dd.dd/d&d0dd1dd2dd3dd4dddddddddd)d)ddd5 didddddddddd)ddd d)d dd dd dd ddddd)dd)dd)dd)dd)idddd)dd)dd)ddddddddddddddddd dd!dddd"d)d#d)id$d)d%dd&dd'dd(dd)dd*dd+d)d,d)d-dd.dd/dd0d)d1d)d2d)d3d&d4ddddd)dd)ddddddd5 ididddddd)ddddddd dd dd dd dd d)dddddddddddd)idd)dd)dd)dddd)ddddddddddddddd dd!ddd&d"dd#did$dd%d)d&d&d'dd(dd)d)d*dd+dd,d&d-dd.dd/d&d0dd1d&d2dd3dd4d)ddddddd)dddddd5 didddddd)dddddd)d d)d d)d dd dd d)dddddddddddd)idd)ddddddddddddddddddddddd dd!ddd&d"dd#did$dd%dd&d)d'dd(dd)d)d*dd+dd,dd-dd.dd/d&d0dd1dd2dd3dd4d&ddddddddddddd5 didddddd&dd)dd)ddd d)d d)d dd dd d)dddd)dddddddd)idd)dddd)dd)ddddddddddddddddd dd!ddd&d"dd#d)id$dd%dd&d&d'dd(dd)d&d*dd+d)d,d&d-d)d.dd/d&d0d&d1d)d2dd3d&d4d)d)dddddd&dddddd5 didddddd)dd)ddddd dd d)d dd dd d)dddd)dddddddd)idddd)dd)ddddddddddddddddddd dd!ddd&d"dd#did$dd%dd&d&d'dd(dd)d)d*dd+dd,dd-dd.dd/d&d0dd1d&d2dd3dd4d)ddddddd)ddd)ddd5 diddddddddddddd dd d)d dd dd dddddddddddddidddddddd)ddddddddddddddddd dd!dddd"dd#d)id$dd%dd&d)d'dd(dd)d)d*dd+d)d,dd-dd.d)d/d)d0dd1dd2d)d3dd4ddddd)ddddddddd5 didddddd)ddddddd dd dd dd dd d)ddddddddddddidd)dddd)ddddddddddddddddddd dd!ddd)d"dd#did$dd%dd&d)d'dd(dd)d)d*dd+dd,d)d-dd.dd/d)d0dd1d)d2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd)d"dd#did$dd%dd&d)d'dd(dd)d)d*dd+dd,dd-dd.dd/d)d0dd1d)d2dd3dd4d)ddddddd)dddddd5 diddddddddddddd dd dd dd dd d)dddd)ddddddddidddddd)ddddddddddddddddddd dd!ddd)d"dd#d)id$dd%dd&d)d'dd(dd)d)d*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 didddddd)ddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd)d"dd#did$dd%dd&d&d'dd(dd)d)d*dd+dd,dd-dd.dd/d)d0dd1dd2dd3dd4d)ddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd)d"dd#d)id$dd%dd&d)d'dd(dd)d)d*dd+dd,dd-dd.dd/d)d0dd1dd2dd3dd4d)ddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd)d"dd#did$dd%dd&d)d'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd ddddddd)ddddddidddd)ddddddddddddddddddddd dd!dddd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"dd#did$d)d%dd&dd'd)d(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d!iddddddddddddd dd dd dd dd dddddddddddddidddddddd)ddddddddddddddddd dd!dddd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-d)d.d)d/dd0d)d1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"d&d#d&id$d&d%d&d&d&d'd&d(d&d)d&d*d&d+d&d,d&d-d&d.d&d/d)d0d&d1d&d2d&d3d&d4d&d&d&d&d&d&d&dddd&ddd5 d"iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"dd#d&id$dd%d)d&d&d'dd(dd)d&d*dd+dd,d&d-d)d.d&d/d&d0dd1d&d2d&d3dd4d&dd)dddd&d&dd)d&ddd5 d#iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"dd#did$d)d%d&d&d&d'dd(d&d)d&d*dd+d&d,d&d-d)d.d&d/d&d0d)d1d&d2d&d3d&d4d)dd)d)d&d)dd&dd)d&ddd5 id$iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"dd#d)id$dd%d)d&d&d'dd(dd)d&d*dd+dd,d&d-dd.d&d/d&d0dd1d&d2d)d3d)d4d&ddddddd&dddddd5 d%iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"d)d#d&id$d)d%d)d&d&d'd&d(d)d)d&d*dd+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d&d3dd4d&dd)d)d)ddd&ddd&ddd5 d&iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd)d"d&d#d&id$d&d%d&d&d)d'd&d(d&d)d)d*d&d+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d&d3d&d4d)d&d&d&d&d&d&dddd&ddd5 d'iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"d&d#d)id$dd%d&d&d&d'dd(dd)d&d*dd+d)d,dd-dd.d&d/d)d0dd1dd2dd3dd4d)ddddddd)dddddd5 d(iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"d&d#d&id$d&d%d&d&d&d'dd(dd)d&d*dd+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d&d3d&d4d&dd)d)d)d)dd)ddd)ddd5 d)iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"d&d#d&id$d&d%d&d&d&d'd&d(d&d)d&d*d&d+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d&d3d&d4d)d&d&d&d&d&d&d)ddd&ddd5 d*iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"d)d#d)id$dd%d)d&d)d'dd(d)d)dd*dd+d&d,d)d-d)d.d&d/d)d0dd1d)d2d&d3d&d4dd)dd)d)ddddddddd5 d+iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"dd#d&id$d)d%dd&d&d'dd(d)d)d&d*dd+dd,d&d-d)d.d&d/d&d0dd1d&d2d&d3d&d4d&ddd&d)ddd&dd)dddd5 d,iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"d&d#d&id$d&d%d)d&d&d'd&d(d)d)d&d*dd+d&d,dd-d)d.d&d/d&d0d)d1d)d2d&d3d&d4d&d)d)d)d)d)dd&d)d&d&ddd5 d-iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"d&d#d&id$dd%dd&d&d'dd(dd)d&d*dd+d)d,d&d-dd.d&d/d&d0d&d1d)d2d)d3dd4d&d)dd)d)d)dd&dd)d&ddd5 d.iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"d)d#d)id$d&d%d&d&d&d'd)d(d)d)d&d*dd+d&d,d)d-dd.d&d/d&d0dd1d)d2d&d3d&d4d&d&d)d&d&d)dd&d)d)d&ddd5 d/iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd)d"d&d#d&id$d&d%d&d&d&d'd&d(d&d)d&d*d&d+d&d,d&d-d&d.d&d/d)d0d&d1d&d2d&d3d&d4d)d&d&d&d&d&d&dddd&ddd5 d0iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"dd#d)id$dd%dd&d&d'dd(dd)d&d*dd+d)d,d&d-dd.d)d/d&d0dd1d&d2d)d3d)d4d&ddd)d)ddd&dd)d)ddd5 d1iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"d&d#d&id$d&d%d&d&d&d'd&d(d)d)d&d*dd+d&d,d&d-d&d.d&d/d&d0d)d1dd2d&d3d&d4d&d)d&d&d)d&dd&dd)d&ddd5 d2iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"d)d#d&id$d)d%d)d&d&d'dd(dd)d&d*dd+d&d,d&d-d&d.d&d/d&d0d&d1d&d2dd3d&d4d&d)d)d)d)d)dd&d)d)d&ddd5 d3iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"d&d#d&id$d)d%d)d&d&d'dd(dd)d&d*dd+d&d,d&d-d)d.d&d/d&d0d)d1d&d2d&d3d&d4d&dd)d)d)ddd&d)d)d&ddd5 d4iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"d&d#d&id$d&d%d&d&d)d'd&d(d&d)d)d*d)d+d&d,d&d-d&d.d&d/d)d0d&d1d&d2d&d3d&d4dd)d)d)d&d&d)ddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"dd#did$dd%dd&d&d'dd(dd)d&d*dd+d)d,d)d-dd.dd/d&d0dd1d)d2d)d3d)d4d)ddddddd)d)ddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"dd#d&id$dd%dd&d)d'dd(dd)d&d*dd+dd,d)d-d)d.d&d/d&d0dd1d&d2dd3d)d4d&ddddddd)dddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"dd#d)id$dd%dd&d&d'dd(dd)d&d*dd+d)d,dd-dd.dd/d)d0dd1dd2dd3dd4d)ddddddd)ddd)ddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"dd#d&id$dd%dd&d&d'dd(dd)d&d*dd+d&d,d)d-d)d.d&d/d&d0dd1d)d2dd3d)d4d&ddddddd)dddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"dd#d)id$dd%dd&d&d'dd(dd)d&d*dd+d&d,d)d-dd.d&d/d)d0d)d1dd2dd3dd4d)ddddddd)dddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!ddd&d"dd#did$dd%dd&d&d'dd(dd)d&d*dd+dd,dd-dd.d)d/d&d0dd1dd2dd3d)d4d&dddddddddd)ddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"d&d#d&id$d&d%d&d&d)d'd&d(d&d)dd*d)d+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d&d3d&d4ddd)d)d&d)d&ddd)dddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/d&d0dd1dd2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"d)d#did$d)d%d)d&dd'd)d(d)d)dd*dd+d)d,d)d-d)d.d)d/dd0dd1d)d2d)d3d)d4dddd)d&ddddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"d&d#d&id$d)d%d&d&d)d'dd(d)d)dd*d)d+d&d,d&d-d&d.d&d/dd0d)d1d)d2d&d3d&d4ddd&d)ddd)ddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd dd dddddddddddddiddddddddddddddddddddddddd dd!dddd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d5 Zidd6dd6d)d6d&d6d/d6d3d6d.d6d1d6d2d6d#d6d,d7d%d6d+d6d0d7d-d6d(d6d8d6id9d6d"d6d4d6d$d6d:d6d;d6d'd6dd6dd6d?d6dd6dd6dd@dd@idd@dd@dd@d d@dd@dd@d d@dd@dAd@dd@d d@dd@dd@d d@ddBddBddBiddBdCdBddBddBd dBd!dBddBdDd@dd@d d@dd@dEd@dd@dFd@dGdHdIdJdKdLidMdNdOdPdQdRdSdTdPdUdVdWdXdYdZd[d\d]dHd\d^d_dWd`dadbd[dcd`dddedfdgdXidhdidjdgdkdldmdndodpdJdqdfd@drd@dsd@d_d@dtd@dld@dudGdvdOdLdQdNdIdUdid]dMdwdxdydwdzdrd{d|dTdydddtdRdjdbdkdndSdxd}d~dddhdqdsd}dudd~ddididdddddddd@dd@dd@dd@dd@dd|ddddddddddddddiddddddddddddddddddddddddddddddddddidddddddd“ddēddƓddȓdd[dd˓dd͓ddϓddѓddӓddzdd֓ddؓddړiddܓddޓdddddddddddddddddd dd dd dd dd dYddcdidpdddddddddddddd|dddddddddddddddddddiddKdddd dd!dddd"dd#dd$dd%dd&dd'dd(dd)dd*dd+dd,dd-idd.dd/dd0dd1dd2dd3dd4dd?dd=dd;dd:dd>dd<dd9ddZddCddiddAdd8ddEddddddddDddddvdddddddddddBdd@dfd7dBd6d@iZeddeeddddZidd6dd6d)d6d&d6d/d6d3d6d.d6d1d6d2d6d#d6d,d7d%d6d+d6d0d7d-d6d(d6d8d6id9d6d"d6d4d6d$d6d:d6d;d6d'd6dd6dd6d?d6dd6dd6dd@dd@idd@dd@dd@d d@dd@dd@d d@dd@dAd@dd@d d@dd@dd@d d@ddBddBddBiddBdCdBddBddBd dBd!dBddBdDd@dd@d d@dd@dEd@dd@dFd@dGdHdIdJdKdLidMdNdOdPdQdRdSdTdPdUdVdWdXdYdZd[d\d]dHd\d^d_dWd`dadbd[dcd`dddedfdgdXidhdidjdgdkdldmdndodpdJdqdfd@drd@dsd@d_d@dtd@dld@dudGdvdOdLdQdNdIdUdid]dMdwdxdydwdzdrd{d|dTdydddtdRdjdbdkdndSdxd}d~dddhdqdsd}dudd~ddididdddddddd@dd@dd@dd@dd@ddddddddddddddddidddddddddddddddddddd^ddFddeddddvddddzdd“iddēddƓddȓdd˓dd͓ddϓddѓddmddӓdd֓ddؓddړddddodd{ddܓddޓiddddddddddddddVddadddddddddddddddYdEdcdDidpdddddddddddddd|ddddd dd dd dd dd ddddddiddddddddddddddddddddddddddddddddddKiddBdd dd!dddd"dd#dd$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.idd/dd0dd1dd2dd3dd4dd?dd=dd;dd:dd>dd<dd9ddZdBdCd@d@d7dAd6d8iZeddeeddddZd S( )SingleByteCharSetModel?- #+%,7/(;!.&$)'"3015269=<8    ) 4*:>r?r<r9r8r;r7r:r6r>r=r@rA@AMBZCcDdEHFmGkeIOJKQLfN^RPnlS[TUwVW`XoYs\]_abgphijtqruvxyz{|}~z ISO-8859-5 Bulgariang! _B?FuxАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюя) charset_namelanguagechar_to_order_maplanguage_modeltypical_positive_ratiokeep_ascii_lettersalphabetz windows-1251N)#pip._vendor.chardet.sbcharsetproberrBULGARIAN_LANG_MODEL"ISO_8859_5_BULGARIAN_CHAR_TO_ORDERISO_8859_5_BULGARIAN_MODEL$WINDOWS_1251_BULGARIAN_CHAR_TO_ORDERWINDOWS_1251_BULGARIAN_MODELrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/langbulgarianmodel.pysNP       !"#$%&'()*+,-./01234B      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234E      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234H      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234K      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234N      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Q      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234T      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234W      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Z      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234]      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234`      !"#$%&'()*+,-./01234"      !"#$%&'()*+,-./01234c      !"#$%&'()*+,-./01234%      !"#$%&'()*+,-./01234f      !"#$%&'()*+,-./01234(      !"#$%&'()*+,-./01234i      !"#$%&'()*+,-./01234+      !"#$%&'()*+,-./01234l      !"#$%&'()*+,-./01234.      !"#$%&'()*+,-./01234o      !"#$%&'()*+,-./012341      !"#$%&'()*+,-./01234r      !"#$%&'()*+,-./012344      !"#$%&'()*+,-./01234u      !"#$%&'()*+,-./012347      !"#$%&'()*+,-./01234x      !"#$%&'()*+,-./01234:      !"#$%&'()*+,-./01234{      !"#$%&'()*+,-./01234=      !"#$%&'()*+,-./01234~      !"#$%&'()*+,-./01234@      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234C      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234F      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234I      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234L      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234)      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~PKH]wN΋Ypython3.10/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-310.pycnu[o ai$@sddlmZmZmZddlmZmZmZddlm Z m Z m Z ddl m Z mZmZddlmZmZmZGdddeZGdd d eZGd d d eZGd d d eZGdddeZGdddeZGdddeZdS))EUCTW_CHAR_TO_FREQ_ORDEREUCTW_TABLE_SIZE EUCTW_TYPICAL_DISTRIBUTION_RATIO)EUCKR_CHAR_TO_FREQ_ORDEREUCKR_TABLE_SIZE EUCKR_TYPICAL_DISTRIBUTION_RATIO)GB2312_CHAR_TO_FREQ_ORDERGB2312_TABLE_SIZE!GB2312_TYPICAL_DISTRIBUTION_RATIO)BIG5_CHAR_TO_FREQ_ORDERBIG5_TABLE_SIZEBIG5_TYPICAL_DISTRIBUTION_RATIO)JIS_CHAR_TO_FREQ_ORDERJIS_TABLE_SIZEJIS_TYPICAL_DISTRIBUTION_RATIOc@sLeZdZdZdZdZdZddZddZd d Z d d Z d dZ ddZ dS)CharDistributionAnalysisigGz?g{Gz?cCs0d|_d|_d|_d|_d|_d|_|dSN)_char_to_freq_order _table_sizetypical_distribution_ratio_done _total_chars _freq_charsresetselfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/chardistribution.py__init__.s z!CharDistributionAnalysis.__init__cCsd|_d|_d|_dS)zreset analyser, clear any stateFN)rrrrrrrr=s zCharDistributionAnalysis.resetcCsd|dkr ||}nd}|dkr,|jd7_||jkr.d|j|kr0|jd7_dSdSdSdS)z"feed a character with known lengthr riN) get_orderrrrr)rcharchar_lenorderrrrfeedFs  zCharDistributionAnalysis.feedcCsT|jdks |j|jkr|jS|j|jkr'|j|j|j|j}||jkr'|S|jS)z(return confidence based on existing datar )rrMINIMUM_DATA_THRESHOLDSURE_NOrSURE_YES)rrrrrget_confidenceTs  z'CharDistributionAnalysis.get_confidencecCs |j|jkSr)rENOUGH_DATA_THRESHOLDrrrrgot_enough_datads z(CharDistributionAnalysis.got_enough_datacCsdS)Nr"r)rbyte_strrrrr#isz"CharDistributionAnalysis.get_orderN) __name__ __module__ __qualname__r-r*r)r(rrr'r,r.r#rrrrr(s  rc$eZdZfddZddZZS)EUCTWDistributionAnalysisc$tt|t|_t|_t|_dSr) superr4rrrrrrrr __class__rrrr z"EUCTWDistributionAnalysis.__init__cC,|d}|dkrd|d|ddSdS)Nr ^rr"rrr/ first_charrrrr#xz#EUCTWDistributionAnalysis.get_orderr0r1r2rr# __classcell__rrr7rr4q r4cr3)EUCKRDistributionAnalysiscr5r) r6rDrrrrrrrrr7rrrr9z"EUCKRDistributionAnalysis.__init__cCr:)Nr r<rr=r"rr>rrrr#r@z#EUCKRDistributionAnalysis.get_orderrArrr7rrDrCrDcr3)GB2312DistributionAnalysiscr5r) r6rFrrrr rr rrr7rrrr9z#GB2312DistributionAnalysis.__init__cCs:|d|d}}|dkr|dkrd|d|dSdS)Nr rrEr=r<r"rrr/r? second_charrrrr#sz$GB2312DistributionAnalysis.get_orderrArrr7rrFrCrFcr3)Big5DistributionAnalysiscr5r) r6rIrr rr rr rrr7rrrr9z!Big5DistributionAnalysis.__init__cCsR|d|d}}|dkr'|dkrd|d|ddSd|d|dSdS) Nr rr=?@r"rrGrrrr#s z"Big5DistributionAnalysis.get_orderrArrr7rrIrCrIcr3)SJISDistributionAnalysiscr5r) r6rNrrrrrrrrr7rrrr9z!SJISDistributionAnalysis.__init__cCsr|d|d}}|dkr|dkrd|d}n|dkr)|dkr)d|dd}nd S||d }|d kr7d }|S) Nr rr"rMr)rr/r?rHr&rrrr#s z"SJISDistributionAnalysis.get_orderrArrr7rrNrCrNcr3)EUCJPDistributionAnalysiscr5r) r6rVrrrrrrrrr7rrrr9z"EUCJPDistributionAnalysis.__init__cCs,|d}|dkrd|d|ddSdS)Nr r<r=rr"r)rr/r$rrrr#r@z#EUCJPDistributionAnalysis.get_orderrArrr7rrVrCrVN) euctwfreqrrr euckrfreqrrr gb2312freqrr r big5freqr r r jisfreqrrrobjectrr4rDrFrIrNrVrrrrsIPKH]ZjZjRpython3.10/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-310.pycnu[o ai{@sdZdZdZdS)g?i(iii Riiii ni!i iL,iAis iiiiiL iS iii iiii.iNiii:iii?iii=iNKiil iii i i i  iii ioi$ iiii ici8iiiiiiiz|it "i ie @i\ii iiiiiiFiiM iQHiiPivif iiiiDiT iiiFiN iEi iOi/isii3<2i i&iLiiiO iiGiiM iii?ii i`iiF i*iigi Zi i:i iiKi i iiiii`iiiig i i qii~iiP i ii iii!iuii*iii i i~iiiieiGi^iii UiCiiBiiiiiii jioi/iiiOi2 i[ii i& iiiiSi(ii ip]ii6iii i' iiiiii8+i% i[ii\iiiiiX i( ii i0i iHi i i"i!i+i i1i"iii iOiG iiifi1iiiiiii2i9li,i iiiiii}ih i#iq iQiMi&i Xiii#ii iijiiMii %i ii$ii'i iiN ii i7Jii!iiiiiMii) iPiU ii ii%i i i ii i iIii3 ii iir i i iimiii$iiixii iii ii ii%i&i iiiiii&ii'iii'ii.i iiiH iiii$#iiDi&iAi iiiiiUiGiiii iQ iPiSi'iidi 0Fiii* iiiiiiiJii iUiiI iR iii<iiS i:i7 i ii i i9ii}ii iiiViPiT ii)iCiiii& i i i)iiim iiiiiii4 iiiin i*iiiiiiiO iiiii i+ i(i i iiiU i(ii5iYiji iliiuii)i i*i+iV i i=i iiiiiii4ii!iiiTi, ixiiiei iiJ iPiis i5iAiV i/iki i iili!i iiAii`ii i iAii iiii ii i iiiiiMi iiiiiiW iii it iii+}iij i8 iiiiiiiii- i)imi iiW ii ii iiaii iP iK i i,ii ii7i' iu ii{ik iiiii i9 iiiiiiiiiii1bii i iiio iiX i,iQ iiiii i i iX iii5Diiliii[i iiY ii%i. iY ii*iii iiR iii ipiincigi+iii'i2iii{iil iim iii: iifi ii|i5 iiiiZ i i i i ii i,ii ii;iiIiYiii[ iXi"ii iiii~iii,iikiii-iiiiiiDiiii>i]ii,iiiiviLiBii&iii iiiiGiiiiBii i! iiiu iiiii i iaiiiiv iS ii}i; iiDii=ii0i ii\ i( iiiivi iiii.ii9iHiiiii] iEiiiiii!ii/ iii i i-iiiQi*ii.i/iiiii0 3ii" ii*iRiiiWiii/iibi.ii iiiiiiRii ii) ii2ii iiiiiiiZ iiT iiw iiii iiiiiii[ Oii i i`i7ix i^ iiiiiii\ iiiiiiigiiin ii i_ii~iii0ii iaiiy i] iiiii ii i;i i-i iiL iii/iiii`ii#i"iiiii0i isiiiidisi iiY ii ikiwio ii iiii1ii2igip iQiiUi iv iiiCiSii^ iii5iiiBii_i ibiNiiXiiii iLici i i iKiw i* iaiGi3ii i iii1i6i i2i6 Niii i i3ii:ii\iqiiii-iii i3i iiiix i i irii4i i_ iiU iiii@ii5i ii ii ii/i+ i6i iiiiiii i7 iZ iiii8i4iiCiii iilii` iiiiiiYiii5i {iiii$i7iiMiV i0irii iigiiVii8ii9i, iZiii{i#iW i0iii$i i i ii4ii[iviiiciiViM i$i- iiiX iii idiiiWi[ iii iiiq i ii1 iiiiitiiii ii i i2 ii2i:i3 i i.iii2ii iiiii%i iii i i iiiiii i i6i i4 ii|iiiSiiii_ i iiiii`iiiii i3iii;ir iiii7iYiLi;ii i iiiiT\iiii<iiVi5 iii iii ii"ixi%ii;i8 i iii2iEi=i!iii^iiwi i"iiiis ii#i<iQiiiri$ii]ii%ii. i&i i3i5iBiiy i'iii ii i i>iY ia ib i(i i i)i*i iii:ii6ii^ii iii(i i+i+i i ixi,i i.ihi/ i-iii iVi ii hiiz i.iiii<iii;i/i?iii i i0i8i i ii5i6i i_)i1i2i i3iyi ii i i^i4i i i?i$i+i\ i i5i_iWii iz i6i0 ii i] i ip i7i ii8i^ i< iiVi9i i6 iiIwi}ic i^ii i9i@ii iAi iii i:iei1iiiBiiiiii i i ii7 i;i<ii=i{ i(i`iRi1 iYiiIi i i i6i id i>iiie i?iioiqiYiniiiliiCiDi{ ii i_ iEiPiUii i iiiiEimii@ii:i ii iAiiiiii# i iNi i iBiiCiWiTiTii iif i;iDii&i i| iiiiii iii<i= i iii iVii iioii iEi iFiii iii iiiDi-i8 iiGidi i i iHit iiiIizi iiJi i iKii i| iiiii> iiiiiiLi:i i=iiMii? i iiiHiiiiiNiii iOiPiiFikiQi9 i ii i iu iiv iiiiiiRiSiii} i i>iiiii i: iTi iiN iiCiiiiUi~ii iWiiGiiii,iiiiiOii|iiiiOi?iVi` ii ii~ i iw iiii@i!iii; iiiiWii"i iXiiYiiRig iuii ih i ix i=i iiZii< iii[i i#ii= i i\i$ii]iHiIi^i7iO i$ i i_i%iviJii i!iwitii`iaibi9 i&ii"i{i i i'iciidi8iiiii[i9iiidiZ i ieiii i@ i!i(i"ifiii i#i$iTigiKii i%iWiMihiiiiiiii%iiiii i` iiyi7imiLijiki i: i> i!iii Bi)ili|i i iziii iiMi ii iiiminiuiq ivii i i*iNioipiiqi7i.iriiy i iii iifii i isi! iyi iOi i iii+iPij i i>iiii iYi iAitiiui% i i ivi iiz i2 iwi,i i ii3iQiii ixi i6i9ik iii&6i i-i iiRiyiiQi9ici i'i.i oi(iBiFi? il i i)iei i izi iSiTi iii{i/ii" i ibi/ii`iii0iuiiviii1ii i iiUii*i i/iEiSii8iZi|i}iFi+i ii!i~i2i,iFiP iim ii iieisiiCi ir iiii iiai3iZi%i-iiii i4iiiiAiii i iii iiiiDi.iiii inii iii iii ii3 i5iJi0i is i ii ii@ iiiVii/i i i6iWiA i7ioi iiPi0ii1iin iaQi2iipi:iiPiibiiiii i{ i3i7iEiii iii| iFiGiXiiiiii]i i4iii} ii i5ii&ii8i i i iiiii iLiiiii i iYi iiiii4 i iB i9i8iiiii iHi i/i3iZi[ii io iii:i0i ini\ii]ii^iii i iiiIiiii;ii4ii<i=i;i ii iiiXi iii5 i_ii i iiiii}i0i>ip iJiiiKi i& iFiiii i i#ii[iiifi >iq ii?ir ii6iiii i iiiiijiiiii@i-ipi9i; i6iyiAiii i i' iiiiiiiViii`ii4iii iKi iai i6 i iiiiii"iiiKi i iiii iYiGioiibifici7i is ipri i8iiii i iA iQ i iC i,i ii iiii\iLiiui~ i iii9iiiBiiZiii iCiiiijidii0ihigiiei iMi} i7 i ii iiDi iiiiifi:iiiNi;i iEiFii( ii<iiiGiMi=iwigii~ it i?iiii itimi# i ii+iiihiiiii[ i iOi i iii iiB iii$ it ii iiia ii iiHiiiiiQi"i< i i ii-i1ii#iu i'iiD i i ii i iIii>iJi% iiiPi i iii i i=ia iiKiiv iiii i ii _iijii?iE i1i i iikii8iQii iliii i imi@i ibiiii iRi ii5ii iiiLi iw iiniii4iHi iiMii iiiiii\ iioiiNi] i ii ii\ix igiiEi iiiiiiipii iiqi iiiiiiOiii iri iZi isitiiii iPeiii iiioi ii^ ii}iiiiziAi& iii i iiini-ii iQiiii iiiiRiiui iiiiBiii iy ii iviwiBihiqiiii<ii*iiiSi"iTiCi>i)i ixiUiiii~iiiziiViiiiiC i)iqiiiWi i iiiDiiETiFpiii#i#iyii iiiGiiz iiiii ii iiSiiXi iiiiiu i i=iHiii_ iiRiiiiiiwiiiYizi{iqiii3ii5ii i i{ ii i|i}iSi~ii i i iZi[iiiiii` iiF ii]i i iniiiIii i iiiii iG iTiJiiKiziSiri\i) ii iv i5ii ib iiijiiiii iii]i^ii iiciiii i ii iai:i1i iiiAihi ia i i6iii ib -ii iH i_ii ii i iii iiii| ii* ifii ii i iD ii iLiWiiiiUii i ii$ii i i iNiiiR ikiiE iiiiiMiiS i' ii`iisiiF ii iai} i i i( ijii i~ iViB[ib iWi iibi iI iic i i ii{ii i ii ici i i idi i i]iiii= ieiiiiii ii iNi iiifigi i i iihiiiii =iiXiiiiiiiiid iiHiCi iiiiTiWi i ii9ii iNi iKiEiji4iJ i iYi iiG i ikiiihiOii i i i]iPiZiiliiQi[ikiiminiRioic iiiiiSiXiiii\i+iiiiiIiTiUiUii iili iDiiiipiiqi ki imii iK iiiiiiVi8 i i iiri@iWiri iCiGiii ii^i ii 8iti i:i i i!iinisi i"i i#i$i]iti i%i i&iriui'i+ i(i)iie i i}i iiii*i41i+ii i i ii ii,ii i> iXitiri? ii i-i iviui{iiw iwii.ixiT i, iii i/i0ii ii1i ii2i iGiRi i i^iiYi iZi i i[i3i^iiii ii i) i\i i4i@ivii5ii6i7iid i]i ii^i8ii&i i i i9 iyiui i iiziRii{ii ii(i_ii<i9iili iii_i iSi`iki i[i iii ixi:i i;i<i! i$i=ii|iii>idi i i?iei iiii ii iii i}i@iAiBii.i~iaiOi i ii`ibii i%i iii i;i iiiiCiiDi iiiif i" iL i i i ii iEi;iiFi&iGi i iix iHi)iiiciiIidiTii i ieiiiii iiJi igi~iUiie i iiiifiai8igi i ibihiKiy iii iLii: i iii i*iM iiii icitiiMiNiii ii ii iiif iiiYidiei*i iiOiH ii# ii#i; i i iiiiI i\i@ iii isi$ i iPiQi i i iRijiSiTii+iiUiiVi iiLi i!i iJ i\4iWi iiXiYiZii[i>iwikifiii+iii% iii$ii\iiiili i]iili^i_ig i%ii`iaigiiii iiN iK ibicidii ic iwi iei ibiyi ifihigihihii'iii imiiz ijid iii i i i<iii|iiiii iiiO iki iliii iaiiimiii ini iiui iniiiie i& i ioiii i i< iipiqiP iQ iiji ii iii(ii_irisi i iii<iEiR ifiiii]iiiIiti=iiuiivii iioi i iki,iliwi' ii imiiiiFi`ii if i ii iSiJixiiyiziniiL ipiOii i i{i i iiA iyiiiU i|i}i~iFi iqii i iiiiii iiiipiiiB iioi iiiipii- iiriiiqiqii( iiriiiisi iii iii i(i. isi) iiti i ii* iiuiiiTiviM i{ iiitii'iiii iiiiiiiig iZiwi i iciiji+ ipiiiixiii ih iiii iiii i, i= i ii i iuiiiii/ iyii i iyivi i iiwiiiiii ii iziiiii>iiCi'iiii{iiZiiii iii iiaiii iiqi?ii ii|ii i"ii ii i}iiiii=iiAi i1ii)iiii?i i iiiixi ii ii i i iihiiS iiii(ii iii'ixiyii ii i i iiiii_i iii> ii}iPiii iiii~ii iN iicii iiiiHii ii iiiiiiiiiiiiij iii i* iiii i i iiih iii_ii/i i<ii~i7ik iT iii]i iU ibi itiiig iizii ii| iiiiiiiii{iii ii0 ii ii+ i i, iiiIiiiii i iiiBi ii4isi iiiii i iii?iCiii iiGi iiiiiiiiiiiiiii|i1 iiimiC iiil iiii i} ii? iiii iiih iiiIiiiiV iiiiiiii^iiii i- i. iii)iii iiii2 iiiiii ii iiAii ii- iiiii i ii ii iiiiii ii iii iiiQi i iO iiiiiiiiziKii i[i iJiii@ ii. iiiiiD ii}i/ i@ii iii i i@iiRiii ij i~iiiJiii iiii i0 iimiiiim i~ ii i ii1 iii iiiiii idiiiiXiii9iii iiiUiiiiiiLii3 ii ii i i iii i ii iii$i(iviii&iibii iii i iiiiii{iiiiiiiiiii2 ii iiii iii iiiiiiii^iiiV i iiiiiiiiiiiiii2iW ii iW ioii iik iX iii iA i4 ii ii3 iii iii ii iii iiiiiii i iHiiiiiiiiiiiDiiiIisi iii ii iiiiiwii{iiiiiii/ in i,iiiii i iii ii ii i ii4 iB iiiiP i5 i ii i ii ii iii|iiziiiii i'ii5 iiii! ii yiiiViii i i iiiiiiiiii i iii-iiiiii ii i i iiii ii" i%iiiiJiC iixiiii i i iil i6 iiiii ii iiiXii ii7 ii i iNi im iiii iWi i i!i ii i i>i8 ii"i#i9 ij iD i i ii$i i%ii iiiXi&ii'iE i i(iF ii)iixi ikiiiii*i+ii iiDiii,iiiiiiiKi-i.i/i: ii0iJiii1i|i iii iii iEi*i2i iiiiiiHixi iii3ii iii3iiii; ipii< i iii ii4i5i i i6iiOi i7i8ii9ii:i ii;iiiii<i iiY i=i>i i i?ii@iAiBi i ii= i iiio i ifiiii i i i iCi iDii# ii i> iiEii iFiZ iE iii i[ i$ i iiGi? ii iiiG iiii@ iHiiA i\ iLiiiii iIi i iiiiiiiJi i i i iKiLi] iMiNi iijiiQ i iB iOiPiiiQi iiiRi iSiTii(iiiiC iiUiiVi iWiXiiiYiiiiZiidi[iciH ii_ii#i0 i\ii]iini i iiii^iii_ik iD ii`iaii ibii i iciiiiidiii iiiidi^ iE ieiiii iiiifii_ i7iiii i iiF iiigi-iii! iiihi iqi;i iiiiXii i iiiiijiiii ikiliii~imiG i` iniyip iiioi>iipiiqi iiiriia iiiisiti" iui|ii?iiiiviiiiiieiiiwixiyiiiiizi{i@i|ii i}i i iii% isiiR ii.iiMi?i ii~iiib iii@ii iiiii iiiiiiii ii6 iI iiii iiiiic iiiiii i i2iiiimii@iiii iiiNii iifiiiiZi iiiiii i\iH iid iiiJ ii ii i iiii iiK iiii# iiii ii iiiiKiiiiigiiiihii>ii.iiiiiiiii)in tiiiii io i iI i i iiiq iiir i iiiiip ii ii iziiiiUiiJ iii1 iK itiiiiii iiiJiiiL i iiiiiiN) EUCTW_TYPICAL_DISTRIBUTION_RATIOEUCTW_TABLE_SIZEEUCTW_CHAR_TO_FREQ_ORDERrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/euctwfreq.pys+PKH]о* Vpython3.10/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-310.pycnu[o ai@s0ddlZddlZddlmZGdddeZdS)N) ProbingStatec@sneZdZdZdddZddZeddZd d Zed d Z d dZ e ddZ e ddZ e ddZdS) CharSetProbergffffff?NcCsd|_||_tt|_dSN)_state lang_filterlogging getLogger__name__logger)selfrr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/charsetprober.py__init__'szCharSetProber.__init__cCs tj|_dSr)r DETECTINGrr r r rreset,s zCharSetProber.resetcCdSrr rr r r charset_name/szCharSetProber.charset_namecCrrr )r bufr r rfeed3zCharSetProber.feedcCs|jSr)rrr r rstate6szCharSetProber.statecCsdS)Ngr rr r rget_confidence:rzCharSetProber.get_confidencecCstdd|}|S)Ns([-])+ )resub)rr r rfilter_high_byte_only=sz#CharSetProber.filter_high_byte_onlycCs\t}td|}|D] }||dd|dd}|s&|dkr&d}||q |S)u9 We define three types of bytes: alphabet: english alphabets [a-zA-Z] international: international characters [€-ÿ] marker: everything else [^a-zA-Z€-ÿ] The input buffer can be thought to contain a series of words delimited by markers. This function works to filter all words that contain at least one international character. All contiguous sequences of markers are replaced by a single space ascii character. This filter applies to all scripts which do not use English characters. s%[a-zA-Z]*[-]+[a-zA-Z]*[^a-zA-Z-]?Nr) bytearrayrfindallextendisalpha)rfilteredwordsword last_charr r rfilter_international_wordsBs  z(CharSetProber.filter_international_wordscCst}d}d}tt|D]7}|||d}|dkrd}n|dkr$d}|dkrD|sD||kr@|s@|||||d|d}q |sP|||d |S) a Returns a copy of ``buf`` that retains only the sequences of English alphabet and high byte characters that are not between <> characters. Also retains English alphabet and high byte characters immediately before occurrences of >. This filter can be applied to all scripts which contain both English characters and extended ASCII characters, but is currently only used by ``Latin1Prober``. Frr>s PKH]Xpython3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-310.pycnu[o ai@sddlmZddlmZddlmZddlmZddlm Z ddl m Z ddl m Z ddlmZdd lmZGd d d eZd S) )CharSetGroupProber) UTF8Prober) SJISProber) EUCJPProber) GB2312Prober) EUCKRProber) CP949Prober) Big5Prober) EUCTWProbercseZdZdfdd ZZS)MBCSGroupProberNcsDtt|j|dttttttt t g|_ | dS)N) lang_filter) superr __init__rrrrrrr r probersreset)selfr  __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/mbcsgroupprober.pyr*s zMBCSGroupProber.__init__)N)__name__ __module__ __qualname__r __classcell__rrrrr )sr N)charsetgroupproberr utf8proberr sjisproberr eucjpproberr gb2312proberr euckrproberr cp949proberr big5proberr euctwproberr r rrrrs         PKH]\66[python3.10/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-310.pycnu[o aiL@sbddlmZididdddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0d+d1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddddddddd+ddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,d+d-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*d+d+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddddddddd+ddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddddddddddddd+d dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0d+d1dd2dd3dd4dddddddddddddd5 d iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+ddddddddddddd dd!dd"dd#did$dd%dd&dd'd+d(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!d+d"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddddddddd+ddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dddddddd+ddddd dd!d+d"dd#did$dd%dd&dd'd+d(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dddddddd+ddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4ddddd+ddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 ididdddddddddd dd dd dd dd dddddddddddddddidddddddddddd+ddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0d+d1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+ddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddd+dd+dd+dddddd+d d+d!d+d"d+d#d+id$d+d%d+d&d+d'dd(d+d)d+d*d+d+d+d,d+d-d+d.dd/dd0d+d1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dd+dddddd+ddddd dd!d+d"dd#did$dd%dd&dd'd+d(dd)d+d*dd+dd,d+d-dd.dd/dd0dd1dd2dd3dd4ddddd+d+dd+dddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddddddddd+ddddd d+d!d+d"dd#did$dd%dd&dd'd+d(dd)dd*d+d+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dddddddd+ddddd dd!d+d"d+d#did$dd%dd&d+d'd+d(dd)d+d*d+d+d+d,d+d-d+d.dd/dd0dd1dd2dd3dd4ddddd+d+d+d+d+ddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddd+dd+dd+dddd+dd+d d+d!d+d"d+d#d+id$d+d%d+d&d+d'dd(d+d)d+d*d+d+d+d,dd-d+d.dd/dd0d+d1dd2dd3dd4ddddd+ddddddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dddddddd+ddddd dd!d+d"dd#did$dd%dd&dd'd+d(dd)d+d*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4ddddd+d+ddd+ddddd5 diddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dd+dddddd+dddd+d d+d!d+d"d+d#did$d+d%dd&d+d'd+d(dd)d+d*d+d+d+d,d+d-d+d.dd/d+d0dd1dd2dd3dd4ddddd+d+dd+dddddd5 d iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dddddddd+ddddd dd!d+d"dd#did$dd%dd&dd'd+d(dd)dd*dd+dd,d+d-dd.dd/dd0dd1dd2dd3dd4ddddd+d+d+ddddddd5 d!iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dd+dd+dd+dd+dd+dd+d d+d!dd"dd#d+id$d+d%d+d&d+d'dd(dd)d+d*d+d+d+d,d+d-d+d.dd/dd0d+d1dd2dd3dd4ddddd+ddd+dddddd5 d"iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dddddd+dd+ddddd dd!dd"dd#did$dd%dd&dd'd+d(dd)dd*dd+d+d,d+d-dd.dd/dd0dd1dd2dd3dd4ddddd+d+dd+d+d+dddd5 d#iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dd+dddddd+ddddd dd!d+d"dd#d+id$d+d%dd&d+d'd+d(dd)d+d*d+d+d+d,d+d-dd.dd/dd0dd1dd2dd3dd4ddddd+d+d+dd+dd+ddd5 id$iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dddd+dd+dd+dd+dd+d d+d!d+d"d+d#d+id$d+d%d+d&d+d'd+d(dd)dd*d+d+d+d,d+d-d+d.dd/d+d0dd1dd2dd3dd4ddddd+d+d+d+d+ddd+dd5 d%iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dd+dddddd+ddddd dd!d+d"dd#did$d+d%d+d&dd'd+d(d+d)dd*dd+dd,d+d-dd.dd/dd0dd1dd2dd3dd4ddddd+d+dddddddd5 d&iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dd+dd+dd+dd+dddd+d d+d!d+d"dd#d+id$dd%dd&d+d'd+d(dd)dd*d+d+d+d,d+d-dd.dd/d+d0d+d1dd2dd3dd4ddddd+d+ddd+dd+ddd5 d'iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddd+dd+dd+dddddd+d d+d!dd"dd#d+id$d+d%d+d&d+d'dd(d+d)d+d*d+d+d+d,dd-d+d.dd/dd0d+d1dd2dd3dd4dddddddddddddd5 d(iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dddddddd+ddddd dd!d+d"dd#did$d+d%dd&dd'd+d(d+d)d+d*dd+dd,d+d-dd.dd/dd0dd1dd2dd3dd4ddddd+d+dddddddd5 d)iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dd+dd+dd+dd+dddd+d dd!d+d"d+d#d+id$d+d%d+d&d+d'd+d(dd)d+d*d+d+d+d,d+d-d+d.dd/dd0d+d1dd2dd3dd4ddddd+d+dd+d+d+d+ddd5 d*iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dd+dddddd+ddddd dd!d+d"dd#d+id$dd%d+d&d+d'd+d(dd)d+d*d+d+d+d,d+d-dd.dd/dd0d+d1dd2dd3dd4ddddd+d+d+d+d+d+d+ddd5 d+iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dd+dddddd+ddddd d+d!d+d"d+d#d+id$d+d%dd&d+d'd+d(dd)d+d*d+d+d+d,d+d-d+d.dd/d+d0dd1dd2dd3dd4ddddd+d+dd+d+d+d+d+dd5 d,iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddddddd+dddddd+d dd!dd"dd#d+id$d+d%d+d&d+d'dd(dd)d+d*d+d+d+d,dd-d+d.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d-iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dddddddd+ddddd dd!d+d"dd#did$dd%dd&dd'd+d(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4ddddd+d+dddddddd5 d.iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d/iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dddddddd+ddddd dd!d+d"dd#did$dd%dd&d+d'd+d(dd)dd*d+d+d+d,d+d-d+d.dd/dd0dd1dd2dd3dd4ddddd+d+ddd+ddddd5 d0iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddd+dddddd+dd+ddddd dd!d+d"dd#d+id$dd%d+d&d+d'd+d(dd)dd*d+d+d+d,d+d-dd.dd/dd0d+d1dd2dd3dd4ddddd+d+d+d+d+dd+ddd5 d1iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d2iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*d+d+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d3iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d4iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddd+dd+dd+dddddd+d dd!dd"d+d#d+id$d+d%d+d&d+d'dd(dd)d+d*d+d+d+d,dd-d+d.dd/dd0d+d1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddd+dddd+dddddd+d d+d!dd"dd#d+id$d+d%d+d&d+d'dd(d+d)d+d*d+d+d+d,dd-d+d.dd/dd0d+d1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddddddddddddd+d dd!dd"dd#did$dd%dd&d+d'dd(dd)d+d*dd+d+d,dd-d+d.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddd+dddd+ddddddd dd!dd"dd#d+id$d+d%dd&d+d'dd(dd)d+d*d+d+d+d,dd-dd.dd/dd0d+d1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddd+ddddddddddd dd!dd"dd#d+id$d+d%d+d&d+d'dd(dd)d+d*d+d+d+d,dd-d+d.dd/dd0d+d1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddddddddddddd+d dd!dd"d+d#did$d+d%dd&dd'dd(dd)d+d*d+d+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddidddddddddddddddddddddddddd+d dd!dd"dd#d+id$d+d%dd&d+d'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$d+d%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddddddd dd!dd"dd#did$dd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d5 Zidd6dd6dd6d+d6d&d6d*d6d$d6d#d6d'd6d!d6d)d7d0d6dd6d%d7d8d6d9d6d/d6idd6dd6d-d6d d6d,d6d"d6d(d6d:d6d;d6dd6dd6dd6dd6dd?dd?idd?dd?dd?dd?d d?d d?dd?dd?d@d?dd?d2d?dd?dd?dd?ddAd dAd dAid1dAddAd dAddAddAdBdAddAd4d?dCd?dDd?d3d?d.d?dEd?dFd?dGddHddIdidJddKddLd dMd dNd dOd dPd dQddRddSddTddUddVddWdNdXddYddZdid[dd\dd]dFd^dJd_dd`ddad?dbd?dcd?ddd?ded?dfd?dgddhddiddjddkdidlddmddnd dod!dpd"dqd#drd$dsd%dtd&dud'dvd(dwdIdxd)dyd*dzd+d{d,d|d-id}dGd~d.dd/dd0dd?dd?dd?dd?dd?ddddddddddddddddiddddddddddddddddddddddddddTddddKddddiddddddddddddddÓddœddƓddǓddȓddɓddʓdd˓ddRdd̓dd͓iddΓddϓddГddѓddғddӓddWddԓddՓdd֓ddדddؓddٓddړddۓddܓddݓiddޓddߓdddddddddd1ddYddddVdddddddddd2ddddidddd3dddddddddddd4ddddHddCddddddddDddLddEiddddddddZdd8ddQddddMddXddddOdddd9dd[ddUdd\dd=iddSdd]dddddddd;ddPdd@dd:dddddddd>ddBdAd<d?dd7dAd6d?iZeddeeddddZidd6dd6dd6d+d6d&d6d*d6d$d6d#d6d'd6d!d6d)d7d0d6dd6d%d7d8d6d9d6d/d6idd6dd6d-d6d d6d,d6d"d6d(d6d:d6d;d6dd6dd6dd6dd6dd?dd?idd?dd?dd?dd?d d?d d?dd?dd?d@d?dd?d2d?dd?dd?dd?ddAd dAd dAid1dAddAd dAddAddAdBdAddAd4d?dCd?dDd?d3d?d.d?dEd?dFd?dGddHddIdidJddKddLd dMd dNd dOd dPd dQddRddSddTddUddVddWdMdXddYddZdid[dd\dd]dFd^dJd_dd`ddad?dbd?dcd?ddd?ded?dfd?dgddhddiddjddkdidlddmddnd dod!dpd"dqd#drd$dsd%dtd&dud'dvd(dwdIdxd)dyd*dzd+d{d,d|d-id}dGd~d.dd/dd0dd?dd?dd?dd?dd?dd“ddēddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddÓddœddƓddǓddȓddɓddʓdd˓ddQdd̓dd͓iddΓddϓddГddѓddғddӓddUddԓddՓdd֓ddדddؓddٓddړddۓddܓddݓiddޓddߓdddddddddd1ddWddddTdddddddddd2ddddidddd3dddddddddddd4ddddHddCddddddddDddKddEiddddddddXdd8ddPddddLddVddddNdddd9ddYddSddZdd=iddRdd[dddddddd;ddOdd@dd:dddddddd>ddBdAd<d?dd7dAd6d?iZeddeeddddZd S( )SingleByteCharSetModel(6- 21&'5$)"#/.+!%9074    > 3,=:) ;<?*8r9r:r=r<r?r;r>r@rAr6r7r8@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~z windows-1250Z Hungariang(P?TuPABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvzÁÉÍÓÖÚÜáéíóöúüŐőŰű) charset_namelanguagechar_to_order_maplanguage_modeltypical_positive_ratiokeep_ascii_lettersalphabetz ISO-8859-2N)#pip._vendor.chardet.sbcharsetproberrZHUNGARIAN_LANG_MODELZ$WINDOWS_1250_HUNGARIAN_CHAR_TO_ORDERZWINDOWS_1250_HUNGARIAN_MODELZ"ISO_8859_2_HUNGARIAN_CHAR_TO_ORDERZISO_8859_2_HUNGARIAN_MODELr r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/langhungarianmodel.pysNP       !"#$%&'()*+,-./01234B      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234E      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234H      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234K      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234N      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Q      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234T      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234W      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Z      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234]      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234`      !"#$%&'()*+,-./01234"      !"#$%&'()*+,-./01234c      !"#$%&'()*+,-./01234%      !"#$%&'()*+,-./01234f      !"#$%&'()*+,-./01234(      !"#$%&'()*+,-./01234i      !"#$%&'()*+,-./01234+      !"#$%&'()*+,-./01234l      !"#$%&'()*+,-./01234.      !"#$%&'()*+,-./01234o      !"#$%&'()*+,-./012341      !"#$%&'()*+,-./01234r      !"#$%&'()*+,-./012344      !"#$%&'()*+,-./01234u      !"#$%&'()*+,-./012347      !"#$%&'()*+,-./01234x      !"#$%&'()*+,-./01234:      !"#$%&'()*+,-./01234{      !"#$%&'()*+,-./01234=      !"#$%&'()*+,-./01234~      !"#$%&'()*+,-./01234@      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234C      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234F      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234I      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234L      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234)      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~PKH]d6dd6dd6dd6d d6dd6dd6dd6d d6d?d6idd6dd6d d6d4d6d@d6dd6d/d6d0d6dAd6d d6dBd6dd6d3d6dCd6dDddEddFdidGddHddIddJddKd dLd dMd dNd dOd dPddQddRddSddTdHdUddVddWdidXddYddZdd[dDd\dd]dd^d6d_d6d`d6dad6dbd6dcd6ddddeddfddgddhdidid djd!dkd"dlddmd#dnd$dod%dpd&dqd'drd(dsd)dtdCdud*dvd+dwd,dxd-dyd.idzd/d{d0d|d1d}d2d~d6dd6dd6dd6dd6ddddddddddddddddiddddddddddddddddddddddddddddddhddddiddddddddddddddmddddddddddddddddgddddiddddddddddddddaddSdd`ddddldddddd3ddddddiddddddddddddddkddLddfddRddXdd~dd4dd}ddedd_dd|idd{dd^ddjddzddGddyddxdddddwddvdd?dd]dduddtddsddrdd@idd>dd=ddYdd\ddIddAddQddJddUdd[dd;ddPddEddWddVddqddNiddBddcdd:ddFddpddMddZddidd<ddbddTddoddOddKdd8dd7dd9d6dniZeddeeddddZdS( )SingleByteCharSetModel%/'4$-5<1.*0,#3&>+8     9: ?6) 27;!=")(r?r<rAr=r9r;r@r>r6r7r8r:@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~z ISO-8859-9TurkishgX4 ?TuRABCDEFGHIJKLMNOPRSTUVYZabcdefghijklmnoprstuvyzÂÇÎÖÛÜâçîöûüĞğİıŞş) charset_namelanguagechar_to_order_maplanguage_modeltypical_positive_ratiokeep_ascii_lettersalphabetN)#pip._vendor.chardet.sbcharsetproberrTURKISH_LANG_MODEL ISO_8859_9_TURKISH_CHAR_TO_ORDERISO_8859_9_TURKISH_MODELrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/langturkishmodel.pys,J       !"#$%&'()*+,-./01234B      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234E      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234H      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234K      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234N      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Q      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234T      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234W      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Z      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234]      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234`      !"#$%&'()*+,-./01234"      !"#$%&'()*+,-./01234c      !"#$%&'()*+,-./01234%      !"#$%&'()*+,-./01234f      !"#$%&'()*+,-./01234(      !"#$%&'()*+,-./01234i      !"#$%&'()*+,-./01234+      !"#$%&'()*+,-./01234l      !"#$%&'()*+,-./01234.      !"#$%&'()*+,-./01234o      !"#$%&'()*+,-./012341      !"#$%&'()*+,-./01234r      !"#$%&'()*+,-./012344      !"#$%&'()*+,-./01234u      !"#$%&'()*+,-./012347      !"#$%&'()*+,-./01234x      !"#$%&'()*+,-./01234:      !"#$%&'()*+,-./01234{      !"#$%&'()*+,-./01234=      !"#$%&'()*+,-./01234~      !"#$%&'()*+,-./01234@      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234C      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234F      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234I      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234L      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234)      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~PKH]e?r r Rpython3.10/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-310.pycnu[o ain@sXddlmZddlmZddlmZmZmZddlm Z m Z m Z m Z GdddeZ dS)) CharSetProber)CodingStateMachine)LanguageFilter ProbingState MachineState) HZ_SM_MODELISO2022CN_SM_MODELISO2022JP_SM_MODELISO2022KR_SM_MODELcsVeZdZdZdfdd ZfddZeddZed d Zd d Z d dZ Z S)EscCharSetProberz This CharSetProber uses a "code scheme" approach for detecting encodings, whereby easily recognizable escape or shift sequences are relied on to identify these encodings. Ncstt|j|dg|_|jtj@r"|jtt |jtt |jtj @r0|jtt |jtj @r>|jttd|_d|_d|_d|_|dS)N) lang_filter)superr __init__ coding_smr rCHINESE_SIMPLIFIEDappendrrrJAPANESEr KOREANr active_sm_count_detected_charset_detected_language_statereset)selfr  __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/escprober.pyr*s    zEscCharSetProber.__init__csJtt||jD] }|sq d|_|q t|j|_d|_d|_dS)NT) r r rractivelenrrr)rrrrrr:s    zEscCharSetProber.resetcC|jSNrrrrr charset_nameEzEscCharSetProber.charset_namecCr r!)rr#rrrlanguageIr%zEscCharSetProber.languagecCs|jrdSdS)NgGz?gr"r#rrrget_confidenceMszEscCharSetProber.get_confidencecCs|D]L}|jD]F}|r|jsq||}|tjkr4d|_|jd8_|jdkr3tj|_|j Sq|tj krMtj |_| |_ |j|_|j Sqq|j S)NFr)rr next_staterERRORrrNOT_MErstateITS_MEFOUND_ITget_coding_state_machinerr&r)rbyte_strcr coding_staterrrfeedSs(       zEscCharSetProber.feedr!) __name__ __module__ __qualname____doc__rrpropertyr$r&r'r3 __classcell__rrrrr #s   r N) charsetproberrcodingstatemachinerenumsrrrescsmrrr r r rrrrs  PKH]]:LLWpython3.10/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-310.pycnu[o ai݄@s6_ddlmZididdddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 d iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0d(d1dd2dd3dd4dd5dddddd(dddddd6 d iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5ddd(ddddddddd6 d iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.d(d/dd0d(d1dd2dd3d(d4d(d5dddd(dddddddd6 d iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 d iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,d(d-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(d(d)dd*dd+dd,d(d-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"dd#dd$d(ddid%dd&d(d'dd(dd)dd*dd+dd,dd-d(d.d(d/dd0d(d1dd2dd3d(d4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$ddd(id%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"dd#dd$ddd(id%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 ididdddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(d(d)dd*dd+dd,d(d-dd.dd/dd0dd1dd2dd3d(d4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,d(d-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$ddd(id%dd&dd'dd(d(d)dd*dd+dd,dd-dd.dd/dd0dd1dd2d(d3dd4d(d5ddddddddddd(d6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddd(dddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(d(d)dd*d(d+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5ddd(d(dddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$ddd(id%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2d(d3dd4dd5ddddddddddd(d6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3d(d4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4d(d5dddddddddddd6 d iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 d!iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%d(d&d(d'd(d(d(d)d(d*dd+d(d,dd-d(d.d(d/d(d0d(d1d(d2dd3d(d4d(d5d(d(d(dd(d(d(ddddd6 d"iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$ddd(id%dd&d(d'dd(d(d)dd*dd+d(d,dd-d(d.d(d/d(d0d(d1d(d2d(d3d(d4d(d5d(d(d(dd(d(d(ddddd6 d#iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&d(d'd(d(dd)dd*dd+d(d,dd-d(d.dd/d(d0d(d1dd2dd3d(d4d(d5d(d(d(ddd(dddddd6 d$iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$ddd(id%dd&d(d'd(d(d(d)d(d*d(d+d(d,dd-d(d.d(d/d(d0d(d1d(d2d(d3d(d4d(d5d(d(d(ddd(dd(dddd6 diddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$d(ddid%d(d&d(d'd(d(dd)d(d*dd+d(d,d(d-d(d.d(d/d(d0d(d1d(d2dd3d(d4d(d5d(d(d(d(d(d(dddddd6 id%iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"dd#d(d$ddd(id%dd&dd'dd(d(d)dd*dd+dd,d(d-dd.d(d/dd0dd1dd2d(d3dd4d(d5dddddddddddd6 d&iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"d(d#d(d$d(dd(id%dd&d(d'dd(d(d)dd*d(d+dd,d(d-d(d.d(d/d(d0d(d1d(d2d(d3dd4d(d5dddddd(dd(d(dd(d6 d'iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"d(d#d(d$d(dd(id%dd&dd'dd(d(d)dd*d(d+dd,d(d-dd.dd/dd0dd1dd2d(d3dd4d(d5dddd(dddd(d(d(d(d6 d(iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"dd#dd$d(ddid%d(d&d(d'd(d(dd)dd*dd+d(d,d(d-d(d.d(d/d(d0d(d1d(d2dd3d(d4d(d5d(d(d(d(d(d(dd(dd(dd6 d)iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(d(d)dd*d(d+dd,dd-dd.dd/dd0dd1dd2d(d3dd4dd5dddddddd(dddd6 d*iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&d(d'dd(dd)dd*dd+d(d,dd-d(d.d(d/d(d0d(d1dd2dd3dd4d(d5d(d(d(ddd(dddddd6 d+iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"d(d#d(d$ddd(id%dd&dd'dd(d(d)dd*d(d+dd,d(d-dd.dd/d(d0dd1dd2d(d3dd4d(d5dddd(dddd(d(d(d(d6 d,iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"d(d#d(d$ddd(id%d(d&d(d'd(d(d(d)dd*d(d+d(d,dd-d(d.d(d/d(d0d(d1d(d2d(d3d(d4d(d5d(d(d(ddd(dd(d(dd(d6 d-iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"d(d#d(d$d(dd(id%dd&dd'd(d(d(d)dd*d(d+dd,d(d-d(d.d(d/d(d0dd1dd2d(d3dd4d(d5ddd(d(dddd(d(d(d(d6 d.iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"d(d#d(d$d(dd(id%dd&dd'dd(d(d)dd*d(d+dd,d(d-dd.d(d/dd0dd1dd2d(d3d(d4dd5ddd(d(dddd(d(d(d(d6 d/iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"d(d#d(d$d(dd(id%d(d&dd'dd(d(d)dd*d(d+dd,d(d-dd.dd/d(d0d(d1dd2d(d3d(d4dd5ddddd(ddd(d(ddd6 d0iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"d(d#d(d$d(dd(id%dd&dd'd(d(d(d)dd*d(d+d(d,d(d-dd.dd/dd0dd1dd2d(d3dd4dd5dd(d(d(dddd(d(d(d(d6 d1iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"d(d#d(d$ddd(id%dd&dd'dd(d(d)dd*d(d+dd,dd-dd.dd/dd0dd1dd2d(d3dd4dd5ddd(ddddd(dd(dd6 d2iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#d(d$d(ddid%d(d&d(d'd(d(d(d)dd*d(d+d(d,d(d-d(d.d(d/d(d0d(d1dd2dd3d(d4d(d5d(d(d(d(d(d(dddd(dd6 d3iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"d(d#d(d$d(dd(id%dd&dd'dd(d(d)dd*d(d+dd,d(d-dd.d(d/dd0dd1dd2d(d3dd4d(d5ddd(d(dddd(d(dd(d6 d4iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"d(d#d(d$d(dd(id%dd&d(d'dd(d(d)dd*d(d+d(d,d(d-d(d.dd/d(d0d(d1dd2d(d3dd4dd5ddd(d(d(d(dd(d(d(d(d6 d5iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#d(d$d(dd(id%d(d&dd'dd(d(d)dd*d(d+d(d,d(d-d(d.dd/d(d0dd1dd2d(d3d(d4dd5dd(d(d(d(d(dd(d(d(dd6 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"d(d#d(d$d(dd(id%dd&dd'dd(d(d)dd*d(d+dd,d(d-dd.dd/d(d0dd1dd2d(d3dd4d(d5dd(d(d(dddd(d(d(d(d6 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#d(d$ddd(id%dd&d(d'dd(dd)dd*dd+d(d,dd-d(d.d(d/d(d0d(d1d(d2d(d3d(d4d(d5d(d(d(ddd(dddddd6 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"d(d#d(d$d(dd(id%dd&dd'dd(d(d)dd*dd+dd,d(d-dd.dd/dd0dd1dd2d(d3dd4d(d5ddd(d(dddd(d(ddd6 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!d(d"dd#d(d$d(dd(id%dd&dd'dd(d(d)dd*dd+dd,d(d-dd.dd/dd0d(d1dd2d(d3dd4d(d5ddd(d(dddd(d(d(d(d6 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(d(d)dd*d(d+dd,dd-dd.dd/dd0dd1dd2dd3dd4dd5dddddddddddd6 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&d(d'dd(dd)dd*dd+d(d,dd-dd.dd/d(d0d(d1dd2dd3d(d4d(d5d(d(d(ddddddddd6 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%d(d&d(d'd(d(dd)dd*dd+dd,dd-d(d.d(d/d(d0d(d1dd2dd3d(d4d(d5d(d(d(ddd(dddddd6 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'dd(d(d)dd*dd+d(d,dd-d(d.d(d/d(d0d(d1dd2d(d3d(d4d(d5d(d(d(ddddddddd6 iddddddddddd dd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dddid%dd&dd'd(d(dd)dd*dd+dd,dd-dd.dd/d(d0d(d1dd2dd3dd4d(d5d(d(d(ddddddddd6 d6 Zidd7dd7dd7d(d7d2d7d,d7d0d7d8d7d4d7d3d7d/d9d-d7d:d7d*d9d5d7d$d7d.d7id!d7d"d7d;d7d&d7d'd7d#d7dd7d?d7d@d7d%d7d1d7d d7d)dAddAiddAddAddAddAddAddAddAddAdBdAd dAddAddAd dAddAddCddCddCid dCddCddCd dCddCddCd dCddAddAddAddAdDdAdEdAdFdAdGdHdIdJdKdLidMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedcdfdgdHdhdididjdKidddkdldmdndod`dpdqdrdsdtdudAd^dAdvdAdNdAdodAdwdAdxdUdPdQdpdedJdfdRdidVdwdydvdLdqdhdMdzd{d|dxd}d_drdld~dOdXdddadbddkdGddIdTdd\d]dgdzidmdyd{dndd|ddddAddAddAddAddAdd7dd7dd7dd7dd7dd7dd7dd7idd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7idd7dd7dd7dd7dd7dd7dd7ddAddddddAddAddAddAddAddAddAiddAddAddAddYddAddAddAddAddAddAddddAddAdddd ddSddWidZdAdtd ddAdd}dddd~dd dd dd dddddduddddddddddiddddddddddddddۓddddddddddddjdd dd{dddd!idd"dd#dd$dddddd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0idd1dd2dd3dd4dd5dd8dddd:dd@dd<ddBdd=ddFdd[dCd;dAd>d9d?d7dAiZeddeeddddZidd7dd7dd7d(d7d2d7d,d7d0d7d8d7d4d7d3d7d/d9d-d7d:d7d*d9d5d7d$d7d.d7id!d7d"d7d;d7d&d7d'd7d#d7dd7d?d7d@d7d%d7d1d7d d7d)dAddAiddAddAddAddAddAddAddAddAdBdAd dAddAddAd dAddAddCddCddCid dCddCddCd dCddCddCd dCddAddAddAddAdDdAdEdAdFdAdGdHdIdJdKdLidMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedcdfdgdHdhdididjdKidddkdldmdndod`dpdqdrdsdtdudAd^dAdvdAdNdAdodAdwdAdxdUdPdQdpdedJdfdRdidVdwdydvdLdqdhdMdzd{d|dxd}d_drdld~dOdXdddadbddkdGddIdTdd\d]dgdzidmdyd{dndd|ddddAddAddAddAddAdd7dd7dd7dd7dd7dd7dd7dd7idd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7dd7idd7dd7dd7dd7dd7dd7dd7ddAddddsddAddAddAddAddAddAddAiddAddAddAddYddAddAddAddAddAddAdddddddddd ddSddWidZdAdtd ddAdd}dddd~dd dd dd dddddduddddddddddiddddddddddddddۓddddddddddddjdd dd{dddd!idd"dd#dd$dddddd%dd&dd'dd(dd)dd*dd+dd,dd-dd.dd/dd0idd1dd2dd3dd4dd5dd8dddd:dd@dd<ddBdd=ddFdd[dCd;dAd>d9d?d7dAiZeddeeddddZd S( )SingleByteCharSetModel<7:$=.63+)"(4/,5&1;'#0%!-829    ) r *r7r8r=r:r<r>r?r9r;>?@ARBdChD^EbFeGtHfIoJKuL\MXNqOUPQviSTrVwW_cYmZ[]`agjxklnpsyz{|}~z windows-1253Greekgs?Fu~ΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπρςστυφχψωόύώ) charset_namelanguagechar_to_order_maplanguage_modeltypical_positive_ratiokeep_ascii_lettersalphabetz ISO-8859-7N)#pip._vendor.chardet.sbcharsetproberrGREEK_LANG_MODEL WINDOWS_1253_GREEK_CHAR_TO_ORDERWINDOWS_1253_GREEK_MODELISO_8859_7_GREEK_CHAR_TO_ORDERISO_8859_7_GREEK_MODELrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/langgreekmodel.pys M       !"#$%&'()*+,-./01234@      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234?      !"#$%&'()*+,-./01234~      !"#$%&'()*+,-./01234>      !"#$%&'()*+,-./01234}      !"#$%&'()*+,-./01234=      !"#$%&'()*+,-./01234|      !"#$%&'()*+,-./01234<      !"#$%&'()*+,-./01234{      !"#$%&'()*+,-./01234;      !"#$%&'()*+,-./01234z      !"#$%&'()*+,-./01234:      !"#$%&'()*+,-./01234y      !"#$%&'()*+,-./012349      !"#$%&'()*+,-./01234x      !"#$%&'()*+,-./012348      !"#$%&'()*+,-./01234w      !"#$%&'()*+,-./012347      !"#$%&'()*+,-./01234v      !"#$%&'()*+,-./012346      !"#$%&'()*+,-./01234u      !"#$%&'()*+,-./012345      !"#$%&'()*+,-./01234t      !"#$%&'()*+,-./012344      !"#$%&'()*+,-./01234s      !"#$%&'()*+,-./012343      !"#$%&'()*+,-./01234r      !"#$%&'()*+,-./012342      !"#$%&'()*+,-./01234q      !"#$%&'()*+,-./012341      !"#$%&'()*+,-./01234p      !"#$%&'()*+,-./012340      !"#$%&'()*+,-./01234o      !"#$%&'()*+,-./01234/      !"#$%&'()*+,-./01234n      !"#$%&'()*+,-./01234.      !"#$%&'()*+,-./01234m      !"#$%&'()*+,-./01234-      !"#$%&'()*+,-./01234l      !"#$%&'()*+,-./01234,      !"#$%&'()*+,-./01234k      !"#$%&'()*+,-./01234+      !"#$%&'()*+,-./01234j      !"#$%&'()*+,-./01234*      !"#$%&'()*+,-./01234i      !"#$%&'()*+,-./01234)      !"#$%&'()*+,-./01234h      !"#$%&'()*+,-./01234(      !"#$%&'()*+,-./01234g      !"#$%&'()*+,-./01234'      !"#$%&'()*+,-./01234?      !"#$%&'()*+,-./01234?      !"#$%&'()*+,-./01234?      !"#$%&'()*+,-./01234?      !"#$%&'()*+,-./01234?      !"#$%&'()*+,-./01234?      !"#$%&'()*+,-./01234?      !"#$%&'()*+,-./01234?      !"#$%&'()*+,-./01234?      !"#$%&'()*+,-./01234+      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~PKH]PVpython3.10/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-310.pycnu[o aiz@s~\ddlmZididdddddddddddd d d d d dd dddddddddddddddidddddddddd dddd dd dd dddd d dd!d ddd"dd#dd$did%dd&dd'dd(dd)dd*d d+dd,dd dd-dd.dd/dd0dd1dd2dd3d d4ddd d dd dddddddd5 didd dddd dd dd ddd dd dd dd dddddddddddddddidddd dddddd dd ddddddddddd dd!ddd d"dd#dd$did%dd&dd'd d(d d)dd*dd+dd,dd dd-dd.dd/dd0dd1d d2d d3dd4dddd ddd ddd dddd5 diddddddddddddd dd dd dd dddddddddddddddidddd dddddddd ddddddddddd dd!dddd"dd#dd$did%dd&dd'd d(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4d dddddd ddddddd5 didddddddddddd d dd d d dd dddddddddddddddidd dddd dddddddddd dddddd d dd!d ddd"dd#dd$did%dd&d d'dd(dd)dd*dd+dd,d d dd-dd.dd/d d0dd1d d2d d3dd4ddd ddddddddddd5 didddd ddddddddd dd dd dd ddddddddddddddd idd dddddddd dddddddd ddddd d d!d ddd"dd#dd$d id%dd&dd'dd(d d)dd*dd+dd,dd dd-dd.dd/d d0dd1d d2dd3dd4d d dd d ddddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd d d!d ddd"dd#dd$d id%dd&dd'dd(dd)dd*dd+d d,d d d d-dd.d d/d d0dd1dd2d d3dd4dddddddddddddd5 d idd dddddd ddddd dd dd d d dddddddddddddddidddd ddddddddddddddddddd dd!d dd d"dd#dd$d id%dd&dd'dd(dd)dd*dd+dd,dd dd-d d.dd/dd0dd1dd2dd3d d4ddddddd ddddddd5 d iddddddddddddd dd dd dd dddddddddddddddidddddddd ddddddddddddddd dd!dddd"dd#d d$did%dd&dd'd d(dd)dd*dd+dd,d d d d-dd.d d/dd0dd1dd2d d3d d4d dddddd d dd dddd5 d idd dd ddddddddd d d dd dd dddddddddddddddidddd dddddd dd ddddddddddd d d!dddd"dd#d d$did%dd&dd'd d(dd)d d*dd+d d,dd dd-dd.d d/d d0dd1dd2dd3dd4d d dd dd dddddddd5 d iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(d d)dd*dd+dd,dd dd-dd.d d/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/d d0dd1dd2dd3dd4dddddddddddddd5 didd ddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dddd"dd#dd$did%d d&dd'dd(dd)d d*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddd dddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dddddddddddddddidddddddddddddddddd ddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.d d/dd0dd1dd2dd3dd4dddddddddddddd5 didd ddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!ddd d"dd#dd$d id%dd&dd'd d(d d)dd*dd+dd,dd dd-dd.d d/dd0dd1dd2dd3dd4d d dd d ddddddddd5 diddddddddddddd d d dd dd ddddddddddddd ddidd dddddd dd dd dd dddd dddd d dd!dddd"dd#dd$did%dd&dd'dd(dd)d d*dd+dd,dd dd-dd.dd/dd0d d1dd2dd3dd4ddd ddddd dd dddd5 didddd dd dddd ddd d d dd dd ddddddddddddd dd idddd dddddd dd dd dddd ddddd d d!d ddd"dd#dd$d id%dd&dd'dd(dd)dd*d d+dd,dd dd-dd.dd/dd0d d1d d2dd3dd4d d d d d ddddddddd5 ididd dddd dddd ddd dd dd dd ddddddddddddddd idddd dddd dddddddddd ddddd dd!ddd d"dd#d d$d id%dd&dd'd d(dd)d d*dd+dd,dd dd-dd.dd/d d0dd1dd2dd3dd4d d dd d ddddddddd5 didd dd dddd dd ddd dd dd dd ddddddddddddddd idddd dddddddddd ddddddddd d d!dddd"d d#d d$did%dd&d d'd d(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1d d2dd3d d4dd dd ddd ddddddd5 didddddddd ddddd dd dd dd dddddddddddddddidddddddd ddddddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 didddddddd ddddd d d d d dd ddddd ddddddddddidddddddddddddddddddd dd d dd!dddd"d d#dd$did%d d&dd'dd(dd)dd*d d+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4ddddddd ddddddd5 didddddddd dd dd d d d d d dd ddddddddddddd ddidd dddddddddddddddd dd dd d d d!dddd"dd#dd$did%dd&dd'dd(dd)dd*d d+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4ddd dddd ddddddd5 didddddd dddd ddd dd d d dd d dddd dddddddd dd idd dd dddddddd dd dd dd ddddd d d!dddd"dd#dd$d id%dd&d d'dd(d d)dd*dd+d d,dd d d-dd.dd/dd0dd1dd2d d3dd4d ddd dddd dd dddd5 didd dddddd ddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd d d!dddd"dd#dd$did%dd&dd'd d(dd)dd*dd+d d,d d dd-dd.dd/dd0dd1d d2dd3dd4ddddddddd ddddd5 diddddddddddddd dd dd dd dddddddddddddddidddddddd ddddddddddddddd dd!ddd d"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,d d dd-dd.dd/d d0dd1dd2dd3dd4ddddddddd ddddd5 didd dd dd dd dd ddd dd dd dd ddddddddddd dd dd idddddd dddddddd dddd ddddd d d!dddd"dd#dd$did%dd&dd'd d(d d)dd*d d+dd,dd dd-dd.dd/dd0d d1dd2d d3dd4d d dd d dd dd ddddd5 diddddddddddddd d d dd dd ddddddddddddddd idddd ddddddddddddddddddd dd!ddd d"dd#dd$did%dd&dd'd d(dd)d d*dd+dd,dd dd-dd.d d/d d0dd1d d2d d3dd4dd dddddddddddd5 didddddd ddddddd dd dd dd dddddddddddddddidddddddddddddddddd ddddd dd!ddd d"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.d d/dd0dd1dd2dd3dd4dddddddddd dddd5 d iddddddddddddd d d d d dd ddddddddddd ddddidd dddd dddddddd dddddddd d dd!d ddd"dd#dd$did%d d&d d'dd(dd)dd*dd+d d,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddd d ddd dddd5 d!idddd ddddddddd dd dd dd dddddddddddddddidd dddd dddddd dd dddd dddd d dd!dddd"dd#d d$did%d d&dd'dd(d d)dd*dd+dd,dd dd-dd.dd/dd0d d1dd2dd3dd4dd d dddd ddddddd5 diddddddddddddd dd d d dd dddddddddddddddidddddd dddddddddd dddd dd d dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*d d+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4ddd dd ddddddddd5 d"iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd d d!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d#idddddd dddd ddd d d dd dd dddddddddddddddidd dddddd dddddd dddddddd d d d!ddd d"dd#d d$d id%dd&dd'dd(d d)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dd d dd ddddddddd5 d$idddddd ddddddd d d d d dd ddddddddddd dddd idd dd dddddddd dd dddd dd ddd dd!dddd"dd#dd$d id%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4ddd d dd dddd dddd5 id%idd dddd dddd ddd dd dd d d ddddddddddddddd idddd ddddddddddddddddddd dd!dddd"dd#dd$did%d d&dd'd d(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dd dd d ddddd dddd5 d&iddddddddddddd dd dd dd ddd dddddddddddd idddd dddddddddddddddddd d d d!dddd"dd#dd$did%d d&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/d d0dd1dd2dd3dd4d ddddddddddddd5 d'idddddddddd ddd dd dd dd dddddddddddddddidddddddddddd ddddddddddd dd!d ddd"dd#d d$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4ddd dd dddd ddddd5 d(idddddddd ddddd dd dd dd ddddddddddddd ddidddddddddddd dddddd ddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+d d,dd dd-dd.d d/d d0dd1dd2d d3d d4dddddddddddddd5 d)idddd dddddd ddd d d dd dd dddddddddddddddidd dddd dddddd dd dddd dd dd d dd!dddd"dd#dd$did%d d&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dd d ddd d ddddddd5 d*iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d+idddd dddd ddddd dd dd dd dddddddddddddddidd dddd dddddddd dddddddd d dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*d d+d d,dd dd-dd.dd/dd0dd1dd2dd3dd4ddd ddddddddddd5 d,idddddd ddddddd d d dd dd dddddddddddddddidddddddddddd ddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddddd dd d d dd dddddddddddddddidd dddddddddddd dd dddd dd d dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*d d+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4ddd ddd dddddddd5 d-idddd dddddd ddd dd dd dd ddddd dddddddd dd idd dd dddddd dd dd dddd dddd d d d!dddd"dd#dd$d id%dd&dd'd d(dd)d d*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4ddd ddddddddddd5 d.idddd ddddddddd dd dd dd dddddddddddddddidd dddddddddddddddddd ddd dd!dddd"dd#dd$did%dd&dd'dd(dd)d d*d d+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dd d d dddddddddd5 d/idddddddddd ddd d d dd dd ddddddddddddddd idddddddd dddddd ddddddddd dd!dddd"dd#d d$did%d d&dd'dd(d d)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4ddd d d d dddddddd5 d0iddddddddddddd dd dd dd ddddddddddddd ddiddddddddddddddddddddddd d d!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d1iddddddddddddd d d dd dd ddddddddddddd ddiddddddddddddddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d2iddddddddddddd dd dd dd ddddddddd ddddddidd dddd dddddddddddd dddd d dd!d ddd"dd#dd$d id%d d&dd'd d(d d)d d*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4d dd dd ddddd dddd5 d3idddddddddd ddd dd dd dd ddddddddddd ddddidddd ddddddddddddddddddd dd!ddd d"dd#dd$d id%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4d d d ddddddddddd5 d4iddddddddddddd dd dd dd ddddddddddd ddddidd dddd dddddddddd dddd ddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 idddddddd ddddd d d dd dd dddddddddddddddiddddddddddddddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)d d*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 idddd dddddd dd d d d d d dd dddddddddddddddidddddddddd dddddddd dd dd d d d!dddd"dd#dd$did%d d&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 idddddd ddddddd dd dd dd ddddddddddddddd iddddddddddddddddddddddd dd!d ddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 idd ddddddddddd d d d d dd ddddddddddddddd idddddddddd ddddddddddddd dd!dddd"dd#d d$did%dd&dd'd d(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 idddd ddddddddd dd dd d d ddddddddddddd ddidddd ddddddddddddddddddd dd!d ddd"dd#dd$did%dd&dd'd d(dd)d d*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4d dddd ddddddddd5 idddd ddddddddd d d d d dd ddddd dddddddd ddidd dddd dddd dddddd dd ddddd dd!dddd"dd#dd$did%dd&dd'dd(d d)dd*dd+d d,dd dd-dd.dd/dd0dd1dd2dd3dd4ddd ddd dddddddd5 idddd ddddddddd d d d d dd ddddddddddddd ddidd dddddddddddddddd dd ddd dd!dddd"dd#d d$did%d d&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4ddd ddddddddddd5 idddd dd dddd ddd d d dd dd ddddddddddddddd idd dd dddd dd dd dddddd dd ddd dd!ddd d"d d#d d$d id%dd&dd'd d(d d)dd*d d+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4ddd d d ddddddddd5 iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddd d d5 iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4ddddddddddd d dd5 iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dddd"dd#dd$did%dd&dd'dd(dd)dd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddd dd5 d5 Zidd6d d6dd6dd6d)d6dd6d7d6d8d6dd6d d6d,d9d4d6d$d6d/d9dd6d#d6d!d6idd6d'd6dd6dd6d(d6d+d6d.d6dd6dd6dd6d1d6d:d6d;d6dd6dd6d2d<d=d<id d<d3d<d-d<d>d<d?d<dd<d0d<d@d<d%d<dd<dd<dd<d&d<d d<ddAddAdBdAid dAddAddAddAddAdCdAddAd d<dDd<dEd<d"d<dd<d*d<dFd<dGdHdIdJdKdLidMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdnidodpdqdrdsdtdudvdldwdxdydzd<d{d<d|d<dXd<dnd<d}d<d~dFddUddWdNddVdYiddddddddgdJddLdd^dxd`ddbdadddidpd}drdddzddcddmddddidd~dddd{dddd<dd<dd<dd<dd<dddddddddddduddddiddddddddddddddddddddddddoddkdddddddd“iddēddƓddȓddʓdd̓ddΓddГddғdddddd֓ddddٓdd[ddddddidd dd dddd dd dddddddddddddddHddPddRddTddZdid\ddfddhddjddtddvddwd dyd!dddd"dd#dddd$dd%dd&dd'dd(idd]dd)ddIdd*dd+dd,dd dd-dd.dd/dd0dd1dd2dd3ddqddddidddddddd4dd:dd@dd;dd=ddddBdd>dd7dd8ddKdd_dd?dd|iddddddMddCddDddGddOddEddQddeddSddsdddddAdd<dd9dAd6d6- = *.? $ ( # ) )!2%&8;<r<r=r6r8r9r;r>r7r:r?r@rA@ABjCkDdEFGHeI^JKLlMmNnOoPQRSYT_UpVqWXZ[\]`abcrfsgthiuvwxyz{|}~zTIS-620Thaig@?Fuกขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛) charset_namelanguagechar_to_order_maplanguage_modeltypical_positive_ratiokeep_ascii_lettersalphabetN)#pip._vendor.chardet.sbcharsetproberrTHAI_LANG_MODELTIS_620_THAI_CHAR_TO_ORDERTIS_620_THAI_MODELrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/langthaimodel.pys,J       !"#$%&'()*+,-./01234B      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234E      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234H      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234K      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234N      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Q      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234T      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234W      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Z      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234]      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234`      !"#$%&'()*+,-./01234"      !"#$%&'()*+,-./01234c      !"#$%&'()*+,-./01234%      !"#$%&'()*+,-./01234f      !"#$%&'()*+,-./01234(      !"#$%&'()*+,-./01234i      !"#$%&'()*+,-./01234+      !"#$%&'()*+,-./01234l      !"#$%&'()*+,-./01234.      !"#$%&'()*+,-./01234o      !"#$%&'()*+,-./012341      !"#$%&'()*+,-./01234r      !"#$%&'()*+,-./012344      !"#$%&'()*+,-./01234u      !"#$%&'()*+,-./012347      !"#$%&'()*+,-./01234x      !"#$%&'()*+,-./01234:      !"#$%&'()*+,-./01234{      !"#$%&'()*+,-./01234=      !"#$%&'()*+,-./01234~      !"#$%&'()*+,-./01234@      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234C      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234F      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234I      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234L      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234)      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~PKH]55Opython3.10/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-310.pycnu[o aiL@s8dZGdddeZGdddeZGdddeZdS))S)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)SrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrSrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)Srrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrc@sPeZdZdZdZdZdZdZddZdd Z d d Z d d Z ddZ ddZ dS)JapaneseContextAnalysisdircCs*d|_d|_d|_d|_d|_|dSN) _total_rel _rel_sample_need_to_skip_char_num_last_char_order_doneresetselfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/jpcntx.py__init__{s  z JapaneseContextAnalysis.__init__cCs*d|_dg|j|_d|_d|_d|_dS)Nrr F)r NUM_OF_CATEGORYrrrrrrrrrs  zJapaneseContextAnalysis.resetcCs|jrdS|j}||kr\||||d\}}||7}||kr*|||_d|_n,|dkrS|jdkrS|jd7_|j|jkrEd|_dS|jt|j|d7<||_||ks dSdS)Nrr rT)rr get_orderrr MAX_REL_THRESHOLDrjp2CharContext)rbyte_str num_bytesiorderchar_lenrrrfeeds"   zJapaneseContextAnalysis.feedcCs |j|jkSr )r ENOUGH_REL_THRESHOLDrrrrgot_enough_datas z'JapaneseContextAnalysis.got_enough_datacCs(|j|jkr|j|jd|jS|jS)Nr)r MINIMUM_DATA_THRESHOLDr DONT_KNOWrrrrget_confidences z&JapaneseContextAnalysis.get_confidencecCsdS)Nr rr)rrrrrrsz!JapaneseContextAnalysis.get_orderN)__name__ __module__ __qualname__rr%r"rr$rrr!r#r&rrrrrrts  rcs0eZdZfddZeddZddZZS)SJISContextAnalysiscstt|d|_dS)N SHIFT_JIS)superr+r _charset_namer __class__rrrs zSJISContextAnalysis.__init__cCs|jSr )r.rrrr charset_namesz SJISContextAnalysis.charset_namecCs|sdS|d}d|krdksnd|krdkr5nnd}|dks1d |kr/dkr4nnd |_nd }t|d krZ|d }|d krZd|krOd krZnd|fS|d|fSd|fS)Nr'rrCP932rr )r.lenrr first_charr second_charrrrrs.   zSJISContextAnalysis.get_order)r(r)r*rpropertyr1r __classcell__rrr/rr+s   r+c@seZdZddZdS)EUCJPContextAnalysiscCs|sdS|d}|dksd|krdkrnnd}n |dkr"d}nd }t|d krG|d }|d krGd|krsVCPKH]cZpython3.10/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-310.pycnu[o ai0@sdZddlZddlZddlZddlmZddlmZmZm Z ddl m Z ddl m Z ddlmZdd lmZGd d d eZdS) a Module containing the UniversalDetector detector class, which is the primary class a user of ``chardet`` should use. :author: Mark Pilgrim (initial port to Python) :author: Shy Shalom (original C code) :author: Dan Blanchard (major refactoring for 3.0) :author: Ian Cordasco N)CharSetGroupProber) InputStateLanguageFilter ProbingState)EscCharSetProber) Latin1Prober)MBCSGroupProber)SBCSGroupProberc @sneZdZdZdZedZedZedZ dddd d d d d dZ e j fddZ ddZddZddZdS)UniversalDetectoraq The ``UniversalDetector`` class underlies the ``chardet.detect`` function and coordinates all of the different charset probers. To get a ``dict`` containing an encoding and its confidence, you can simply run: .. code:: u = UniversalDetector() u.feed(some_bytes) u.close() detected = u.result g?s[-]s(|~{)s[-]z Windows-1252z Windows-1250z Windows-1251z Windows-1256z Windows-1253z Windows-1255z Windows-1254z Windows-1257)z iso-8859-1z iso-8859-2z iso-8859-5z iso-8859-6z iso-8859-7z iso-8859-8z iso-8859-9z iso-8859-13cCsNd|_g|_d|_d|_d|_d|_d|_||_t t |_ d|_ | dS)N)_esc_charset_prober_charset_probersresultdone _got_data _input_state _last_char lang_filterlogging getLogger__name__logger_has_win_bytesreset)selfrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/universaldetector.py__init__Qs  zUniversalDetector.__init__cCsVdddd|_d|_d|_d|_tj|_d|_|jr|j |j D]}| q"dS)z Reset the UniversalDetector and all of its probers back to their initial states. This is called by ``__init__``, so you only need to call this directly in between analyses of different documents. Nencoding confidencelanguageF) rrrrr PURE_ASCIIrrr rr )rproberrrrr^s   zUniversalDetector.resetcCs6|jrdSt|s dSt|tst|}|jso|tjr%dddd|_n;|tj tj fr6dddd|_n*|drCdddd|_n|d rPd ddd|_n|tj tj fr`d ddd|_d |_|jd durod |_dS|j tjkr|j|rtj|_ n|j tjkr|j|j|rtj|_ |dd|_|j tjkr|jst|j|_|j|tjkr|jj|j|jjd|_d |_dSdS|j tjkr|jst |jg|_|jt!j"@r|j#t$|j#t%|jD]}||tjkr |j||jd|_d |_nq|j&|rd |_'dSdSdS)a Takes a chunk of a document and feeds it through all of the relevant charset probers. After calling ``feed``, you can check the value of the ``done`` attribute to see if you need to continue feeding the ``UniversalDetector`` more data, or if it has made a prediction (in the ``result`` attribute). .. note:: You should always call ``close`` when you're done feeding in your document if ``done`` is not already ``True``. Nz UTF-8-SIG?rzUTF-32szX-ISO-10646-UCS-4-3412szX-ISO-10646-UCS-4-2143zUTF-16Tr )(rlen isinstance bytearrayr startswithcodecsBOM_UTF8r BOM_UTF32_LE BOM_UTF32_BEBOM_LEBOM_BErrr$HIGH_BYTE_DETECTORsearch HIGH_BYTE ESC_DETECTORr ESC_ASCIIr rrfeedrFOUND_IT charset_nameget_confidencer"r r rNON_CJKappendr rWIN_BYTE_DETECTORr)rbyte_strr%rrrr8os                zUniversalDetector.feedc Csf|jr|jSd|_|js|jdnY|jtjkr!dddd|_nK|jtjkrld}d}d}|j D]}|s5q0| }||krA|}|}q0|rl||j krl|j }|j }| }|d rd|jrd|j||}|||jd|_|jtjkr|jd dur|jd |j D]+}|sqt|tr|jD]}|jd |j |j| qq|jd |j |j| q|jS) z Stop analyzing the current document and come up with a final prediction. :returns: The ``result`` attribute, a ``dict`` with the keys `encoding`, `confidence`, and `language`. Tzno data received!asciir&r'rNrziso-8859r z no probers hit minimum thresholdz%s %s confidence = %s)rrrrdebugrrr$r5r r;MINIMUM_THRESHOLDr:lowerr,r ISO_WIN_MAPgetr"getEffectiveLevelrDEBUGr*rprobers) rprober_confidencemax_prober_confidence max_proberr%r:lower_charset_namer! group_proberrrrclosesn          zUniversalDetector.closeN)r __module__ __qualname____doc__rBrecompiler3r6r>rDrALLrrr8rNrrrrr 3s&      mr )rQr-rrRcharsetgroupproberrenumsrrr escproberr latin1proberrmbcsgroupproberr sbcsgroupproberr objectr rrrrs      PKH]co Upython3.10/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-310.pycnu[o ai6@s,ddlmZddlmZGdddeZdS)) CharSetProber) ProbingStatecseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZfddZddZddZddZddZddZeddZeddZedd ZZS)! HebrewProberg{Gz?z ISO-8859-8z windows-1255cs>tt|d|_d|_d|_d|_d|_d|_| dSN) superr__init___final_char_logical_score_final_char_visual_score_prev _before_prev_logical_prober_visual_proberresetself __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/hebrewprober.pyrs zHebrewProber.__init__cCsd|_d|_d|_d|_dS)N )rrrrrrrrrs zHebrewProber.resetcCs||_||_dSr)rr)r logicalProber visualProberrrrset_model_proberss zHebrewProber.set_model_proberscCs||j|j|j|j|jfvSr) FINAL_KAF FINAL_MEM FINAL_NUNFINAL_PE FINAL_TSADIrcrrris_finalszHebrewProber.is_finalcCs||j|j|j|jfvSr) NORMAL_KAF NORMAL_MEM NORMAL_NUN NORMAL_PEr*rrr is_non_finals zHebrewProber.is_non_finalcCs|jtjkr tjS||}|D]D}|dkr7|jdkr6||jr)|jd7_n$||jr6|j d7_ n|jdkrM||jrM|dkrM|j d7_ |j|_||_qtj S)Nr!r) staterNOT_MEfilter_high_byte_onlyrr,rrr1r DETECTING)rbyte_strcurrrrfeeds&       zHebrewProber.feedcCsx|j|j}||jkr|jS||j kr|jS|j|j}||jkr)|jS||j kr2|jS|dkr9|jS|jS)Ng) rrMIN_FINAL_CHAR_DISTANCELOGICAL_HEBREW_NAMEVISUAL_HEBREW_NAMErget_confidencerMIN_MODEL_DISTANCE)rfinalsubmodelsubrrr charset_names     zHebrewProber.charset_namecCsdS)NHebrewrrrrrlanguageszHebrewProber.languagecCs(|jjtjkr|jjtjkrtjStjSr)rr2rr3rr5rrrrr2szHebrewProber.state)__name__ __module__ __qualname__r%r-r&r.r'r/r(r0r) NORMAL_TSADIr9r=r;r:rrr$r,r1r8propertyr@rBr2 __classcell__rrrrrs6   ;  rN) charsetproberrenumsrrrrrrs  cPKH]-s==Xpython3.10/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-310.pycnu[o ai@s~\ddlmZididddddddddddd d d d dd d d ddd ddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd ddd ddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd d d dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 didddddd dddddd d d d dd d d d dd ddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4ddddddddd ddddd5 didddd ddddddddd d d d d dd d dd ddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 didddddddd dd dd d dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d iddddddddddddd dd dd dd ddd ddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4ddddddddd ddddd5 d iddddddddddddd d d dd d d dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d idd dddddd ddddd dd d d dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4ddddddddd ddddd5 d idddddddd ddddd dd dd dd ddd ddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4ddddddddddd dd d5 didddddddd dd ddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4ddddddddd ddddd5 diddddddddddddd dd dd dd d ddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd ddddddd ddddddddiddddddddddddddddddddddd dd!dd"d d#dd$dd%did&dd dd'dd(dd)ddd d*dd+dd,dd-dd.d d/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)ddd d*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 ididdddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"d d#d d$d d%d id&d d d d'd d(d d)d dd d*d d+d d,d d-dd.d d/dd0d d1d d2d d3dd4d dd d d d d ddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,d d-dd.d d/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#d d$dd%d id&dd dd'dd(dd)dddd*dd+dd,d d-dd.d d/dd0d d1dd2dd3dd4ddd dd d dddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#d d$d d%d id&dd dd'd d(dd)ddd&d*dd+d d,d d-d d.d d/d d0d d1d d2dd3dd4d dd d d d d ddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"d d#d d$dd%d id&d d dd'dd(d d)ddd&d*d d+dd,d d-d d.dd/d d0d d1dd2d d3dd4ddddd d d ddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"d d#d d$dd%d id&d d dd'dd(d d)ddd d*d d+dd,d d-d d.d d/d d0d d1d d2dd3dd4dd ddd d d ddddddd5 diddddddddddddd dd dd dd dddddddddddddddidddddddddddddddd ddddddd dd!dd"d d#d d$d d%d id&d d dd'd d(d d)d dd&d*dd+d d,d d-d d.d d/d d0d d1d d2d d3d d4d dd d d d d ddddddd5 diddddddddddddd dd dd dd dddddddddddddddidddddddddddddddd ddddddd dd!dd"d d#d d$d d%d id&d&d d d'd d(d d)ddd d*d d+d d,d d-d d.d d/d d0d d1dd2d d3dd4d dd d d d d ddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"d d#d d$dd%d id&d d dd'dd(dd)dddd*dd+d d,d d-d d.d d/d d0d d1d d2d d3dd4d dd d d d d ddddddd5 diddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,d d-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 diddddddddddddd dd dd dd dddddddddddddddidd&dddddd&dd dd dd&dd&dd ddddd d d!dd"d d#d d$dd%d id&dd d d'dd(dd)ddd d*d d+d d,d d-dd.d d/dd0d d1dd2d d3dd4ddddd d d ddddddd5 d iddddddddddddd dd dd dd dddddddddddddddidd dddddd dd dd dd dd ddddddd dd!dd"dd#dd$dd%did&dd d d'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d!iddddddddddddd dd dd dd dddddddddddddddidd dddddd dddd dddd ddddddd dd!dd"dd#dd$dd%did&dd d d'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d"iddddddddddddd dd dd dd dddddddddddddddidddd dd dd dd dd dd dd dd ddddd dd!dd"d d#d&d$d&d%d&id&d&d d&d'd&d(d&d)d&dd&d*d&d+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d d3d&d4d&dd&d&d&d&d&ddddddd5 d#iddddddddddddd dd dd dd dddddddddddddddidd dddddd dd dd dd dd dd dddd&d dd!dd"d&d#d&d$d&d%d&id&d&d d&d'd&d(d&d)d&dd&d*d d+d&d,d&d-d d.d&d/d&d0d&d1d&d2d&d3dd4d&d d&d&d&d&d&ddddddd5 d$iddddddddddddd dd dd dd ddddddddd ddddddidd dddddddddddd dd dddddd d dd!dd"d d#d&d$d d%d&id&d&d d&d'd&d(d d)d dd&d*dd+dd,d&d-d&d.d&d/d&d0d&d1d d2d&d3d d4d dddd&d&d&ddddddd5 d%iddddddddddddd dd dd dd dddddddddddddddidd dddddd dd dd dd dd dd dddd d dd!dd"d&d#d&d$d&d%d&id&d&d d&d'dd(d d)d dd&d*d d+d d,d&d-d&d.d&d/d d0d&d1d d2d&d3d d4d&dd d&d&d&d&ddddddd5 id&iddddddddddddd dd dd dd dddddddddddddddidddddd dd dd dd dd&dd dddddd d dd!dd"d&d#d&d$d&d%d&id&d&d d&d'd&d(d&d)d&dd&d*dd+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d&d3dd4d&dd&d&d&d&d&dddddd d5 d iddddddddddddd dd dd dd dddddddddddddddidd dddddd dddddd dd dd&dddd&d dd!dd"d&d#d&d$d&d%d&id&d&d d&d'd&d(d&d)d&dd&d*d&d+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d&d3d&d4d&d&d&d&d&d&d&dddddd d5 d'iddddddddddddd dd dd dd dddddddddddddddidd dddddddd dd dd dd dddddd d dd!dd"d&d#d d$d d%d id&d&d d&d'd d(d d)ddd&d*dd+d&d,d&d-d d.d&d/d d0d d1dd2d d3dd4ddd d&d&dd ddddddd5 d(iddddddddddddd dd dd dd dddddddddddddddidd dddd dd dd dd dd dd dd ddddd dd!dd"d d#d&d$d d%d&id&d&d d&d'd&d(d d)d dd&d*dd+d d,d&d-d&d.d&d/d d0d&d1d&d2dd3d d4d d d&d&d&d&d&ddddddd5 d)iddddddddddddd dd dd dd dddddddddddddddidd dddddd dddddd ddddddddd dd!dd"d&d#d&d$d&d%did&d&d d&d'd d(d&d)d dd&d*dd+d d,d&d-d d.d d/d d0d&d1d d2d&d3d d4d&dd d d&d d&ddddddd5 diddddddddddddd dd dd dd dddddddddddddddidd dddddd dd dddd dd dd dddd d dd!dd"d&d#d&d$d&d%d&id&d&d d&d'd&d(d&d)d&dd&d*d&d+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d&d3d&d4d&d&d&d&d&d&d&dddddd d5 d*iddddddddddddd dd dd dd dddddddddddddddidd dddddddddddddd ddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d+iddddddddddddd dd dd dd dddddddddddddddidd dddddd dd dd dd dd dddddd&d dd!dd"d&d#d&d$d d%d&id&d&d d&d'd&d(d&d)d dd&d*d&d+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d d3d&d4d&dd d d&d&d&ddddddd5 d,iddddddddddddd dd dd dd dddddddddddddddidd&dddddd dd dd dd dd dd dddd d dd!dd"d&d#d&d$d&d%d&id&d&d d&d'd&d(d&d)d&dd&d*d&d+d&d,d&d-d&d.d&d/d d0d&d1d&d2d&d3d d4d&d d&d&d&d&d&ddddddd5 d-iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4ddddddddddddd d5 d.iddddddddddddd dd dd dd dddddddddddddddidd dddddd dd dd dd dd dd dddd d dd!dd"d&d#d&d$d&d%d&id&d&d d&d'd&d(d&d)d&dd&d*d d+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d&d3dd4d&d d&d&d&d&d&ddddddd5 d/iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4ddddddddddddd d5 d0iddddddddddddd dd dd dd dddddddddddddddidd dddddd dd dd dd dd dddddd d dd!dd"d&d#d&d$d&d%d&id&d&d d&d'd&d(d&d)d&dd&d*d d+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d&d3d d4d&d d&d&d&d&d&ddddddd5 d1iddddddddddddd dd dd dd dddddddddddddddidd dddddd dddd dd dddddd dd d dd!dd"d d#d&d$d&d%d&id&d&d d&d'dd(d&d)d&dd&d*d d+d&d,d&d-d d.d&d/d d0d&d1d d2d&d3d&d4d&dd d&d&dd&ddddddd5 d2iddddddddddddd dd dd dd dddddddddddddddidddddd dd dd dd dd dd dd ddddd dd!dd"d d#d&d$d&d%d&id&d&d d&d'd&d(dd)d&dd&d*d d+d d,d&d-d&d.d&d/d d0d&d1d&d2d d3dd4d d d&d&d&d&d&ddddddd5 d3iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 d4iddddddddddddd dd dd dd dddddddddddddddidd dddddd dddd dddd dddddd d dd!dd"d&d#d d$d&d%d id&d&d d&d'd d(d&d)d&dd&d*d d+d&d,d&d-d d.d d/d&d0d&d1d&d2d&d3d d4d d d&d&d&d&d&ddddddd5 iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd dddddddddddddddidd dddddd dd dddd dd dddddd d dd!dd"d&d#d&d$d d%d&id&d&d d&d'dd(d&d)d dd&d*dd+dd,d&d-d d.d&d/d d0d&d1dd2d&d3d d4d&d d d&d&dd&ddddddd5 iddddddddddddd dd dd dd dddddddddddddddidd dddddd dd dddd dd dd dddd d dd!dd"d&d#d&d$d d%d&id&d&d d&d'd d(d&d)d&dd&d*dd+dd,d&d-d d.d&d/d d0d&d1d&d2d&d3d d4d&d d&d d&d&d&ddddddd5 iddddddddddddd dd dd dd ddddddddd ddddddidd dddddd dd dd dd dd dd ddddd dd!dd"d&d#d&d$d&d%d&id&d&d d&d'd&d(d&d)d&dd&d*d&d+d&d,d&d-d&d.d&d/d&d0d&d1d&d2d&d3d d4d&d&d&d&d&d&d&dddddd d5 iddddddddddddd dd dd dd dddddddddddddddidddddddddddddddddddddd d d&d!d d"d&d#d&d$d&d%d&id&d&d d&d'd d(d&d)d&dd&d*d&d+d&d,d&d-d&d.d&d/d d0d&d1d d2d&d3d d4d&dd d&d&d&d&ddddddd5 iddddddddddddd dd dd dd dddddddddddddddidd dddddd dd dd dd dd dddddd d dd!dd"d&d#d&d$d&d%d id&d&d d&d'd d(d&d)d dd&d*d d+d&d,d&d-d&d.d&d/d&d0d&d1d d2d&d3d d4d&dd d&d&d&d&dddddd d5 iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd d dd ddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"d d#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddddd5 iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4dddddddddddd dd5 iddddddddddddd dd dd dd dddddddddddddddiddddddddddddddddddddddd dd!dd"dd#dd$dd%did&dd dd'dd(dd)dddd*dd+dd,dd-dd.dd/dd0dd1dd2dd3dd4ddddddddddddd d5 d5 Zidd6dd6d d6d&d6d,d6d7d6d.d6d8d6d#d6d"d6d9d:d-d6d0d6d2d:d(d6d+d6d%d6id;d6d4d6d1d6d$d6dd?dd?idd?dd?dd?dd?d d?dd?d@d?dd?dd?d d?dd?d!d?dAd?dBd?ddCd dCddCid dCdDdCddCd dCddCddCddCdEd?dd?dd?dd?dd?dd?dFd?dGdHdIdJdKdLidMdNdHdOdPdQdRdSdTdUdVdMdWdXdYdZd[d\d]dVd^d_dLd`dNd^dadbd\dcdddRdedKid`dfdcdgdhdedidjdQdkdUdldJd?dOd?dmd?dnd?d_d?dod?dSddpdWdqddrddsdidfd[dkdPdtdFduddvdudgdmdwddxdGdyd dXd dZdIdzdydjd dld d{dd|dd}daid~d]ddpdbdYddwdd?dd?dd?dd?dd?dddddddddddd@ddEddidddddddddddddddddddddddDddBddAddTdd>ddnddiddzddddxdddddddddddd{dddd}ddrddddÓdd|dd~ddtiddddɓdd˓ddhddqddϓddvddddddԓddddדddٓddsddܓddޓddiddddddddddddddddddiddddddddddddddddidddddddddddd dd!ddddddddddddddddddddidddddddd"dd#dd$dd%dd&dd dd'dd(dd)dddd*dd+dd,dd-idd.dd/dd0dd1dd2dd3dd4dd=dd<dd;dd8dd9dd7dddCdCd?dd:dod6d?iZeddeeddddZdS( )SingleByteCharSetModel2<=*58613+,?"70'9;)!%$#>&-    )   4/.:(r;r9r:r8r7r6r<rAr?r>r=r@@AEB[CODP\FYGaHZIJoKpLRMN_UQyVSTfkWXrgs]^`bcdehijlmnqtuvwxz{|}~z windows-1255Hebrewg C|?Fu<אבגדהוזחטיךכלםמןנסעףפץצקרשתװױײ) charset_namelanguagechar_to_order_maplanguage_modeltypical_positive_ratiokeep_ascii_lettersalphabetN)#pip._vendor.chardet.sbcharsetproberrHEBREW_LANG_MODEL!WINDOWS_1255_HEBREW_CHAR_TO_ORDERWINDOWS_1255_HEBREW_MODELrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/langhebrewmodel.pys,J       !"#$%&'()*+,-./01234B      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234E      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234H      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234K      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234N      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Q      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234T      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234W      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234Z      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234]      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234`      !"#$%&'()*+,-./01234"      !"#$%&'()*+,-./01234c      !"#$%&'()*+,-./01234%      !"#$%&'()*+,-./01234f      !"#$%&'()*+,-./01234(      !"#$%&'()*+,-./01234i      !"#$%&'()*+,-./01234+      !"#$%&'()*+,-./01234l      !"#$%&'()*+,-./01234.      !"#$%&'()*+,-./01234o      !"#$%&'()*+,-./012341      !"#$%&'()*+,-./01234r      !"#$%&'()*+,-./012344      !"#$%&'()*+,-./01234u      !"#$%&'()*+,-./012347      !"#$%&'()*+,-./01234x      !"#$%&'()*+,-./01234:      !"#$%&'()*+,-./01234{      !"#$%&'()*+,-./01234=      !"#$%&'()*+,-./01234~      !"#$%&'()*+,-./01234@      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234C      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234F      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234I      !"#$%&'()*+,-./01234       !"#$%&'()*+,-./01234L      !"#$%&'()*+,-./01234      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234A      !"#$%&'()*+,-./01234)      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~PKH]OVVPpython3.10/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-310.pycnu[o aid@sdZdZdZdS)g@i((i'iOii}i ii ii] i i ii iiiiii iiiXi}iiikig i i ikiiiiiiii%i&01,-iiiiiii iii<iiipiiiiiiigiiiiWiXii ih i"iiiii i ii\iii i/ ii iiiii0 ii ihi iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii i i i i iiiiiiiiiiiiiiiiiii ii!i"i#i$i%i&i'i(i)i*i+i,i-i.i/i0i1i2i3i4i5i6i7iiViji4iiiiBiii8i9i:i;i<i=i>iviiiiSiieiifi iid i+iiiaiw iiiiIii~ii ii?i@iAiBiCiDi ii- i iiiii iiEi^ i. i i3iii iFi/ iYi i iiiji iiGiHiIiJiqi1 iYik/i2#i *[\5i!i! %@il'iA 4 <ii-ii7Si~iKi=E;7i7i8m& OiK=i~idiLiMiNiOiPiQiRiSiTiUiVY>J"ip piTi_i.XiLijei9P ilyii Di )ihi F?+iiigciB]iN8j:i5iii7Ri4Gdinihit63$WCi i: ix ii*iV i iWiXiYiZi[i\i]i^i_i`iiaibicidieifigihiiijikiliminioipiqirisiti iuiviwixiyizi{i|iiiiili}i i~iii i i iiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiikii i> i i i i i ij iiiZi[i\i]ii ii ii i i i i iiiiiiiiiiiiiiiiiii i!i"i#i$i%i&i'i(i)i*i+i,i-i.i/i0i1i2i3i4i5i6i7i8i9i:i;i<i=i>i?i@iAiBiCiDiEiFiGiHiIiJiKiLiMiNiOiPiQiRiSiTiUiViWiXiYiZi[i\i]i^i_i`iaibicidieifigihiiijikiliminioipiqirisitiuiviwixiyizi{i|i}i~iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii i i i i iiiiiiiiiiiiiiiiiii i!i"i#i$i%i&i'i(i)i*i+i,i-i.i/i0i1i2i3i4i5i6i7i8i9i:i;i<i=i>i?i@iAiBiCiDiEiFiGiHiIiJiKiLiMiNiOiPiQiRiSiTiUiViWiXiYiZi[i\i]i^i_i`iaibicidieifigihiiijikiliminioipiqirisitiuiviwixiyizi{i|i}i~iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii i i i i iiiiiiiiiiiiiiiiiii i!i"i#i$i%i&i'i(i)i*i+i,i-i.i/i0i1i2i3i4i5i6i7i8i9i:i;i<i=i>i?i@iAiBiCiDiEiFiGiHiIiJiKiLiMiNiOiPiQiRiSiTiUiViWiXiYiZi[i\i]i^i_i`iaibicidieifigihiiijikiliminioipiqirisitiuiviwixiyizi{i|i}i~iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii i iiiiiii2 iii{iTiia i i^iii|i i=iimik i i ii iViy i ii iq iiii i iiii!ii ii ii iCiOi3iiiiiir iiinii+iiii ipiqi i; Ai iiiCi0 iini iiiTiCioi ii i# iii~iiPiiiiii ii i i$ iz ii i&iiiii iiiii_iiUii is i ii iIiiiiiiii3 iii$iWi1 i5iPi iiiiiiiX iiiil iiiHii iiiiii i iWii~ipii$iiii@iLi i iiiiuii iJiI iW iii_ii i<iiii]iDiiiiihiiiiifi-i}it ii iiii,i ibiiiXiiiFii{ i`iii+i3iqiimii4 iiiiiiBiliX i ii% iii% i2 iuii i iiJii|irii@i iii iii ii iL iiiiiiib iJ i icii iiiii4 iRiim iTiii iiiiiie iii? i iiiii-i ii*iEi ii+i ii& i iii/iii.isi[ii+ii ii iBic iiiiii i) ii,i iu ii ii9i& iiiiiiv iiY i i3 ii iiiiDiiiiidiii| i(iyiiiii<i8i iiii i id i5 iBiini iiiii|i i!ii)i@ in imi i i0iaiii zi'ii iWii[iviii iii io i i ii iii' ii i"iii9iii iiJiiihiiie ii\iiip i@iiQi9iii iiiw iiiEiiJiIi iiiiiifii ii i i1i ii iii' iri iiii iiici iqiixiii i2iiiii i*iiibiFiiviidi iii!iRiiiQiiiiPiiiiiiii( iii_ ii` iiif ii6 iiAiiia iiiuiTi i2iiiiii i^iCii ii[ii ivi%iiiini!iFiiZi^iiiidiiiix iii]i iBiici i iiiPiqi i iHiY iii( ii iigi}iKi iii4 iiWii iiCig i-idiikii4i} iiq i~ i+i iiihi@ i i i@iA iDi:iiiei iiqiwiiiiiiiidiiZii* iM i[iiisiZ i i ii>ii'i-i i ii ii) iiiiitiFi7 iiti#iiiiiiYiiifikib i1ii ii6ioic iiqi iiii iuii:iiiN iiUi=i iviilNiiii]ii;iii iiiliLi i}iiiiiB i8 iQii#i`iTii ixiiri iiiiii ii3iniiiiiii{iii@i iiii9 ii5 ih id iZ iiiiiiiiisi-ir iiiii[ ii0iiiii.iSi iRiO iii ii;i i4iy i i;iiz iipii i i ii: i(i|i ii"iiiiii iOiieiii iC iti) ii6Kiii8iiP iihii ii ii3i$iii* i=bie ii i4iii i.i7ii\ iiiiji iiiiiii/iii i=ii^ii5 i ii i\iiiii9i#i+ i is i,ii7iiiYiii iMii+ ii iQii6 iiiiiiyi iisi#i{ i iUifi<iiiviii)i iiiiiimi<iii iiigii lii iD ibiui i iDiBiii i[ i ii8iii>i iii iiii i] iiDiii6iZii i5ii i i<imi i, i iiui^ i iiigiiIiiigi ii\i:i iMti iiEioiiiiEiRii iiEij igiWiiiKi iCii=ii]i$i!ii iii`iKiviii0ii^i i3ii"iiiiaik ii; iwiiiiiii iyiiiiiPiii iwiiit i iii iiiJiaiii]iiii iiiiLihiiii iu ijiii#iCiii iai!si| ii iYii iiiihiOi5iiiziii iSiiLii.ii&ii i< i7iisiA iiiMi iisii*i, i%i i iikii&ifiOiji"ii(i-ii[iii ii- i=ii} iiMiSiii iiiii ii i i ii ii~ iiJitikivieiyiii< i if iiMki iiioiiiwiv ilii]iii.i iiii/if iqi$ig iiGinii>i6 i= ii iii iNi ixiiei* iih iiii$iiiioibi,ii iiitiii i ii iVii iiiiiiiw iiipiHi Viiii<iZi i8riwii&i ii/iiiii>ii> iE ixii&ieiiwi iii5iii ii\iiiSii iiii2iiii+i'ii%iiix iOii iQ iiiiiii_Hiiii igiiiy ii i0i&i+ i iiii il i'ii'izii i ii_ iiii i ii? i ii iz iim i|i ii ig i0iii ii*ii i i`iwiii i#ici)iiiR i iiTiiriiViiii_iiiiiriii i` ixiii iiifiiin i= i*iAii i(ixiS i{iT ii9iiiMi irii;ii(ii%ii[ia ib iiiDiiii- i\ iii iio iEimi)ii!iiic ii, i1ii] iii>iIii iTiiii iiiyiikizixiiNi iiii i5i i i"iiHi<id ii iiih i ii ip iii:iLi1iii iii> iiq i?iZiMiIi iiB iK iDii#i i iYi>iiii`iiiiiiiiiiiii iiiciiiiiiTiiaii2iyi/ii"iU ibii ii/ii ii i i{i iij i i5i*iiiiiaixiii iiFiiii7 iii i?iwiiiiii+ii8 ii iNi iii,iinii i i ioisi_i?ii iii i iii?i0i i iiyi3ifi i=iiilii iivi]ii i iiizi iiyijiiui iipiijii iiiziiir iiiiiiiiiFii'i i{ ini ixui$iiiiMiiik iipi i^ iqi i`i|ii ii i| i i i ii i iiii iGi ii-iiZi1iYii- i ieiii[iC iiie i i.i-iiii iii i i7 ibil i iii{ii.i i iizii i ii? iii9 ii iiii}ii iaii i Qi idi;iV ii/i^iD ii?im i i i9iIi iii iii i{i}i iiiii&ii~iiXii i} i ii9i ii:ii"i\iii i_ i8iWi~ i^i%iPisi iwii ii8 i iLiii. iii iiiNiiPiiSiiii:iRi'i0ibiii iiiiizii iiiiiKii i iriiqi iiin iL iiiiiiiiiiXi@ iigiii4ii: iiiiri iiQi ii i;i'i i>iibimiiwiiis iiiiA iit i9 iiiii io i^iii2iiciii i iriii i!iitii1i{i iiiiisiiiii ixiviaip iii iiLiOiiiUi i.ii)i. iiEi i"iiyii iiii(i iiiq iE i6i i i2iui6i iiii. iii iiiViiisi iiiGiGijitiiWii iii`iiiiui ii ii{iQii iOiCi ii iiJi i i i$iiii/ iii_iiiij iRii7iii/ ii3iDiu i6iXi4iii iiii>iiii0 i`i` i iiiiUii i irii i)ii5iiHii iii~ir ii iiiii ii]iiiiiii i@ iii iaiiviiii/i!i6iiii7iwi i i3ici8ixii iiB iiiM iiF iigiiii(ii i: iiiHii if ii"i i~iii i iyii i ii i!iNi i4iA iidieiziiii iiii0 ii iiiiiii{iii i iifi(iliiGi ii^iB imiF i|iiUiii2iRiii#ii iiiFi Uiiii1i icikiiN iSi i iii$iO ii iYiiii iiGi iiiW i iC i?i ii~iiiUiFiiiiiiii iC i iiiiei iiiii/ iQi_iv i; i i iPi)iGimi iiiG i,iIiz_i i i9inii iAi i iX ii#iVi)i< i%ii}iiiHiw i5iipi.iiiimiiii i#ihi|ibii ii@i(i^izi iiAi i i i"i ig ii|iiiii6iiXiii,iii iii$i#iIik iiiii:i iiQi ioih iVi$i iitiiiiY i,iii i iD ii i~i i iii%iii iii ii i i7i/i ii iEiVii iE iuii&iiii i iioiiiZiiiii i iiii!iini8ii'iiiiiii iiGi iRi2iii:ii,iiZ ilii(iXiP i?ii i ioiiiii iiWi*ii;i8ii&i)ii i ioiiiiiHi_iii0iix ii0 ii; ii iiiXii ii1iZi*i%i i|idi`iiiSiji}i\iiiiG i ii ifqi%iBii1 ipii"iiiii i|iiii iil i2 i i iii@ihii;iii ii iii&iiii}ii%i iii i?ii iia iy ii iii ii= i1 ii<ii{i#iiii iAii iitiii ii> i iKi3 iii=ii\i i i'iAi+igiib iKiiiii ii ii4 ii*iim i ii ioiNii0i(ii ii$i4i i{i iiiQ iiiUiiii,i`ii iii ij i)i ii-i6i iF i2i)ii i*i iYN)JIS_TYPICAL_DISTRIBUTION_RATIOJIS_TABLE_SIZEJIS_CHAR_TO_FREQ_ORDERrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/jisfreq.pys+PKH]Y鸼Opython3.10/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-310.pycnu[o ai@sNddlZejdkrdZdZeefZeZej Z dSdZdZe efZeZej Z dS)N)rTF) sys version_infoPY2PY3strunicode string_types text_typedict iteritemsbytesitemsrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/compat.pys   PKH]=Tpython3.10/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-310.pycnu[o ai@sDddlmZddlmZddlmZddlmZGdddeZdS))MultiByteCharSetProber)CodingStateMachine)EUCTWDistributionAnalysis)EUCTW_SM_MODELcs4eZdZfddZeddZeddZZS) EUCTWProbercs,tt|tt|_t|_|dS)N) superr__init__rr coding_smrdistribution_analyzerresetself __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/euctwprober.pyr"s  zEUCTWProber.__init__cCdS)NzEUC-TWrr rrr charset_name(zEUCTWProber.charset_namecCr)NTaiwanrr rrrlanguage,rzEUCTWProber.language)__name__ __module__ __qualname__rpropertyrr __classcell__rrrrr!s   rN) mbcharsetproberrcodingstatemachinerchardistributionrmbcssmrrrrrrs    PKH]ߦ Spython3.10/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-310.pycnu[o ai@s`ddlmZddlmZddlmZddlmZddlm Z ddl m Z m Z GdddeZ d S) )MultiByteCharSetProber)CodingStateMachine)SJISDistributionAnalysis)SJISContextAnalysis) SJIS_SM_MODEL) ProbingState MachineStatecsPeZdZfddZfddZeddZeddZd d Zd d Z Z S) SJISProbercs4tt|tt|_t|_t|_ | dSN) superr __init__rr coding_smrdistribution_analyzerrcontext_analyzerresetself __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/sjisprober.pyr %s   zSJISProber.__init__cstt||jdSr )r r rrrrrrr,szSJISProber.resetcCs|jjSr )r charset_namerrrrr0szSJISProber.charset_namecCsdS)NJapaneserrrrrlanguage4szSJISProber.languagecCs@tt|D]y}|j||}|tjkr&|jd|j|j |t j |_ nZ|tj kr1t j|_ nO|tjkr|j}|dkr]|d|jd<|j|jd|d||j|j|q|j||d||d|||j||d|d|q|d|jd<|jt jkr|jr||jkrt j|_ |jS)Nz!%s %s prober hit error at byte %sr)rangelenr next_staterERRORloggerdebugrrrNOT_ME_stateITS_MEFOUND_ITSTARTget_current_charlen _last_charrfeedrstate DETECTINGgot_enough_dataget_confidenceSHORTCUT_THRESHOLD)rbyte_stri coding_statechar_lenrrrr+8sD       zSJISProber.feedcCs|j}|j}t||Sr )rr/rmax)r context_conf distrib_confrrrr/Ys   zSJISProber.get_confidence) __name__ __module__ __qualname__r rpropertyrrr+r/ __classcell__rrrrr $s    !r N)mbcharsetproberrcodingstatemachinerchardistributionrjpcntxrmbcssmrenumsrrr rrrrs     PKH]?python3.10/site-packages/pip/_vendor/chardet/mbcsgroupprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Universal charset detector code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 2001 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # Shy Shalom - original C code # Proofpoint, Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .charsetgroupprober import CharSetGroupProber from .utf8prober import UTF8Prober from .sjisprober import SJISProber from .eucjpprober import EUCJPProber from .gb2312prober import GB2312Prober from .euckrprober import EUCKRProber from .cp949prober import CP949Prober from .big5prober import Big5Prober from .euctwprober import EUCTWProber class MBCSGroupProber(CharSetGroupProber): def __init__(self, lang_filter=None): super(MBCSGroupProber, self).__init__(lang_filter=lang_filter) self.probers = [ UTF8Prober(), SJISProber(), EUCJPProber(), GB2312Prober(), EUCKRProber(), CP949Prober(), Big5Prober(), EUCTWProber() ] self.reset() PKH]Y(=$$@python3.10/site-packages/pip/_vendor/chardet/chardistribution.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Communicator client code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .euctwfreq import (EUCTW_CHAR_TO_FREQ_ORDER, EUCTW_TABLE_SIZE, EUCTW_TYPICAL_DISTRIBUTION_RATIO) from .euckrfreq import (EUCKR_CHAR_TO_FREQ_ORDER, EUCKR_TABLE_SIZE, EUCKR_TYPICAL_DISTRIBUTION_RATIO) from .gb2312freq import (GB2312_CHAR_TO_FREQ_ORDER, GB2312_TABLE_SIZE, GB2312_TYPICAL_DISTRIBUTION_RATIO) from .big5freq import (BIG5_CHAR_TO_FREQ_ORDER, BIG5_TABLE_SIZE, BIG5_TYPICAL_DISTRIBUTION_RATIO) from .jisfreq import (JIS_CHAR_TO_FREQ_ORDER, JIS_TABLE_SIZE, JIS_TYPICAL_DISTRIBUTION_RATIO) class CharDistributionAnalysis(object): ENOUGH_DATA_THRESHOLD = 1024 SURE_YES = 0.99 SURE_NO = 0.01 MINIMUM_DATA_THRESHOLD = 3 def __init__(self): # Mapping table to get frequency order from char order (get from # GetOrder()) self._char_to_freq_order = None self._table_size = None # Size of above table # This is a constant value which varies from language to language, # used in calculating confidence. See # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html # for further detail. self.typical_distribution_ratio = None self._done = None self._total_chars = None self._freq_chars = None self.reset() def reset(self): """reset analyser, clear any state""" # If this flag is set to True, detection is done and conclusion has # been made self._done = False self._total_chars = 0 # Total characters encountered # The number of characters whose frequency order is less than 512 self._freq_chars = 0 def feed(self, char, char_len): """feed a character with known length""" if char_len == 2: # we only care about 2-bytes character in our distribution analysis order = self.get_order(char) else: order = -1 if order >= 0: self._total_chars += 1 # order is valid if order < self._table_size: if 512 > self._char_to_freq_order[order]: self._freq_chars += 1 def get_confidence(self): """return confidence based on existing data""" # if we didn't receive any character in our consideration range, # return negative answer if self._total_chars <= 0 or self._freq_chars <= self.MINIMUM_DATA_THRESHOLD: return self.SURE_NO if self._total_chars != self._freq_chars: r = (self._freq_chars / ((self._total_chars - self._freq_chars) * self.typical_distribution_ratio)) if r < self.SURE_YES: return r # normalize confidence (we don't want to be 100% sure) return self.SURE_YES def got_enough_data(self): # It is not necessary to receive all data to draw conclusion. # For charset detection, certain amount of data is enough return self._total_chars > self.ENOUGH_DATA_THRESHOLD def get_order(self, byte_str): # We do not handle characters based on the original encoding string, # but convert this encoding string to a number, here called order. # This allows multiple encodings of a language to share one frequency # table. return -1 class EUCTWDistributionAnalysis(CharDistributionAnalysis): def __init__(self): super(EUCTWDistributionAnalysis, self).__init__() self._char_to_freq_order = EUCTW_CHAR_TO_FREQ_ORDER self._table_size = EUCTW_TABLE_SIZE self.typical_distribution_ratio = EUCTW_TYPICAL_DISTRIBUTION_RATIO def get_order(self, byte_str): # for euc-TW encoding, we are interested # first byte range: 0xc4 -- 0xfe # second byte range: 0xa1 -- 0xfe # no validation needed here. State machine has done that first_char = byte_str[0] if first_char >= 0xC4: return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 else: return -1 class EUCKRDistributionAnalysis(CharDistributionAnalysis): def __init__(self): super(EUCKRDistributionAnalysis, self).__init__() self._char_to_freq_order = EUCKR_CHAR_TO_FREQ_ORDER self._table_size = EUCKR_TABLE_SIZE self.typical_distribution_ratio = EUCKR_TYPICAL_DISTRIBUTION_RATIO def get_order(self, byte_str): # for euc-KR encoding, we are interested # first byte range: 0xb0 -- 0xfe # second byte range: 0xa1 -- 0xfe # no validation needed here. State machine has done that first_char = byte_str[0] if first_char >= 0xB0: return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 else: return -1 class GB2312DistributionAnalysis(CharDistributionAnalysis): def __init__(self): super(GB2312DistributionAnalysis, self).__init__() self._char_to_freq_order = GB2312_CHAR_TO_FREQ_ORDER self._table_size = GB2312_TABLE_SIZE self.typical_distribution_ratio = GB2312_TYPICAL_DISTRIBUTION_RATIO def get_order(self, byte_str): # for GB2312 encoding, we are interested # first byte range: 0xb0 -- 0xfe # second byte range: 0xa1 -- 0xfe # no validation needed here. State machine has done that first_char, second_char = byte_str[0], byte_str[1] if (first_char >= 0xB0) and (second_char >= 0xA1): return 94 * (first_char - 0xB0) + second_char - 0xA1 else: return -1 class Big5DistributionAnalysis(CharDistributionAnalysis): def __init__(self): super(Big5DistributionAnalysis, self).__init__() self._char_to_freq_order = BIG5_CHAR_TO_FREQ_ORDER self._table_size = BIG5_TABLE_SIZE self.typical_distribution_ratio = BIG5_TYPICAL_DISTRIBUTION_RATIO def get_order(self, byte_str): # for big5 encoding, we are interested # first byte range: 0xa4 -- 0xfe # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe # no validation needed here. State machine has done that first_char, second_char = byte_str[0], byte_str[1] if first_char >= 0xA4: if second_char >= 0xA1: return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63 else: return 157 * (first_char - 0xA4) + second_char - 0x40 else: return -1 class SJISDistributionAnalysis(CharDistributionAnalysis): def __init__(self): super(SJISDistributionAnalysis, self).__init__() self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER self._table_size = JIS_TABLE_SIZE self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO def get_order(self, byte_str): # for sjis encoding, we are interested # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe # no validation needed here. State machine has done that first_char, second_char = byte_str[0], byte_str[1] if (first_char >= 0x81) and (first_char <= 0x9F): order = 188 * (first_char - 0x81) elif (first_char >= 0xE0) and (first_char <= 0xEF): order = 188 * (first_char - 0xE0 + 31) else: return -1 order = order + second_char - 0x40 if second_char > 0x7F: order = -1 return order class EUCJPDistributionAnalysis(CharDistributionAnalysis): def __init__(self): super(EUCJPDistributionAnalysis, self).__init__() self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER self._table_size = JIS_TABLE_SIZE self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO def get_order(self, byte_str): # for euc-JP encoding, we are interested # first byte range: 0xa0 -- 0xfe # second byte range: 0xa1 -- 0xfe # no validation needed here. State machine has done that char = byte_str[0] if char >= 0xA0: return 94 * (char - 0xA1) + byte_str[1] - 0xa1 else: return -1 PKH]~<python3.10/site-packages/pip/_vendor/chardet/gb2312prober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .mbcharsetprober import MultiByteCharSetProber from .codingstatemachine import CodingStateMachine from .chardistribution import GB2312DistributionAnalysis from .mbcssm import GB2312_SM_MODEL class GB2312Prober(MultiByteCharSetProber): def __init__(self): super(GB2312Prober, self).__init__() self.coding_sm = CodingStateMachine(GB2312_SM_MODEL) self.distribution_analyzer = GB2312DistributionAnalysis() self.reset() @property def charset_name(self): return "GB2312" @property def language(self): return "Chinese" PKH]&QLLBpython3.10/site-packages/pip/_vendor/chardet/langhungarianmodel.pynu[# -*- coding: utf-8 -*- from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel # 3: Positive # 2: Likely # 1: Unlikely # 0: Negative HUNGARIAN_LANG_MODEL = { 28: { # 'A' 28: 0, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 2, # 'D' 32: 1, # 'E' 50: 1, # 'F' 49: 2, # 'G' 38: 1, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 2, # 'K' 41: 2, # 'L' 34: 1, # 'M' 35: 2, # 'N' 47: 1, # 'O' 46: 2, # 'P' 43: 2, # 'R' 33: 2, # 'S' 37: 2, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 2, # 'Z' 2: 0, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 2, # 'd' 1: 1, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 1, # 'h' 9: 1, # 'i' 22: 1, # 'j' 7: 2, # 'k' 6: 2, # 'l' 13: 2, # 'm' 4: 2, # 'n' 8: 0, # 'o' 23: 2, # 'p' 10: 2, # 'r' 5: 1, # 's' 3: 1, # 't' 21: 1, # 'u' 19: 1, # 'v' 62: 1, # 'x' 16: 0, # 'y' 11: 3, # 'z' 51: 1, # 'Á' 44: 0, # 'É' 61: 1, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 40: { # 'B' 28: 2, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 0, # 'M' 35: 1, # 'N' 47: 2, # 'O' 46: 0, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 3, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 2, # 'i' 22: 1, # 'j' 7: 0, # 'k' 6: 1, # 'l' 13: 0, # 'm' 4: 0, # 'n' 8: 2, # 'o' 23: 1, # 'p' 10: 2, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 3, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 0, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 2, # 'á' 15: 2, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 1, # 'ő' 56: 1, # 'ű' }, 54: { # 'C' 28: 1, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 1, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 1, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 0, # 'N' 47: 1, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 2, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 0, # 'V' 55: 1, # 'Y' 52: 1, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 1, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 1, # 'h' 9: 1, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 1, # 'l' 13: 0, # 'm' 4: 0, # 'n' 8: 2, # 'o' 23: 0, # 'p' 10: 1, # 'r' 5: 3, # 's' 3: 0, # 't' 21: 1, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 1, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 1, # 'á' 15: 1, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 45: { # 'D' 28: 2, # 'A' 40: 1, # 'B' 54: 0, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 0, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 2, # 'O' 46: 0, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 1, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 3, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 1, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 0, # 'l' 13: 0, # 'm' 4: 0, # 'n' 8: 1, # 'o' 23: 0, # 'p' 10: 2, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 2, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 1, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 1, # 'á' 15: 1, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 1, # 'ő' 56: 0, # 'ű' }, 32: { # 'E' 28: 1, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 1, # 'E' 50: 1, # 'F' 49: 2, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 2, # 'K' 41: 2, # 'L' 34: 2, # 'M' 35: 2, # 'N' 47: 1, # 'O' 46: 1, # 'P' 43: 2, # 'R' 33: 2, # 'S' 37: 2, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 1, # 'Z' 2: 1, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 2, # 'd' 1: 1, # 'e' 27: 1, # 'f' 12: 3, # 'g' 20: 1, # 'h' 9: 1, # 'i' 22: 1, # 'j' 7: 1, # 'k' 6: 2, # 'l' 13: 2, # 'm' 4: 2, # 'n' 8: 0, # 'o' 23: 1, # 'p' 10: 2, # 'r' 5: 2, # 's' 3: 1, # 't' 21: 2, # 'u' 19: 1, # 'v' 62: 1, # 'x' 16: 0, # 'y' 11: 3, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 0, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 0, # 'Ú' 63: 1, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 1, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 50: { # 'F' 28: 1, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 1, # 'E' 50: 1, # 'F' 49: 0, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 1, # 'O' 46: 0, # 'P' 43: 1, # 'R' 33: 0, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 0, # 'V' 55: 1, # 'Y' 52: 0, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 2, # 'e' 27: 1, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 2, # 'i' 22: 1, # 'j' 7: 0, # 'k' 6: 1, # 'l' 13: 0, # 'm' 4: 0, # 'n' 8: 2, # 'o' 23: 0, # 'p' 10: 2, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 1, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 0, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 0, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 0, # 'Ú' 63: 1, # 'Ü' 14: 1, # 'á' 15: 1, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 2, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 1, # 'ő' 56: 1, # 'ű' }, 49: { # 'G' 28: 2, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 1, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 2, # 'Y' 52: 1, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 2, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 1, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 1, # 'l' 13: 0, # 'm' 4: 0, # 'n' 8: 2, # 'o' 23: 0, # 'p' 10: 2, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 1, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 2, # 'y' 11: 0, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 1, # 'á' 15: 1, # 'é' 30: 0, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 1, # 'ő' 56: 0, # 'ű' }, 38: { # 'H' 28: 2, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 0, # 'D' 32: 1, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 1, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 1, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 1, # 'O' 46: 0, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 0, # 'V' 55: 1, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 2, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 2, # 'i' 22: 1, # 'j' 7: 0, # 'k' 6: 1, # 'l' 13: 1, # 'm' 4: 0, # 'n' 8: 3, # 'o' 23: 0, # 'p' 10: 1, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 2, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 0, # 'z' 51: 2, # 'Á' 44: 2, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 2, # 'á' 15: 1, # 'é' 30: 2, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 1, # 'ő' 56: 1, # 'ű' }, 39: { # 'I' 28: 2, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 1, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 2, # 'K' 41: 2, # 'L' 34: 1, # 'M' 35: 2, # 'N' 47: 1, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 2, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 2, # 'Z' 2: 0, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 2, # 'd' 1: 0, # 'e' 27: 1, # 'f' 12: 2, # 'g' 20: 1, # 'h' 9: 0, # 'i' 22: 1, # 'j' 7: 1, # 'k' 6: 2, # 'l' 13: 2, # 'm' 4: 1, # 'n' 8: 0, # 'o' 23: 1, # 'p' 10: 2, # 'r' 5: 2, # 's' 3: 2, # 't' 21: 0, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 1, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 0, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 53: { # 'J' 28: 2, # 'A' 40: 0, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 1, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 1, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 2, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 1, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 0, # 'l' 13: 0, # 'm' 4: 0, # 'n' 8: 1, # 'o' 23: 0, # 'p' 10: 0, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 2, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 0, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 0, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 2, # 'á' 15: 1, # 'é' 30: 0, # 'í' 25: 2, # 'ó' 24: 2, # 'ö' 31: 1, # 'ú' 29: 0, # 'ü' 42: 1, # 'ő' 56: 0, # 'ű' }, 36: { # 'K' 28: 2, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 0, # 'G' 38: 1, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 2, # 'O' 46: 0, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 0, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 2, # 'e' 27: 1, # 'f' 12: 0, # 'g' 20: 1, # 'h' 9: 3, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 1, # 'l' 13: 1, # 'm' 4: 1, # 'n' 8: 2, # 'o' 23: 0, # 'p' 10: 2, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 1, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 0, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 2, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 2, # 'á' 15: 2, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 2, # 'ö' 31: 1, # 'ú' 29: 2, # 'ü' 42: 1, # 'ő' 56: 0, # 'ű' }, 41: { # 'L' 28: 2, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 2, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 2, # 'O' 46: 0, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 2, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 1, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 3, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 2, # 'i' 22: 1, # 'j' 7: 0, # 'k' 6: 1, # 'l' 13: 0, # 'm' 4: 0, # 'n' 8: 2, # 'o' 23: 0, # 'p' 10: 0, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 2, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 0, # 'z' 51: 2, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 2, # 'á' 15: 1, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 0, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 34: { # 'M' 28: 2, # 'A' 40: 1, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 0, # 'G' 38: 1, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 1, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 1, # 'Z' 2: 3, # 'a' 18: 0, # 'b' 26: 1, # 'c' 17: 0, # 'd' 1: 3, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 3, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 0, # 'l' 13: 1, # 'm' 4: 1, # 'n' 8: 3, # 'o' 23: 0, # 'p' 10: 1, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 2, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 0, # 'z' 51: 2, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 2, # 'á' 15: 2, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 1, # 'ű' }, 35: { # 'N' 28: 2, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 2, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 1, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 2, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 2, # 'Y' 52: 1, # 'Z' 2: 3, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 3, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 2, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 0, # 'l' 13: 0, # 'm' 4: 1, # 'n' 8: 2, # 'o' 23: 0, # 'p' 10: 0, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 1, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 2, # 'y' 11: 0, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 1, # 'á' 15: 2, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 1, # 'ő' 56: 0, # 'ű' }, 47: { # 'O' 28: 1, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 1, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 2, # 'K' 41: 2, # 'L' 34: 2, # 'M' 35: 2, # 'N' 47: 1, # 'O' 46: 1, # 'P' 43: 2, # 'R' 33: 2, # 'S' 37: 2, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 1, # 'Z' 2: 0, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 1, # 'd' 1: 1, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 1, # 'h' 9: 1, # 'i' 22: 1, # 'j' 7: 2, # 'k' 6: 2, # 'l' 13: 1, # 'm' 4: 1, # 'n' 8: 1, # 'o' 23: 1, # 'p' 10: 2, # 'r' 5: 1, # 's' 3: 2, # 't' 21: 1, # 'u' 19: 0, # 'v' 62: 1, # 'x' 16: 0, # 'y' 11: 1, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 0, # 'Í' 58: 1, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 46: { # 'P' 28: 1, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 1, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 0, # 'M' 35: 1, # 'N' 47: 1, # 'O' 46: 1, # 'P' 43: 2, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 1, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 2, # 'e' 27: 1, # 'f' 12: 0, # 'g' 20: 1, # 'h' 9: 2, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 1, # 'l' 13: 0, # 'm' 4: 1, # 'n' 8: 2, # 'o' 23: 0, # 'p' 10: 2, # 'r' 5: 1, # 's' 3: 0, # 't' 21: 1, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 0, # 'z' 51: 2, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 0, # 'Ú' 63: 1, # 'Ü' 14: 3, # 'á' 15: 2, # 'é' 30: 0, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 0, # 'ú' 29: 1, # 'ü' 42: 1, # 'ő' 56: 0, # 'ű' }, 43: { # 'R' 28: 2, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 2, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 2, # 'S' 37: 2, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 1, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 2, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 1, # 'h' 9: 2, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 0, # 'l' 13: 0, # 'm' 4: 0, # 'n' 8: 2, # 'o' 23: 0, # 'p' 10: 0, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 1, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 0, # 'z' 51: 2, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 2, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 2, # 'á' 15: 2, # 'é' 30: 1, # 'í' 25: 2, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 33: { # 'S' 28: 2, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 2, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 2, # 'S' 37: 2, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 3, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 1, # 'c' 17: 0, # 'd' 1: 2, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 1, # 'h' 9: 2, # 'i' 22: 0, # 'j' 7: 1, # 'k' 6: 1, # 'l' 13: 1, # 'm' 4: 0, # 'n' 8: 2, # 'o' 23: 1, # 'p' 10: 0, # 'r' 5: 0, # 's' 3: 1, # 't' 21: 1, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 3, # 'z' 51: 2, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 2, # 'á' 15: 1, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 1, # 'ő' 56: 1, # 'ű' }, 37: { # 'T' 28: 2, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 2, # 'O' 46: 1, # 'P' 43: 2, # 'R' 33: 1, # 'S' 37: 2, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 1, # 'Z' 2: 2, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 2, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 1, # 'h' 9: 2, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 0, # 'l' 13: 0, # 'm' 4: 0, # 'n' 8: 2, # 'o' 23: 0, # 'p' 10: 1, # 'r' 5: 1, # 's' 3: 0, # 't' 21: 2, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 1, # 'z' 51: 2, # 'Á' 44: 2, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 2, # 'á' 15: 1, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 2, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 1, # 'ő' 56: 1, # 'ű' }, 57: { # 'U' 28: 1, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 1, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 1, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 2, # 'S' 37: 1, # 'T' 57: 0, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 1, # 'Z' 2: 0, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 1, # 'd' 1: 1, # 'e' 27: 0, # 'f' 12: 2, # 'g' 20: 0, # 'h' 9: 0, # 'i' 22: 1, # 'j' 7: 1, # 'k' 6: 1, # 'l' 13: 1, # 'm' 4: 1, # 'n' 8: 0, # 'o' 23: 1, # 'p' 10: 1, # 'r' 5: 1, # 's' 3: 1, # 't' 21: 0, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 1, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 1, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 48: { # 'V' 28: 2, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 0, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 1, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 2, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 2, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 1, # 'l' 13: 0, # 'm' 4: 0, # 'n' 8: 2, # 'o' 23: 0, # 'p' 10: 0, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 1, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 0, # 'z' 51: 2, # 'Á' 44: 2, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 0, # 'Ú' 63: 1, # 'Ü' 14: 2, # 'á' 15: 2, # 'é' 30: 1, # 'í' 25: 0, # 'ó' 24: 1, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 55: { # 'Y' 28: 2, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 1, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 2, # 'Z' 2: 1, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 1, # 'd' 1: 1, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 0, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 0, # 'l' 13: 0, # 'm' 4: 0, # 'n' 8: 1, # 'o' 23: 1, # 'p' 10: 0, # 'r' 5: 0, # 's' 3: 0, # 't' 21: 0, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 0, # 'z' 51: 1, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 52: { # 'Z' 28: 2, # 'A' 40: 1, # 'B' 54: 0, # 'C' 45: 1, # 'D' 32: 2, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 2, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 2, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 2, # 'S' 37: 1, # 'T' 57: 1, # 'U' 48: 1, # 'V' 55: 1, # 'Y' 52: 1, # 'Z' 2: 1, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 1, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 1, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 0, # 'l' 13: 0, # 'm' 4: 1, # 'n' 8: 1, # 'o' 23: 0, # 'p' 10: 1, # 'r' 5: 2, # 's' 3: 0, # 't' 21: 1, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 0, # 'z' 51: 2, # 'Á' 44: 1, # 'É' 61: 1, # 'Í' 58: 1, # 'Ó' 59: 1, # 'Ö' 60: 1, # 'Ú' 63: 1, # 'Ü' 14: 1, # 'á' 15: 1, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 2: { # 'a' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 1, # 'a' 18: 3, # 'b' 26: 3, # 'c' 17: 3, # 'd' 1: 2, # 'e' 27: 2, # 'f' 12: 3, # 'g' 20: 3, # 'h' 9: 3, # 'i' 22: 3, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 2, # 'o' 23: 3, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 3, # 'v' 62: 1, # 'x' 16: 2, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 1, # 'á' 15: 1, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 18: { # 'b' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 3, # 'b' 26: 1, # 'c' 17: 1, # 'd' 1: 3, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 1, # 'h' 9: 3, # 'i' 22: 2, # 'j' 7: 2, # 'k' 6: 2, # 'l' 13: 1, # 'm' 4: 2, # 'n' 8: 3, # 'o' 23: 1, # 'p' 10: 3, # 'r' 5: 2, # 's' 3: 1, # 't' 21: 3, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 1, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 2, # 'í' 25: 3, # 'ó' 24: 2, # 'ö' 31: 2, # 'ú' 29: 2, # 'ü' 42: 2, # 'ő' 56: 1, # 'ű' }, 26: { # 'c' 28: 0, # 'A' 40: 0, # 'B' 54: 1, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 1, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 2, # 'a' 18: 1, # 'b' 26: 2, # 'c' 17: 1, # 'd' 1: 3, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 3, # 'h' 9: 3, # 'i' 22: 1, # 'j' 7: 2, # 'k' 6: 1, # 'l' 13: 1, # 'm' 4: 1, # 'n' 8: 3, # 'o' 23: 1, # 'p' 10: 2, # 'r' 5: 3, # 's' 3: 2, # 't' 21: 2, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 2, # 'á' 15: 2, # 'é' 30: 2, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 17: { # 'd' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 2, # 'b' 26: 1, # 'c' 17: 2, # 'd' 1: 3, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 2, # 'h' 9: 3, # 'i' 22: 3, # 'j' 7: 2, # 'k' 6: 1, # 'l' 13: 2, # 'm' 4: 3, # 'n' 8: 3, # 'o' 23: 1, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 3, # 'v' 62: 0, # 'x' 16: 2, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 3, # 'í' 25: 3, # 'ó' 24: 3, # 'ö' 31: 2, # 'ú' 29: 2, # 'ü' 42: 2, # 'ő' 56: 1, # 'ű' }, 1: { # 'e' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 2, # 'a' 18: 3, # 'b' 26: 3, # 'c' 17: 3, # 'd' 1: 2, # 'e' 27: 3, # 'f' 12: 3, # 'g' 20: 3, # 'h' 9: 3, # 'i' 22: 3, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 2, # 'o' 23: 3, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 2, # 'u' 19: 3, # 'v' 62: 2, # 'x' 16: 2, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 1, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 27: { # 'f' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 1, # 'd' 1: 3, # 'e' 27: 2, # 'f' 12: 1, # 'g' 20: 1, # 'h' 9: 3, # 'i' 22: 2, # 'j' 7: 1, # 'k' 6: 1, # 'l' 13: 1, # 'm' 4: 1, # 'n' 8: 3, # 'o' 23: 0, # 'p' 10: 3, # 'r' 5: 1, # 's' 3: 1, # 't' 21: 2, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 0, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 3, # 'ö' 31: 1, # 'ú' 29: 2, # 'ü' 42: 1, # 'ő' 56: 1, # 'ű' }, 12: { # 'g' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 3, # 'b' 26: 2, # 'c' 17: 2, # 'd' 1: 3, # 'e' 27: 2, # 'f' 12: 3, # 'g' 20: 3, # 'h' 9: 3, # 'i' 22: 3, # 'j' 7: 2, # 'k' 6: 3, # 'l' 13: 2, # 'm' 4: 3, # 'n' 8: 3, # 'o' 23: 1, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 3, # 'v' 62: 0, # 'x' 16: 3, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 2, # 'í' 25: 3, # 'ó' 24: 2, # 'ö' 31: 2, # 'ú' 29: 2, # 'ü' 42: 2, # 'ő' 56: 1, # 'ű' }, 20: { # 'h' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 0, # 'd' 1: 3, # 'e' 27: 0, # 'f' 12: 1, # 'g' 20: 2, # 'h' 9: 3, # 'i' 22: 1, # 'j' 7: 1, # 'k' 6: 1, # 'l' 13: 1, # 'm' 4: 1, # 'n' 8: 3, # 'o' 23: 0, # 'p' 10: 1, # 'r' 5: 2, # 's' 3: 1, # 't' 21: 3, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 2, # 'y' 11: 0, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 3, # 'í' 25: 2, # 'ó' 24: 2, # 'ö' 31: 2, # 'ú' 29: 1, # 'ü' 42: 1, # 'ő' 56: 1, # 'ű' }, 9: { # 'i' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 3, # 'b' 26: 3, # 'c' 17: 3, # 'd' 1: 3, # 'e' 27: 3, # 'f' 12: 3, # 'g' 20: 3, # 'h' 9: 2, # 'i' 22: 2, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 2, # 'o' 23: 2, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 3, # 'v' 62: 1, # 'x' 16: 1, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 2, # 'é' 30: 1, # 'í' 25: 3, # 'ó' 24: 1, # 'ö' 31: 2, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 1, # 'ű' }, 22: { # 'j' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 2, # 'b' 26: 1, # 'c' 17: 3, # 'd' 1: 3, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 2, # 'h' 9: 1, # 'i' 22: 2, # 'j' 7: 2, # 'k' 6: 2, # 'l' 13: 1, # 'm' 4: 2, # 'n' 8: 3, # 'o' 23: 1, # 'p' 10: 2, # 'r' 5: 2, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 1, # 'í' 25: 3, # 'ó' 24: 3, # 'ö' 31: 3, # 'ú' 29: 2, # 'ü' 42: 1, # 'ő' 56: 1, # 'ű' }, 7: { # 'k' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 3, # 'b' 26: 2, # 'c' 17: 1, # 'd' 1: 3, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 2, # 'h' 9: 3, # 'i' 22: 2, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 1, # 'm' 4: 3, # 'n' 8: 3, # 'o' 23: 1, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 2, # 'v' 62: 0, # 'x' 16: 2, # 'y' 11: 1, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 3, # 'í' 25: 2, # 'ó' 24: 3, # 'ö' 31: 1, # 'ú' 29: 3, # 'ü' 42: 1, # 'ő' 56: 1, # 'ű' }, 6: { # 'l' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 1, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 1, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 2, # 'b' 26: 3, # 'c' 17: 3, # 'd' 1: 3, # 'e' 27: 3, # 'f' 12: 3, # 'g' 20: 3, # 'h' 9: 3, # 'i' 22: 3, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 3, # 'o' 23: 2, # 'p' 10: 2, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 3, # 'v' 62: 0, # 'x' 16: 3, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 3, # 'í' 25: 3, # 'ó' 24: 3, # 'ö' 31: 2, # 'ú' 29: 2, # 'ü' 42: 3, # 'ő' 56: 1, # 'ű' }, 13: { # 'm' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 3, # 'b' 26: 2, # 'c' 17: 1, # 'd' 1: 3, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 2, # 'h' 9: 3, # 'i' 22: 2, # 'j' 7: 1, # 'k' 6: 3, # 'l' 13: 3, # 'm' 4: 2, # 'n' 8: 3, # 'o' 23: 3, # 'p' 10: 2, # 'r' 5: 2, # 's' 3: 2, # 't' 21: 3, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 2, # 'í' 25: 2, # 'ó' 24: 2, # 'ö' 31: 2, # 'ú' 29: 2, # 'ü' 42: 1, # 'ő' 56: 2, # 'ű' }, 4: { # 'n' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 3, # 'b' 26: 3, # 'c' 17: 3, # 'd' 1: 3, # 'e' 27: 2, # 'f' 12: 3, # 'g' 20: 3, # 'h' 9: 3, # 'i' 22: 2, # 'j' 7: 3, # 'k' 6: 2, # 'l' 13: 2, # 'm' 4: 3, # 'n' 8: 3, # 'o' 23: 2, # 'p' 10: 2, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 2, # 'v' 62: 1, # 'x' 16: 3, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 2, # 'í' 25: 2, # 'ó' 24: 3, # 'ö' 31: 2, # 'ú' 29: 3, # 'ü' 42: 2, # 'ő' 56: 1, # 'ű' }, 8: { # 'o' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 1, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 2, # 'a' 18: 3, # 'b' 26: 3, # 'c' 17: 3, # 'd' 1: 2, # 'e' 27: 2, # 'f' 12: 3, # 'g' 20: 3, # 'h' 9: 2, # 'i' 22: 2, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 1, # 'o' 23: 3, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 2, # 'u' 19: 3, # 'v' 62: 1, # 'x' 16: 1, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 1, # 'á' 15: 2, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 23: { # 'p' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 1, # 'b' 26: 2, # 'c' 17: 1, # 'd' 1: 3, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 2, # 'h' 9: 3, # 'i' 22: 2, # 'j' 7: 2, # 'k' 6: 3, # 'l' 13: 1, # 'm' 4: 2, # 'n' 8: 3, # 'o' 23: 3, # 'p' 10: 3, # 'r' 5: 2, # 's' 3: 2, # 't' 21: 3, # 'u' 19: 2, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 2, # 'í' 25: 2, # 'ó' 24: 2, # 'ö' 31: 1, # 'ú' 29: 2, # 'ü' 42: 1, # 'ő' 56: 1, # 'ű' }, 10: { # 'r' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 3, # 'b' 26: 3, # 'c' 17: 3, # 'd' 1: 3, # 'e' 27: 2, # 'f' 12: 3, # 'g' 20: 2, # 'h' 9: 3, # 'i' 22: 3, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 3, # 'o' 23: 2, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 3, # 'v' 62: 1, # 'x' 16: 2, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 2, # 'í' 25: 3, # 'ó' 24: 3, # 'ö' 31: 3, # 'ú' 29: 3, # 'ü' 42: 2, # 'ő' 56: 2, # 'ű' }, 5: { # 's' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 3, # 'b' 26: 2, # 'c' 17: 2, # 'd' 1: 3, # 'e' 27: 2, # 'f' 12: 2, # 'g' 20: 2, # 'h' 9: 3, # 'i' 22: 1, # 'j' 7: 3, # 'k' 6: 2, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 3, # 'o' 23: 2, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 2, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 3, # 'í' 25: 3, # 'ó' 24: 3, # 'ö' 31: 3, # 'ú' 29: 3, # 'ü' 42: 2, # 'ő' 56: 1, # 'ű' }, 3: { # 't' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 3, # 'b' 26: 2, # 'c' 17: 1, # 'd' 1: 3, # 'e' 27: 2, # 'f' 12: 1, # 'g' 20: 3, # 'h' 9: 3, # 'i' 22: 3, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 2, # 'm' 4: 3, # 'n' 8: 3, # 'o' 23: 1, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 3, # 'v' 62: 0, # 'x' 16: 3, # 'y' 11: 1, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 2, # 'í' 25: 3, # 'ó' 24: 3, # 'ö' 31: 3, # 'ú' 29: 3, # 'ü' 42: 3, # 'ő' 56: 2, # 'ű' }, 21: { # 'u' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 1, # 'a' 18: 2, # 'b' 26: 2, # 'c' 17: 3, # 'd' 1: 2, # 'e' 27: 1, # 'f' 12: 3, # 'g' 20: 2, # 'h' 9: 2, # 'i' 22: 2, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 1, # 'o' 23: 2, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 1, # 'u' 19: 3, # 'v' 62: 1, # 'x' 16: 1, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 2, # 'á' 15: 1, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 0, # 'ö' 31: 1, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 19: { # 'v' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 2, # 'b' 26: 1, # 'c' 17: 1, # 'd' 1: 3, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 1, # 'h' 9: 3, # 'i' 22: 1, # 'j' 7: 1, # 'k' 6: 1, # 'l' 13: 1, # 'm' 4: 1, # 'n' 8: 3, # 'o' 23: 1, # 'p' 10: 1, # 'r' 5: 2, # 's' 3: 2, # 't' 21: 2, # 'u' 19: 2, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 1, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 2, # 'í' 25: 2, # 'ó' 24: 2, # 'ö' 31: 1, # 'ú' 29: 2, # 'ü' 42: 1, # 'ő' 56: 1, # 'ű' }, 62: { # 'x' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 1, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 0, # 'd' 1: 1, # 'e' 27: 1, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 1, # 'i' 22: 0, # 'j' 7: 1, # 'k' 6: 1, # 'l' 13: 1, # 'm' 4: 1, # 'n' 8: 1, # 'o' 23: 1, # 'p' 10: 1, # 'r' 5: 1, # 's' 3: 1, # 't' 21: 1, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 0, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 1, # 'á' 15: 1, # 'é' 30: 1, # 'í' 25: 1, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 16: { # 'y' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 2, # 'b' 26: 1, # 'c' 17: 1, # 'd' 1: 3, # 'e' 27: 2, # 'f' 12: 2, # 'g' 20: 2, # 'h' 9: 3, # 'i' 22: 2, # 'j' 7: 2, # 'k' 6: 2, # 'l' 13: 2, # 'm' 4: 3, # 'n' 8: 3, # 'o' 23: 2, # 'p' 10: 2, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 3, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 2, # 'í' 25: 2, # 'ó' 24: 3, # 'ö' 31: 2, # 'ú' 29: 2, # 'ü' 42: 1, # 'ő' 56: 2, # 'ű' }, 11: { # 'z' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 3, # 'a' 18: 2, # 'b' 26: 1, # 'c' 17: 3, # 'd' 1: 3, # 'e' 27: 1, # 'f' 12: 2, # 'g' 20: 2, # 'h' 9: 3, # 'i' 22: 1, # 'j' 7: 3, # 'k' 6: 2, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 3, # 'o' 23: 1, # 'p' 10: 2, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 3, # 'u' 19: 2, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 3, # 'á' 15: 3, # 'é' 30: 3, # 'í' 25: 3, # 'ó' 24: 3, # 'ö' 31: 2, # 'ú' 29: 3, # 'ü' 42: 2, # 'ő' 56: 1, # 'ű' }, 51: { # 'Á' 28: 0, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 0, # 'E' 50: 1, # 'F' 49: 2, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 2, # 'L' 34: 1, # 'M' 35: 2, # 'N' 47: 0, # 'O' 46: 1, # 'P' 43: 2, # 'R' 33: 2, # 'S' 37: 1, # 'T' 57: 0, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 1, # 'Z' 2: 0, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 1, # 'd' 1: 0, # 'e' 27: 0, # 'f' 12: 1, # 'g' 20: 1, # 'h' 9: 0, # 'i' 22: 1, # 'j' 7: 1, # 'k' 6: 2, # 'l' 13: 2, # 'm' 4: 0, # 'n' 8: 0, # 'o' 23: 1, # 'p' 10: 1, # 'r' 5: 1, # 's' 3: 1, # 't' 21: 0, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 1, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 1, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 44: { # 'É' 28: 0, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 1, # 'E' 50: 0, # 'F' 49: 2, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 2, # 'L' 34: 1, # 'M' 35: 2, # 'N' 47: 0, # 'O' 46: 1, # 'P' 43: 2, # 'R' 33: 2, # 'S' 37: 2, # 'T' 57: 0, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 1, # 'Z' 2: 0, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 1, # 'd' 1: 0, # 'e' 27: 0, # 'f' 12: 1, # 'g' 20: 1, # 'h' 9: 0, # 'i' 22: 1, # 'j' 7: 1, # 'k' 6: 2, # 'l' 13: 1, # 'm' 4: 2, # 'n' 8: 0, # 'o' 23: 1, # 'p' 10: 2, # 'r' 5: 3, # 's' 3: 1, # 't' 21: 0, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 0, # 'z' 51: 0, # 'Á' 44: 1, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 61: { # 'Í' 28: 0, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 0, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 1, # 'J' 36: 0, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 0, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 0, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 1, # 'Z' 2: 0, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 0, # 'e' 27: 0, # 'f' 12: 2, # 'g' 20: 0, # 'h' 9: 0, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 0, # 'l' 13: 1, # 'm' 4: 0, # 'n' 8: 0, # 'o' 23: 0, # 'p' 10: 1, # 'r' 5: 0, # 's' 3: 1, # 't' 21: 0, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 1, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 58: { # 'Ó' 28: 1, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 0, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 1, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 2, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 0, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 0, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 1, # 'Z' 2: 0, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 1, # 'd' 1: 0, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 2, # 'h' 9: 0, # 'i' 22: 0, # 'j' 7: 1, # 'k' 6: 1, # 'l' 13: 0, # 'm' 4: 1, # 'n' 8: 0, # 'o' 23: 1, # 'p' 10: 1, # 'r' 5: 1, # 's' 3: 0, # 't' 21: 0, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 1, # 'z' 51: 0, # 'Á' 44: 1, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 59: { # 'Ö' 28: 0, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 0, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 0, # 'O' 46: 1, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 0, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 1, # 'Z' 2: 0, # 'a' 18: 0, # 'b' 26: 1, # 'c' 17: 1, # 'd' 1: 0, # 'e' 27: 0, # 'f' 12: 0, # 'g' 20: 0, # 'h' 9: 0, # 'i' 22: 0, # 'j' 7: 1, # 'k' 6: 1, # 'l' 13: 1, # 'm' 4: 1, # 'n' 8: 0, # 'o' 23: 0, # 'p' 10: 2, # 'r' 5: 1, # 's' 3: 1, # 't' 21: 0, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 1, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 60: { # 'Ú' 28: 0, # 'A' 40: 1, # 'B' 54: 1, # 'C' 45: 1, # 'D' 32: 0, # 'E' 50: 1, # 'F' 49: 1, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 0, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 1, # 'Z' 2: 0, # 'a' 18: 0, # 'b' 26: 0, # 'c' 17: 0, # 'd' 1: 0, # 'e' 27: 0, # 'f' 12: 2, # 'g' 20: 0, # 'h' 9: 0, # 'i' 22: 2, # 'j' 7: 0, # 'k' 6: 0, # 'l' 13: 0, # 'm' 4: 1, # 'n' 8: 0, # 'o' 23: 0, # 'p' 10: 1, # 'r' 5: 1, # 's' 3: 1, # 't' 21: 0, # 'u' 19: 0, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 0, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 63: { # 'Ü' 28: 0, # 'A' 40: 1, # 'B' 54: 0, # 'C' 45: 1, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 1, # 'G' 38: 1, # 'H' 39: 0, # 'I' 53: 1, # 'J' 36: 1, # 'K' 41: 1, # 'L' 34: 1, # 'M' 35: 1, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 1, # 'R' 33: 1, # 'S' 37: 1, # 'T' 57: 0, # 'U' 48: 1, # 'V' 55: 0, # 'Y' 52: 1, # 'Z' 2: 0, # 'a' 18: 1, # 'b' 26: 0, # 'c' 17: 1, # 'd' 1: 0, # 'e' 27: 0, # 'f' 12: 1, # 'g' 20: 0, # 'h' 9: 0, # 'i' 22: 0, # 'j' 7: 0, # 'k' 6: 1, # 'l' 13: 0, # 'm' 4: 1, # 'n' 8: 0, # 'o' 23: 0, # 'p' 10: 1, # 'r' 5: 1, # 's' 3: 1, # 't' 21: 0, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 1, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 14: { # 'á' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 1, # 'a' 18: 3, # 'b' 26: 3, # 'c' 17: 3, # 'd' 1: 1, # 'e' 27: 2, # 'f' 12: 3, # 'g' 20: 2, # 'h' 9: 2, # 'i' 22: 3, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 1, # 'o' 23: 2, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 2, # 'u' 19: 3, # 'v' 62: 0, # 'x' 16: 1, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 1, # 'á' 15: 2, # 'é' 30: 1, # 'í' 25: 0, # 'ó' 24: 1, # 'ö' 31: 0, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 15: { # 'é' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 1, # 'a' 18: 3, # 'b' 26: 2, # 'c' 17: 3, # 'd' 1: 1, # 'e' 27: 1, # 'f' 12: 3, # 'g' 20: 3, # 'h' 9: 2, # 'i' 22: 2, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 1, # 'o' 23: 3, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 0, # 'u' 19: 3, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 1, # 'á' 15: 1, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 30: { # 'í' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 0, # 'a' 18: 1, # 'b' 26: 2, # 'c' 17: 1, # 'd' 1: 0, # 'e' 27: 1, # 'f' 12: 3, # 'g' 20: 0, # 'h' 9: 0, # 'i' 22: 1, # 'j' 7: 1, # 'k' 6: 2, # 'l' 13: 2, # 'm' 4: 3, # 'n' 8: 0, # 'o' 23: 1, # 'p' 10: 3, # 'r' 5: 2, # 's' 3: 3, # 't' 21: 0, # 'u' 19: 3, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 25: { # 'ó' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 2, # 'a' 18: 3, # 'b' 26: 2, # 'c' 17: 3, # 'd' 1: 1, # 'e' 27: 2, # 'f' 12: 2, # 'g' 20: 2, # 'h' 9: 2, # 'i' 22: 2, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 2, # 'm' 4: 3, # 'n' 8: 1, # 'o' 23: 2, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 1, # 'u' 19: 2, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 1, # 'á' 15: 1, # 'é' 30: 1, # 'í' 25: 0, # 'ó' 24: 1, # 'ö' 31: 1, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 24: { # 'ö' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 0, # 'a' 18: 3, # 'b' 26: 1, # 'c' 17: 2, # 'd' 1: 0, # 'e' 27: 1, # 'f' 12: 2, # 'g' 20: 1, # 'h' 9: 0, # 'i' 22: 1, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 8: 0, # 'o' 23: 2, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 3, # 't' 21: 0, # 'u' 19: 3, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 3, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 31: { # 'ú' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 1, # 'a' 18: 1, # 'b' 26: 2, # 'c' 17: 1, # 'd' 1: 1, # 'e' 27: 2, # 'f' 12: 3, # 'g' 20: 1, # 'h' 9: 1, # 'i' 22: 3, # 'j' 7: 1, # 'k' 6: 3, # 'l' 13: 1, # 'm' 4: 2, # 'n' 8: 0, # 'o' 23: 1, # 'p' 10: 3, # 'r' 5: 3, # 's' 3: 2, # 't' 21: 1, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 1, # 'á' 15: 1, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 29: { # 'ü' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 1, # 'a' 18: 1, # 'b' 26: 1, # 'c' 17: 2, # 'd' 1: 1, # 'e' 27: 1, # 'f' 12: 3, # 'g' 20: 2, # 'h' 9: 1, # 'i' 22: 1, # 'j' 7: 3, # 'k' 6: 3, # 'l' 13: 1, # 'm' 4: 3, # 'n' 8: 0, # 'o' 23: 1, # 'p' 10: 2, # 'r' 5: 2, # 's' 3: 2, # 't' 21: 0, # 'u' 19: 2, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 1, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 42: { # 'ő' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 1, # 'a' 18: 2, # 'b' 26: 1, # 'c' 17: 2, # 'd' 1: 1, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 1, # 'h' 9: 1, # 'i' 22: 1, # 'j' 7: 2, # 'k' 6: 3, # 'l' 13: 1, # 'm' 4: 2, # 'n' 8: 1, # 'o' 23: 1, # 'p' 10: 2, # 'r' 5: 2, # 's' 3: 2, # 't' 21: 1, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 1, # 'é' 30: 1, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 1, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, 56: { # 'ű' 28: 0, # 'A' 40: 0, # 'B' 54: 0, # 'C' 45: 0, # 'D' 32: 0, # 'E' 50: 0, # 'F' 49: 0, # 'G' 38: 0, # 'H' 39: 0, # 'I' 53: 0, # 'J' 36: 0, # 'K' 41: 0, # 'L' 34: 0, # 'M' 35: 0, # 'N' 47: 0, # 'O' 46: 0, # 'P' 43: 0, # 'R' 33: 0, # 'S' 37: 0, # 'T' 57: 0, # 'U' 48: 0, # 'V' 55: 0, # 'Y' 52: 0, # 'Z' 2: 1, # 'a' 18: 1, # 'b' 26: 0, # 'c' 17: 1, # 'd' 1: 1, # 'e' 27: 1, # 'f' 12: 1, # 'g' 20: 1, # 'h' 9: 1, # 'i' 22: 1, # 'j' 7: 1, # 'k' 6: 1, # 'l' 13: 0, # 'm' 4: 2, # 'n' 8: 0, # 'o' 23: 0, # 'p' 10: 1, # 'r' 5: 1, # 's' 3: 1, # 't' 21: 0, # 'u' 19: 1, # 'v' 62: 0, # 'x' 16: 0, # 'y' 11: 2, # 'z' 51: 0, # 'Á' 44: 0, # 'É' 61: 0, # 'Í' 58: 0, # 'Ó' 59: 0, # 'Ö' 60: 0, # 'Ú' 63: 0, # 'Ü' 14: 0, # 'á' 15: 0, # 'é' 30: 0, # 'í' 25: 0, # 'ó' 24: 0, # 'ö' 31: 0, # 'ú' 29: 0, # 'ü' 42: 0, # 'ő' 56: 0, # 'ű' }, } # 255: Undefined characters that did not exist in training text # 254: Carriage/Return # 253: symbol (punctuation) that does not belong to word # 252: 0 - 9 # 251: Control characters # Character Mapping Table(s): WINDOWS_1250_HUNGARIAN_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 28, # 'A' 66: 40, # 'B' 67: 54, # 'C' 68: 45, # 'D' 69: 32, # 'E' 70: 50, # 'F' 71: 49, # 'G' 72: 38, # 'H' 73: 39, # 'I' 74: 53, # 'J' 75: 36, # 'K' 76: 41, # 'L' 77: 34, # 'M' 78: 35, # 'N' 79: 47, # 'O' 80: 46, # 'P' 81: 72, # 'Q' 82: 43, # 'R' 83: 33, # 'S' 84: 37, # 'T' 85: 57, # 'U' 86: 48, # 'V' 87: 64, # 'W' 88: 68, # 'X' 89: 55, # 'Y' 90: 52, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 2, # 'a' 98: 18, # 'b' 99: 26, # 'c' 100: 17, # 'd' 101: 1, # 'e' 102: 27, # 'f' 103: 12, # 'g' 104: 20, # 'h' 105: 9, # 'i' 106: 22, # 'j' 107: 7, # 'k' 108: 6, # 'l' 109: 13, # 'm' 110: 4, # 'n' 111: 8, # 'o' 112: 23, # 'p' 113: 67, # 'q' 114: 10, # 'r' 115: 5, # 's' 116: 3, # 't' 117: 21, # 'u' 118: 19, # 'v' 119: 65, # 'w' 120: 62, # 'x' 121: 16, # 'y' 122: 11, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 161, # '€' 129: 162, # None 130: 163, # '‚' 131: 164, # None 132: 165, # '„' 133: 166, # '…' 134: 167, # '†' 135: 168, # '‡' 136: 169, # None 137: 170, # '‰' 138: 171, # 'Š' 139: 172, # '‹' 140: 173, # 'Ś' 141: 174, # 'Ť' 142: 175, # 'Ž' 143: 176, # 'Ź' 144: 177, # None 145: 178, # '‘' 146: 179, # '’' 147: 180, # '“' 148: 78, # '”' 149: 181, # '•' 150: 69, # '–' 151: 182, # '—' 152: 183, # None 153: 184, # '™' 154: 185, # 'š' 155: 186, # '›' 156: 187, # 'ś' 157: 188, # 'ť' 158: 189, # 'ž' 159: 190, # 'ź' 160: 191, # '\xa0' 161: 192, # 'ˇ' 162: 193, # '˘' 163: 194, # 'Ł' 164: 195, # '¤' 165: 196, # 'Ą' 166: 197, # '¦' 167: 76, # '§' 168: 198, # '¨' 169: 199, # '©' 170: 200, # 'Ş' 171: 201, # '«' 172: 202, # '¬' 173: 203, # '\xad' 174: 204, # '®' 175: 205, # 'Ż' 176: 81, # '°' 177: 206, # '±' 178: 207, # '˛' 179: 208, # 'ł' 180: 209, # '´' 181: 210, # 'µ' 182: 211, # '¶' 183: 212, # '·' 184: 213, # '¸' 185: 214, # 'ą' 186: 215, # 'ş' 187: 216, # '»' 188: 217, # 'Ľ' 189: 218, # '˝' 190: 219, # 'ľ' 191: 220, # 'ż' 192: 221, # 'Ŕ' 193: 51, # 'Á' 194: 83, # 'Â' 195: 222, # 'Ă' 196: 80, # 'Ä' 197: 223, # 'Ĺ' 198: 224, # 'Ć' 199: 225, # 'Ç' 200: 226, # 'Č' 201: 44, # 'É' 202: 227, # 'Ę' 203: 228, # 'Ë' 204: 229, # 'Ě' 205: 61, # 'Í' 206: 230, # 'Î' 207: 231, # 'Ď' 208: 232, # 'Đ' 209: 233, # 'Ń' 210: 234, # 'Ň' 211: 58, # 'Ó' 212: 235, # 'Ô' 213: 66, # 'Ő' 214: 59, # 'Ö' 215: 236, # '×' 216: 237, # 'Ř' 217: 238, # 'Ů' 218: 60, # 'Ú' 219: 70, # 'Ű' 220: 63, # 'Ü' 221: 239, # 'Ý' 222: 240, # 'Ţ' 223: 241, # 'ß' 224: 84, # 'ŕ' 225: 14, # 'á' 226: 75, # 'â' 227: 242, # 'ă' 228: 71, # 'ä' 229: 82, # 'ĺ' 230: 243, # 'ć' 231: 73, # 'ç' 232: 244, # 'č' 233: 15, # 'é' 234: 85, # 'ę' 235: 79, # 'ë' 236: 86, # 'ě' 237: 30, # 'í' 238: 77, # 'î' 239: 87, # 'ď' 240: 245, # 'đ' 241: 246, # 'ń' 242: 247, # 'ň' 243: 25, # 'ó' 244: 74, # 'ô' 245: 42, # 'ő' 246: 24, # 'ö' 247: 248, # '÷' 248: 249, # 'ř' 249: 250, # 'ů' 250: 31, # 'ú' 251: 56, # 'ű' 252: 29, # 'ü' 253: 251, # 'ý' 254: 252, # 'ţ' 255: 253, # '˙' } WINDOWS_1250_HUNGARIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1250', language='Hungarian', char_to_order_map=WINDOWS_1250_HUNGARIAN_CHAR_TO_ORDER, language_model=HUNGARIAN_LANG_MODEL, typical_positive_ratio=0.947368, keep_ascii_letters=True, alphabet='ABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvzÁÉÍÓÖÚÜáéíóöúüŐőŰű') ISO_8859_2_HUNGARIAN_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 28, # 'A' 66: 40, # 'B' 67: 54, # 'C' 68: 45, # 'D' 69: 32, # 'E' 70: 50, # 'F' 71: 49, # 'G' 72: 38, # 'H' 73: 39, # 'I' 74: 53, # 'J' 75: 36, # 'K' 76: 41, # 'L' 77: 34, # 'M' 78: 35, # 'N' 79: 47, # 'O' 80: 46, # 'P' 81: 71, # 'Q' 82: 43, # 'R' 83: 33, # 'S' 84: 37, # 'T' 85: 57, # 'U' 86: 48, # 'V' 87: 64, # 'W' 88: 68, # 'X' 89: 55, # 'Y' 90: 52, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 2, # 'a' 98: 18, # 'b' 99: 26, # 'c' 100: 17, # 'd' 101: 1, # 'e' 102: 27, # 'f' 103: 12, # 'g' 104: 20, # 'h' 105: 9, # 'i' 106: 22, # 'j' 107: 7, # 'k' 108: 6, # 'l' 109: 13, # 'm' 110: 4, # 'n' 111: 8, # 'o' 112: 23, # 'p' 113: 67, # 'q' 114: 10, # 'r' 115: 5, # 's' 116: 3, # 't' 117: 21, # 'u' 118: 19, # 'v' 119: 65, # 'w' 120: 62, # 'x' 121: 16, # 'y' 122: 11, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 159, # '\x80' 129: 160, # '\x81' 130: 161, # '\x82' 131: 162, # '\x83' 132: 163, # '\x84' 133: 164, # '\x85' 134: 165, # '\x86' 135: 166, # '\x87' 136: 167, # '\x88' 137: 168, # '\x89' 138: 169, # '\x8a' 139: 170, # '\x8b' 140: 171, # '\x8c' 141: 172, # '\x8d' 142: 173, # '\x8e' 143: 174, # '\x8f' 144: 175, # '\x90' 145: 176, # '\x91' 146: 177, # '\x92' 147: 178, # '\x93' 148: 179, # '\x94' 149: 180, # '\x95' 150: 181, # '\x96' 151: 182, # '\x97' 152: 183, # '\x98' 153: 184, # '\x99' 154: 185, # '\x9a' 155: 186, # '\x9b' 156: 187, # '\x9c' 157: 188, # '\x9d' 158: 189, # '\x9e' 159: 190, # '\x9f' 160: 191, # '\xa0' 161: 192, # 'Ą' 162: 193, # '˘' 163: 194, # 'Ł' 164: 195, # '¤' 165: 196, # 'Ľ' 166: 197, # 'Ś' 167: 75, # '§' 168: 198, # '¨' 169: 199, # 'Š' 170: 200, # 'Ş' 171: 201, # 'Ť' 172: 202, # 'Ź' 173: 203, # '\xad' 174: 204, # 'Ž' 175: 205, # 'Ż' 176: 79, # '°' 177: 206, # 'ą' 178: 207, # '˛' 179: 208, # 'ł' 180: 209, # '´' 181: 210, # 'ľ' 182: 211, # 'ś' 183: 212, # 'ˇ' 184: 213, # '¸' 185: 214, # 'š' 186: 215, # 'ş' 187: 216, # 'ť' 188: 217, # 'ź' 189: 218, # '˝' 190: 219, # 'ž' 191: 220, # 'ż' 192: 221, # 'Ŕ' 193: 51, # 'Á' 194: 81, # 'Â' 195: 222, # 'Ă' 196: 78, # 'Ä' 197: 223, # 'Ĺ' 198: 224, # 'Ć' 199: 225, # 'Ç' 200: 226, # 'Č' 201: 44, # 'É' 202: 227, # 'Ę' 203: 228, # 'Ë' 204: 229, # 'Ě' 205: 61, # 'Í' 206: 230, # 'Î' 207: 231, # 'Ď' 208: 232, # 'Đ' 209: 233, # 'Ń' 210: 234, # 'Ň' 211: 58, # 'Ó' 212: 235, # 'Ô' 213: 66, # 'Ő' 214: 59, # 'Ö' 215: 236, # '×' 216: 237, # 'Ř' 217: 238, # 'Ů' 218: 60, # 'Ú' 219: 69, # 'Ű' 220: 63, # 'Ü' 221: 239, # 'Ý' 222: 240, # 'Ţ' 223: 241, # 'ß' 224: 82, # 'ŕ' 225: 14, # 'á' 226: 74, # 'â' 227: 242, # 'ă' 228: 70, # 'ä' 229: 80, # 'ĺ' 230: 243, # 'ć' 231: 72, # 'ç' 232: 244, # 'č' 233: 15, # 'é' 234: 83, # 'ę' 235: 77, # 'ë' 236: 84, # 'ě' 237: 30, # 'í' 238: 76, # 'î' 239: 85, # 'ď' 240: 245, # 'đ' 241: 246, # 'ń' 242: 247, # 'ň' 243: 25, # 'ó' 244: 73, # 'ô' 245: 42, # 'ő' 246: 24, # 'ö' 247: 248, # '÷' 248: 249, # 'ř' 249: 250, # 'ů' 250: 31, # 'ú' 251: 56, # 'ű' 252: 29, # 'ü' 253: 251, # 'ý' 254: 252, # 'ţ' 255: 253, # '˙' } ISO_8859_2_HUNGARIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-2', language='Hungarian', char_to_order_map=ISO_8859_2_HUNGARIAN_CHAR_TO_ORDER, language_model=HUNGARIAN_LANG_MODEL, typical_positive_ratio=0.947368, keep_ascii_letters=True, alphabet='ABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvzÁÉÍÓÖÚÜáéíóöúüŐőŰű') PKH] 7Х;python3.10/site-packages/pip/_vendor/chardet/eucjpprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .enums import ProbingState, MachineState from .mbcharsetprober import MultiByteCharSetProber from .codingstatemachine import CodingStateMachine from .chardistribution import EUCJPDistributionAnalysis from .jpcntx import EUCJPContextAnalysis from .mbcssm import EUCJP_SM_MODEL class EUCJPProber(MultiByteCharSetProber): def __init__(self): super(EUCJPProber, self).__init__() self.coding_sm = CodingStateMachine(EUCJP_SM_MODEL) self.distribution_analyzer = EUCJPDistributionAnalysis() self.context_analyzer = EUCJPContextAnalysis() self.reset() def reset(self): super(EUCJPProber, self).reset() self.context_analyzer.reset() @property def charset_name(self): return "EUC-JP" @property def language(self): return "Japanese" def feed(self, byte_str): for i in range(len(byte_str)): # PY3K: byte_str is a byte array, so byte_str[i] is an int, not a byte coding_state = self.coding_sm.next_state(byte_str[i]) if coding_state == MachineState.ERROR: self.logger.debug('%s %s prober hit error at byte %s', self.charset_name, self.language, i) self._state = ProbingState.NOT_ME break elif coding_state == MachineState.ITS_ME: self._state = ProbingState.FOUND_IT break elif coding_state == MachineState.START: char_len = self.coding_sm.get_current_charlen() if i == 0: self._last_char[1] = byte_str[0] self.context_analyzer.feed(self._last_char, char_len) self.distribution_analyzer.feed(self._last_char, char_len) else: self.context_analyzer.feed(byte_str[i - 1:i + 1], char_len) self.distribution_analyzer.feed(byte_str[i - 1:i + 1], char_len) self._last_char[0] = byte_str[-1] if self.state == ProbingState.DETECTING: if (self.context_analyzer.got_enough_data() and (self.get_confidence() > self.SHORTCUT_THRESHOLD)): self._state = ProbingState.FOUND_IT return self.state def get_confidence(self): context_conf = self.context_analyzer.get_confidence() distrib_conf = self.distribution_analyzer.get_confidence() return max(context_conf, distrib_conf) PKH]A;python3.10/site-packages/pip/_vendor/chardet/euctwprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .mbcharsetprober import MultiByteCharSetProber from .codingstatemachine import CodingStateMachine from .chardistribution import EUCTWDistributionAnalysis from .mbcssm import EUCTW_SM_MODEL class EUCTWProber(MultiByteCharSetProber): def __init__(self): super(EUCTWProber, self).__init__() self.coding_sm = CodingStateMachine(EUCTW_SM_MODEL) self.distribution_analyzer = EUCTWDistributionAnalysis() self.reset() @property def charset_name(self): return "EUC-TW" @property def language(self): return "Taiwan" PKH]B1??;python3.10/site-packages/pip/_vendor/chardet/cp949prober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .chardistribution import EUCKRDistributionAnalysis from .codingstatemachine import CodingStateMachine from .mbcharsetprober import MultiByteCharSetProber from .mbcssm import CP949_SM_MODEL class CP949Prober(MultiByteCharSetProber): def __init__(self): super(CP949Prober, self).__init__() self.coding_sm = CodingStateMachine(CP949_SM_MODEL) # NOTE: CP949 is a superset of EUC-KR, so the distribution should be # not different. self.distribution_analyzer = EUCKRDistributionAnalysis() self.reset() @property def charset_name(self): return "CP949" @property def language(self): return "Korean" PKH]= :python3.10/site-packages/pip/_vendor/chardet/utf8prober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .charsetprober import CharSetProber from .enums import ProbingState, MachineState from .codingstatemachine import CodingStateMachine from .mbcssm import UTF8_SM_MODEL class UTF8Prober(CharSetProber): ONE_CHAR_PROB = 0.5 def __init__(self): super(UTF8Prober, self).__init__() self.coding_sm = CodingStateMachine(UTF8_SM_MODEL) self._num_mb_chars = None self.reset() def reset(self): super(UTF8Prober, self).reset() self.coding_sm.reset() self._num_mb_chars = 0 @property def charset_name(self): return "utf-8" @property def language(self): return "" def feed(self, byte_str): for c in byte_str: coding_state = self.coding_sm.next_state(c) if coding_state == MachineState.ERROR: self._state = ProbingState.NOT_ME break elif coding_state == MachineState.ITS_ME: self._state = ProbingState.FOUND_IT break elif coding_state == MachineState.START: if self.coding_sm.get_current_charlen() >= 2: self._num_mb_chars += 1 if self.state == ProbingState.DETECTING: if self.get_confidence() > self.SHORTCUT_THRESHOLD: self._state = ProbingState.FOUND_IT return self.state def get_confidence(self): unlike = 0.99 if self._num_mb_chars < 6: unlike *= self.ONE_CHAR_PROB ** self._num_mb_chars return 1.0 - unlike else: return unlike PKH]gf:python3.10/site-packages/pip/_vendor/chardet/big5prober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Communicator client code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .mbcharsetprober import MultiByteCharSetProber from .codingstatemachine import CodingStateMachine from .chardistribution import Big5DistributionAnalysis from .mbcssm import BIG5_SM_MODEL class Big5Prober(MultiByteCharSetProber): def __init__(self): super(Big5Prober, self).__init__() self.coding_sm = CodingStateMachine(BIG5_SM_MODEL) self.distribution_analyzer = Big5DistributionAnalysis() self.reset() @property def charset_name(self): return "Big5" @property def language(self): return "Chinese" PKH]icc6python3.10/site-packages/pip/_vendor/chardet/mbcssm.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .enums import MachineState # BIG5 BIG5_CLS = ( 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value 1,1,1,1,1,1,0,0, # 08 - 0f 1,1,1,1,1,1,1,1, # 10 - 17 1,1,1,0,1,1,1,1, # 18 - 1f 1,1,1,1,1,1,1,1, # 20 - 27 1,1,1,1,1,1,1,1, # 28 - 2f 1,1,1,1,1,1,1,1, # 30 - 37 1,1,1,1,1,1,1,1, # 38 - 3f 2,2,2,2,2,2,2,2, # 40 - 47 2,2,2,2,2,2,2,2, # 48 - 4f 2,2,2,2,2,2,2,2, # 50 - 57 2,2,2,2,2,2,2,2, # 58 - 5f 2,2,2,2,2,2,2,2, # 60 - 67 2,2,2,2,2,2,2,2, # 68 - 6f 2,2,2,2,2,2,2,2, # 70 - 77 2,2,2,2,2,2,2,1, # 78 - 7f 4,4,4,4,4,4,4,4, # 80 - 87 4,4,4,4,4,4,4,4, # 88 - 8f 4,4,4,4,4,4,4,4, # 90 - 97 4,4,4,4,4,4,4,4, # 98 - 9f 4,3,3,3,3,3,3,3, # a0 - a7 3,3,3,3,3,3,3,3, # a8 - af 3,3,3,3,3,3,3,3, # b0 - b7 3,3,3,3,3,3,3,3, # b8 - bf 3,3,3,3,3,3,3,3, # c0 - c7 3,3,3,3,3,3,3,3, # c8 - cf 3,3,3,3,3,3,3,3, # d0 - d7 3,3,3,3,3,3,3,3, # d8 - df 3,3,3,3,3,3,3,3, # e0 - e7 3,3,3,3,3,3,3,3, # e8 - ef 3,3,3,3,3,3,3,3, # f0 - f7 3,3,3,3,3,3,3,0 # f8 - ff ) BIG5_ST = ( MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,#08-0f MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START#10-17 ) BIG5_CHAR_LEN_TABLE = (0, 1, 1, 2, 0) BIG5_SM_MODEL = {'class_table': BIG5_CLS, 'class_factor': 5, 'state_table': BIG5_ST, 'char_len_table': BIG5_CHAR_LEN_TABLE, 'name': 'Big5'} # CP949 CP949_CLS = ( 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff ) CP949_ST = ( #cls= 0 1 2 3 4 5 6 7 8 9 # previous state = MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START, 4, 5,MachineState.ERROR, 6, # MachineState.START MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, # MachineState.ERROR MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME, # MachineState.ITS_ME MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 3 MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 4 MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 5 MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 6 ) CP949_CHAR_LEN_TABLE = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2) CP949_SM_MODEL = {'class_table': CP949_CLS, 'class_factor': 10, 'state_table': CP949_ST, 'char_len_table': CP949_CHAR_LEN_TABLE, 'name': 'CP949'} # EUC-JP EUCJP_CLS = ( 4,4,4,4,4,4,4,4, # 00 - 07 4,4,4,4,4,4,5,5, # 08 - 0f 4,4,4,4,4,4,4,4, # 10 - 17 4,4,4,5,4,4,4,4, # 18 - 1f 4,4,4,4,4,4,4,4, # 20 - 27 4,4,4,4,4,4,4,4, # 28 - 2f 4,4,4,4,4,4,4,4, # 30 - 37 4,4,4,4,4,4,4,4, # 38 - 3f 4,4,4,4,4,4,4,4, # 40 - 47 4,4,4,4,4,4,4,4, # 48 - 4f 4,4,4,4,4,4,4,4, # 50 - 57 4,4,4,4,4,4,4,4, # 58 - 5f 4,4,4,4,4,4,4,4, # 60 - 67 4,4,4,4,4,4,4,4, # 68 - 6f 4,4,4,4,4,4,4,4, # 70 - 77 4,4,4,4,4,4,4,4, # 78 - 7f 5,5,5,5,5,5,5,5, # 80 - 87 5,5,5,5,5,5,1,3, # 88 - 8f 5,5,5,5,5,5,5,5, # 90 - 97 5,5,5,5,5,5,5,5, # 98 - 9f 5,2,2,2,2,2,2,2, # a0 - a7 2,2,2,2,2,2,2,2, # a8 - af 2,2,2,2,2,2,2,2, # b0 - b7 2,2,2,2,2,2,2,2, # b8 - bf 2,2,2,2,2,2,2,2, # c0 - c7 2,2,2,2,2,2,2,2, # c8 - cf 2,2,2,2,2,2,2,2, # d0 - d7 2,2,2,2,2,2,2,2, # d8 - df 0,0,0,0,0,0,0,0, # e0 - e7 0,0,0,0,0,0,0,0, # e8 - ef 0,0,0,0,0,0,0,0, # f0 - f7 0,0,0,0,0,0,0,5 # f8 - ff ) EUCJP_ST = ( 3, 4, 3, 5,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f MachineState.ITS_ME,MachineState.ITS_ME,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 3,MachineState.ERROR,#18-1f 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START#20-27 ) EUCJP_CHAR_LEN_TABLE = (2, 2, 2, 3, 1, 0) EUCJP_SM_MODEL = {'class_table': EUCJP_CLS, 'class_factor': 6, 'state_table': EUCJP_ST, 'char_len_table': EUCJP_CHAR_LEN_TABLE, 'name': 'EUC-JP'} # EUC-KR EUCKR_CLS = ( 1,1,1,1,1,1,1,1, # 00 - 07 1,1,1,1,1,1,0,0, # 08 - 0f 1,1,1,1,1,1,1,1, # 10 - 17 1,1,1,0,1,1,1,1, # 18 - 1f 1,1,1,1,1,1,1,1, # 20 - 27 1,1,1,1,1,1,1,1, # 28 - 2f 1,1,1,1,1,1,1,1, # 30 - 37 1,1,1,1,1,1,1,1, # 38 - 3f 1,1,1,1,1,1,1,1, # 40 - 47 1,1,1,1,1,1,1,1, # 48 - 4f 1,1,1,1,1,1,1,1, # 50 - 57 1,1,1,1,1,1,1,1, # 58 - 5f 1,1,1,1,1,1,1,1, # 60 - 67 1,1,1,1,1,1,1,1, # 68 - 6f 1,1,1,1,1,1,1,1, # 70 - 77 1,1,1,1,1,1,1,1, # 78 - 7f 0,0,0,0,0,0,0,0, # 80 - 87 0,0,0,0,0,0,0,0, # 88 - 8f 0,0,0,0,0,0,0,0, # 90 - 97 0,0,0,0,0,0,0,0, # 98 - 9f 0,2,2,2,2,2,2,2, # a0 - a7 2,2,2,2,2,3,3,3, # a8 - af 2,2,2,2,2,2,2,2, # b0 - b7 2,2,2,2,2,2,2,2, # b8 - bf 2,2,2,2,2,2,2,2, # c0 - c7 2,3,2,2,2,2,2,2, # c8 - cf 2,2,2,2,2,2,2,2, # d0 - d7 2,2,2,2,2,2,2,2, # d8 - df 2,2,2,2,2,2,2,2, # e0 - e7 2,2,2,2,2,2,2,2, # e8 - ef 2,2,2,2,2,2,2,2, # f0 - f7 2,2,2,2,2,2,2,0 # f8 - ff ) EUCKR_ST = ( MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #08-0f ) EUCKR_CHAR_LEN_TABLE = (0, 1, 2, 0) EUCKR_SM_MODEL = {'class_table': EUCKR_CLS, 'class_factor': 4, 'state_table': EUCKR_ST, 'char_len_table': EUCKR_CHAR_LEN_TABLE, 'name': 'EUC-KR'} # EUC-TW EUCTW_CLS = ( 2,2,2,2,2,2,2,2, # 00 - 07 2,2,2,2,2,2,0,0, # 08 - 0f 2,2,2,2,2,2,2,2, # 10 - 17 2,2,2,0,2,2,2,2, # 18 - 1f 2,2,2,2,2,2,2,2, # 20 - 27 2,2,2,2,2,2,2,2, # 28 - 2f 2,2,2,2,2,2,2,2, # 30 - 37 2,2,2,2,2,2,2,2, # 38 - 3f 2,2,2,2,2,2,2,2, # 40 - 47 2,2,2,2,2,2,2,2, # 48 - 4f 2,2,2,2,2,2,2,2, # 50 - 57 2,2,2,2,2,2,2,2, # 58 - 5f 2,2,2,2,2,2,2,2, # 60 - 67 2,2,2,2,2,2,2,2, # 68 - 6f 2,2,2,2,2,2,2,2, # 70 - 77 2,2,2,2,2,2,2,2, # 78 - 7f 0,0,0,0,0,0,0,0, # 80 - 87 0,0,0,0,0,0,6,0, # 88 - 8f 0,0,0,0,0,0,0,0, # 90 - 97 0,0,0,0,0,0,0,0, # 98 - 9f 0,3,4,4,4,4,4,4, # a0 - a7 5,5,1,1,1,1,1,1, # a8 - af 1,1,1,1,1,1,1,1, # b0 - b7 1,1,1,1,1,1,1,1, # b8 - bf 1,1,3,1,3,3,3,3, # c0 - c7 3,3,3,3,3,3,3,3, # c8 - cf 3,3,3,3,3,3,3,3, # d0 - d7 3,3,3,3,3,3,3,3, # d8 - df 3,3,3,3,3,3,3,3, # e0 - e7 3,3,3,3,3,3,3,3, # e8 - ef 3,3,3,3,3,3,3,3, # f0 - f7 3,3,3,3,3,3,3,0 # f8 - ff ) EUCTW_ST = ( MachineState.ERROR,MachineState.ERROR,MachineState.START, 3, 3, 3, 4,MachineState.ERROR,#00-07 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.ERROR,#10-17 MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,#20-27 MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f ) EUCTW_CHAR_LEN_TABLE = (0, 0, 1, 2, 2, 2, 3) EUCTW_SM_MODEL = {'class_table': EUCTW_CLS, 'class_factor': 7, 'state_table': EUCTW_ST, 'char_len_table': EUCTW_CHAR_LEN_TABLE, 'name': 'x-euc-tw'} # GB2312 GB2312_CLS = ( 1,1,1,1,1,1,1,1, # 00 - 07 1,1,1,1,1,1,0,0, # 08 - 0f 1,1,1,1,1,1,1,1, # 10 - 17 1,1,1,0,1,1,1,1, # 18 - 1f 1,1,1,1,1,1,1,1, # 20 - 27 1,1,1,1,1,1,1,1, # 28 - 2f 3,3,3,3,3,3,3,3, # 30 - 37 3,3,1,1,1,1,1,1, # 38 - 3f 2,2,2,2,2,2,2,2, # 40 - 47 2,2,2,2,2,2,2,2, # 48 - 4f 2,2,2,2,2,2,2,2, # 50 - 57 2,2,2,2,2,2,2,2, # 58 - 5f 2,2,2,2,2,2,2,2, # 60 - 67 2,2,2,2,2,2,2,2, # 68 - 6f 2,2,2,2,2,2,2,2, # 70 - 77 2,2,2,2,2,2,2,4, # 78 - 7f 5,6,6,6,6,6,6,6, # 80 - 87 6,6,6,6,6,6,6,6, # 88 - 8f 6,6,6,6,6,6,6,6, # 90 - 97 6,6,6,6,6,6,6,6, # 98 - 9f 6,6,6,6,6,6,6,6, # a0 - a7 6,6,6,6,6,6,6,6, # a8 - af 6,6,6,6,6,6,6,6, # b0 - b7 6,6,6,6,6,6,6,6, # b8 - bf 6,6,6,6,6,6,6,6, # c0 - c7 6,6,6,6,6,6,6,6, # c8 - cf 6,6,6,6,6,6,6,6, # d0 - d7 6,6,6,6,6,6,6,6, # d8 - df 6,6,6,6,6,6,6,6, # e0 - e7 6,6,6,6,6,6,6,6, # e8 - ef 6,6,6,6,6,6,6,6, # f0 - f7 6,6,6,6,6,6,6,0 # f8 - ff ) GB2312_ST = ( MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, 3,MachineState.ERROR,#00-07 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,#10-17 4,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#20-27 MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f ) # To be accurate, the length of class 6 can be either 2 or 4. # But it is not necessary to discriminate between the two since # it is used for frequency analysis only, and we are validating # each code range there as well. So it is safe to set it to be # 2 here. GB2312_CHAR_LEN_TABLE = (0, 1, 1, 1, 1, 1, 2) GB2312_SM_MODEL = {'class_table': GB2312_CLS, 'class_factor': 7, 'state_table': GB2312_ST, 'char_len_table': GB2312_CHAR_LEN_TABLE, 'name': 'GB2312'} # Shift_JIS SJIS_CLS = ( 1,1,1,1,1,1,1,1, # 00 - 07 1,1,1,1,1,1,0,0, # 08 - 0f 1,1,1,1,1,1,1,1, # 10 - 17 1,1,1,0,1,1,1,1, # 18 - 1f 1,1,1,1,1,1,1,1, # 20 - 27 1,1,1,1,1,1,1,1, # 28 - 2f 1,1,1,1,1,1,1,1, # 30 - 37 1,1,1,1,1,1,1,1, # 38 - 3f 2,2,2,2,2,2,2,2, # 40 - 47 2,2,2,2,2,2,2,2, # 48 - 4f 2,2,2,2,2,2,2,2, # 50 - 57 2,2,2,2,2,2,2,2, # 58 - 5f 2,2,2,2,2,2,2,2, # 60 - 67 2,2,2,2,2,2,2,2, # 68 - 6f 2,2,2,2,2,2,2,2, # 70 - 77 2,2,2,2,2,2,2,1, # 78 - 7f 3,3,3,3,3,2,2,3, # 80 - 87 3,3,3,3,3,3,3,3, # 88 - 8f 3,3,3,3,3,3,3,3, # 90 - 97 3,3,3,3,3,3,3,3, # 98 - 9f #0xa0 is illegal in sjis encoding, but some pages does #contain such byte. We need to be more error forgiven. 2,2,2,2,2,2,2,2, # a0 - a7 2,2,2,2,2,2,2,2, # a8 - af 2,2,2,2,2,2,2,2, # b0 - b7 2,2,2,2,2,2,2,2, # b8 - bf 2,2,2,2,2,2,2,2, # c0 - c7 2,2,2,2,2,2,2,2, # c8 - cf 2,2,2,2,2,2,2,2, # d0 - d7 2,2,2,2,2,2,2,2, # d8 - df 3,3,3,3,3,3,3,3, # e0 - e7 3,3,3,3,3,4,4,4, # e8 - ef 3,3,3,3,3,3,3,3, # f0 - f7 3,3,3,3,3,0,0,0) # f8 - ff SJIS_ST = ( MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START #10-17 ) SJIS_CHAR_LEN_TABLE = (0, 1, 1, 2, 0, 0) SJIS_SM_MODEL = {'class_table': SJIS_CLS, 'class_factor': 6, 'state_table': SJIS_ST, 'char_len_table': SJIS_CHAR_LEN_TABLE, 'name': 'Shift_JIS'} # UCS2-BE UCS2BE_CLS = ( 0,0,0,0,0,0,0,0, # 00 - 07 0,0,1,0,0,2,0,0, # 08 - 0f 0,0,0,0,0,0,0,0, # 10 - 17 0,0,0,3,0,0,0,0, # 18 - 1f 0,0,0,0,0,0,0,0, # 20 - 27 0,3,3,3,3,3,0,0, # 28 - 2f 0,0,0,0,0,0,0,0, # 30 - 37 0,0,0,0,0,0,0,0, # 38 - 3f 0,0,0,0,0,0,0,0, # 40 - 47 0,0,0,0,0,0,0,0, # 48 - 4f 0,0,0,0,0,0,0,0, # 50 - 57 0,0,0,0,0,0,0,0, # 58 - 5f 0,0,0,0,0,0,0,0, # 60 - 67 0,0,0,0,0,0,0,0, # 68 - 6f 0,0,0,0,0,0,0,0, # 70 - 77 0,0,0,0,0,0,0,0, # 78 - 7f 0,0,0,0,0,0,0,0, # 80 - 87 0,0,0,0,0,0,0,0, # 88 - 8f 0,0,0,0,0,0,0,0, # 90 - 97 0,0,0,0,0,0,0,0, # 98 - 9f 0,0,0,0,0,0,0,0, # a0 - a7 0,0,0,0,0,0,0,0, # a8 - af 0,0,0,0,0,0,0,0, # b0 - b7 0,0,0,0,0,0,0,0, # b8 - bf 0,0,0,0,0,0,0,0, # c0 - c7 0,0,0,0,0,0,0,0, # c8 - cf 0,0,0,0,0,0,0,0, # d0 - d7 0,0,0,0,0,0,0,0, # d8 - df 0,0,0,0,0,0,0,0, # e0 - e7 0,0,0,0,0,0,0,0, # e8 - ef 0,0,0,0,0,0,0,0, # f0 - f7 0,0,0,0,0,0,4,5 # f8 - ff ) UCS2BE_ST = ( 5, 7, 7,MachineState.ERROR, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f MachineState.ITS_ME,MachineState.ITS_ME, 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,#10-17 6, 6, 6, 6, 6,MachineState.ITS_ME, 6, 6,#18-1f 6, 6, 6, 6, 5, 7, 7,MachineState.ERROR,#20-27 5, 8, 6, 6,MachineState.ERROR, 6, 6, 6,#28-2f 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #30-37 ) UCS2BE_CHAR_LEN_TABLE = (2, 2, 2, 0, 2, 2) UCS2BE_SM_MODEL = {'class_table': UCS2BE_CLS, 'class_factor': 6, 'state_table': UCS2BE_ST, 'char_len_table': UCS2BE_CHAR_LEN_TABLE, 'name': 'UTF-16BE'} # UCS2-LE UCS2LE_CLS = ( 0,0,0,0,0,0,0,0, # 00 - 07 0,0,1,0,0,2,0,0, # 08 - 0f 0,0,0,0,0,0,0,0, # 10 - 17 0,0,0,3,0,0,0,0, # 18 - 1f 0,0,0,0,0,0,0,0, # 20 - 27 0,3,3,3,3,3,0,0, # 28 - 2f 0,0,0,0,0,0,0,0, # 30 - 37 0,0,0,0,0,0,0,0, # 38 - 3f 0,0,0,0,0,0,0,0, # 40 - 47 0,0,0,0,0,0,0,0, # 48 - 4f 0,0,0,0,0,0,0,0, # 50 - 57 0,0,0,0,0,0,0,0, # 58 - 5f 0,0,0,0,0,0,0,0, # 60 - 67 0,0,0,0,0,0,0,0, # 68 - 6f 0,0,0,0,0,0,0,0, # 70 - 77 0,0,0,0,0,0,0,0, # 78 - 7f 0,0,0,0,0,0,0,0, # 80 - 87 0,0,0,0,0,0,0,0, # 88 - 8f 0,0,0,0,0,0,0,0, # 90 - 97 0,0,0,0,0,0,0,0, # 98 - 9f 0,0,0,0,0,0,0,0, # a0 - a7 0,0,0,0,0,0,0,0, # a8 - af 0,0,0,0,0,0,0,0, # b0 - b7 0,0,0,0,0,0,0,0, # b8 - bf 0,0,0,0,0,0,0,0, # c0 - c7 0,0,0,0,0,0,0,0, # c8 - cf 0,0,0,0,0,0,0,0, # d0 - d7 0,0,0,0,0,0,0,0, # d8 - df 0,0,0,0,0,0,0,0, # e0 - e7 0,0,0,0,0,0,0,0, # e8 - ef 0,0,0,0,0,0,0,0, # f0 - f7 0,0,0,0,0,0,4,5 # f8 - ff ) UCS2LE_ST = ( 6, 6, 7, 6, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f MachineState.ITS_ME,MachineState.ITS_ME, 5, 5, 5,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#10-17 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR, 6, 6,#18-1f 7, 6, 8, 8, 5, 5, 5,MachineState.ERROR,#20-27 5, 5, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5,#28-2f 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR,MachineState.START,MachineState.START #30-37 ) UCS2LE_CHAR_LEN_TABLE = (2, 2, 2, 2, 2, 2) UCS2LE_SM_MODEL = {'class_table': UCS2LE_CLS, 'class_factor': 6, 'state_table': UCS2LE_ST, 'char_len_table': UCS2LE_CHAR_LEN_TABLE, 'name': 'UTF-16LE'} # UTF-8 UTF8_CLS = ( 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value 1,1,1,1,1,1,0,0, # 08 - 0f 1,1,1,1,1,1,1,1, # 10 - 17 1,1,1,0,1,1,1,1, # 18 - 1f 1,1,1,1,1,1,1,1, # 20 - 27 1,1,1,1,1,1,1,1, # 28 - 2f 1,1,1,1,1,1,1,1, # 30 - 37 1,1,1,1,1,1,1,1, # 38 - 3f 1,1,1,1,1,1,1,1, # 40 - 47 1,1,1,1,1,1,1,1, # 48 - 4f 1,1,1,1,1,1,1,1, # 50 - 57 1,1,1,1,1,1,1,1, # 58 - 5f 1,1,1,1,1,1,1,1, # 60 - 67 1,1,1,1,1,1,1,1, # 68 - 6f 1,1,1,1,1,1,1,1, # 70 - 77 1,1,1,1,1,1,1,1, # 78 - 7f 2,2,2,2,3,3,3,3, # 80 - 87 4,4,4,4,4,4,4,4, # 88 - 8f 4,4,4,4,4,4,4,4, # 90 - 97 4,4,4,4,4,4,4,4, # 98 - 9f 5,5,5,5,5,5,5,5, # a0 - a7 5,5,5,5,5,5,5,5, # a8 - af 5,5,5,5,5,5,5,5, # b0 - b7 5,5,5,5,5,5,5,5, # b8 - bf 0,0,6,6,6,6,6,6, # c0 - c7 6,6,6,6,6,6,6,6, # c8 - cf 6,6,6,6,6,6,6,6, # d0 - d7 6,6,6,6,6,6,6,6, # d8 - df 7,8,8,8,8,8,8,8, # e0 - e7 8,8,8,8,8,9,8,8, # e8 - ef 10,11,11,11,11,11,11,11, # f0 - f7 12,13,13,13,14,15,0,0 # f8 - ff ) UTF8_ST = ( MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12, 10,#00-07 9, 11, 8, 7, 6, 5, 4, 3,#08-0f MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#20-27 MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#28-2f MachineState.ERROR,MachineState.ERROR, 5, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#30-37 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#38-3f MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#40-47 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#48-4f MachineState.ERROR,MachineState.ERROR, 7, 7, 7, 7,MachineState.ERROR,MachineState.ERROR,#50-57 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#58-5f MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 7, 7,MachineState.ERROR,MachineState.ERROR,#60-67 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#68-6f MachineState.ERROR,MachineState.ERROR, 9, 9, 9, 9,MachineState.ERROR,MachineState.ERROR,#70-77 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#78-7f MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 9,MachineState.ERROR,MachineState.ERROR,#80-87 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#88-8f MachineState.ERROR,MachineState.ERROR, 12, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,#90-97 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#98-9f MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12,MachineState.ERROR,MachineState.ERROR,#a0-a7 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#a8-af MachineState.ERROR,MachineState.ERROR, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b0-b7 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b8-bf MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,#c0-c7 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR #c8-cf ) UTF8_CHAR_LEN_TABLE = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6) UTF8_SM_MODEL = {'class_table': UTF8_CLS, 'class_factor': 16, 'state_table': UTF8_ST, 'char_len_table': UTF8_CHAR_LEN_TABLE, 'name': 'UTF-8'} PKH]y%jLL6python3.10/site-packages/pip/_vendor/chardet/jpcntx.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Communicator client code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### # This is hiragana 2-char sequence table, the number in each cell represents its frequency category jp2CharContext = ( (0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), (2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), (0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), (0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), (1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), (0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), (0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), (0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), (0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), (0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), (2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), (0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), (0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), (0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), (2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), (0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), (1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), (0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), (0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), (0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), (0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), (0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), (0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), (0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), (0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), (0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), (0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), (0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), (0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), (1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), (0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), (0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), (0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), (0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), (0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), (2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), (0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), (0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), (0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), (0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), (0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), (0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), (0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), (0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), (0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), (0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), (0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), (0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), (0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), (0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), (0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), (0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), (0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), (0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), (0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), (2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), (0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), (0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), (0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), (0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), (1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), (0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), (0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), (0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), (0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), (0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), (0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), (0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), (0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), (1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), (0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), (0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), (0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), (0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), (0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1), ) class JapaneseContextAnalysis(object): NUM_OF_CATEGORY = 6 DONT_KNOW = -1 ENOUGH_REL_THRESHOLD = 100 MAX_REL_THRESHOLD = 1000 MINIMUM_DATA_THRESHOLD = 4 def __init__(self): self._total_rel = None self._rel_sample = None self._need_to_skip_char_num = None self._last_char_order = None self._done = None self.reset() def reset(self): self._total_rel = 0 # total sequence received # category counters, each integer counts sequence in its category self._rel_sample = [0] * self.NUM_OF_CATEGORY # if last byte in current buffer is not the last byte of a character, # we need to know how many bytes to skip in next buffer self._need_to_skip_char_num = 0 self._last_char_order = -1 # The order of previous char # If this flag is set to True, detection is done and conclusion has # been made self._done = False def feed(self, byte_str, num_bytes): if self._done: return # The buffer we got is byte oriented, and a character may span in more than one # buffers. In case the last one or two byte in last buffer is not # complete, we record how many byte needed to complete that character # and skip these bytes here. We can choose to record those bytes as # well and analyse the character once it is complete, but since a # character will not make much difference, by simply skipping # this character will simply our logic and improve performance. i = self._need_to_skip_char_num while i < num_bytes: order, char_len = self.get_order(byte_str[i:i + 2]) i += char_len if i > num_bytes: self._need_to_skip_char_num = i - num_bytes self._last_char_order = -1 else: if (order != -1) and (self._last_char_order != -1): self._total_rel += 1 if self._total_rel > self.MAX_REL_THRESHOLD: self._done = True break self._rel_sample[jp2CharContext[self._last_char_order][order]] += 1 self._last_char_order = order def got_enough_data(self): return self._total_rel > self.ENOUGH_REL_THRESHOLD def get_confidence(self): # This is just one way to calculate confidence. It works well for me. if self._total_rel > self.MINIMUM_DATA_THRESHOLD: return (self._total_rel - self._rel_sample[0]) / self._total_rel else: return self.DONT_KNOW def get_order(self, byte_str): return -1, 1 class SJISContextAnalysis(JapaneseContextAnalysis): def __init__(self): super(SJISContextAnalysis, self).__init__() self._charset_name = "SHIFT_JIS" @property def charset_name(self): return self._charset_name def get_order(self, byte_str): if not byte_str: return -1, 1 # find out current char's byte length first_char = byte_str[0] if (0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC): char_len = 2 if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): self._charset_name = "CP932" else: char_len = 1 # return its order if it is hiragana if len(byte_str) > 1: second_char = byte_str[1] if (first_char == 202) and (0x9F <= second_char <= 0xF1): return second_char - 0x9F, char_len return -1, char_len class EUCJPContextAnalysis(JapaneseContextAnalysis): def get_order(self, byte_str): if not byte_str: return -1, 1 # find out current char's byte length first_char = byte_str[0] if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE): char_len = 2 elif first_char == 0x8F: char_len = 3 else: char_len = 1 # return its order if it is hiragana if len(byte_str) > 1: second_char = byte_str[1] if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3): return second_char - 0xA1, char_len return -1, char_len PKH]IՅ{{9python3.10/site-packages/pip/_vendor/chardet/euctwfreq.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Communicator client code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### # EUCTW frequency table # Converted from big5 work # by Taiwan's Mandarin Promotion Council # # 128 --> 0.42261 # 256 --> 0.57851 # 512 --> 0.74851 # 1024 --> 0.89384 # 2048 --> 0.97583 # # Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 # Random Distribution Ration = 512/(5401-512)=0.105 # # Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75 # Char to FreqOrder table , EUCTW_TABLE_SIZE = 5376 EUCTW_CHAR_TO_FREQ_ORDER = ( 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742 3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758 1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790 3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806 4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822 7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886 2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902 1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918 3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950 1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966 3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982 2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014 3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030 1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046 7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078 7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094 1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142 3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158 3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190 2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206 2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254 3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270 1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286 1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302 1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318 2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350 4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366 1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382 7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398 2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478 7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510 1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558 7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574 1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606 3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622 4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638 3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686 1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702 4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718 3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734 3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750 2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766 7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782 3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798 7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814 1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830 2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846 1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878 1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894 4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910 3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974 2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990 7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006 1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022 2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038 1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054 1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070 7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086 7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102 7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118 3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134 4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150 1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166 7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182 2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198 7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214 3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230 3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246 7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262 2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278 7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310 4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326 2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342 7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358 3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374 2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390 2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422 2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438 1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454 1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470 2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486 1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502 7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518 7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534 2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550 4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566 1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582 7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614 4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646 2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678 1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694 1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726 3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742 3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758 1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774 3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790 7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806 7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822 1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838 2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854 1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870 3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886 2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902 3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918 2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934 4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950 4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966 3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998 3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030 3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046 3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062 3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078 1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094 7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126 7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142 1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174 4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190 3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222 2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238 2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254 3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270 1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286 4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302 2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318 1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334 1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350 2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366 3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382 1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398 7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414 1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430 4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446 1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478 1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494 3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510 3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526 2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542 1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558 4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590 7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606 2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622 3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638 4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670 7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686 7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702 1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718 4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734 3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750 2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766 3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782 3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798 2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814 1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830 4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846 3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862 3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878 2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894 4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910 7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926 3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942 2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958 3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974 1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990 2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006 3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022 4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038 2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054 2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070 7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086 1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102 2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118 1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134 3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150 4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166 2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182 3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198 3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214 2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230 4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246 2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262 3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278 4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294 7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310 3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342 1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358 4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374 1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390 4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406 7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438 7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454 2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470 1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486 1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502 3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566 3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582 2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614 7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630 1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646 3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662 7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678 1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694 7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710 4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726 1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742 2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758 2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774 4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822 3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838 3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854 1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870 2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886 7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902 1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918 1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934 3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966 1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982 4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998 7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014 2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030 3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062 1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078 2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094 2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110 7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126 7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142 7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158 2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174 2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190 1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206 4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222 3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238 3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254 4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270 4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286 2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302 2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318 7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334 4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350 7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366 2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382 1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398 3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414 4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430 2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462 2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478 1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494 2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510 2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526 4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542 7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558 1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574 3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590 7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606 1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622 8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638 2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654 8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670 2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686 2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702 8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718 8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734 8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766 8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782 4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798 3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814 8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830 1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846 8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878 1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910 4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926 1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942 4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958 1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990 3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006 4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022 8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054 3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086 2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102 ) PKH]?]݄݄>python3.10/site-packages/pip/_vendor/chardet/langgreekmodel.pynu[# -*- coding: utf-8 -*- from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel # 3: Positive # 2: Likely # 1: Unlikely # 0: Negative GREEK_LANG_MODEL = { 60: { # 'e' 60: 2, # 'e' 55: 1, # 'o' 58: 2, # 't' 36: 1, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 1, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 55: { # 'o' 60: 0, # 'e' 55: 2, # 'o' 58: 2, # 't' 36: 1, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 1, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 1, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 58: { # 't' 60: 2, # 'e' 55: 1, # 'o' 58: 1, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 2, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 1, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 36: { # '·' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 61: { # 'Ά' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 1, # 'γ' 21: 2, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 1, # 'π' 8: 2, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 46: { # 'Έ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 2, # 'β' 20: 2, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 2, # 'κ' 16: 2, # 'λ' 10: 0, # 'μ' 6: 3, # 'ν' 30: 2, # 'ξ' 4: 0, # 'ο' 9: 2, # 'π' 8: 2, # 'ρ' 14: 0, # 'ς' 7: 1, # 'σ' 2: 2, # 'τ' 12: 0, # 'υ' 28: 2, # 'φ' 23: 3, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 54: { # 'Ό' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 2, # 'μ' 6: 2, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 2, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 2, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 2, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 31: { # 'Α' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 2, # 'Β' 43: 2, # 'Γ' 41: 1, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 2, # 'Θ' 47: 2, # 'Ι' 44: 2, # 'Κ' 53: 2, # 'Λ' 38: 2, # 'Μ' 49: 2, # 'Ν' 59: 1, # 'Ξ' 39: 0, # 'Ο' 35: 2, # 'Π' 48: 2, # 'Ρ' 37: 2, # 'Σ' 33: 2, # 'Τ' 45: 2, # 'Υ' 56: 2, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 2, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 1, # 'θ' 5: 0, # 'ι' 11: 2, # 'κ' 16: 3, # 'λ' 10: 2, # 'μ' 6: 3, # 'ν' 30: 2, # 'ξ' 4: 0, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 2, # 'ς' 7: 2, # 'σ' 2: 0, # 'τ' 12: 3, # 'υ' 28: 2, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 2, # 'ύ' 27: 0, # 'ώ' }, 51: { # 'Β' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 1, # 'Ε' 40: 1, # 'Η' 52: 0, # 'Θ' 47: 1, # 'Ι' 44: 0, # 'Κ' 53: 1, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 2, # 'ά' 18: 2, # 'έ' 22: 2, # 'ή' 15: 0, # 'ί' 1: 2, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 2, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 2, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 2, # 'ο' 9: 0, # 'π' 8: 2, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 43: { # 'Γ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 1, # 'Α' 51: 0, # 'Β' 43: 2, # 'Γ' 41: 0, # 'Δ' 34: 2, # 'Ε' 40: 1, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 1, # 'Κ' 53: 1, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 1, # 'Ο' 35: 0, # 'Π' 48: 2, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 2, # 'Υ' 56: 0, # 'Φ' 50: 1, # 'Χ' 57: 2, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 2, # 'ί' 1: 2, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 2, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 3, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 0, # 'μ' 6: 2, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 0, # 'π' 8: 2, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 41: { # 'Δ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 2, # 'Ε' 40: 2, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 2, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 2, # 'ή' 15: 2, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 2, # 'η' 25: 0, # 'θ' 5: 3, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 2, # 'ο' 9: 0, # 'π' 8: 2, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 2, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 2, # 'ω' 19: 1, # 'ό' 26: 2, # 'ύ' 27: 2, # 'ώ' }, 34: { # 'Ε' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 0, # 'Β' 43: 2, # 'Γ' 41: 2, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 2, # 'Κ' 53: 2, # 'Λ' 38: 2, # 'Μ' 49: 2, # 'Ν' 59: 1, # 'Ξ' 39: 0, # 'Ο' 35: 2, # 'Π' 48: 2, # 'Ρ' 37: 2, # 'Σ' 33: 2, # 'Τ' 45: 2, # 'Υ' 56: 0, # 'Φ' 50: 2, # 'Χ' 57: 2, # 'Ω' 17: 3, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 3, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 3, # 'γ' 21: 2, # 'δ' 3: 1, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 1, # 'θ' 5: 2, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 2, # 'μ' 6: 3, # 'ν' 30: 2, # 'ξ' 4: 0, # 'ο' 9: 3, # 'π' 8: 2, # 'ρ' 14: 0, # 'ς' 7: 2, # 'σ' 2: 2, # 'τ' 12: 2, # 'υ' 28: 2, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 1, # 'ύ' 27: 0, # 'ώ' }, 40: { # 'Η' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 1, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 2, # 'Θ' 47: 0, # 'Ι' 44: 2, # 'Κ' 53: 0, # 'Λ' 38: 2, # 'Μ' 49: 2, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 2, # 'Π' 48: 2, # 'Ρ' 37: 2, # 'Σ' 33: 2, # 'Τ' 45: 1, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 0, # 'μ' 6: 1, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 1, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 52: { # 'Θ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 2, # 'Ε' 40: 2, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 1, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 1, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 2, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 2, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 2, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 2, # 'ύ' 27: 0, # 'ώ' }, 47: { # 'Ι' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 1, # 'Β' 43: 1, # 'Γ' 41: 2, # 'Δ' 34: 2, # 'Ε' 40: 2, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 2, # 'Κ' 53: 2, # 'Λ' 38: 2, # 'Μ' 49: 2, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 2, # 'Ρ' 37: 2, # 'Σ' 33: 2, # 'Τ' 45: 0, # 'Υ' 56: 2, # 'Φ' 50: 0, # 'Χ' 57: 2, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 2, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 2, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 1, # 'ν' 30: 0, # 'ξ' 4: 2, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 2, # 'σ' 2: 1, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 1, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 44: { # 'Κ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 1, # 'Δ' 34: 2, # 'Ε' 40: 2, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 1, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 2, # 'Ρ' 37: 0, # 'Σ' 33: 1, # 'Τ' 45: 2, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 1, # 'Ω' 17: 3, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 2, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 2, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 2, # 'ο' 9: 0, # 'π' 8: 2, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 2, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 2, # 'ό' 26: 2, # 'ύ' 27: 2, # 'ώ' }, 53: { # 'Λ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 2, # 'Ε' 40: 2, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 0, # 'Κ' 53: 2, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 2, # 'Σ' 33: 0, # 'Τ' 45: 2, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 2, # 'Ω' 17: 2, # 'ά' 18: 2, # 'έ' 22: 0, # 'ή' 15: 2, # 'ί' 1: 2, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 2, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 1, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 2, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 2, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 2, # 'ό' 26: 2, # 'ύ' 27: 0, # 'ώ' }, 38: { # 'Μ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 2, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 2, # 'Ε' 40: 2, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 2, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 2, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 2, # 'ά' 18: 2, # 'έ' 22: 2, # 'ή' 15: 2, # 'ί' 1: 2, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 2, # 'η' 25: 0, # 'θ' 5: 3, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 2, # 'ο' 9: 3, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 2, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 2, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 49: { # 'Ν' 60: 2, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 2, # 'Ε' 40: 2, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 2, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 2, # 'Ω' 17: 0, # 'ά' 18: 2, # 'έ' 22: 0, # 'ή' 15: 2, # 'ί' 1: 2, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 1, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 2, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 1, # 'ω' 19: 2, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 59: { # 'Ξ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 1, # 'Ε' 40: 1, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 1, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 2, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 2, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 2, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 39: { # 'Ο' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 1, # 'Β' 43: 2, # 'Γ' 41: 2, # 'Δ' 34: 2, # 'Ε' 40: 1, # 'Η' 52: 2, # 'Θ' 47: 2, # 'Ι' 44: 2, # 'Κ' 53: 2, # 'Λ' 38: 2, # 'Μ' 49: 2, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 2, # 'Π' 48: 2, # 'Ρ' 37: 2, # 'Σ' 33: 2, # 'Τ' 45: 2, # 'Υ' 56: 2, # 'Φ' 50: 2, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 2, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 3, # 'ι' 11: 2, # 'κ' 16: 2, # 'λ' 10: 2, # 'μ' 6: 2, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 2, # 'π' 8: 2, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 2, # 'τ' 12: 2, # 'υ' 28: 1, # 'φ' 23: 1, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 2, # 'ύ' 27: 0, # 'ώ' }, 35: { # 'Π' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 2, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 0, # 'Κ' 53: 2, # 'Λ' 38: 1, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 2, # 'Ρ' 37: 0, # 'Σ' 33: 1, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 1, # 'Χ' 57: 2, # 'Ω' 17: 2, # 'ά' 18: 1, # 'έ' 22: 1, # 'ή' 15: 2, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 2, # 'η' 25: 0, # 'θ' 5: 2, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 0, # 'μ' 6: 2, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 3, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 2, # 'υ' 28: 0, # 'φ' 23: 2, # 'χ' 42: 0, # 'ψ' 24: 2, # 'ω' 19: 2, # 'ό' 26: 0, # 'ύ' 27: 3, # 'ώ' }, 48: { # 'Ρ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 0, # 'Β' 43: 1, # 'Γ' 41: 1, # 'Δ' 34: 2, # 'Ε' 40: 2, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 2, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 2, # 'Ρ' 37: 0, # 'Σ' 33: 1, # 'Τ' 45: 1, # 'Υ' 56: 0, # 'Φ' 50: 1, # 'Χ' 57: 1, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 2, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 1, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 3, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 2, # 'ω' 19: 0, # 'ό' 26: 2, # 'ύ' 27: 0, # 'ώ' }, 37: { # 'Σ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 1, # 'Δ' 34: 2, # 'Ε' 40: 2, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 2, # 'Κ' 53: 0, # 'Λ' 38: 2, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 2, # 'Σ' 33: 2, # 'Τ' 45: 2, # 'Υ' 56: 0, # 'Φ' 50: 2, # 'Χ' 57: 2, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 2, # 'ή' 15: 2, # 'ί' 1: 2, # 'α' 29: 2, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 0, # 'θ' 5: 2, # 'ι' 11: 2, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 2, # 'ο' 9: 2, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 0, # 'φ' 23: 2, # 'χ' 42: 0, # 'ψ' 24: 2, # 'ω' 19: 0, # 'ό' 26: 2, # 'ύ' 27: 2, # 'ώ' }, 33: { # 'Τ' 60: 0, # 'e' 55: 1, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 2, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 2, # 'Ε' 40: 2, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 2, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 2, # 'Ρ' 37: 0, # 'Σ' 33: 1, # 'Τ' 45: 1, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 2, # 'Ω' 17: 2, # 'ά' 18: 2, # 'έ' 22: 0, # 'ή' 15: 2, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 2, # 'ε' 32: 0, # 'ζ' 13: 2, # 'η' 25: 0, # 'θ' 5: 2, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 2, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 2, # 'ρ' 14: 0, # 'ς' 7: 2, # 'σ' 2: 0, # 'τ' 12: 2, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 2, # 'ό' 26: 2, # 'ύ' 27: 3, # 'ώ' }, 45: { # 'Υ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 2, # 'Γ' 41: 0, # 'Δ' 34: 1, # 'Ε' 40: 2, # 'Η' 52: 2, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 1, # 'Λ' 38: 2, # 'Μ' 49: 2, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 2, # 'Π' 48: 1, # 'Ρ' 37: 2, # 'Σ' 33: 2, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 1, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 3, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 56: { # 'Φ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 1, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 1, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 2, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 2, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 2, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 2, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 2, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 2, # 'τ' 12: 2, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 1, # 'ύ' 27: 1, # 'ώ' }, 50: { # 'Χ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 1, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 2, # 'Ε' 40: 2, # 'Η' 52: 0, # 'Θ' 47: 2, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 1, # 'Ν' 59: 0, # 'Ξ' 39: 1, # 'Ο' 35: 0, # 'Π' 48: 2, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 1, # 'Χ' 57: 1, # 'Ω' 17: 2, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 2, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 2, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 2, # 'ο' 9: 0, # 'π' 8: 3, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 2, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 2, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 57: { # 'Ω' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 1, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 1, # 'Λ' 38: 0, # 'Μ' 49: 2, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 2, # 'Ρ' 37: 2, # 'Σ' 33: 2, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 0, # 'π' 8: 2, # 'ρ' 14: 2, # 'ς' 7: 2, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 1, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 17: { # 'ά' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 2, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 3, # 'β' 20: 3, # 'γ' 21: 3, # 'δ' 3: 3, # 'ε' 32: 3, # 'ζ' 13: 0, # 'η' 25: 3, # 'θ' 5: 2, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 3, # 'ξ' 4: 0, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 3, # 'φ' 23: 3, # 'χ' 42: 3, # 'ψ' 24: 2, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 18: { # 'έ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 3, # 'α' 29: 2, # 'β' 20: 3, # 'γ' 21: 2, # 'δ' 3: 3, # 'ε' 32: 2, # 'ζ' 13: 0, # 'η' 25: 3, # 'θ' 5: 0, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 3, # 'ξ' 4: 3, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 3, # 'φ' 23: 3, # 'χ' 42: 3, # 'ψ' 24: 2, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 22: { # 'ή' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 1, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 3, # 'γ' 21: 3, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 3, # 'θ' 5: 0, # 'ι' 11: 3, # 'κ' 16: 2, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 2, # 'ξ' 4: 0, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 2, # 'φ' 23: 3, # 'χ' 42: 2, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 15: { # 'ί' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 3, # 'α' 29: 2, # 'β' 20: 3, # 'γ' 21: 3, # 'δ' 3: 3, # 'ε' 32: 3, # 'ζ' 13: 3, # 'η' 25: 3, # 'θ' 5: 0, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 3, # 'ξ' 4: 3, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 1, # 'φ' 23: 3, # 'χ' 42: 2, # 'ψ' 24: 3, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 1: { # 'α' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 2, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 2, # 'έ' 22: 0, # 'ή' 15: 3, # 'ί' 1: 0, # 'α' 29: 3, # 'β' 20: 3, # 'γ' 21: 3, # 'δ' 3: 2, # 'ε' 32: 3, # 'ζ' 13: 1, # 'η' 25: 3, # 'θ' 5: 3, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 3, # 'ξ' 4: 2, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 3, # 'φ' 23: 3, # 'χ' 42: 2, # 'ψ' 24: 0, # 'ω' 19: 2, # 'ό' 26: 2, # 'ύ' 27: 0, # 'ώ' }, 29: { # 'β' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 2, # 'έ' 22: 3, # 'ή' 15: 2, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 2, # 'γ' 21: 2, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 2, # 'η' 25: 0, # 'θ' 5: 3, # 'ι' 11: 0, # 'κ' 16: 3, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 3, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 2, # 'ω' 19: 2, # 'ό' 26: 2, # 'ύ' 27: 2, # 'ώ' }, 20: { # 'γ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 3, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 0, # 'θ' 5: 3, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 3, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 3, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 2, # 'υ' 28: 0, # 'φ' 23: 3, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 2, # 'ύ' 27: 3, # 'ώ' }, 21: { # 'δ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 2, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 0, # 'θ' 5: 3, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 3, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 3, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 3, # 'ύ' 27: 3, # 'ώ' }, 3: { # 'ε' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 2, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 3, # 'ί' 1: 2, # 'α' 29: 3, # 'β' 20: 3, # 'γ' 21: 3, # 'δ' 3: 2, # 'ε' 32: 2, # 'ζ' 13: 0, # 'η' 25: 3, # 'θ' 5: 3, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 3, # 'ξ' 4: 2, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 3, # 'φ' 23: 3, # 'χ' 42: 2, # 'ψ' 24: 3, # 'ω' 19: 2, # 'ό' 26: 3, # 'ύ' 27: 2, # 'ώ' }, 32: { # 'ζ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 2, # 'ά' 18: 2, # 'έ' 22: 2, # 'ή' 15: 2, # 'ί' 1: 2, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 0, # 'θ' 5: 2, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 1, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 2, # 'ό' 26: 0, # 'ύ' 27: 2, # 'ώ' }, 13: { # 'η' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 2, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 3, # 'γ' 21: 2, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 3, # 'θ' 5: 0, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 2, # 'ξ' 4: 0, # 'ο' 9: 2, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 2, # 'φ' 23: 3, # 'χ' 42: 2, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 25: { # 'θ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 2, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 2, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 0, # 'θ' 5: 3, # 'ι' 11: 0, # 'κ' 16: 1, # 'λ' 10: 3, # 'μ' 6: 2, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 3, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 3, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 3, # 'ύ' 27: 3, # 'ώ' }, 5: { # 'ι' 60: 0, # 'e' 55: 1, # 'o' 58: 0, # 't' 36: 2, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 1, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 0, # 'ί' 1: 3, # 'α' 29: 3, # 'β' 20: 3, # 'γ' 21: 3, # 'δ' 3: 3, # 'ε' 32: 2, # 'ζ' 13: 3, # 'η' 25: 3, # 'θ' 5: 0, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 3, # 'ξ' 4: 3, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 2, # 'φ' 23: 3, # 'χ' 42: 2, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 0, # 'ύ' 27: 3, # 'ώ' }, 11: { # 'κ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 3, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 2, # 'θ' 5: 3, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 2, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 2, # 'π' 8: 3, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 2, # 'φ' 23: 2, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 3, # 'ύ' 27: 3, # 'ώ' }, 16: { # 'λ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 1, # 'β' 20: 2, # 'γ' 21: 1, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 2, # 'θ' 5: 3, # 'ι' 11: 2, # 'κ' 16: 3, # 'λ' 10: 2, # 'μ' 6: 2, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 3, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 2, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 3, # 'ύ' 27: 3, # 'ώ' }, 10: { # 'μ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 1, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 3, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 0, # 'θ' 5: 3, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 3, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 2, # 'υ' 28: 3, # 'φ' 23: 0, # 'χ' 42: 2, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 2, # 'ύ' 27: 2, # 'ώ' }, 6: { # 'ν' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 2, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 3, # 'δ' 3: 3, # 'ε' 32: 2, # 'ζ' 13: 3, # 'η' 25: 3, # 'θ' 5: 3, # 'ι' 11: 0, # 'κ' 16: 1, # 'λ' 10: 0, # 'μ' 6: 2, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 3, # 'ύ' 27: 3, # 'ώ' }, 30: { # 'ξ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 2, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 2, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 0, # 'θ' 5: 2, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 3, # 'τ' 12: 2, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 2, # 'ό' 26: 3, # 'ύ' 27: 1, # 'ώ' }, 4: { # 'ο' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 2, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 2, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 2, # 'α' 29: 3, # 'β' 20: 3, # 'γ' 21: 3, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 3, # 'θ' 5: 3, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 2, # 'ξ' 4: 2, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 3, # 'φ' 23: 3, # 'χ' 42: 2, # 'ψ' 24: 2, # 'ω' 19: 1, # 'ό' 26: 3, # 'ύ' 27: 2, # 'ώ' }, 9: { # 'π' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 0, # 'θ' 5: 3, # 'ι' 11: 0, # 'κ' 16: 3, # 'λ' 10: 0, # 'μ' 6: 2, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 3, # 'ρ' 14: 2, # 'ς' 7: 0, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 0, # 'φ' 23: 2, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 2, # 'ύ' 27: 3, # 'ώ' }, 8: { # 'ρ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 2, # 'β' 20: 3, # 'γ' 21: 2, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 3, # 'θ' 5: 3, # 'ι' 11: 3, # 'κ' 16: 1, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 2, # 'ξ' 4: 3, # 'ο' 9: 2, # 'π' 8: 2, # 'ρ' 14: 0, # 'ς' 7: 2, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 3, # 'φ' 23: 3, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 3, # 'ύ' 27: 3, # 'ώ' }, 14: { # 'ς' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 2, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 0, # 'θ' 5: 0, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 0, # 'τ' 12: 0, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 7: { # 'σ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 2, # 'ά' 18: 2, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 3, # 'β' 20: 0, # 'γ' 21: 2, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 3, # 'θ' 5: 3, # 'ι' 11: 3, # 'κ' 16: 2, # 'λ' 10: 3, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 3, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 3, # 'φ' 23: 3, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 3, # 'ύ' 27: 2, # 'ώ' }, 2: { # 'τ' 60: 0, # 'e' 55: 2, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 2, # 'ζ' 13: 3, # 'η' 25: 0, # 'θ' 5: 3, # 'ι' 11: 2, # 'κ' 16: 2, # 'λ' 10: 3, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 3, # 'ρ' 14: 0, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 2, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 3, # 'ύ' 27: 3, # 'ώ' }, 12: { # 'υ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 2, # 'ά' 18: 2, # 'έ' 22: 3, # 'ή' 15: 2, # 'ί' 1: 3, # 'α' 29: 2, # 'β' 20: 3, # 'γ' 21: 2, # 'δ' 3: 2, # 'ε' 32: 2, # 'ζ' 13: 2, # 'η' 25: 3, # 'θ' 5: 2, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 3, # 'ξ' 4: 3, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 2, # 'φ' 23: 3, # 'χ' 42: 2, # 'ψ' 24: 2, # 'ω' 19: 2, # 'ό' 26: 0, # 'ύ' 27: 2, # 'ώ' }, 28: { # 'φ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 3, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 2, # 'η' 25: 2, # 'θ' 5: 3, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 0, # 'μ' 6: 1, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 3, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 1, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 2, # 'ύ' 27: 2, # 'ώ' }, 23: { # 'χ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 3, # 'ά' 18: 2, # 'έ' 22: 3, # 'ή' 15: 3, # 'ί' 1: 3, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 2, # 'η' 25: 2, # 'θ' 5: 3, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 2, # 'μ' 6: 3, # 'ν' 30: 0, # 'ξ' 4: 3, # 'ο' 9: 0, # 'π' 8: 3, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 3, # 'τ' 12: 3, # 'υ' 28: 0, # 'φ' 23: 2, # 'χ' 42: 0, # 'ψ' 24: 3, # 'ω' 19: 3, # 'ό' 26: 3, # 'ύ' 27: 3, # 'ώ' }, 42: { # 'ψ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 2, # 'ά' 18: 2, # 'έ' 22: 1, # 'ή' 15: 2, # 'ί' 1: 2, # 'α' 29: 0, # 'β' 20: 0, # 'γ' 21: 0, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 3, # 'η' 25: 0, # 'θ' 5: 2, # 'ι' 11: 0, # 'κ' 16: 0, # 'λ' 10: 0, # 'μ' 6: 0, # 'ν' 30: 0, # 'ξ' 4: 2, # 'ο' 9: 0, # 'π' 8: 0, # 'ρ' 14: 0, # 'ς' 7: 0, # 'σ' 2: 2, # 'τ' 12: 1, # 'υ' 28: 0, # 'φ' 23: 0, # 'χ' 42: 0, # 'ψ' 24: 2, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 24: { # 'ω' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 1, # 'ά' 18: 0, # 'έ' 22: 2, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 2, # 'β' 20: 3, # 'γ' 21: 2, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 0, # 'η' 25: 3, # 'θ' 5: 2, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 0, # 'ξ' 4: 0, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 2, # 'φ' 23: 2, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 19: { # 'ό' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 3, # 'β' 20: 3, # 'γ' 21: 3, # 'δ' 3: 1, # 'ε' 32: 2, # 'ζ' 13: 2, # 'η' 25: 2, # 'θ' 5: 2, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 1, # 'ξ' 4: 2, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 2, # 'φ' 23: 3, # 'χ' 42: 2, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 26: { # 'ύ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 2, # 'α' 29: 2, # 'β' 20: 2, # 'γ' 21: 1, # 'δ' 3: 3, # 'ε' 32: 0, # 'ζ' 13: 2, # 'η' 25: 3, # 'θ' 5: 0, # 'ι' 11: 3, # 'κ' 16: 3, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 2, # 'ξ' 4: 3, # 'ο' 9: 3, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 2, # 'φ' 23: 2, # 'χ' 42: 2, # 'ψ' 24: 2, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, 27: { # 'ώ' 60: 0, # 'e' 55: 0, # 'o' 58: 0, # 't' 36: 0, # '·' 61: 0, # 'Ά' 46: 0, # 'Έ' 54: 0, # 'Ό' 31: 0, # 'Α' 51: 0, # 'Β' 43: 0, # 'Γ' 41: 0, # 'Δ' 34: 0, # 'Ε' 40: 0, # 'Η' 52: 0, # 'Θ' 47: 0, # 'Ι' 44: 0, # 'Κ' 53: 0, # 'Λ' 38: 0, # 'Μ' 49: 0, # 'Ν' 59: 0, # 'Ξ' 39: 0, # 'Ο' 35: 0, # 'Π' 48: 0, # 'Ρ' 37: 0, # 'Σ' 33: 0, # 'Τ' 45: 0, # 'Υ' 56: 0, # 'Φ' 50: 0, # 'Χ' 57: 0, # 'Ω' 17: 0, # 'ά' 18: 0, # 'έ' 22: 0, # 'ή' 15: 0, # 'ί' 1: 0, # 'α' 29: 1, # 'β' 20: 0, # 'γ' 21: 3, # 'δ' 3: 0, # 'ε' 32: 0, # 'ζ' 13: 1, # 'η' 25: 2, # 'θ' 5: 2, # 'ι' 11: 0, # 'κ' 16: 2, # 'λ' 10: 3, # 'μ' 6: 3, # 'ν' 30: 1, # 'ξ' 4: 0, # 'ο' 9: 2, # 'π' 8: 3, # 'ρ' 14: 3, # 'ς' 7: 3, # 'σ' 2: 3, # 'τ' 12: 0, # 'υ' 28: 1, # 'φ' 23: 1, # 'χ' 42: 0, # 'ψ' 24: 0, # 'ω' 19: 0, # 'ό' 26: 0, # 'ύ' 27: 0, # 'ώ' }, } # 255: Undefined characters that did not exist in training text # 254: Carriage/Return # 253: symbol (punctuation) that does not belong to word # 252: 0 - 9 # 251: Control characters # Character Mapping Table(s): WINDOWS_1253_GREEK_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 82, # 'A' 66: 100, # 'B' 67: 104, # 'C' 68: 94, # 'D' 69: 98, # 'E' 70: 101, # 'F' 71: 116, # 'G' 72: 102, # 'H' 73: 111, # 'I' 74: 187, # 'J' 75: 117, # 'K' 76: 92, # 'L' 77: 88, # 'M' 78: 113, # 'N' 79: 85, # 'O' 80: 79, # 'P' 81: 118, # 'Q' 82: 105, # 'R' 83: 83, # 'S' 84: 67, # 'T' 85: 114, # 'U' 86: 119, # 'V' 87: 95, # 'W' 88: 99, # 'X' 89: 109, # 'Y' 90: 188, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 72, # 'a' 98: 70, # 'b' 99: 80, # 'c' 100: 81, # 'd' 101: 60, # 'e' 102: 96, # 'f' 103: 93, # 'g' 104: 89, # 'h' 105: 68, # 'i' 106: 120, # 'j' 107: 97, # 'k' 108: 77, # 'l' 109: 86, # 'm' 110: 69, # 'n' 111: 55, # 'o' 112: 78, # 'p' 113: 115, # 'q' 114: 65, # 'r' 115: 66, # 's' 116: 58, # 't' 117: 76, # 'u' 118: 106, # 'v' 119: 103, # 'w' 120: 87, # 'x' 121: 107, # 'y' 122: 112, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 255, # '€' 129: 255, # None 130: 255, # '‚' 131: 255, # 'ƒ' 132: 255, # '„' 133: 255, # '…' 134: 255, # '†' 135: 255, # '‡' 136: 255, # None 137: 255, # '‰' 138: 255, # None 139: 255, # '‹' 140: 255, # None 141: 255, # None 142: 255, # None 143: 255, # None 144: 255, # None 145: 255, # '‘' 146: 255, # '’' 147: 255, # '“' 148: 255, # '”' 149: 255, # '•' 150: 255, # '–' 151: 255, # '—' 152: 255, # None 153: 255, # '™' 154: 255, # None 155: 255, # '›' 156: 255, # None 157: 255, # None 158: 255, # None 159: 255, # None 160: 253, # '\xa0' 161: 233, # '΅' 162: 61, # 'Ά' 163: 253, # '£' 164: 253, # '¤' 165: 253, # '¥' 166: 253, # '¦' 167: 253, # '§' 168: 253, # '¨' 169: 253, # '©' 170: 253, # None 171: 253, # '«' 172: 253, # '¬' 173: 74, # '\xad' 174: 253, # '®' 175: 253, # '―' 176: 253, # '°' 177: 253, # '±' 178: 253, # '²' 179: 253, # '³' 180: 247, # '΄' 181: 253, # 'µ' 182: 253, # '¶' 183: 36, # '·' 184: 46, # 'Έ' 185: 71, # 'Ή' 186: 73, # 'Ί' 187: 253, # '»' 188: 54, # 'Ό' 189: 253, # '½' 190: 108, # 'Ύ' 191: 123, # 'Ώ' 192: 110, # 'ΐ' 193: 31, # 'Α' 194: 51, # 'Β' 195: 43, # 'Γ' 196: 41, # 'Δ' 197: 34, # 'Ε' 198: 91, # 'Ζ' 199: 40, # 'Η' 200: 52, # 'Θ' 201: 47, # 'Ι' 202: 44, # 'Κ' 203: 53, # 'Λ' 204: 38, # 'Μ' 205: 49, # 'Ν' 206: 59, # 'Ξ' 207: 39, # 'Ο' 208: 35, # 'Π' 209: 48, # 'Ρ' 210: 250, # None 211: 37, # 'Σ' 212: 33, # 'Τ' 213: 45, # 'Υ' 214: 56, # 'Φ' 215: 50, # 'Χ' 216: 84, # 'Ψ' 217: 57, # 'Ω' 218: 120, # 'Ϊ' 219: 121, # 'Ϋ' 220: 17, # 'ά' 221: 18, # 'έ' 222: 22, # 'ή' 223: 15, # 'ί' 224: 124, # 'ΰ' 225: 1, # 'α' 226: 29, # 'β' 227: 20, # 'γ' 228: 21, # 'δ' 229: 3, # 'ε' 230: 32, # 'ζ' 231: 13, # 'η' 232: 25, # 'θ' 233: 5, # 'ι' 234: 11, # 'κ' 235: 16, # 'λ' 236: 10, # 'μ' 237: 6, # 'ν' 238: 30, # 'ξ' 239: 4, # 'ο' 240: 9, # 'π' 241: 8, # 'ρ' 242: 14, # 'ς' 243: 7, # 'σ' 244: 2, # 'τ' 245: 12, # 'υ' 246: 28, # 'φ' 247: 23, # 'χ' 248: 42, # 'ψ' 249: 24, # 'ω' 250: 64, # 'ϊ' 251: 75, # 'ϋ' 252: 19, # 'ό' 253: 26, # 'ύ' 254: 27, # 'ώ' 255: 253, # None } WINDOWS_1253_GREEK_MODEL = SingleByteCharSetModel(charset_name='windows-1253', language='Greek', char_to_order_map=WINDOWS_1253_GREEK_CHAR_TO_ORDER, language_model=GREEK_LANG_MODEL, typical_positive_ratio=0.982851, keep_ascii_letters=False, alphabet='ΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπρςστυφχψωόύώ') ISO_8859_7_GREEK_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 82, # 'A' 66: 100, # 'B' 67: 104, # 'C' 68: 94, # 'D' 69: 98, # 'E' 70: 101, # 'F' 71: 116, # 'G' 72: 102, # 'H' 73: 111, # 'I' 74: 187, # 'J' 75: 117, # 'K' 76: 92, # 'L' 77: 88, # 'M' 78: 113, # 'N' 79: 85, # 'O' 80: 79, # 'P' 81: 118, # 'Q' 82: 105, # 'R' 83: 83, # 'S' 84: 67, # 'T' 85: 114, # 'U' 86: 119, # 'V' 87: 95, # 'W' 88: 99, # 'X' 89: 109, # 'Y' 90: 188, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 72, # 'a' 98: 70, # 'b' 99: 80, # 'c' 100: 81, # 'd' 101: 60, # 'e' 102: 96, # 'f' 103: 93, # 'g' 104: 89, # 'h' 105: 68, # 'i' 106: 120, # 'j' 107: 97, # 'k' 108: 77, # 'l' 109: 86, # 'm' 110: 69, # 'n' 111: 55, # 'o' 112: 78, # 'p' 113: 115, # 'q' 114: 65, # 'r' 115: 66, # 's' 116: 58, # 't' 117: 76, # 'u' 118: 106, # 'v' 119: 103, # 'w' 120: 87, # 'x' 121: 107, # 'y' 122: 112, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 255, # '\x80' 129: 255, # '\x81' 130: 255, # '\x82' 131: 255, # '\x83' 132: 255, # '\x84' 133: 255, # '\x85' 134: 255, # '\x86' 135: 255, # '\x87' 136: 255, # '\x88' 137: 255, # '\x89' 138: 255, # '\x8a' 139: 255, # '\x8b' 140: 255, # '\x8c' 141: 255, # '\x8d' 142: 255, # '\x8e' 143: 255, # '\x8f' 144: 255, # '\x90' 145: 255, # '\x91' 146: 255, # '\x92' 147: 255, # '\x93' 148: 255, # '\x94' 149: 255, # '\x95' 150: 255, # '\x96' 151: 255, # '\x97' 152: 255, # '\x98' 153: 255, # '\x99' 154: 255, # '\x9a' 155: 255, # '\x9b' 156: 255, # '\x9c' 157: 255, # '\x9d' 158: 255, # '\x9e' 159: 255, # '\x9f' 160: 253, # '\xa0' 161: 233, # '‘' 162: 90, # '’' 163: 253, # '£' 164: 253, # '€' 165: 253, # '₯' 166: 253, # '¦' 167: 253, # '§' 168: 253, # '¨' 169: 253, # '©' 170: 253, # 'ͺ' 171: 253, # '«' 172: 253, # '¬' 173: 74, # '\xad' 174: 253, # None 175: 253, # '―' 176: 253, # '°' 177: 253, # '±' 178: 253, # '²' 179: 253, # '³' 180: 247, # '΄' 181: 248, # '΅' 182: 61, # 'Ά' 183: 36, # '·' 184: 46, # 'Έ' 185: 71, # 'Ή' 186: 73, # 'Ί' 187: 253, # '»' 188: 54, # 'Ό' 189: 253, # '½' 190: 108, # 'Ύ' 191: 123, # 'Ώ' 192: 110, # 'ΐ' 193: 31, # 'Α' 194: 51, # 'Β' 195: 43, # 'Γ' 196: 41, # 'Δ' 197: 34, # 'Ε' 198: 91, # 'Ζ' 199: 40, # 'Η' 200: 52, # 'Θ' 201: 47, # 'Ι' 202: 44, # 'Κ' 203: 53, # 'Λ' 204: 38, # 'Μ' 205: 49, # 'Ν' 206: 59, # 'Ξ' 207: 39, # 'Ο' 208: 35, # 'Π' 209: 48, # 'Ρ' 210: 250, # None 211: 37, # 'Σ' 212: 33, # 'Τ' 213: 45, # 'Υ' 214: 56, # 'Φ' 215: 50, # 'Χ' 216: 84, # 'Ψ' 217: 57, # 'Ω' 218: 120, # 'Ϊ' 219: 121, # 'Ϋ' 220: 17, # 'ά' 221: 18, # 'έ' 222: 22, # 'ή' 223: 15, # 'ί' 224: 124, # 'ΰ' 225: 1, # 'α' 226: 29, # 'β' 227: 20, # 'γ' 228: 21, # 'δ' 229: 3, # 'ε' 230: 32, # 'ζ' 231: 13, # 'η' 232: 25, # 'θ' 233: 5, # 'ι' 234: 11, # 'κ' 235: 16, # 'λ' 236: 10, # 'μ' 237: 6, # 'ν' 238: 30, # 'ξ' 239: 4, # 'ο' 240: 9, # 'π' 241: 8, # 'ρ' 242: 14, # 'ς' 243: 7, # 'σ' 244: 2, # 'τ' 245: 12, # 'υ' 246: 28, # 'φ' 247: 23, # 'χ' 248: 42, # 'ψ' 249: 24, # 'ω' 250: 64, # 'ϊ' 251: 75, # 'ϋ' 252: 19, # 'ό' 253: 26, # 'ύ' 254: 27, # 'ώ' 255: 253, # None } ISO_8859_7_GREEK_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-7', language='Greek', char_to_order_map=ISO_8859_7_GREEK_CHAR_TO_ORDER, language_model=GREEK_LANG_MODEL, typical_positive_ratio=0.982851, keep_ascii_letters=False, alphabet='ΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπρςστυφχψωόύώ') PKH]Bpython3.10/site-packages/pip/_vendor/chardet/charsetgroupprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Communicator client code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .enums import ProbingState from .charsetprober import CharSetProber class CharSetGroupProber(CharSetProber): def __init__(self, lang_filter=None): super(CharSetGroupProber, self).__init__(lang_filter=lang_filter) self._active_num = 0 self.probers = [] self._best_guess_prober = None def reset(self): super(CharSetGroupProber, self).reset() self._active_num = 0 for prober in self.probers: if prober: prober.reset() prober.active = True self._active_num += 1 self._best_guess_prober = None @property def charset_name(self): if not self._best_guess_prober: self.get_confidence() if not self._best_guess_prober: return None return self._best_guess_prober.charset_name @property def language(self): if not self._best_guess_prober: self.get_confidence() if not self._best_guess_prober: return None return self._best_guess_prober.language def feed(self, byte_str): for prober in self.probers: if not prober: continue if not prober.active: continue state = prober.feed(byte_str) if not state: continue if state == ProbingState.FOUND_IT: self._best_guess_prober = prober self._state = ProbingState.FOUND_IT return self.state elif state == ProbingState.NOT_ME: prober.active = False self._active_num -= 1 if self._active_num <= 0: self._state = ProbingState.NOT_ME return self.state return self.state def get_confidence(self): state = self.state if state == ProbingState.FOUND_IT: return 0.99 elif state == ProbingState.NOT_ME: return 0.01 best_conf = 0.0 self._best_guess_prober = None for prober in self.probers: if not prober: continue if not prober.active: self.logger.debug('%s not active', prober.charset_name) continue conf = prober.get_confidence() self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, conf) if best_conf < conf: best_conf = conf self._best_guess_prober = prober if not self._best_guess_prober: return 0.0 return best_conf PKH]c?python3.10/site-packages/pip/_vendor/chardet/langhebrewmodel.pynu[# -*- coding: utf-8 -*- from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel # 3: Positive # 2: Likely # 1: Unlikely # 0: Negative HEBREW_LANG_MODEL = { 50: { # 'a' 50: 0, # 'a' 60: 1, # 'c' 61: 1, # 'd' 42: 1, # 'e' 53: 1, # 'i' 56: 2, # 'l' 54: 2, # 'n' 49: 0, # 'o' 51: 2, # 'r' 43: 1, # 's' 44: 2, # 't' 63: 1, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 1, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 1, # 'ק' 7: 0, # 'ר' 10: 1, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 1, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 60: { # 'c' 50: 1, # 'a' 60: 1, # 'c' 61: 0, # 'd' 42: 1, # 'e' 53: 1, # 'i' 56: 1, # 'l' 54: 0, # 'n' 49: 1, # 'o' 51: 1, # 'r' 43: 1, # 's' 44: 2, # 't' 63: 1, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 1, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 1, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 61: { # 'd' 50: 1, # 'a' 60: 0, # 'c' 61: 1, # 'd' 42: 1, # 'e' 53: 1, # 'i' 56: 1, # 'l' 54: 1, # 'n' 49: 2, # 'o' 51: 1, # 'r' 43: 1, # 's' 44: 0, # 't' 63: 1, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 1, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 1, # '–' 52: 1, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 42: { # 'e' 50: 1, # 'a' 60: 1, # 'c' 61: 2, # 'd' 42: 1, # 'e' 53: 1, # 'i' 56: 2, # 'l' 54: 2, # 'n' 49: 1, # 'o' 51: 2, # 'r' 43: 2, # 's' 44: 2, # 't' 63: 1, # 'u' 34: 1, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 1, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 1, # '–' 52: 2, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 53: { # 'i' 50: 1, # 'a' 60: 2, # 'c' 61: 1, # 'd' 42: 1, # 'e' 53: 0, # 'i' 56: 1, # 'l' 54: 2, # 'n' 49: 2, # 'o' 51: 1, # 'r' 43: 2, # 's' 44: 2, # 't' 63: 1, # 'u' 34: 0, # '\xa0' 55: 1, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 1, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 56: { # 'l' 50: 1, # 'a' 60: 1, # 'c' 61: 1, # 'd' 42: 2, # 'e' 53: 2, # 'i' 56: 2, # 'l' 54: 1, # 'n' 49: 1, # 'o' 51: 0, # 'r' 43: 1, # 's' 44: 1, # 't' 63: 1, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 1, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 54: { # 'n' 50: 1, # 'a' 60: 1, # 'c' 61: 1, # 'd' 42: 1, # 'e' 53: 1, # 'i' 56: 1, # 'l' 54: 1, # 'n' 49: 1, # 'o' 51: 0, # 'r' 43: 1, # 's' 44: 2, # 't' 63: 1, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 1, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 2, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 49: { # 'o' 50: 1, # 'a' 60: 1, # 'c' 61: 1, # 'd' 42: 1, # 'e' 53: 1, # 'i' 56: 1, # 'l' 54: 2, # 'n' 49: 1, # 'o' 51: 2, # 'r' 43: 1, # 's' 44: 1, # 't' 63: 1, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 1, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 51: { # 'r' 50: 2, # 'a' 60: 1, # 'c' 61: 1, # 'd' 42: 2, # 'e' 53: 1, # 'i' 56: 1, # 'l' 54: 1, # 'n' 49: 2, # 'o' 51: 1, # 'r' 43: 1, # 's' 44: 1, # 't' 63: 1, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 2, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 43: { # 's' 50: 1, # 'a' 60: 1, # 'c' 61: 0, # 'd' 42: 2, # 'e' 53: 1, # 'i' 56: 1, # 'l' 54: 1, # 'n' 49: 1, # 'o' 51: 1, # 'r' 43: 1, # 's' 44: 2, # 't' 63: 1, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 1, # '’' 47: 0, # '“' 46: 2, # '”' 58: 0, # '†' 40: 2, # '…' }, 44: { # 't' 50: 1, # 'a' 60: 1, # 'c' 61: 0, # 'd' 42: 2, # 'e' 53: 2, # 'i' 56: 1, # 'l' 54: 0, # 'n' 49: 1, # 'o' 51: 1, # 'r' 43: 1, # 's' 44: 1, # 't' 63: 1, # 'u' 34: 1, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 2, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 63: { # 'u' 50: 1, # 'a' 60: 1, # 'c' 61: 1, # 'd' 42: 1, # 'e' 53: 1, # 'i' 56: 1, # 'l' 54: 1, # 'n' 49: 0, # 'o' 51: 1, # 'r' 43: 2, # 's' 44: 1, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 1, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 34: { # '\xa0' 50: 1, # 'a' 60: 0, # 'c' 61: 1, # 'd' 42: 0, # 'e' 53: 1, # 'i' 56: 0, # 'l' 54: 1, # 'n' 49: 1, # 'o' 51: 0, # 'r' 43: 1, # 's' 44: 1, # 't' 63: 0, # 'u' 34: 2, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 1, # 'ב' 20: 1, # 'ג' 16: 1, # 'ד' 3: 1, # 'ה' 2: 1, # 'ו' 24: 1, # 'ז' 14: 1, # 'ח' 22: 1, # 'ט' 1: 2, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 1, # 'ל' 11: 0, # 'ם' 6: 2, # 'מ' 23: 0, # 'ן' 12: 1, # 'נ' 19: 1, # 'ס' 13: 1, # 'ע' 26: 0, # 'ף' 18: 1, # 'פ' 27: 0, # 'ץ' 21: 1, # 'צ' 17: 1, # 'ק' 7: 1, # 'ר' 10: 1, # 'ש' 5: 1, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 55: { # '´' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 1, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 1, # 'ה' 2: 1, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 2, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 1, # 'ל' 11: 0, # 'ם' 6: 1, # 'מ' 23: 1, # 'ן' 12: 1, # 'נ' 19: 1, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 1, # 'ר' 10: 1, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 48: { # '¼' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 1, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 1, # 'ל' 11: 0, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 39: { # '½' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 1, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 1, # 'צ' 17: 1, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 57: { # '¾' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 30: { # 'ְ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 1, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 1, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 2, # 'ב' 20: 2, # 'ג' 16: 2, # 'ד' 3: 2, # 'ה' 2: 2, # 'ו' 24: 2, # 'ז' 14: 2, # 'ח' 22: 2, # 'ט' 1: 2, # 'י' 25: 2, # 'ך' 15: 2, # 'כ' 4: 2, # 'ל' 11: 1, # 'ם' 6: 2, # 'מ' 23: 0, # 'ן' 12: 2, # 'נ' 19: 2, # 'ס' 13: 2, # 'ע' 26: 0, # 'ף' 18: 2, # 'פ' 27: 0, # 'ץ' 21: 2, # 'צ' 17: 2, # 'ק' 7: 2, # 'ר' 10: 2, # 'ש' 5: 2, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 59: { # 'ֱ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 1, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 1, # 'ב' 20: 1, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 1, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 1, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 2, # 'ל' 11: 0, # 'ם' 6: 2, # 'מ' 23: 0, # 'ן' 12: 1, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 1, # 'ר' 10: 1, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 41: { # 'ֲ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 2, # 'ב' 20: 1, # 'ג' 16: 2, # 'ד' 3: 1, # 'ה' 2: 1, # 'ו' 24: 1, # 'ז' 14: 1, # 'ח' 22: 1, # 'ט' 1: 1, # 'י' 25: 1, # 'ך' 15: 1, # 'כ' 4: 2, # 'ל' 11: 0, # 'ם' 6: 2, # 'מ' 23: 0, # 'ן' 12: 2, # 'נ' 19: 1, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 1, # 'פ' 27: 0, # 'ץ' 21: 2, # 'צ' 17: 1, # 'ק' 7: 2, # 'ר' 10: 2, # 'ש' 5: 1, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 33: { # 'ִ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 1, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 1, # 'ִ' 37: 0, # 'ֵ' 36: 1, # 'ֶ' 31: 0, # 'ַ' 29: 1, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 1, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 2, # 'ב' 20: 2, # 'ג' 16: 2, # 'ד' 3: 1, # 'ה' 2: 1, # 'ו' 24: 2, # 'ז' 14: 1, # 'ח' 22: 1, # 'ט' 1: 3, # 'י' 25: 1, # 'ך' 15: 2, # 'כ' 4: 2, # 'ל' 11: 2, # 'ם' 6: 2, # 'מ' 23: 2, # 'ן' 12: 2, # 'נ' 19: 2, # 'ס' 13: 1, # 'ע' 26: 0, # 'ף' 18: 2, # 'פ' 27: 1, # 'ץ' 21: 2, # 'צ' 17: 2, # 'ק' 7: 2, # 'ר' 10: 2, # 'ש' 5: 2, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 37: { # 'ֵ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 1, # 'ֶ' 31: 1, # 'ַ' 29: 1, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 2, # 'ב' 20: 1, # 'ג' 16: 2, # 'ד' 3: 2, # 'ה' 2: 1, # 'ו' 24: 1, # 'ז' 14: 2, # 'ח' 22: 1, # 'ט' 1: 3, # 'י' 25: 2, # 'ך' 15: 1, # 'כ' 4: 2, # 'ל' 11: 2, # 'ם' 6: 1, # 'מ' 23: 2, # 'ן' 12: 2, # 'נ' 19: 1, # 'ס' 13: 2, # 'ע' 26: 1, # 'ף' 18: 1, # 'פ' 27: 1, # 'ץ' 21: 1, # 'צ' 17: 1, # 'ק' 7: 2, # 'ר' 10: 2, # 'ש' 5: 2, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 36: { # 'ֶ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 1, # 'ֶ' 31: 1, # 'ַ' 29: 1, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 2, # 'ב' 20: 1, # 'ג' 16: 2, # 'ד' 3: 2, # 'ה' 2: 1, # 'ו' 24: 1, # 'ז' 14: 2, # 'ח' 22: 1, # 'ט' 1: 2, # 'י' 25: 2, # 'ך' 15: 1, # 'כ' 4: 2, # 'ל' 11: 2, # 'ם' 6: 2, # 'מ' 23: 2, # 'ן' 12: 2, # 'נ' 19: 2, # 'ס' 13: 1, # 'ע' 26: 1, # 'ף' 18: 1, # 'פ' 27: 2, # 'ץ' 21: 1, # 'צ' 17: 1, # 'ק' 7: 2, # 'ר' 10: 2, # 'ש' 5: 2, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 31: { # 'ַ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 1, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 1, # 'ֶ' 31: 0, # 'ַ' 29: 2, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 2, # 'ב' 20: 2, # 'ג' 16: 2, # 'ד' 3: 2, # 'ה' 2: 1, # 'ו' 24: 2, # 'ז' 14: 2, # 'ח' 22: 2, # 'ט' 1: 3, # 'י' 25: 1, # 'ך' 15: 2, # 'כ' 4: 2, # 'ל' 11: 2, # 'ם' 6: 2, # 'מ' 23: 2, # 'ן' 12: 2, # 'נ' 19: 2, # 'ס' 13: 2, # 'ע' 26: 2, # 'ף' 18: 2, # 'פ' 27: 1, # 'ץ' 21: 2, # 'צ' 17: 2, # 'ק' 7: 2, # 'ר' 10: 2, # 'ש' 5: 2, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 29: { # 'ָ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 1, # 'ַ' 29: 2, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 1, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 2, # 'ב' 20: 2, # 'ג' 16: 2, # 'ד' 3: 3, # 'ה' 2: 2, # 'ו' 24: 2, # 'ז' 14: 2, # 'ח' 22: 1, # 'ט' 1: 2, # 'י' 25: 2, # 'ך' 15: 2, # 'כ' 4: 2, # 'ל' 11: 2, # 'ם' 6: 2, # 'מ' 23: 2, # 'ן' 12: 2, # 'נ' 19: 1, # 'ס' 13: 2, # 'ע' 26: 1, # 'ף' 18: 2, # 'פ' 27: 1, # 'ץ' 21: 2, # 'צ' 17: 2, # 'ק' 7: 2, # 'ר' 10: 2, # 'ש' 5: 2, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 35: { # 'ֹ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 1, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 2, # 'ב' 20: 1, # 'ג' 16: 2, # 'ד' 3: 2, # 'ה' 2: 1, # 'ו' 24: 1, # 'ז' 14: 1, # 'ח' 22: 1, # 'ט' 1: 1, # 'י' 25: 1, # 'ך' 15: 2, # 'כ' 4: 2, # 'ל' 11: 2, # 'ם' 6: 2, # 'מ' 23: 2, # 'ן' 12: 2, # 'נ' 19: 2, # 'ס' 13: 2, # 'ע' 26: 1, # 'ף' 18: 2, # 'פ' 27: 1, # 'ץ' 21: 2, # 'צ' 17: 2, # 'ק' 7: 2, # 'ר' 10: 2, # 'ש' 5: 2, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 62: { # 'ֻ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 1, # 'ב' 20: 1, # 'ג' 16: 1, # 'ד' 3: 1, # 'ה' 2: 1, # 'ו' 24: 1, # 'ז' 14: 1, # 'ח' 22: 0, # 'ט' 1: 1, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 2, # 'ל' 11: 1, # 'ם' 6: 1, # 'מ' 23: 1, # 'ן' 12: 1, # 'נ' 19: 1, # 'ס' 13: 1, # 'ע' 26: 0, # 'ף' 18: 1, # 'פ' 27: 0, # 'ץ' 21: 1, # 'צ' 17: 1, # 'ק' 7: 1, # 'ר' 10: 1, # 'ש' 5: 1, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 28: { # 'ּ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 3, # 'ְ' 59: 0, # 'ֱ' 41: 1, # 'ֲ' 33: 3, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 3, # 'ַ' 29: 3, # 'ָ' 35: 2, # 'ֹ' 62: 1, # 'ֻ' 28: 0, # 'ּ' 38: 2, # 'ׁ' 45: 1, # 'ׂ' 9: 2, # 'א' 8: 2, # 'ב' 20: 1, # 'ג' 16: 2, # 'ד' 3: 1, # 'ה' 2: 2, # 'ו' 24: 1, # 'ז' 14: 1, # 'ח' 22: 1, # 'ט' 1: 2, # 'י' 25: 2, # 'ך' 15: 2, # 'כ' 4: 2, # 'ל' 11: 1, # 'ם' 6: 2, # 'מ' 23: 1, # 'ן' 12: 2, # 'נ' 19: 1, # 'ס' 13: 2, # 'ע' 26: 1, # 'ף' 18: 1, # 'פ' 27: 1, # 'ץ' 21: 1, # 'צ' 17: 1, # 'ק' 7: 2, # 'ר' 10: 2, # 'ש' 5: 2, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 38: { # 'ׁ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 1, # 'ֹ' 62: 1, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 2, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 1, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 1, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 45: { # 'ׂ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 1, # 'ֵ' 36: 2, # 'ֶ' 31: 1, # 'ַ' 29: 2, # 'ָ' 35: 1, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 0, # 'ב' 20: 1, # 'ג' 16: 0, # 'ד' 3: 1, # 'ה' 2: 2, # 'ו' 24: 0, # 'ז' 14: 1, # 'ח' 22: 0, # 'ט' 1: 1, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 1, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 1, # 'נ' 19: 0, # 'ס' 13: 1, # 'ע' 26: 0, # 'ף' 18: 1, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 1, # 'ר' 10: 0, # 'ש' 5: 1, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 9: { # 'א' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 1, # '´' 48: 1, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 2, # 'ֱ' 41: 2, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 2, # 'ֹ' 62: 1, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 3, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 2, # 'ע' 26: 3, # 'ף' 18: 3, # 'פ' 27: 1, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 8: { # 'ב' 50: 0, # 'a' 60: 0, # 'c' 61: 1, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 1, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 2, # 'ֹ' 62: 1, # 'ֻ' 28: 3, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 2, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 2, # 'ם' 6: 3, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 3, # 'ע' 26: 1, # 'ף' 18: 3, # 'פ' 27: 2, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 1, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 20: { # 'ג' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 2, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 1, # 'ִ' 37: 1, # 'ֵ' 36: 1, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 1, # 'ֹ' 62: 0, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 3, # 'ב' 20: 2, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 2, # 'ח' 22: 2, # 'ט' 1: 3, # 'י' 25: 1, # 'ך' 15: 1, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 2, # 'ס' 13: 3, # 'ע' 26: 2, # 'ף' 18: 2, # 'פ' 27: 1, # 'ץ' 21: 1, # 'צ' 17: 1, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 1, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 0, # '…' }, 16: { # 'ד' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 2, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 1, # 'ז' 14: 2, # 'ח' 22: 2, # 'ט' 1: 3, # 'י' 25: 2, # 'ך' 15: 2, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 2, # 'ן' 12: 3, # 'נ' 19: 2, # 'ס' 13: 3, # 'ע' 26: 2, # 'ף' 18: 3, # 'פ' 27: 0, # 'ץ' 21: 2, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 3: { # 'ה' 50: 0, # 'a' 60: 0, # 'c' 61: 1, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 0, # '´' 48: 1, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 1, # 'ְ' 59: 1, # 'ֱ' 41: 2, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 3, # 'ַ' 29: 2, # 'ָ' 35: 1, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 1, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 3, # 'ע' 26: 0, # 'ף' 18: 3, # 'פ' 27: 1, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 1, # '–' 52: 1, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 2, # '…' }, 2: { # 'ו' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 1, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 1, # '´' 48: 1, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 1, # 'ֵ' 36: 1, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 3, # 'ֹ' 62: 0, # 'ֻ' 28: 3, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 3, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 3, # 'ע' 26: 3, # 'ף' 18: 3, # 'פ' 27: 3, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 1, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 2, # '…' }, 24: { # 'ז' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 1, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 1, # 'ֲ' 33: 1, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 1, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 2, # 'ב' 20: 2, # 'ג' 16: 2, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 2, # 'ז' 14: 2, # 'ח' 22: 1, # 'ט' 1: 3, # 'י' 25: 1, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 2, # 'ם' 6: 3, # 'מ' 23: 2, # 'ן' 12: 2, # 'נ' 19: 1, # 'ס' 13: 2, # 'ע' 26: 1, # 'ף' 18: 1, # 'פ' 27: 0, # 'ץ' 21: 2, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 1, # 'ש' 5: 2, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 1, # '…' }, 14: { # 'ח' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 1, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 1, # 'ֱ' 41: 2, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 2, # 'ֹ' 62: 1, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 3, # 'ב' 20: 2, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 2, # 'ח' 22: 2, # 'ט' 1: 3, # 'י' 25: 1, # 'ך' 15: 2, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 2, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 1, # 'ע' 26: 2, # 'ף' 18: 2, # 'פ' 27: 2, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 1, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 22: { # 'ט' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 1, # 'ֵ' 36: 1, # 'ֶ' 31: 2, # 'ַ' 29: 1, # 'ָ' 35: 1, # 'ֹ' 62: 1, # 'ֻ' 28: 1, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 1, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 2, # 'ז' 14: 3, # 'ח' 22: 2, # 'ט' 1: 3, # 'י' 25: 1, # 'ך' 15: 2, # 'כ' 4: 3, # 'ל' 11: 2, # 'ם' 6: 2, # 'מ' 23: 2, # 'ן' 12: 3, # 'נ' 19: 2, # 'ס' 13: 3, # 'ע' 26: 2, # 'ף' 18: 3, # 'פ' 27: 1, # 'ץ' 21: 2, # 'צ' 17: 2, # 'ק' 7: 3, # 'ר' 10: 2, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 1, # '…' }, 1: { # 'י' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 1, # '´' 48: 1, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 1, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 2, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 3, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 3, # 'ע' 26: 3, # 'ף' 18: 3, # 'פ' 27: 3, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 1, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 2, # '…' }, 25: { # 'ך' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 2, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 1, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 1, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 1, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 1, # 'ל' 11: 0, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 1, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 1, # '…' }, 15: { # 'כ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 1, # 'ֹ' 62: 1, # 'ֻ' 28: 3, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 2, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 3, # 'ח' 22: 2, # 'ט' 1: 3, # 'י' 25: 3, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 2, # 'ע' 26: 3, # 'ף' 18: 3, # 'פ' 27: 1, # 'ץ' 21: 2, # 'צ' 17: 2, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 4: { # 'ל' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 1, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 3, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 2, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 3, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 2, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 3, # 'ע' 26: 2, # 'ף' 18: 3, # 'פ' 27: 2, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 1, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 11: { # 'ם' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 1, # 'ב' 20: 1, # 'ג' 16: 0, # 'ד' 3: 1, # 'ה' 2: 1, # 'ו' 24: 1, # 'ז' 14: 1, # 'ח' 22: 0, # 'ט' 1: 1, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 1, # 'ל' 11: 1, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 1, # 'נ' 19: 0, # 'ס' 13: 1, # 'ע' 26: 0, # 'ף' 18: 1, # 'פ' 27: 1, # 'ץ' 21: 1, # 'צ' 17: 1, # 'ק' 7: 1, # 'ר' 10: 1, # 'ש' 5: 1, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 2, # '…' }, 6: { # 'מ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 1, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 2, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 2, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 3, # 'ע' 26: 0, # 'ף' 18: 3, # 'פ' 27: 2, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 1, # '…' }, 23: { # 'ן' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 0, # '´' 48: 1, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 1, # 'ב' 20: 1, # 'ג' 16: 1, # 'ד' 3: 1, # 'ה' 2: 1, # 'ו' 24: 0, # 'ז' 14: 1, # 'ח' 22: 1, # 'ט' 1: 1, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 1, # 'ל' 11: 1, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 1, # 'נ' 19: 1, # 'ס' 13: 1, # 'ע' 26: 1, # 'ף' 18: 1, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 1, # 'ק' 7: 1, # 'ר' 10: 1, # 'ש' 5: 1, # 'ת' 32: 1, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 2, # '…' }, 12: { # 'נ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 1, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 2, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 3, # 'ע' 26: 2, # 'ף' 18: 3, # 'פ' 27: 2, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 19: { # 'ס' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 1, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 1, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 1, # 'ָ' 35: 1, # 'ֹ' 62: 2, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 1, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 2, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 2, # 'ם' 6: 3, # 'מ' 23: 2, # 'ן' 12: 3, # 'נ' 19: 2, # 'ס' 13: 3, # 'ע' 26: 3, # 'ף' 18: 3, # 'פ' 27: 0, # 'ץ' 21: 2, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 1, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 13: { # 'ע' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 1, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 1, # 'ְ' 59: 1, # 'ֱ' 41: 2, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 2, # 'ֹ' 62: 1, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 1, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 2, # 'ך' 15: 2, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 2, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 2, # 'ע' 26: 1, # 'ף' 18: 2, # 'פ' 27: 2, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 26: { # 'ף' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 1, # 'ו' 24: 0, # 'ז' 14: 1, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 1, # 'ל' 11: 0, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 1, # 'ס' 13: 0, # 'ע' 26: 1, # 'ף' 18: 1, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 1, # 'ק' 7: 1, # 'ר' 10: 1, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 1, # '…' }, 18: { # 'פ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 1, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 1, # 'ֵ' 36: 2, # 'ֶ' 31: 1, # 'ַ' 29: 2, # 'ָ' 35: 1, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 2, # 'ב' 20: 3, # 'ג' 16: 2, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 2, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 2, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 2, # 'ם' 6: 2, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 3, # 'ע' 26: 2, # 'ף' 18: 2, # 'פ' 27: 2, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 0, # '…' }, 27: { # 'ץ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 1, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 1, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 1, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 1, # 'ר' 10: 0, # 'ש' 5: 1, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 1, # '…' }, 21: { # 'צ' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 1, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 1, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 1, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 2, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 1, # 'ז' 14: 3, # 'ח' 22: 2, # 'ט' 1: 3, # 'י' 25: 1, # 'ך' 15: 1, # 'כ' 4: 3, # 'ל' 11: 2, # 'ם' 6: 3, # 'מ' 23: 2, # 'ן' 12: 3, # 'נ' 19: 1, # 'ס' 13: 3, # 'ע' 26: 2, # 'ף' 18: 3, # 'פ' 27: 2, # 'ץ' 21: 2, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 0, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 17: { # 'ק' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 1, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 1, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 2, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 2, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 2, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 1, # 'ך' 15: 1, # 'כ' 4: 3, # 'ל' 11: 2, # 'ם' 6: 3, # 'מ' 23: 2, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 3, # 'ע' 26: 2, # 'ף' 18: 3, # 'פ' 27: 2, # 'ץ' 21: 3, # 'צ' 17: 2, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 1, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 7: { # 'ר' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 2, # '´' 48: 1, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 1, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 2, # 'ֹ' 62: 1, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 3, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 3, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 3, # 'ס' 13: 3, # 'ע' 26: 2, # 'ף' 18: 3, # 'פ' 27: 3, # 'ץ' 21: 3, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 2, # '…' }, 10: { # 'ש' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 1, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 1, # 'ִ' 37: 1, # 'ֵ' 36: 1, # 'ֶ' 31: 1, # 'ַ' 29: 1, # 'ָ' 35: 1, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 3, # 'ׁ' 45: 2, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 3, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 2, # 'ז' 14: 3, # 'ח' 22: 3, # 'ט' 1: 3, # 'י' 25: 3, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 2, # 'ן' 12: 3, # 'נ' 19: 2, # 'ס' 13: 3, # 'ע' 26: 2, # 'ף' 18: 3, # 'פ' 27: 1, # 'ץ' 21: 2, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 1, # '…' }, 5: { # 'ת' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 1, # '\xa0' 55: 0, # '´' 48: 1, # '¼' 39: 1, # '½' 57: 0, # '¾' 30: 2, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 2, # 'ִ' 37: 2, # 'ֵ' 36: 2, # 'ֶ' 31: 2, # 'ַ' 29: 2, # 'ָ' 35: 1, # 'ֹ' 62: 1, # 'ֻ' 28: 2, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 3, # 'א' 8: 3, # 'ב' 20: 3, # 'ג' 16: 2, # 'ד' 3: 3, # 'ה' 2: 3, # 'ו' 24: 2, # 'ז' 14: 3, # 'ח' 22: 2, # 'ט' 1: 3, # 'י' 25: 2, # 'ך' 15: 3, # 'כ' 4: 3, # 'ל' 11: 3, # 'ם' 6: 3, # 'מ' 23: 3, # 'ן' 12: 3, # 'נ' 19: 2, # 'ס' 13: 3, # 'ע' 26: 2, # 'ף' 18: 3, # 'פ' 27: 1, # 'ץ' 21: 2, # 'צ' 17: 3, # 'ק' 7: 3, # 'ר' 10: 3, # 'ש' 5: 3, # 'ת' 32: 1, # '–' 52: 1, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 2, # '…' }, 32: { # '–' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 1, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 1, # 'ב' 20: 1, # 'ג' 16: 1, # 'ד' 3: 1, # 'ה' 2: 1, # 'ו' 24: 0, # 'ז' 14: 1, # 'ח' 22: 0, # 'ט' 1: 1, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 1, # 'ל' 11: 0, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 1, # 'ס' 13: 1, # 'ע' 26: 0, # 'ף' 18: 1, # 'פ' 27: 0, # 'ץ' 21: 1, # 'צ' 17: 0, # 'ק' 7: 1, # 'ר' 10: 1, # 'ש' 5: 1, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 52: { # '’' 50: 1, # 'a' 60: 0, # 'c' 61: 1, # 'd' 42: 1, # 'e' 53: 1, # 'i' 56: 1, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 1, # 'r' 43: 2, # 's' 44: 2, # 't' 63: 1, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 1, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 1, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 47: { # '“' 50: 1, # 'a' 60: 1, # 'c' 61: 1, # 'd' 42: 1, # 'e' 53: 1, # 'i' 56: 1, # 'l' 54: 1, # 'n' 49: 1, # 'o' 51: 1, # 'r' 43: 1, # 's' 44: 1, # 't' 63: 1, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 2, # 'א' 8: 1, # 'ב' 20: 1, # 'ג' 16: 1, # 'ד' 3: 1, # 'ה' 2: 1, # 'ו' 24: 1, # 'ז' 14: 1, # 'ח' 22: 1, # 'ט' 1: 1, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 1, # 'ל' 11: 0, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 1, # 'נ' 19: 1, # 'ס' 13: 1, # 'ע' 26: 0, # 'ף' 18: 1, # 'פ' 27: 0, # 'ץ' 21: 1, # 'צ' 17: 1, # 'ק' 7: 1, # 'ר' 10: 1, # 'ש' 5: 1, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 46: { # '”' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 1, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 1, # 'ב' 20: 1, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 1, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 1, # 'ל' 11: 0, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 1, # 'צ' 17: 0, # 'ק' 7: 1, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 0, # '†' 40: 0, # '…' }, 58: { # '†' 50: 0, # 'a' 60: 0, # 'c' 61: 0, # 'd' 42: 0, # 'e' 53: 0, # 'i' 56: 0, # 'l' 54: 0, # 'n' 49: 0, # 'o' 51: 0, # 'r' 43: 0, # 's' 44: 0, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 0, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 0, # 'ה' 2: 0, # 'ו' 24: 0, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 0, # 'י' 25: 0, # 'ך' 15: 0, # 'כ' 4: 0, # 'ל' 11: 0, # 'ם' 6: 0, # 'מ' 23: 0, # 'ן' 12: 0, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 0, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 0, # 'ר' 10: 0, # 'ש' 5: 0, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 0, # '”' 58: 2, # '†' 40: 0, # '…' }, 40: { # '…' 50: 1, # 'a' 60: 1, # 'c' 61: 1, # 'd' 42: 1, # 'e' 53: 1, # 'i' 56: 0, # 'l' 54: 1, # 'n' 49: 0, # 'o' 51: 1, # 'r' 43: 1, # 's' 44: 1, # 't' 63: 0, # 'u' 34: 0, # '\xa0' 55: 0, # '´' 48: 0, # '¼' 39: 0, # '½' 57: 0, # '¾' 30: 0, # 'ְ' 59: 0, # 'ֱ' 41: 0, # 'ֲ' 33: 0, # 'ִ' 37: 0, # 'ֵ' 36: 0, # 'ֶ' 31: 0, # 'ַ' 29: 0, # 'ָ' 35: 0, # 'ֹ' 62: 0, # 'ֻ' 28: 0, # 'ּ' 38: 0, # 'ׁ' 45: 0, # 'ׂ' 9: 1, # 'א' 8: 0, # 'ב' 20: 0, # 'ג' 16: 0, # 'ד' 3: 1, # 'ה' 2: 1, # 'ו' 24: 1, # 'ז' 14: 0, # 'ח' 22: 0, # 'ט' 1: 1, # 'י' 25: 0, # 'ך' 15: 1, # 'כ' 4: 1, # 'ל' 11: 0, # 'ם' 6: 1, # 'מ' 23: 0, # 'ן' 12: 1, # 'נ' 19: 0, # 'ס' 13: 0, # 'ע' 26: 0, # 'ף' 18: 1, # 'פ' 27: 0, # 'ץ' 21: 0, # 'צ' 17: 0, # 'ק' 7: 1, # 'ר' 10: 1, # 'ש' 5: 1, # 'ת' 32: 0, # '–' 52: 0, # '’' 47: 0, # '“' 46: 1, # '”' 58: 0, # '†' 40: 2, # '…' }, } # 255: Undefined characters that did not exist in training text # 254: Carriage/Return # 253: symbol (punctuation) that does not belong to word # 252: 0 - 9 # 251: Control characters # Character Mapping Table(s): WINDOWS_1255_HEBREW_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 69, # 'A' 66: 91, # 'B' 67: 79, # 'C' 68: 80, # 'D' 69: 92, # 'E' 70: 89, # 'F' 71: 97, # 'G' 72: 90, # 'H' 73: 68, # 'I' 74: 111, # 'J' 75: 112, # 'K' 76: 82, # 'L' 77: 73, # 'M' 78: 95, # 'N' 79: 85, # 'O' 80: 78, # 'P' 81: 121, # 'Q' 82: 86, # 'R' 83: 71, # 'S' 84: 67, # 'T' 85: 102, # 'U' 86: 107, # 'V' 87: 84, # 'W' 88: 114, # 'X' 89: 103, # 'Y' 90: 115, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 50, # 'a' 98: 74, # 'b' 99: 60, # 'c' 100: 61, # 'd' 101: 42, # 'e' 102: 76, # 'f' 103: 70, # 'g' 104: 64, # 'h' 105: 53, # 'i' 106: 105, # 'j' 107: 93, # 'k' 108: 56, # 'l' 109: 65, # 'm' 110: 54, # 'n' 111: 49, # 'o' 112: 66, # 'p' 113: 110, # 'q' 114: 51, # 'r' 115: 43, # 's' 116: 44, # 't' 117: 63, # 'u' 118: 81, # 'v' 119: 77, # 'w' 120: 98, # 'x' 121: 75, # 'y' 122: 108, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 124, # '€' 129: 202, # None 130: 203, # '‚' 131: 204, # 'ƒ' 132: 205, # '„' 133: 40, # '…' 134: 58, # '†' 135: 206, # '‡' 136: 207, # 'ˆ' 137: 208, # '‰' 138: 209, # None 139: 210, # '‹' 140: 211, # None 141: 212, # None 142: 213, # None 143: 214, # None 144: 215, # None 145: 83, # '‘' 146: 52, # '’' 147: 47, # '“' 148: 46, # '”' 149: 72, # '•' 150: 32, # '–' 151: 94, # '—' 152: 216, # '˜' 153: 113, # '™' 154: 217, # None 155: 109, # '›' 156: 218, # None 157: 219, # None 158: 220, # None 159: 221, # None 160: 34, # '\xa0' 161: 116, # '¡' 162: 222, # '¢' 163: 118, # '£' 164: 100, # '₪' 165: 223, # '¥' 166: 224, # '¦' 167: 117, # '§' 168: 119, # '¨' 169: 104, # '©' 170: 125, # '×' 171: 225, # '«' 172: 226, # '¬' 173: 87, # '\xad' 174: 99, # '®' 175: 227, # '¯' 176: 106, # '°' 177: 122, # '±' 178: 123, # '²' 179: 228, # '³' 180: 55, # '´' 181: 229, # 'µ' 182: 230, # '¶' 183: 101, # '·' 184: 231, # '¸' 185: 232, # '¹' 186: 120, # '÷' 187: 233, # '»' 188: 48, # '¼' 189: 39, # '½' 190: 57, # '¾' 191: 234, # '¿' 192: 30, # 'ְ' 193: 59, # 'ֱ' 194: 41, # 'ֲ' 195: 88, # 'ֳ' 196: 33, # 'ִ' 197: 37, # 'ֵ' 198: 36, # 'ֶ' 199: 31, # 'ַ' 200: 29, # 'ָ' 201: 35, # 'ֹ' 202: 235, # None 203: 62, # 'ֻ' 204: 28, # 'ּ' 205: 236, # 'ֽ' 206: 126, # '־' 207: 237, # 'ֿ' 208: 238, # '׀' 209: 38, # 'ׁ' 210: 45, # 'ׂ' 211: 239, # '׃' 212: 240, # 'װ' 213: 241, # 'ױ' 214: 242, # 'ײ' 215: 243, # '׳' 216: 127, # '״' 217: 244, # None 218: 245, # None 219: 246, # None 220: 247, # None 221: 248, # None 222: 249, # None 223: 250, # None 224: 9, # 'א' 225: 8, # 'ב' 226: 20, # 'ג' 227: 16, # 'ד' 228: 3, # 'ה' 229: 2, # 'ו' 230: 24, # 'ז' 231: 14, # 'ח' 232: 22, # 'ט' 233: 1, # 'י' 234: 25, # 'ך' 235: 15, # 'כ' 236: 4, # 'ל' 237: 11, # 'ם' 238: 6, # 'מ' 239: 23, # 'ן' 240: 12, # 'נ' 241: 19, # 'ס' 242: 13, # 'ע' 243: 26, # 'ף' 244: 18, # 'פ' 245: 27, # 'ץ' 246: 21, # 'צ' 247: 17, # 'ק' 248: 7, # 'ר' 249: 10, # 'ש' 250: 5, # 'ת' 251: 251, # None 252: 252, # None 253: 128, # '\u200e' 254: 96, # '\u200f' 255: 253, # None } WINDOWS_1255_HEBREW_MODEL = SingleByteCharSetModel(charset_name='windows-1255', language='Hebrew', char_to_order_map=WINDOWS_1255_HEBREW_CHAR_TO_ORDER, language_model=HEBREW_LANG_MODEL, typical_positive_ratio=0.984004, keep_ascii_letters=False, alphabet='אבגדהוזחטיךכלםמןנסעףפץצקרשתװױײ') PKH]֑g2:python3.10/site-packages/pip/_vendor/chardet/sjisprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .mbcharsetprober import MultiByteCharSetProber from .codingstatemachine import CodingStateMachine from .chardistribution import SJISDistributionAnalysis from .jpcntx import SJISContextAnalysis from .mbcssm import SJIS_SM_MODEL from .enums import ProbingState, MachineState class SJISProber(MultiByteCharSetProber): def __init__(self): super(SJISProber, self).__init__() self.coding_sm = CodingStateMachine(SJIS_SM_MODEL) self.distribution_analyzer = SJISDistributionAnalysis() self.context_analyzer = SJISContextAnalysis() self.reset() def reset(self): super(SJISProber, self).reset() self.context_analyzer.reset() @property def charset_name(self): return self.context_analyzer.charset_name @property def language(self): return "Japanese" def feed(self, byte_str): for i in range(len(byte_str)): coding_state = self.coding_sm.next_state(byte_str[i]) if coding_state == MachineState.ERROR: self.logger.debug('%s %s prober hit error at byte %s', self.charset_name, self.language, i) self._state = ProbingState.NOT_ME break elif coding_state == MachineState.ITS_ME: self._state = ProbingState.FOUND_IT break elif coding_state == MachineState.START: char_len = self.coding_sm.get_current_charlen() if i == 0: self._last_char[1] = byte_str[0] self.context_analyzer.feed(self._last_char[2 - char_len:], char_len) self.distribution_analyzer.feed(self._last_char, char_len) else: self.context_analyzer.feed(byte_str[i + 1 - char_len:i + 3 - char_len], char_len) self.distribution_analyzer.feed(byte_str[i - 1:i + 1], char_len) self._last_char[0] = byte_str[-1] if self.state == ProbingState.DETECTING: if (self.context_analyzer.got_enough_data() and (self.get_confidence() > self.SHORTCUT_THRESHOLD)): self._state = ProbingState.FOUND_IT return self.state def get_confidence(self): context_conf = self.context_analyzer.get_confidence() distrib_conf = self.distribution_analyzer.get_confidence() return max(context_conf, distrib_conf) PKH]D}}5python3.10/site-packages/pip/_vendor/chardet/enums.pynu[""" All of the Enums that are used throughout the chardet package. :author: Dan Blanchard (dan.blanchard@gmail.com) """ class InputState(object): """ This enum represents the different states a universal detector can be in. """ PURE_ASCII = 0 ESC_ASCII = 1 HIGH_BYTE = 2 class LanguageFilter(object): """ This enum represents the different language filters we can apply to a ``UniversalDetector``. """ CHINESE_SIMPLIFIED = 0x01 CHINESE_TRADITIONAL = 0x02 JAPANESE = 0x04 KOREAN = 0x08 NON_CJK = 0x10 ALL = 0x1F CHINESE = CHINESE_SIMPLIFIED | CHINESE_TRADITIONAL CJK = CHINESE | JAPANESE | KOREAN class ProbingState(object): """ This enum represents the different states a prober can be in. """ DETECTING = 0 FOUND_IT = 1 NOT_ME = 2 class MachineState(object): """ This enum represents the different states a state machine can be in. """ START = 0 ERROR = 1 ITS_ME = 2 class SequenceLikelihood(object): """ This enum represents the likelihood of a character following the previous one. """ NEGATIVE = 0 UNLIKELY = 1 LIKELY = 2 POSITIVE = 3 @classmethod def get_num_categories(cls): """:returns: The number of likelihood categories in the enum.""" return 4 class CharacterCategory(object): """ This enum represents the different categories language models for ``SingleByteCharsetProber`` put characters into. Anything less than CONTROL is considered a letter. """ UNDEFINED = 255 LINE_BREAK = 254 SYMBOL = 253 DIGIT = 252 CONTROL = 251 PKH]=nn9python3.10/site-packages/pip/_vendor/chardet/escprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .charsetprober import CharSetProber from .codingstatemachine import CodingStateMachine from .enums import LanguageFilter, ProbingState, MachineState from .escsm import (HZ_SM_MODEL, ISO2022CN_SM_MODEL, ISO2022JP_SM_MODEL, ISO2022KR_SM_MODEL) class EscCharSetProber(CharSetProber): """ This CharSetProber uses a "code scheme" approach for detecting encodings, whereby easily recognizable escape or shift sequences are relied on to identify these encodings. """ def __init__(self, lang_filter=None): super(EscCharSetProber, self).__init__(lang_filter=lang_filter) self.coding_sm = [] if self.lang_filter & LanguageFilter.CHINESE_SIMPLIFIED: self.coding_sm.append(CodingStateMachine(HZ_SM_MODEL)) self.coding_sm.append(CodingStateMachine(ISO2022CN_SM_MODEL)) if self.lang_filter & LanguageFilter.JAPANESE: self.coding_sm.append(CodingStateMachine(ISO2022JP_SM_MODEL)) if self.lang_filter & LanguageFilter.KOREAN: self.coding_sm.append(CodingStateMachine(ISO2022KR_SM_MODEL)) self.active_sm_count = None self._detected_charset = None self._detected_language = None self._state = None self.reset() def reset(self): super(EscCharSetProber, self).reset() for coding_sm in self.coding_sm: if not coding_sm: continue coding_sm.active = True coding_sm.reset() self.active_sm_count = len(self.coding_sm) self._detected_charset = None self._detected_language = None @property def charset_name(self): return self._detected_charset @property def language(self): return self._detected_language def get_confidence(self): if self._detected_charset: return 0.99 else: return 0.00 def feed(self, byte_str): for c in byte_str: for coding_sm in self.coding_sm: if not coding_sm or not coding_sm.active: continue coding_state = coding_sm.next_state(c) if coding_state == MachineState.ERROR: coding_sm.active = False self.active_sm_count -= 1 if self.active_sm_count <= 0: self._state = ProbingState.NOT_ME return self.state elif coding_state == MachineState.ITS_ME: self._state = ProbingState.FOUND_IT self._detected_charset = coding_sm.get_coding_state_machine() self._detected_language = coding_sm.language return self.state return self.state PKH]1vv@python3.10/site-packages/pip/_vendor/chardet/langturkishmodel.pynu[# -*- coding: utf-8 -*- from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel # 3: Positive # 2: Likely # 1: Unlikely # 0: Negative TURKISH_LANG_MODEL = { 23: { # 'A' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 0, # 'c' 12: 2, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 1, # 'g' 25: 1, # 'h' 3: 1, # 'i' 24: 0, # 'j' 10: 2, # 'k' 5: 1, # 'l' 13: 1, # 'm' 4: 1, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 1, # 'r' 8: 1, # 's' 9: 1, # 't' 14: 1, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 3, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 0, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 37: { # 'B' 23: 0, # 'A' 37: 0, # 'B' 47: 2, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 2, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 1, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 1, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 0, # 'Z' 1: 2, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 0, # 'k' 5: 0, # 'l' 13: 1, # 'm' 4: 1, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 2, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 1, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 1, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 0, # 'ı' 40: 1, # 'Ş' 19: 1, # 'ş' }, 47: { # 'C' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 1, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 1, # 'L' 20: 0, # 'M' 46: 1, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 1, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 2, # 'j' 10: 1, # 'k' 5: 2, # 'l' 13: 2, # 'm' 4: 2, # 'n' 15: 1, # 'o' 26: 0, # 'p' 7: 2, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 1, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 1, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 39: { # 'D' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 1, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 1, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 2, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 2, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 0, # 'k' 5: 1, # 'l' 13: 3, # 'm' 4: 0, # 'n' 15: 1, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 1, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 1, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 0, # 'İ' 6: 1, # 'ı' 40: 1, # 'Ş' 19: 0, # 'ş' }, 29: { # 'E' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 1, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 0, # 'c' 12: 2, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 1, # 'g' 25: 0, # 'h' 3: 1, # 'i' 24: 1, # 'j' 10: 0, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 1, # 's' 9: 1, # 't' 14: 1, # 'u' 32: 1, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 2, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 52: { # 'F' 23: 0, # 'A' 37: 1, # 'B' 47: 1, # 'C' 39: 1, # 'D' 29: 1, # 'E' 52: 2, # 'F' 36: 0, # 'G' 45: 2, # 'H' 53: 1, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 1, # 'N' 42: 1, # 'O' 48: 2, # 'P' 44: 1, # 'R' 35: 1, # 'S' 31: 1, # 'T' 51: 1, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 2, # 'Y' 56: 0, # 'Z' 1: 0, # 'a' 21: 1, # 'b' 28: 1, # 'c' 12: 1, # 'd' 2: 0, # 'e' 18: 1, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 2, # 'i' 24: 1, # 'j' 10: 0, # 'k' 5: 0, # 'l' 13: 1, # 'm' 4: 2, # 'n' 15: 1, # 'o' 26: 0, # 'p' 7: 2, # 'r' 8: 1, # 's' 9: 1, # 't' 14: 1, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 1, # 'y' 22: 1, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 1, # 'Ö' 55: 2, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 2, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 1, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 2, # 'ş' }, 36: { # 'G' 23: 1, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 1, # 'F' 36: 2, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 2, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 2, # 'N' 42: 1, # 'O' 48: 1, # 'P' 44: 1, # 'R' 35: 1, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 2, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 1, # 'c' 12: 0, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 1, # 'j' 10: 1, # 'k' 5: 0, # 'l' 13: 3, # 'm' 4: 2, # 'n' 15: 0, # 'o' 26: 1, # 'p' 7: 0, # 'r' 8: 1, # 's' 9: 1, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 1, # 'x' 11: 0, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 2, # 'Ö' 55: 0, # 'Ü' 59: 1, # 'â' 33: 2, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 1, # 'İ' 6: 2, # 'ı' 40: 2, # 'Ş' 19: 1, # 'ş' }, 45: { # 'H' 23: 0, # 'A' 37: 1, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 2, # 'F' 36: 2, # 'G' 45: 1, # 'H' 53: 1, # 'I' 60: 0, # 'J' 16: 2, # 'K' 49: 1, # 'L' 20: 0, # 'M' 46: 1, # 'N' 42: 1, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 2, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 2, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 2, # 'i' 24: 0, # 'j' 10: 1, # 'k' 5: 0, # 'l' 13: 2, # 'm' 4: 0, # 'n' 15: 1, # 'o' 26: 1, # 'p' 7: 1, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 1, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 2, # 'ğ' 41: 1, # 'İ' 6: 0, # 'ı' 40: 2, # 'Ş' 19: 1, # 'ş' }, 53: { # 'I' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 1, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 2, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 2, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 2, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 0, # 'k' 5: 2, # 'l' 13: 2, # 'm' 4: 0, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 2, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 2, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 0, # 'ı' 40: 1, # 'Ş' 19: 1, # 'ş' }, 60: { # 'J' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 0, # 'a' 21: 1, # 'b' 28: 0, # 'c' 12: 1, # 'd' 2: 0, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 1, # 'i' 24: 0, # 'j' 10: 0, # 'k' 5: 0, # 'l' 13: 0, # 'm' 4: 1, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 1, # 's' 9: 0, # 't' 14: 0, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 0, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 16: { # 'K' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 3, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 2, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 2, # 'a' 21: 3, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 1, # 'e' 18: 3, # 'f' 27: 3, # 'g' 25: 3, # 'h' 3: 3, # 'i' 24: 2, # 'j' 10: 3, # 'k' 5: 0, # 'l' 13: 0, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 1, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 0, # 'u' 32: 3, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 2, # 'y' 22: 1, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 2, # 'ü' 30: 0, # 'ğ' 41: 1, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 49: { # 'L' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 2, # 'E' 52: 0, # 'F' 36: 1, # 'G' 45: 1, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 0, # 'N' 42: 2, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 0, # 'Z' 1: 0, # 'a' 21: 3, # 'b' 28: 0, # 'c' 12: 2, # 'd' 2: 0, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 2, # 'i' 24: 0, # 'j' 10: 1, # 'k' 5: 0, # 'l' 13: 0, # 'm' 4: 2, # 'n' 15: 1, # 'o' 26: 1, # 'p' 7: 1, # 'r' 8: 1, # 's' 9: 1, # 't' 14: 0, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 2, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 2, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 1, # 'ü' 30: 1, # 'ğ' 41: 0, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 20: { # 'M' 23: 1, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 1, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 1, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 2, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 1, # 'g' 25: 1, # 'h' 3: 2, # 'i' 24: 2, # 'j' 10: 2, # 'k' 5: 2, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 1, # 'p' 7: 3, # 'r' 8: 0, # 's' 9: 2, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 2, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 3, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 46: { # 'N' 23: 0, # 'A' 37: 1, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 1, # 'F' 36: 1, # 'G' 45: 1, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 2, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 1, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 1, # 'R' 35: 1, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 2, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 1, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 2, # 'j' 10: 1, # 'k' 5: 1, # 'l' 13: 3, # 'm' 4: 2, # 'n' 15: 1, # 'o' 26: 1, # 'p' 7: 1, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 1, # 'x' 11: 1, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 1, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 1, # 'İ' 6: 2, # 'ı' 40: 1, # 'Ş' 19: 1, # 'ş' }, 42: { # 'O' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 1, # 'F' 36: 0, # 'G' 45: 1, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 2, # 'K' 49: 1, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 2, # 'P' 44: 1, # 'R' 35: 1, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 2, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 0, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 0, # 'n' 15: 1, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 2, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 2, # 'Ç' 50: 1, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 2, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 2, # 'İ' 6: 1, # 'ı' 40: 1, # 'Ş' 19: 1, # 'ş' }, 48: { # 'P' 23: 0, # 'A' 37: 0, # 'B' 47: 2, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 2, # 'F' 36: 1, # 'G' 45: 1, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 2, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 1, # 'N' 42: 1, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 1, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 2, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 1, # 'k' 5: 0, # 'l' 13: 2, # 'm' 4: 0, # 'n' 15: 2, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 2, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 2, # 'x' 11: 0, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 2, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 2, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 1, # 'İ' 6: 0, # 'ı' 40: 2, # 'Ş' 19: 1, # 'ş' }, 44: { # 'R' 23: 0, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 1, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 1, # 'b' 28: 1, # 'c' 12: 0, # 'd' 2: 2, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 1, # 'k' 5: 2, # 'l' 13: 2, # 'm' 4: 0, # 'n' 15: 1, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 2, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 1, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 1, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 1, # 'ü' 30: 1, # 'ğ' 41: 0, # 'İ' 6: 2, # 'ı' 40: 1, # 'Ş' 19: 1, # 'ş' }, 35: { # 'S' 23: 0, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 1, # 'F' 36: 1, # 'G' 45: 1, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 1, # 'L' 20: 1, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 1, # 'k' 5: 1, # 'l' 13: 2, # 'm' 4: 1, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 1, # 't' 14: 2, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 1, # 'z' 63: 0, # '·' 54: 2, # 'Ç' 50: 2, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 3, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 2, # 'Ş' 19: 1, # 'ş' }, 31: { # 'T' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 1, # 'J' 16: 2, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 2, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 2, # 'b' 28: 0, # 'c' 12: 1, # 'd' 2: 3, # 'e' 18: 2, # 'f' 27: 2, # 'g' 25: 0, # 'h' 3: 1, # 'i' 24: 1, # 'j' 10: 2, # 'k' 5: 2, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 2, # 'p' 7: 2, # 'r' 8: 0, # 's' 9: 2, # 't' 14: 2, # 'u' 32: 1, # 'v' 57: 1, # 'w' 58: 1, # 'x' 11: 2, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 1, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 51: { # 'U' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 1, # 'F' 36: 1, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 1, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 1, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 1, # 'c' 12: 0, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 2, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 1, # 'k' 5: 1, # 'l' 13: 3, # 'm' 4: 2, # 'n' 15: 0, # 'o' 26: 1, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 2, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 1, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 1, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 1, # 'ş' }, 38: { # 'V' 23: 1, # 'A' 37: 1, # 'B' 47: 1, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 2, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 3, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 1, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 0, # 'k' 5: 2, # 'l' 13: 2, # 'm' 4: 0, # 'n' 15: 2, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 1, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 1, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 1, # 'Ö' 55: 0, # 'Ü' 59: 1, # 'â' 33: 2, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 1, # 'İ' 6: 3, # 'ı' 40: 2, # 'Ş' 19: 1, # 'ş' }, 62: { # 'W' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 0, # 'a' 21: 0, # 'b' 28: 0, # 'c' 12: 0, # 'd' 2: 0, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 0, # 'k' 5: 0, # 'l' 13: 0, # 'm' 4: 0, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 0, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 0, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 43: { # 'Y' 23: 0, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 2, # 'F' 36: 0, # 'G' 45: 1, # 'H' 53: 1, # 'I' 60: 0, # 'J' 16: 2, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 2, # 'N' 42: 0, # 'O' 48: 2, # 'P' 44: 1, # 'R' 35: 1, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 2, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 2, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 1, # 'j' 10: 1, # 'k' 5: 1, # 'l' 13: 3, # 'm' 4: 0, # 'n' 15: 2, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 1, # 'x' 11: 0, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 2, # 'Ö' 55: 1, # 'Ü' 59: 1, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 1, # 'İ' 6: 0, # 'ı' 40: 2, # 'Ş' 19: 1, # 'ş' }, 56: { # 'Z' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 2, # 'Z' 1: 2, # 'a' 21: 1, # 'b' 28: 0, # 'c' 12: 0, # 'd' 2: 2, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 2, # 'i' 24: 1, # 'j' 10: 0, # 'k' 5: 0, # 'l' 13: 1, # 'm' 4: 1, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 1, # 'r' 8: 1, # 's' 9: 0, # 't' 14: 2, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 1, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 1, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 1: { # 'a' 23: 3, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 0, # 'D' 29: 3, # 'E' 52: 0, # 'F' 36: 1, # 'G' 45: 1, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 3, # 'M' 46: 1, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 3, # 'T' 51: 0, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 2, # 'Z' 1: 2, # 'a' 21: 3, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 2, # 'e' 18: 3, # 'f' 27: 3, # 'g' 25: 3, # 'h' 3: 3, # 'i' 24: 3, # 'j' 10: 3, # 'k' 5: 0, # 'l' 13: 2, # 'm' 4: 3, # 'n' 15: 1, # 'o' 26: 3, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 3, # 'u' 32: 3, # 'v' 57: 2, # 'w' 58: 0, # 'x' 11: 3, # 'y' 22: 0, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 1, # 'î' 34: 1, # 'ö' 17: 3, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 1, # 'ş' }, 21: { # 'b' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 1, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 1, # 'J' 16: 2, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 1, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 2, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 3, # 'g' 25: 1, # 'h' 3: 3, # 'i' 24: 2, # 'j' 10: 3, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 3, # 'p' 7: 1, # 'r' 8: 2, # 's' 9: 2, # 't' 14: 2, # 'u' 32: 1, # 'v' 57: 0, # 'w' 58: 1, # 'x' 11: 3, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 0, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 28: { # 'c' 23: 0, # 'A' 37: 1, # 'B' 47: 1, # 'C' 39: 1, # 'D' 29: 2, # 'E' 52: 0, # 'F' 36: 2, # 'G' 45: 2, # 'H' 53: 1, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 1, # 'N' 42: 1, # 'O' 48: 2, # 'P' 44: 1, # 'R' 35: 1, # 'S' 31: 2, # 'T' 51: 2, # 'U' 38: 2, # 'V' 62: 0, # 'W' 43: 3, # 'Y' 56: 0, # 'Z' 1: 1, # 'a' 21: 1, # 'b' 28: 2, # 'c' 12: 2, # 'd' 2: 1, # 'e' 18: 1, # 'f' 27: 2, # 'g' 25: 2, # 'h' 3: 3, # 'i' 24: 1, # 'j' 10: 3, # 'k' 5: 0, # 'l' 13: 2, # 'm' 4: 3, # 'n' 15: 2, # 'o' 26: 2, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 1, # 'u' 32: 0, # 'v' 57: 1, # 'w' 58: 0, # 'x' 11: 2, # 'y' 22: 1, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 1, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 1, # 'î' 34: 2, # 'ö' 17: 2, # 'ü' 30: 2, # 'ğ' 41: 1, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 2, # 'ş' }, 12: { # 'd' 23: 1, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 2, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 3, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 1, # 'S' 31: 1, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 2, # 'b' 28: 1, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 1, # 'f' 27: 3, # 'g' 25: 3, # 'h' 3: 2, # 'i' 24: 3, # 'j' 10: 2, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 1, # 'o' 26: 2, # 'p' 7: 3, # 'r' 8: 2, # 's' 9: 2, # 't' 14: 3, # 'u' 32: 1, # 'v' 57: 0, # 'w' 58: 1, # 'x' 11: 3, # 'y' 22: 1, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 1, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 2: { # 'e' 23: 2, # 'A' 37: 0, # 'B' 47: 2, # 'C' 39: 0, # 'D' 29: 3, # 'E' 52: 1, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 1, # 'K' 49: 0, # 'L' 20: 3, # 'M' 46: 1, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 1, # 'R' 35: 0, # 'S' 31: 3, # 'T' 51: 0, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 3, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 2, # 'e' 18: 3, # 'f' 27: 3, # 'g' 25: 3, # 'h' 3: 3, # 'i' 24: 3, # 'j' 10: 3, # 'k' 5: 0, # 'l' 13: 2, # 'm' 4: 3, # 'n' 15: 1, # 'o' 26: 3, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 3, # 'u' 32: 3, # 'v' 57: 2, # 'w' 58: 0, # 'x' 11: 3, # 'y' 22: 1, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 3, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 18: { # 'f' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 2, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 2, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 1, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 2, # 'f' 27: 1, # 'g' 25: 1, # 'h' 3: 1, # 'i' 24: 1, # 'j' 10: 1, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 2, # 'p' 7: 1, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 1, # 'u' 32: 2, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 1, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 1, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 1, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 27: { # 'g' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 1, # 'S' 31: 1, # 'T' 51: 0, # 'U' 38: 2, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 1, # 'b' 28: 0, # 'c' 12: 1, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 2, # 'g' 25: 1, # 'h' 3: 2, # 'i' 24: 3, # 'j' 10: 2, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 2, # 'n' 15: 0, # 'o' 26: 1, # 'p' 7: 2, # 'r' 8: 2, # 's' 9: 3, # 't' 14: 3, # 'u' 32: 1, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 1, # 'y' 22: 0, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 25: { # 'h' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 2, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 0, # 'c' 12: 2, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 1, # 'g' 25: 2, # 'h' 3: 2, # 'i' 24: 3, # 'j' 10: 3, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 1, # 'o' 26: 1, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 2, # 't' 14: 3, # 'u' 32: 2, # 'v' 57: 1, # 'w' 58: 0, # 'x' 11: 1, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 3: { # 'i' 23: 2, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 1, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 3, # 'M' 46: 0, # 'N' 42: 1, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 1, # 'S' 31: 2, # 'T' 51: 0, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 2, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 2, # 'f' 27: 3, # 'g' 25: 1, # 'h' 3: 3, # 'i' 24: 2, # 'j' 10: 3, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 1, # 'o' 26: 3, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 3, # 'u' 32: 2, # 'v' 57: 1, # 'w' 58: 1, # 'x' 11: 3, # 'y' 22: 1, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 1, # 'Ü' 59: 0, # 'â' 33: 2, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 3, # 'ü' 30: 0, # 'ğ' 41: 1, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 24: { # 'j' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 1, # 'J' 16: 2, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 1, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 1, # 'Z' 1: 3, # 'a' 21: 1, # 'b' 28: 1, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 2, # 'f' 27: 1, # 'g' 25: 1, # 'h' 3: 2, # 'i' 24: 1, # 'j' 10: 2, # 'k' 5: 2, # 'l' 13: 3, # 'm' 4: 2, # 'n' 15: 0, # 'o' 26: 1, # 'p' 7: 2, # 'r' 8: 3, # 's' 9: 2, # 't' 14: 3, # 'u' 32: 2, # 'v' 57: 0, # 'w' 58: 2, # 'x' 11: 1, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 1, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 10: { # 'k' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 3, # 'T' 51: 0, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 1, # 'Z' 1: 3, # 'a' 21: 2, # 'b' 28: 0, # 'c' 12: 2, # 'd' 2: 3, # 'e' 18: 1, # 'f' 27: 2, # 'g' 25: 2, # 'h' 3: 3, # 'i' 24: 2, # 'j' 10: 2, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 3, # 'p' 7: 2, # 'r' 8: 2, # 's' 9: 2, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 1, # 'x' 11: 3, # 'y' 22: 0, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 3, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 3, # 'ü' 30: 1, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 1, # 'ş' }, 5: { # 'l' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 3, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 1, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 0, # 'a' 21: 3, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 1, # 'e' 18: 3, # 'f' 27: 3, # 'g' 25: 2, # 'h' 3: 3, # 'i' 24: 2, # 'j' 10: 3, # 'k' 5: 1, # 'l' 13: 1, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 2, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 2, # 'u' 32: 2, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 3, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 2, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 13: { # 'm' 23: 1, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 3, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 3, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 3, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 0, # 'Z' 1: 2, # 'a' 21: 3, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 2, # 'e' 18: 3, # 'f' 27: 3, # 'g' 25: 3, # 'h' 3: 3, # 'i' 24: 3, # 'j' 10: 3, # 'k' 5: 0, # 'l' 13: 2, # 'm' 4: 3, # 'n' 15: 1, # 'o' 26: 2, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 2, # 'u' 32: 2, # 'v' 57: 1, # 'w' 58: 0, # 'x' 11: 3, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 3, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 1, # 'ş' }, 4: { # 'n' 23: 1, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 1, # 'H' 53: 0, # 'I' 60: 2, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 3, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 2, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 2, # 'b' 28: 1, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 1, # 'f' 27: 2, # 'g' 25: 3, # 'h' 3: 2, # 'i' 24: 2, # 'j' 10: 3, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 1, # 'o' 26: 3, # 'p' 7: 2, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 3, # 'u' 32: 2, # 'v' 57: 0, # 'w' 58: 2, # 'x' 11: 3, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 2, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 1, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 15: { # 'o' 23: 0, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 2, # 'F' 36: 1, # 'G' 45: 1, # 'H' 53: 1, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 2, # 'L' 20: 0, # 'M' 46: 2, # 'N' 42: 1, # 'O' 48: 2, # 'P' 44: 1, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 1, # 'i' 24: 2, # 'j' 10: 1, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 2, # 'n' 15: 2, # 'o' 26: 0, # 'p' 7: 1, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 2, # 'x' 11: 0, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 2, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 3, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 2, # 'ğ' 41: 2, # 'İ' 6: 3, # 'ı' 40: 2, # 'Ş' 19: 2, # 'ş' }, 26: { # 'p' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 1, # 'b' 28: 0, # 'c' 12: 1, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 1, # 'g' 25: 1, # 'h' 3: 2, # 'i' 24: 3, # 'j' 10: 1, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 2, # 'n' 15: 0, # 'o' 26: 2, # 'p' 7: 2, # 'r' 8: 1, # 's' 9: 1, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 1, # 'x' 11: 1, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 3, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 1, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 7: { # 'r' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 1, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 2, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 2, # 'T' 51: 1, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 1, # 'Z' 1: 3, # 'a' 21: 1, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 2, # 'g' 25: 3, # 'h' 3: 2, # 'i' 24: 2, # 'j' 10: 3, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 2, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 3, # 'u' 32: 2, # 'v' 57: 0, # 'w' 58: 1, # 'x' 11: 2, # 'y' 22: 0, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 2, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 3, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 8: { # 's' 23: 1, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 1, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 3, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 2, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 1, # 'Z' 1: 3, # 'a' 21: 2, # 'b' 28: 1, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 2, # 'g' 25: 2, # 'h' 3: 2, # 'i' 24: 3, # 'j' 10: 3, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 3, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 3, # 'u' 32: 2, # 'v' 57: 0, # 'w' 58: 1, # 'x' 11: 2, # 'y' 22: 1, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 2, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 2, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 1, # 'ş' }, 9: { # 't' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 1, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 2, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 1, # 'Z' 1: 3, # 'a' 21: 3, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 2, # 'f' 27: 2, # 'g' 25: 2, # 'h' 3: 2, # 'i' 24: 2, # 'j' 10: 3, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 2, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 3, # 'u' 32: 3, # 'v' 57: 0, # 'w' 58: 2, # 'x' 11: 2, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 3, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 2, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 14: { # 'u' 23: 3, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 3, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 1, # 'H' 53: 0, # 'I' 60: 1, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 3, # 'M' 46: 2, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 3, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 2, # 'Z' 1: 2, # 'a' 21: 3, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 2, # 'e' 18: 2, # 'f' 27: 3, # 'g' 25: 3, # 'h' 3: 3, # 'i' 24: 2, # 'j' 10: 3, # 'k' 5: 0, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 3, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 3, # 'u' 32: 2, # 'v' 57: 2, # 'w' 58: 0, # 'x' 11: 3, # 'y' 22: 0, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 3, # 'ü' 30: 1, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 32: { # 'v' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 0, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 1, # 'j' 10: 1, # 'k' 5: 3, # 'l' 13: 2, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 1, # 'p' 7: 1, # 'r' 8: 2, # 's' 9: 3, # 't' 14: 3, # 'u' 32: 1, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 2, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 1, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 57: { # 'w' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 1, # 'a' 21: 0, # 'b' 28: 0, # 'c' 12: 0, # 'd' 2: 2, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 1, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 1, # 'k' 5: 0, # 'l' 13: 0, # 'm' 4: 1, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 1, # 's' 9: 0, # 't' 14: 1, # 'u' 32: 0, # 'v' 57: 2, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 0, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 1, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 0, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 58: { # 'x' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 1, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 1, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 0, # 'a' 21: 1, # 'b' 28: 0, # 'c' 12: 2, # 'd' 2: 1, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 2, # 'i' 24: 2, # 'j' 10: 1, # 'k' 5: 0, # 'l' 13: 0, # 'm' 4: 2, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 1, # 'r' 8: 2, # 's' 9: 1, # 't' 14: 0, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 2, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 1, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 11: { # 'y' 23: 1, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 1, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 1, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 1, # 'Z' 1: 3, # 'a' 21: 1, # 'b' 28: 0, # 'c' 12: 2, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 2, # 'g' 25: 2, # 'h' 3: 2, # 'i' 24: 1, # 'j' 10: 2, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 1, # 'p' 7: 2, # 'r' 8: 1, # 's' 9: 2, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 1, # 'x' 11: 3, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 3, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 2, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 22: { # 'z' 23: 2, # 'A' 37: 2, # 'B' 47: 1, # 'C' 39: 2, # 'D' 29: 3, # 'E' 52: 1, # 'F' 36: 2, # 'G' 45: 2, # 'H' 53: 1, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 3, # 'M' 46: 2, # 'N' 42: 2, # 'O' 48: 2, # 'P' 44: 1, # 'R' 35: 1, # 'S' 31: 3, # 'T' 51: 2, # 'U' 38: 2, # 'V' 62: 0, # 'W' 43: 2, # 'Y' 56: 1, # 'Z' 1: 1, # 'a' 21: 2, # 'b' 28: 1, # 'c' 12: 2, # 'd' 2: 2, # 'e' 18: 3, # 'f' 27: 2, # 'g' 25: 2, # 'h' 3: 3, # 'i' 24: 2, # 'j' 10: 3, # 'k' 5: 0, # 'l' 13: 2, # 'm' 4: 3, # 'n' 15: 2, # 'o' 26: 2, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 0, # 'u' 32: 2, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 3, # 'y' 22: 2, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 2, # 'Ü' 59: 1, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 2, # 'ö' 17: 2, # 'ü' 30: 2, # 'ğ' 41: 1, # 'İ' 6: 3, # 'ı' 40: 1, # 'Ş' 19: 2, # 'ş' }, 63: { # '·' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 0, # 'a' 21: 0, # 'b' 28: 0, # 'c' 12: 0, # 'd' 2: 1, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 0, # 'k' 5: 0, # 'l' 13: 2, # 'm' 4: 0, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 2, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 0, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 54: { # 'Ç' 23: 0, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 1, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 1, # 'G' 45: 1, # 'H' 53: 1, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 1, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 2, # 'Y' 56: 0, # 'Z' 1: 0, # 'a' 21: 1, # 'b' 28: 0, # 'c' 12: 1, # 'd' 2: 0, # 'e' 18: 0, # 'f' 27: 1, # 'g' 25: 0, # 'h' 3: 3, # 'i' 24: 0, # 'j' 10: 1, # 'k' 5: 0, # 'l' 13: 0, # 'm' 4: 2, # 'n' 15: 1, # 'o' 26: 0, # 'p' 7: 2, # 'r' 8: 0, # 's' 9: 1, # 't' 14: 0, # 'u' 32: 2, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 2, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 1, # 'ş' }, 50: { # 'Ö' 23: 0, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 1, # 'D' 29: 2, # 'E' 52: 0, # 'F' 36: 1, # 'G' 45: 2, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 1, # 'N' 42: 2, # 'O' 48: 2, # 'P' 44: 1, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 2, # 'Y' 56: 0, # 'Z' 1: 0, # 'a' 21: 2, # 'b' 28: 1, # 'c' 12: 2, # 'd' 2: 0, # 'e' 18: 1, # 'f' 27: 1, # 'g' 25: 1, # 'h' 3: 2, # 'i' 24: 0, # 'j' 10: 2, # 'k' 5: 0, # 'l' 13: 0, # 'm' 4: 3, # 'n' 15: 2, # 'o' 26: 2, # 'p' 7: 3, # 'r' 8: 1, # 's' 9: 2, # 't' 14: 0, # 'u' 32: 1, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 1, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 2, # 'ö' 17: 2, # 'ü' 30: 1, # 'ğ' 41: 0, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 1, # 'ş' }, 55: { # 'Ü' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 2, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 1, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 1, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 2, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 2, # 'e' 18: 0, # 'f' 27: 1, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 0, # 'k' 5: 1, # 'l' 13: 1, # 'm' 4: 1, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 1, # 't' 14: 2, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 1, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 1, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 1, # 'İ' 6: 0, # 'ı' 40: 0, # 'Ş' 19: 1, # 'ş' }, 59: { # 'â' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 1, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 1, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 2, # 'a' 21: 0, # 'b' 28: 0, # 'c' 12: 0, # 'd' 2: 2, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 0, # 'j' 10: 0, # 'k' 5: 0, # 'l' 13: 2, # 'm' 4: 0, # 'n' 15: 1, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 2, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 1, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 1, # 'ı' 40: 1, # 'Ş' 19: 0, # 'ş' }, 33: { # 'ç' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 3, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 2, # 'T' 51: 0, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 0, # 'Z' 1: 0, # 'a' 21: 3, # 'b' 28: 0, # 'c' 12: 2, # 'd' 2: 0, # 'e' 18: 2, # 'f' 27: 1, # 'g' 25: 3, # 'h' 3: 3, # 'i' 24: 0, # 'j' 10: 3, # 'k' 5: 0, # 'l' 13: 0, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 1, # 'p' 7: 3, # 'r' 8: 2, # 's' 9: 3, # 't' 14: 0, # 'u' 32: 2, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 2, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 1, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 61: { # 'î' 23: 0, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 0, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 0, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 1, # 'Z' 1: 2, # 'a' 21: 0, # 'b' 28: 0, # 'c' 12: 0, # 'd' 2: 2, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 1, # 'j' 10: 0, # 'k' 5: 0, # 'l' 13: 1, # 'm' 4: 1, # 'n' 15: 0, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 1, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 1, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 1, # 'î' 34: 0, # 'ö' 17: 0, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 1, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 34: { # 'ö' 23: 0, # 'A' 37: 1, # 'B' 47: 1, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 2, # 'F' 36: 1, # 'G' 45: 1, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 1, # 'L' 20: 0, # 'M' 46: 1, # 'N' 42: 1, # 'O' 48: 2, # 'P' 44: 1, # 'R' 35: 1, # 'S' 31: 1, # 'T' 51: 1, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 1, # 'Z' 1: 3, # 'a' 21: 1, # 'b' 28: 2, # 'c' 12: 1, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 2, # 'g' 25: 2, # 'h' 3: 1, # 'i' 24: 2, # 'j' 10: 1, # 'k' 5: 2, # 'l' 13: 3, # 'm' 4: 2, # 'n' 15: 2, # 'o' 26: 0, # 'p' 7: 0, # 'r' 8: 3, # 's' 9: 1, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 1, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 2, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 2, # 'ç' 61: 0, # 'î' 34: 2, # 'ö' 17: 0, # 'ü' 30: 2, # 'ğ' 41: 1, # 'İ' 6: 1, # 'ı' 40: 2, # 'Ş' 19: 1, # 'ş' }, 17: { # 'ü' 23: 0, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 0, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 1, # 'J' 16: 1, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 0, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 1, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 0, # 'Y' 56: 1, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 0, # 'c' 12: 1, # 'd' 2: 3, # 'e' 18: 1, # 'f' 27: 2, # 'g' 25: 0, # 'h' 3: 1, # 'i' 24: 1, # 'j' 10: 2, # 'k' 5: 3, # 'l' 13: 2, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 2, # 'p' 7: 2, # 'r' 8: 3, # 's' 9: 2, # 't' 14: 3, # 'u' 32: 1, # 'v' 57: 1, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 2, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 2, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 30: { # 'ğ' 23: 0, # 'A' 37: 2, # 'B' 47: 1, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 2, # 'F' 36: 1, # 'G' 45: 0, # 'H' 53: 1, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 1, # 'M' 46: 2, # 'N' 42: 2, # 'O' 48: 1, # 'P' 44: 1, # 'R' 35: 0, # 'S' 31: 1, # 'T' 51: 0, # 'U' 38: 2, # 'V' 62: 0, # 'W' 43: 2, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 0, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 2, # 'e' 18: 0, # 'f' 27: 0, # 'g' 25: 0, # 'h' 3: 0, # 'i' 24: 3, # 'j' 10: 1, # 'k' 5: 2, # 'l' 13: 3, # 'm' 4: 0, # 'n' 15: 1, # 'o' 26: 0, # 'p' 7: 1, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 2, # 'Ç' 50: 2, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 0, # 'î' 34: 2, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 2, # 'İ' 6: 2, # 'ı' 40: 2, # 'Ş' 19: 1, # 'ş' }, 41: { # 'İ' 23: 0, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 1, # 'D' 29: 1, # 'E' 52: 0, # 'F' 36: 2, # 'G' 45: 2, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 1, # 'N' 42: 1, # 'O' 48: 2, # 'P' 44: 0, # 'R' 35: 1, # 'S' 31: 1, # 'T' 51: 1, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 2, # 'Y' 56: 0, # 'Z' 1: 1, # 'a' 21: 2, # 'b' 28: 1, # 'c' 12: 2, # 'd' 2: 1, # 'e' 18: 0, # 'f' 27: 3, # 'g' 25: 2, # 'h' 3: 2, # 'i' 24: 2, # 'j' 10: 2, # 'k' 5: 0, # 'l' 13: 1, # 'm' 4: 3, # 'n' 15: 1, # 'o' 26: 1, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 2, # 't' 14: 0, # 'u' 32: 0, # 'v' 57: 1, # 'w' 58: 0, # 'x' 11: 2, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 1, # 'Ü' 59: 1, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 1, # 'ö' 17: 1, # 'ü' 30: 2, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 1, # 'ş' }, 6: { # 'ı' 23: 2, # 'A' 37: 0, # 'B' 47: 0, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 0, # 'F' 36: 1, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 2, # 'J' 16: 3, # 'K' 49: 0, # 'L' 20: 3, # 'M' 46: 1, # 'N' 42: 0, # 'O' 48: 0, # 'P' 44: 0, # 'R' 35: 0, # 'S' 31: 2, # 'T' 51: 0, # 'U' 38: 0, # 'V' 62: 0, # 'W' 43: 2, # 'Y' 56: 1, # 'Z' 1: 3, # 'a' 21: 2, # 'b' 28: 1, # 'c' 12: 3, # 'd' 2: 3, # 'e' 18: 3, # 'f' 27: 3, # 'g' 25: 2, # 'h' 3: 3, # 'i' 24: 3, # 'j' 10: 3, # 'k' 5: 3, # 'l' 13: 3, # 'm' 4: 3, # 'n' 15: 0, # 'o' 26: 3, # 'p' 7: 3, # 'r' 8: 3, # 's' 9: 3, # 't' 14: 3, # 'u' 32: 3, # 'v' 57: 1, # 'w' 58: 1, # 'x' 11: 3, # 'y' 22: 0, # 'z' 63: 1, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 2, # 'ç' 61: 0, # 'î' 34: 0, # 'ö' 17: 3, # 'ü' 30: 0, # 'ğ' 41: 0, # 'İ' 6: 3, # 'ı' 40: 0, # 'Ş' 19: 0, # 'ş' }, 40: { # 'Ş' 23: 0, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 1, # 'D' 29: 1, # 'E' 52: 0, # 'F' 36: 1, # 'G' 45: 2, # 'H' 53: 1, # 'I' 60: 0, # 'J' 16: 0, # 'K' 49: 0, # 'L' 20: 2, # 'M' 46: 1, # 'N' 42: 1, # 'O' 48: 2, # 'P' 44: 2, # 'R' 35: 1, # 'S' 31: 1, # 'T' 51: 0, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 2, # 'Y' 56: 1, # 'Z' 1: 0, # 'a' 21: 2, # 'b' 28: 0, # 'c' 12: 2, # 'd' 2: 0, # 'e' 18: 3, # 'f' 27: 0, # 'g' 25: 2, # 'h' 3: 3, # 'i' 24: 2, # 'j' 10: 1, # 'k' 5: 0, # 'l' 13: 1, # 'm' 4: 3, # 'n' 15: 2, # 'o' 26: 0, # 'p' 7: 3, # 'r' 8: 2, # 's' 9: 2, # 't' 14: 1, # 'u' 32: 3, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 2, # 'y' 22: 0, # 'z' 63: 0, # '·' 54: 0, # 'Ç' 50: 0, # 'Ö' 55: 1, # 'Ü' 59: 0, # 'â' 33: 0, # 'ç' 61: 0, # 'î' 34: 2, # 'ö' 17: 1, # 'ü' 30: 2, # 'ğ' 41: 0, # 'İ' 6: 2, # 'ı' 40: 1, # 'Ş' 19: 2, # 'ş' }, 19: { # 'ş' 23: 0, # 'A' 37: 0, # 'B' 47: 1, # 'C' 39: 0, # 'D' 29: 0, # 'E' 52: 2, # 'F' 36: 1, # 'G' 45: 0, # 'H' 53: 0, # 'I' 60: 0, # 'J' 16: 3, # 'K' 49: 2, # 'L' 20: 0, # 'M' 46: 1, # 'N' 42: 1, # 'O' 48: 1, # 'P' 44: 1, # 'R' 35: 1, # 'S' 31: 0, # 'T' 51: 1, # 'U' 38: 1, # 'V' 62: 0, # 'W' 43: 1, # 'Y' 56: 0, # 'Z' 1: 3, # 'a' 21: 1, # 'b' 28: 2, # 'c' 12: 0, # 'd' 2: 3, # 'e' 18: 0, # 'f' 27: 2, # 'g' 25: 1, # 'h' 3: 1, # 'i' 24: 0, # 'j' 10: 2, # 'k' 5: 2, # 'l' 13: 3, # 'm' 4: 0, # 'n' 15: 0, # 'o' 26: 1, # 'p' 7: 3, # 'r' 8: 0, # 's' 9: 0, # 't' 14: 3, # 'u' 32: 0, # 'v' 57: 0, # 'w' 58: 0, # 'x' 11: 0, # 'y' 22: 2, # 'z' 63: 0, # '·' 54: 1, # 'Ç' 50: 2, # 'Ö' 55: 0, # 'Ü' 59: 0, # 'â' 33: 1, # 'ç' 61: 1, # 'î' 34: 2, # 'ö' 17: 0, # 'ü' 30: 1, # 'ğ' 41: 1, # 'İ' 6: 1, # 'ı' 40: 1, # 'Ş' 19: 1, # 'ş' }, } # 255: Undefined characters that did not exist in training text # 254: Carriage/Return # 253: symbol (punctuation) that does not belong to word # 252: 0 - 9 # 251: Control characters # Character Mapping Table(s): ISO_8859_9_TURKISH_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 255, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 255, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 255, # ' ' 33: 255, # '!' 34: 255, # '"' 35: 255, # '#' 36: 255, # '$' 37: 255, # '%' 38: 255, # '&' 39: 255, # "'" 40: 255, # '(' 41: 255, # ')' 42: 255, # '*' 43: 255, # '+' 44: 255, # ',' 45: 255, # '-' 46: 255, # '.' 47: 255, # '/' 48: 255, # '0' 49: 255, # '1' 50: 255, # '2' 51: 255, # '3' 52: 255, # '4' 53: 255, # '5' 54: 255, # '6' 55: 255, # '7' 56: 255, # '8' 57: 255, # '9' 58: 255, # ':' 59: 255, # ';' 60: 255, # '<' 61: 255, # '=' 62: 255, # '>' 63: 255, # '?' 64: 255, # '@' 65: 23, # 'A' 66: 37, # 'B' 67: 47, # 'C' 68: 39, # 'D' 69: 29, # 'E' 70: 52, # 'F' 71: 36, # 'G' 72: 45, # 'H' 73: 53, # 'I' 74: 60, # 'J' 75: 16, # 'K' 76: 49, # 'L' 77: 20, # 'M' 78: 46, # 'N' 79: 42, # 'O' 80: 48, # 'P' 81: 69, # 'Q' 82: 44, # 'R' 83: 35, # 'S' 84: 31, # 'T' 85: 51, # 'U' 86: 38, # 'V' 87: 62, # 'W' 88: 65, # 'X' 89: 43, # 'Y' 90: 56, # 'Z' 91: 255, # '[' 92: 255, # '\\' 93: 255, # ']' 94: 255, # '^' 95: 255, # '_' 96: 255, # '`' 97: 1, # 'a' 98: 21, # 'b' 99: 28, # 'c' 100: 12, # 'd' 101: 2, # 'e' 102: 18, # 'f' 103: 27, # 'g' 104: 25, # 'h' 105: 3, # 'i' 106: 24, # 'j' 107: 10, # 'k' 108: 5, # 'l' 109: 13, # 'm' 110: 4, # 'n' 111: 15, # 'o' 112: 26, # 'p' 113: 64, # 'q' 114: 7, # 'r' 115: 8, # 's' 116: 9, # 't' 117: 14, # 'u' 118: 32, # 'v' 119: 57, # 'w' 120: 58, # 'x' 121: 11, # 'y' 122: 22, # 'z' 123: 255, # '{' 124: 255, # '|' 125: 255, # '}' 126: 255, # '~' 127: 255, # '\x7f' 128: 180, # '\x80' 129: 179, # '\x81' 130: 178, # '\x82' 131: 177, # '\x83' 132: 176, # '\x84' 133: 175, # '\x85' 134: 174, # '\x86' 135: 173, # '\x87' 136: 172, # '\x88' 137: 171, # '\x89' 138: 170, # '\x8a' 139: 169, # '\x8b' 140: 168, # '\x8c' 141: 167, # '\x8d' 142: 166, # '\x8e' 143: 165, # '\x8f' 144: 164, # '\x90' 145: 163, # '\x91' 146: 162, # '\x92' 147: 161, # '\x93' 148: 160, # '\x94' 149: 159, # '\x95' 150: 101, # '\x96' 151: 158, # '\x97' 152: 157, # '\x98' 153: 156, # '\x99' 154: 155, # '\x9a' 155: 154, # '\x9b' 156: 153, # '\x9c' 157: 152, # '\x9d' 158: 151, # '\x9e' 159: 106, # '\x9f' 160: 150, # '\xa0' 161: 149, # '¡' 162: 148, # '¢' 163: 147, # '£' 164: 146, # '¤' 165: 145, # '¥' 166: 144, # '¦' 167: 100, # '§' 168: 143, # '¨' 169: 142, # '©' 170: 141, # 'ª' 171: 140, # '«' 172: 139, # '¬' 173: 138, # '\xad' 174: 137, # '®' 175: 136, # '¯' 176: 94, # '°' 177: 80, # '±' 178: 93, # '²' 179: 135, # '³' 180: 105, # '´' 181: 134, # 'µ' 182: 133, # '¶' 183: 63, # '·' 184: 132, # '¸' 185: 131, # '¹' 186: 130, # 'º' 187: 129, # '»' 188: 128, # '¼' 189: 127, # '½' 190: 126, # '¾' 191: 125, # '¿' 192: 124, # 'À' 193: 104, # 'Á' 194: 73, # 'Â' 195: 99, # 'Ã' 196: 79, # 'Ä' 197: 85, # 'Å' 198: 123, # 'Æ' 199: 54, # 'Ç' 200: 122, # 'È' 201: 98, # 'É' 202: 92, # 'Ê' 203: 121, # 'Ë' 204: 120, # 'Ì' 205: 91, # 'Í' 206: 103, # 'Î' 207: 119, # 'Ï' 208: 68, # 'Ğ' 209: 118, # 'Ñ' 210: 117, # 'Ò' 211: 97, # 'Ó' 212: 116, # 'Ô' 213: 115, # 'Õ' 214: 50, # 'Ö' 215: 90, # '×' 216: 114, # 'Ø' 217: 113, # 'Ù' 218: 112, # 'Ú' 219: 111, # 'Û' 220: 55, # 'Ü' 221: 41, # 'İ' 222: 40, # 'Ş' 223: 86, # 'ß' 224: 89, # 'à' 225: 70, # 'á' 226: 59, # 'â' 227: 78, # 'ã' 228: 71, # 'ä' 229: 82, # 'å' 230: 88, # 'æ' 231: 33, # 'ç' 232: 77, # 'è' 233: 66, # 'é' 234: 84, # 'ê' 235: 83, # 'ë' 236: 110, # 'ì' 237: 75, # 'í' 238: 61, # 'î' 239: 96, # 'ï' 240: 30, # 'ğ' 241: 67, # 'ñ' 242: 109, # 'ò' 243: 74, # 'ó' 244: 87, # 'ô' 245: 102, # 'õ' 246: 34, # 'ö' 247: 95, # '÷' 248: 81, # 'ø' 249: 108, # 'ù' 250: 76, # 'ú' 251: 72, # 'û' 252: 17, # 'ü' 253: 6, # 'ı' 254: 19, # 'ş' 255: 107, # 'ÿ' } ISO_8859_9_TURKISH_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-9', language='Turkish', char_to_order_map=ISO_8859_9_TURKISH_CHAR_TO_ORDER, language_model=TURKISH_LANG_MODEL, typical_positive_ratio=0.97029, keep_ascii_letters=True, alphabet='ABCDEFGHIJKLMNOPRSTUVYZabcdefghijklmnoprstuvyzÂÇÎÖÛÜâçîöûüĞğİıŞş') PKH]<python3.10/site-packages/pip/_vendor/chardet/latin1prober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Universal charset detector code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 2001 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # Shy Shalom - original C code # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .charsetprober import CharSetProber from .enums import ProbingState FREQ_CAT_NUM = 4 UDF = 0 # undefined OTH = 1 # other ASC = 2 # ascii capital letter ASS = 3 # ascii small letter ACV = 4 # accent capital vowel ACO = 5 # accent capital other ASV = 6 # accent small vowel ASO = 7 # accent small other CLASS_NUM = 8 # total classes Latin1_CharToClass = ( OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF ) # 0 : illegal # 1 : very unlikely # 2 : normal # 3 : very likely Latin1ClassModel = ( # UDF OTH ASC ASS ACV ACO ASV ASO 0, 0, 0, 0, 0, 0, 0, 0, # UDF 0, 3, 3, 3, 3, 3, 3, 3, # OTH 0, 3, 3, 3, 3, 3, 3, 3, # ASC 0, 3, 3, 3, 1, 1, 3, 3, # ASS 0, 3, 3, 3, 1, 2, 1, 2, # ACV 0, 3, 3, 3, 3, 3, 3, 3, # ACO 0, 3, 1, 3, 1, 1, 1, 3, # ASV 0, 3, 1, 3, 1, 1, 3, 3, # ASO ) class Latin1Prober(CharSetProber): def __init__(self): super(Latin1Prober, self).__init__() self._last_char_class = None self._freq_counter = None self.reset() def reset(self): self._last_char_class = OTH self._freq_counter = [0] * FREQ_CAT_NUM CharSetProber.reset(self) @property def charset_name(self): return "ISO-8859-1" @property def language(self): return "" def feed(self, byte_str): byte_str = self.filter_with_english_letters(byte_str) for c in byte_str: char_class = Latin1_CharToClass[c] freq = Latin1ClassModel[(self._last_char_class * CLASS_NUM) + char_class] if freq == 0: self._state = ProbingState.NOT_ME break self._freq_counter[freq] += 1 self._last_char_class = char_class return self.state def get_confidence(self): if self.state == ProbingState.NOT_ME: return 0.01 total = sum(self._freq_counter) if total < 0.01: confidence = 0.0 else: confidence = ((self._freq_counter[3] - self._freq_counter[1] * 20.0) / total) if confidence < 0.0: confidence = 0.0 # lower the confidence of latin1 so that other more accurate # detector can take priority. confidence = confidence * 0.73 return confidence PKH]&;python3.10/site-packages/pip/_vendor/chardet/euckrprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .mbcharsetprober import MultiByteCharSetProber from .codingstatemachine import CodingStateMachine from .chardistribution import EUCKRDistributionAnalysis from .mbcssm import EUCKR_SM_MODEL class EUCKRProber(MultiByteCharSetProber): def __init__(self): super(EUCKRProber, self).__init__() self.coding_sm = CodingStateMachine(EUCKR_SM_MODEL) self.distribution_analyzer = EUCKRDistributionAnalysis() self.reset() @property def charset_name(self): return "EUC-KR" @property def language(self): return "Korean" PKH]l7python3.10/site-packages/pip/_vendor/chardet/version.pynu[""" This module exists only to simplify retrieving the version number of chardet from within setup.py and from chardet subpackages. :author: Dan Blanchard (dan.blanchard@gmail.com) """ __version__ = "4.0.0" VERSION = __version__.split('.') PKH]  6python3.10/site-packages/pip/_vendor/chardet/compat.pynu[######################## BEGIN LICENSE BLOCK ######################## # Contributor(s): # Dan Blanchard # Ian Cordasco # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### import sys if sys.version_info < (3, 0): PY2 = True PY3 = False string_types = (str, unicode) text_type = unicode iteritems = dict.iteritems else: PY2 = False PY3 = True string_types = (bytes, str) text_type = str iteritems = dict.items PKH]t˜˜Bpython3.10/site-packages/pip/_vendor/chardet/langbulgarianmodel.pynu[# -*- coding: utf-8 -*- from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel # 3: Positive # 2: Likely # 1: Unlikely # 0: Negative BULGARIAN_LANG_MODEL = { 63: { # 'e' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 0, # 'а' 18: 1, # 'б' 9: 1, # 'в' 20: 1, # 'г' 11: 1, # 'д' 3: 1, # 'е' 23: 1, # 'ж' 15: 1, # 'з' 2: 0, # 'и' 26: 1, # 'й' 12: 1, # 'к' 10: 1, # 'л' 14: 1, # 'м' 6: 1, # 'н' 4: 1, # 'о' 13: 1, # 'п' 7: 1, # 'р' 8: 1, # 'с' 5: 1, # 'т' 19: 0, # 'у' 29: 1, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 1, # 'ч' 27: 1, # 'ш' 24: 1, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 45: { # '\xad' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 0, # 'Г' 37: 1, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 1, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 0, # 'Л' 38: 1, # 'М' 36: 0, # 'Н' 41: 1, # 'О' 30: 1, # 'П' 39: 1, # 'Р' 28: 1, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 1, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 0, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 0, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 0, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 0, # 'о' 13: 0, # 'п' 7: 0, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 0, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 31: { # 'А' 63: 0, # 'e' 45: 1, # '\xad' 31: 1, # 'А' 32: 1, # 'Б' 35: 2, # 'В' 43: 1, # 'Г' 37: 2, # 'Д' 44: 2, # 'Е' 55: 1, # 'Ж' 47: 2, # 'З' 40: 1, # 'И' 59: 1, # 'Й' 33: 1, # 'К' 46: 2, # 'Л' 38: 1, # 'М' 36: 2, # 'Н' 41: 1, # 'О' 30: 2, # 'П' 39: 2, # 'Р' 28: 2, # 'С' 34: 2, # 'Т' 51: 1, # 'У' 48: 2, # 'Ф' 49: 1, # 'Х' 53: 1, # 'Ц' 50: 1, # 'Ч' 54: 1, # 'Ш' 57: 2, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 1, # 'Я' 1: 1, # 'а' 18: 2, # 'б' 9: 2, # 'в' 20: 2, # 'г' 11: 2, # 'д' 3: 1, # 'е' 23: 1, # 'ж' 15: 2, # 'з' 2: 0, # 'и' 26: 2, # 'й' 12: 2, # 'к' 10: 3, # 'л' 14: 2, # 'м' 6: 3, # 'н' 4: 0, # 'о' 13: 2, # 'п' 7: 2, # 'р' 8: 2, # 'с' 5: 2, # 'т' 19: 1, # 'у' 29: 2, # 'ф' 25: 1, # 'х' 22: 1, # 'ц' 21: 1, # 'ч' 27: 1, # 'ш' 24: 0, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 32: { # 'Б' 63: 0, # 'e' 45: 0, # '\xad' 31: 2, # 'А' 32: 2, # 'Б' 35: 1, # 'В' 43: 1, # 'Г' 37: 2, # 'Д' 44: 1, # 'Е' 55: 1, # 'Ж' 47: 2, # 'З' 40: 1, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 2, # 'Н' 41: 2, # 'О' 30: 1, # 'П' 39: 1, # 'Р' 28: 2, # 'С' 34: 2, # 'Т' 51: 1, # 'У' 48: 2, # 'Ф' 49: 1, # 'Х' 53: 1, # 'Ц' 50: 1, # 'Ч' 54: 0, # 'Ш' 57: 1, # 'Щ' 61: 2, # 'Ъ' 60: 1, # 'Ю' 56: 1, # 'Я' 1: 3, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 1, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 2, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 2, # 'р' 8: 1, # 'с' 5: 0, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 3, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 2, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 35: { # 'В' 63: 0, # 'e' 45: 0, # '\xad' 31: 2, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 0, # 'Г' 37: 1, # 'Д' 44: 2, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 2, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 1, # 'О' 30: 1, # 'П' 39: 2, # 'Р' 28: 2, # 'С' 34: 1, # 'Т' 51: 1, # 'У' 48: 2, # 'Ф' 49: 0, # 'Х' 53: 1, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 1, # 'Ъ' 60: 1, # 'Ю' 56: 2, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 1, # 'д' 3: 3, # 'е' 23: 1, # 'ж' 15: 2, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 2, # 'л' 14: 1, # 'м' 6: 2, # 'н' 4: 2, # 'о' 13: 1, # 'п' 7: 2, # 'р' 8: 2, # 'с' 5: 2, # 'т' 19: 1, # 'у' 29: 0, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 2, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 43: { # 'Г' 63: 0, # 'e' 45: 0, # '\xad' 31: 2, # 'А' 32: 1, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 1, # 'Д' 44: 2, # 'Е' 55: 0, # 'Ж' 47: 1, # 'З' 40: 1, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 0, # 'М' 36: 1, # 'Н' 41: 1, # 'О' 30: 0, # 'П' 39: 1, # 'Р' 28: 1, # 'С' 34: 0, # 'Т' 51: 1, # 'У' 48: 1, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 1, # 'Щ' 61: 1, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 2, # 'а' 18: 1, # 'б' 9: 1, # 'в' 20: 0, # 'г' 11: 1, # 'д' 3: 3, # 'е' 23: 1, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 2, # 'л' 14: 1, # 'м' 6: 1, # 'н' 4: 2, # 'о' 13: 0, # 'п' 7: 2, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 1, # 'щ' 17: 2, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 37: { # 'Д' 63: 0, # 'e' 45: 0, # '\xad' 31: 2, # 'А' 32: 1, # 'Б' 35: 2, # 'В' 43: 1, # 'Г' 37: 2, # 'Д' 44: 2, # 'Е' 55: 2, # 'Ж' 47: 1, # 'З' 40: 2, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 2, # 'О' 30: 2, # 'П' 39: 1, # 'Р' 28: 2, # 'С' 34: 1, # 'Т' 51: 1, # 'У' 48: 1, # 'Ф' 49: 0, # 'Х' 53: 1, # 'Ц' 50: 1, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 1, # 'Ъ' 60: 1, # 'Ю' 56: 1, # 'Я' 1: 3, # 'а' 18: 0, # 'б' 9: 2, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 3, # 'е' 23: 3, # 'ж' 15: 1, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 1, # 'л' 14: 1, # 'м' 6: 2, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 2, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 1, # 'ь' 42: 2, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 44: { # 'Е' 63: 0, # 'e' 45: 0, # '\xad' 31: 1, # 'А' 32: 1, # 'Б' 35: 2, # 'В' 43: 1, # 'Г' 37: 1, # 'Д' 44: 1, # 'Е' 55: 1, # 'Ж' 47: 1, # 'З' 40: 1, # 'И' 59: 1, # 'Й' 33: 2, # 'К' 46: 2, # 'Л' 38: 1, # 'М' 36: 2, # 'Н' 41: 2, # 'О' 30: 1, # 'П' 39: 2, # 'Р' 28: 2, # 'С' 34: 2, # 'Т' 51: 1, # 'У' 48: 2, # 'Ф' 49: 1, # 'Х' 53: 2, # 'Ц' 50: 1, # 'Ч' 54: 1, # 'Ш' 57: 1, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 1, # 'Я' 1: 0, # 'а' 18: 1, # 'б' 9: 2, # 'в' 20: 1, # 'г' 11: 2, # 'д' 3: 0, # 'е' 23: 1, # 'ж' 15: 1, # 'з' 2: 0, # 'и' 26: 1, # 'й' 12: 2, # 'к' 10: 2, # 'л' 14: 2, # 'м' 6: 2, # 'н' 4: 0, # 'о' 13: 1, # 'п' 7: 2, # 'р' 8: 2, # 'с' 5: 1, # 'т' 19: 1, # 'у' 29: 1, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 1, # 'ч' 27: 1, # 'ш' 24: 1, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 55: { # 'Ж' 63: 0, # 'e' 45: 0, # '\xad' 31: 1, # 'А' 32: 0, # 'Б' 35: 1, # 'В' 43: 0, # 'Г' 37: 1, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 1, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 1, # 'Н' 41: 1, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 1, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 2, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 1, # 'д' 3: 2, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 2, # 'о' 13: 1, # 'п' 7: 1, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 1, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 47: { # 'З' 63: 0, # 'e' 45: 0, # '\xad' 31: 2, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 1, # 'Г' 37: 1, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 1, # 'З' 40: 1, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 2, # 'Н' 41: 1, # 'О' 30: 1, # 'П' 39: 1, # 'Р' 28: 1, # 'С' 34: 1, # 'Т' 51: 1, # 'У' 48: 0, # 'Ф' 49: 1, # 'Х' 53: 1, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 1, # 'Ъ' 60: 0, # 'Ю' 56: 1, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 2, # 'в' 20: 1, # 'г' 11: 2, # 'д' 3: 2, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 1, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 2, # 'л' 14: 1, # 'м' 6: 1, # 'н' 4: 1, # 'о' 13: 0, # 'п' 7: 1, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 1, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 40: { # 'И' 63: 0, # 'e' 45: 1, # '\xad' 31: 1, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 1, # 'Г' 37: 1, # 'Д' 44: 2, # 'Е' 55: 1, # 'Ж' 47: 2, # 'З' 40: 1, # 'И' 59: 1, # 'Й' 33: 2, # 'К' 46: 2, # 'Л' 38: 2, # 'М' 36: 2, # 'Н' 41: 1, # 'О' 30: 1, # 'П' 39: 2, # 'Р' 28: 2, # 'С' 34: 2, # 'Т' 51: 0, # 'У' 48: 1, # 'Ф' 49: 1, # 'Х' 53: 1, # 'Ц' 50: 1, # 'Ч' 54: 1, # 'Ш' 57: 1, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 2, # 'Я' 1: 1, # 'а' 18: 1, # 'б' 9: 3, # 'в' 20: 2, # 'г' 11: 1, # 'д' 3: 1, # 'е' 23: 0, # 'ж' 15: 3, # 'з' 2: 0, # 'и' 26: 1, # 'й' 12: 1, # 'к' 10: 2, # 'л' 14: 2, # 'м' 6: 2, # 'н' 4: 0, # 'о' 13: 1, # 'п' 7: 2, # 'р' 8: 2, # 'с' 5: 2, # 'т' 19: 0, # 'у' 29: 1, # 'ф' 25: 1, # 'х' 22: 1, # 'ц' 21: 1, # 'ч' 27: 1, # 'ш' 24: 1, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 59: { # 'Й' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 1, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 1, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 1, # 'С' 34: 1, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 1, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 1, # 'Я' 1: 0, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 1, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 0, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 2, # 'о' 13: 0, # 'п' 7: 0, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 0, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 33: { # 'К' 63: 0, # 'e' 45: 1, # '\xad' 31: 2, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 1, # 'Г' 37: 1, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 1, # 'З' 40: 2, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 0, # 'М' 36: 2, # 'Н' 41: 2, # 'О' 30: 2, # 'П' 39: 1, # 'Р' 28: 2, # 'С' 34: 1, # 'Т' 51: 1, # 'У' 48: 1, # 'Ф' 49: 1, # 'Х' 53: 1, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 1, # 'Ъ' 60: 1, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 0, # 'б' 9: 1, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 2, # 'е' 23: 1, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 2, # 'л' 14: 1, # 'м' 6: 2, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 3, # 'р' 8: 1, # 'с' 5: 0, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 1, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 1, # 'ь' 42: 2, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 46: { # 'Л' 63: 1, # 'e' 45: 0, # '\xad' 31: 2, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 2, # 'Г' 37: 1, # 'Д' 44: 2, # 'Е' 55: 0, # 'Ж' 47: 1, # 'З' 40: 2, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 0, # 'М' 36: 1, # 'Н' 41: 2, # 'О' 30: 1, # 'П' 39: 0, # 'Р' 28: 1, # 'С' 34: 1, # 'Т' 51: 1, # 'У' 48: 0, # 'Ф' 49: 1, # 'Х' 53: 1, # 'Ц' 50: 1, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 1, # 'Ъ' 60: 1, # 'Ю' 56: 1, # 'Я' 1: 2, # 'а' 18: 0, # 'б' 9: 1, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 2, # 'о' 13: 0, # 'п' 7: 0, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 1, # 'ь' 42: 2, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 38: { # 'М' 63: 0, # 'e' 45: 0, # '\xad' 31: 2, # 'А' 32: 1, # 'Б' 35: 2, # 'В' 43: 0, # 'Г' 37: 1, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 1, # 'З' 40: 2, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 2, # 'О' 30: 1, # 'П' 39: 1, # 'Р' 28: 2, # 'С' 34: 1, # 'Т' 51: 1, # 'У' 48: 1, # 'Ф' 49: 0, # 'Х' 53: 1, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 1, # 'Ъ' 60: 0, # 'Ю' 56: 1, # 'Я' 1: 3, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 2, # 'л' 14: 0, # 'м' 6: 2, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 1, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 1, # 'ь' 42: 2, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 36: { # 'Н' 63: 0, # 'e' 45: 0, # '\xad' 31: 2, # 'А' 32: 2, # 'Б' 35: 1, # 'В' 43: 1, # 'Г' 37: 2, # 'Д' 44: 2, # 'Е' 55: 1, # 'Ж' 47: 1, # 'З' 40: 2, # 'И' 59: 1, # 'Й' 33: 2, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 2, # 'О' 30: 1, # 'П' 39: 1, # 'Р' 28: 2, # 'С' 34: 2, # 'Т' 51: 1, # 'У' 48: 1, # 'Ф' 49: 1, # 'Х' 53: 1, # 'Ц' 50: 1, # 'Ч' 54: 1, # 'Ш' 57: 0, # 'Щ' 61: 1, # 'Ъ' 60: 1, # 'Ю' 56: 1, # 'Я' 1: 3, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 1, # 'г' 11: 0, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 0, # 'р' 8: 0, # 'с' 5: 1, # 'т' 19: 1, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 1, # 'ш' 24: 0, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 2, # 'ю' 16: 2, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 41: { # 'О' 63: 0, # 'e' 45: 0, # '\xad' 31: 1, # 'А' 32: 1, # 'Б' 35: 2, # 'В' 43: 1, # 'Г' 37: 2, # 'Д' 44: 1, # 'Е' 55: 1, # 'Ж' 47: 1, # 'З' 40: 1, # 'И' 59: 1, # 'Й' 33: 2, # 'К' 46: 2, # 'Л' 38: 2, # 'М' 36: 2, # 'Н' 41: 2, # 'О' 30: 1, # 'П' 39: 2, # 'Р' 28: 2, # 'С' 34: 2, # 'Т' 51: 1, # 'У' 48: 1, # 'Ф' 49: 1, # 'Х' 53: 0, # 'Ц' 50: 1, # 'Ч' 54: 1, # 'Ш' 57: 1, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 1, # 'Я' 1: 1, # 'а' 18: 2, # 'б' 9: 2, # 'в' 20: 2, # 'г' 11: 1, # 'д' 3: 1, # 'е' 23: 1, # 'ж' 15: 1, # 'з' 2: 0, # 'и' 26: 1, # 'й' 12: 2, # 'к' 10: 2, # 'л' 14: 1, # 'м' 6: 1, # 'н' 4: 0, # 'о' 13: 2, # 'п' 7: 2, # 'р' 8: 2, # 'с' 5: 3, # 'т' 19: 1, # 'у' 29: 1, # 'ф' 25: 1, # 'х' 22: 1, # 'ц' 21: 2, # 'ч' 27: 0, # 'ш' 24: 2, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 30: { # 'П' 63: 0, # 'e' 45: 1, # '\xad' 31: 2, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 1, # 'Г' 37: 1, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 1, # 'З' 40: 2, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 2, # 'О' 30: 2, # 'П' 39: 2, # 'Р' 28: 2, # 'С' 34: 1, # 'Т' 51: 2, # 'У' 48: 1, # 'Ф' 49: 0, # 'Х' 53: 1, # 'Ц' 50: 1, # 'Ч' 54: 1, # 'Ш' 57: 0, # 'Щ' 61: 1, # 'Ъ' 60: 1, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 2, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 3, # 'л' 14: 0, # 'м' 6: 1, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 3, # 'р' 8: 1, # 'с' 5: 1, # 'т' 19: 2, # 'у' 29: 1, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 1, # 'ч' 27: 1, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 39: { # 'Р' 63: 0, # 'e' 45: 1, # '\xad' 31: 2, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 2, # 'Г' 37: 2, # 'Д' 44: 2, # 'Е' 55: 0, # 'Ж' 47: 1, # 'З' 40: 2, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 0, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 2, # 'О' 30: 2, # 'П' 39: 1, # 'Р' 28: 1, # 'С' 34: 1, # 'Т' 51: 1, # 'У' 48: 1, # 'Ф' 49: 1, # 'Х' 53: 1, # 'Ц' 50: 1, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 1, # 'Ъ' 60: 1, # 'Ю' 56: 1, # 'Я' 1: 3, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 2, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 1, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 0, # 'р' 8: 1, # 'с' 5: 0, # 'т' 19: 3, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 28: { # 'С' 63: 1, # 'e' 45: 0, # '\xad' 31: 3, # 'А' 32: 2, # 'Б' 35: 2, # 'В' 43: 1, # 'Г' 37: 2, # 'Д' 44: 2, # 'Е' 55: 1, # 'Ж' 47: 1, # 'З' 40: 2, # 'И' 59: 0, # 'Й' 33: 2, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 2, # 'О' 30: 2, # 'П' 39: 1, # 'Р' 28: 2, # 'С' 34: 2, # 'Т' 51: 1, # 'У' 48: 1, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 1, # 'Ъ' 60: 1, # 'Ю' 56: 1, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 2, # 'в' 20: 1, # 'г' 11: 1, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 2, # 'к' 10: 3, # 'л' 14: 2, # 'м' 6: 1, # 'н' 4: 3, # 'о' 13: 3, # 'п' 7: 2, # 'р' 8: 0, # 'с' 5: 3, # 'т' 19: 2, # 'у' 29: 2, # 'ф' 25: 1, # 'х' 22: 1, # 'ц' 21: 1, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 3, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 34: { # 'Т' 63: 0, # 'e' 45: 0, # '\xad' 31: 2, # 'А' 32: 2, # 'Б' 35: 1, # 'В' 43: 0, # 'Г' 37: 1, # 'Д' 44: 2, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 2, # 'И' 59: 0, # 'Й' 33: 2, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 2, # 'О' 30: 1, # 'П' 39: 2, # 'Р' 28: 2, # 'С' 34: 1, # 'Т' 51: 1, # 'У' 48: 1, # 'Ф' 49: 0, # 'Х' 53: 1, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 1, # 'Ъ' 60: 0, # 'Ю' 56: 1, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 1, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 1, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 3, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 2, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 51: { # 'У' 63: 0, # 'e' 45: 1, # '\xad' 31: 1, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 1, # 'Г' 37: 1, # 'Д' 44: 2, # 'Е' 55: 1, # 'Ж' 47: 1, # 'З' 40: 1, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 0, # 'О' 30: 1, # 'П' 39: 1, # 'Р' 28: 1, # 'С' 34: 2, # 'Т' 51: 0, # 'У' 48: 1, # 'Ф' 49: 1, # 'Х' 53: 1, # 'Ц' 50: 1, # 'Ч' 54: 1, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 1, # 'а' 18: 1, # 'б' 9: 2, # 'в' 20: 1, # 'г' 11: 1, # 'д' 3: 2, # 'е' 23: 1, # 'ж' 15: 1, # 'з' 2: 2, # 'и' 26: 1, # 'й' 12: 2, # 'к' 10: 1, # 'л' 14: 1, # 'м' 6: 2, # 'н' 4: 2, # 'о' 13: 1, # 'п' 7: 1, # 'р' 8: 2, # 'с' 5: 1, # 'т' 19: 1, # 'у' 29: 0, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 2, # 'ч' 27: 1, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 48: { # 'Ф' 63: 0, # 'e' 45: 0, # '\xad' 31: 2, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 2, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 0, # 'М' 36: 1, # 'Н' 41: 1, # 'О' 30: 2, # 'П' 39: 1, # 'Р' 28: 2, # 'С' 34: 1, # 'Т' 51: 1, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 2, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 2, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 2, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 2, # 'о' 13: 0, # 'п' 7: 2, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 1, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 49: { # 'Х' 63: 0, # 'e' 45: 0, # '\xad' 31: 1, # 'А' 32: 0, # 'Б' 35: 1, # 'В' 43: 1, # 'Г' 37: 1, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 1, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 1, # 'О' 30: 1, # 'П' 39: 1, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 1, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 2, # 'а' 18: 0, # 'б' 9: 1, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 2, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 1, # 'л' 14: 1, # 'м' 6: 0, # 'н' 4: 2, # 'о' 13: 0, # 'п' 7: 2, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 53: { # 'Ц' 63: 0, # 'e' 45: 0, # '\xad' 31: 1, # 'А' 32: 0, # 'Б' 35: 1, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 2, # 'И' 59: 0, # 'Й' 33: 2, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 1, # 'Р' 28: 2, # 'С' 34: 0, # 'Т' 51: 1, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 2, # 'а' 18: 0, # 'б' 9: 2, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 2, # 'е' 23: 0, # 'ж' 15: 1, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 1, # 'о' 13: 0, # 'п' 7: 1, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 1, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 50: { # 'Ч' 63: 0, # 'e' 45: 0, # '\xad' 31: 2, # 'А' 32: 1, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 1, # 'З' 40: 1, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 0, # 'М' 36: 1, # 'Н' 41: 1, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 1, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 2, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 3, # 'е' 23: 1, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 1, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 2, # 'о' 13: 0, # 'п' 7: 1, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 1, # 'ь' 42: 0, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 54: { # 'Ш' 63: 0, # 'e' 45: 0, # '\xad' 31: 1, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 1, # 'З' 40: 1, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 1, # 'Н' 41: 1, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 1, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 2, # 'а' 18: 0, # 'б' 9: 2, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 2, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 2, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 1, # 'л' 14: 1, # 'м' 6: 1, # 'н' 4: 2, # 'о' 13: 1, # 'п' 7: 1, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 1, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 1, # 'ь' 42: 0, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 57: { # 'Щ' 63: 0, # 'e' 45: 0, # '\xad' 31: 1, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 1, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 1, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 2, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 2, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 1, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 1, # 'о' 13: 0, # 'п' 7: 1, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 1, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 61: { # 'Ъ' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 0, # 'Г' 37: 1, # 'Д' 44: 0, # 'Е' 55: 1, # 'Ж' 47: 1, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 2, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 0, # 'О' 30: 1, # 'П' 39: 2, # 'Р' 28: 1, # 'С' 34: 1, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 1, # 'Х' 53: 1, # 'Ц' 50: 1, # 'Ч' 54: 1, # 'Ш' 57: 1, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 0, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 0, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 0, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 1, # 'л' 14: 0, # 'м' 6: 1, # 'н' 4: 0, # 'о' 13: 0, # 'п' 7: 1, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 0, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 60: { # 'Ю' 63: 0, # 'e' 45: 0, # '\xad' 31: 1, # 'А' 32: 1, # 'Б' 35: 0, # 'В' 43: 1, # 'Г' 37: 1, # 'Д' 44: 0, # 'Е' 55: 1, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 0, # 'М' 36: 1, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 1, # 'Р' 28: 1, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 0, # 'а' 18: 1, # 'б' 9: 1, # 'в' 20: 2, # 'г' 11: 1, # 'д' 3: 0, # 'е' 23: 2, # 'ж' 15: 1, # 'з' 2: 1, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 1, # 'л' 14: 1, # 'м' 6: 1, # 'н' 4: 0, # 'о' 13: 1, # 'п' 7: 1, # 'р' 8: 1, # 'с' 5: 1, # 'т' 19: 0, # 'у' 29: 0, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 56: { # 'Я' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 1, # 'Б' 35: 1, # 'В' 43: 1, # 'Г' 37: 1, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 1, # 'Л' 38: 1, # 'М' 36: 1, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 1, # 'С' 34: 2, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 0, # 'а' 18: 1, # 'б' 9: 1, # 'в' 20: 1, # 'г' 11: 1, # 'д' 3: 0, # 'е' 23: 0, # 'ж' 15: 1, # 'з' 2: 1, # 'и' 26: 1, # 'й' 12: 1, # 'к' 10: 1, # 'л' 14: 2, # 'м' 6: 2, # 'н' 4: 0, # 'о' 13: 2, # 'п' 7: 1, # 'р' 8: 1, # 'с' 5: 1, # 'т' 19: 0, # 'у' 29: 0, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 1, # 'ш' 24: 0, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 1: { # 'а' 63: 1, # 'e' 45: 1, # '\xad' 31: 1, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 1, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 1, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 3, # 'г' 11: 3, # 'д' 3: 3, # 'е' 23: 3, # 'ж' 15: 3, # 'з' 2: 3, # 'и' 26: 3, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 3, # 'м' 6: 3, # 'н' 4: 2, # 'о' 13: 3, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 3, # 'у' 29: 3, # 'ф' 25: 3, # 'х' 22: 3, # 'ц' 21: 3, # 'ч' 27: 3, # 'ш' 24: 3, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 18: { # 'б' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 0, # 'б' 9: 3, # 'в' 20: 1, # 'г' 11: 2, # 'д' 3: 3, # 'е' 23: 1, # 'ж' 15: 1, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 3, # 'л' 14: 2, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 1, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 0, # 'т' 19: 3, # 'у' 29: 0, # 'ф' 25: 2, # 'х' 22: 1, # 'ц' 21: 1, # 'ч' 27: 1, # 'ш' 24: 3, # 'щ' 17: 3, # 'ъ' 52: 1, # 'ь' 42: 2, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 9: { # 'в' 63: 1, # 'e' 45: 1, # '\xad' 31: 0, # 'А' 32: 1, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 1, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 0, # 'в' 20: 2, # 'г' 11: 3, # 'д' 3: 3, # 'е' 23: 1, # 'ж' 15: 3, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 2, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 2, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 2, # 'х' 22: 2, # 'ц' 21: 3, # 'ч' 27: 2, # 'ш' 24: 1, # 'щ' 17: 3, # 'ъ' 52: 1, # 'ь' 42: 2, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 20: { # 'г' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 2, # 'в' 20: 1, # 'г' 11: 2, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 1, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 3, # 'л' 14: 1, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 1, # 'п' 7: 3, # 'р' 8: 2, # 'с' 5: 2, # 'т' 19: 3, # 'у' 29: 1, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 1, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 3, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 11: { # 'д' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 2, # 'б' 9: 3, # 'в' 20: 2, # 'г' 11: 2, # 'д' 3: 3, # 'е' 23: 3, # 'ж' 15: 2, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 3, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 3, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 1, # 'т' 19: 3, # 'у' 29: 1, # 'ф' 25: 2, # 'х' 22: 2, # 'ц' 21: 2, # 'ч' 27: 1, # 'ш' 24: 1, # 'щ' 17: 3, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 3: { # 'е' 63: 0, # 'e' 45: 1, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 2, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 3, # 'г' 11: 3, # 'д' 3: 2, # 'е' 23: 3, # 'ж' 15: 3, # 'з' 2: 2, # 'и' 26: 3, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 3, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 3, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 2, # 'у' 29: 3, # 'ф' 25: 3, # 'х' 22: 3, # 'ц' 21: 3, # 'ч' 27: 3, # 'ш' 24: 3, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 23: { # 'ж' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 3, # 'б' 9: 2, # 'в' 20: 1, # 'г' 11: 3, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 2, # 'к' 10: 1, # 'л' 14: 1, # 'м' 6: 3, # 'н' 4: 2, # 'о' 13: 1, # 'п' 7: 1, # 'р' 8: 1, # 'с' 5: 1, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 1, # 'ц' 21: 1, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 15: { # 'з' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 3, # 'г' 11: 3, # 'д' 3: 3, # 'е' 23: 1, # 'ж' 15: 1, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 3, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 3, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 3, # 'у' 29: 1, # 'ф' 25: 2, # 'х' 22: 2, # 'ц' 21: 2, # 'ч' 27: 2, # 'ш' 24: 1, # 'щ' 17: 2, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 2, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 2: { # 'и' 63: 1, # 'e' 45: 1, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 1, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 1, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 1, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 1, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 3, # 'г' 11: 3, # 'д' 3: 3, # 'е' 23: 3, # 'ж' 15: 3, # 'з' 2: 3, # 'и' 26: 3, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 3, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 3, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 2, # 'у' 29: 3, # 'ф' 25: 3, # 'х' 22: 3, # 'ц' 21: 3, # 'ч' 27: 3, # 'ш' 24: 3, # 'щ' 17: 2, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 26: { # 'й' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 1, # 'а' 18: 2, # 'б' 9: 2, # 'в' 20: 1, # 'г' 11: 2, # 'д' 3: 2, # 'е' 23: 0, # 'ж' 15: 2, # 'з' 2: 1, # 'и' 26: 0, # 'й' 12: 3, # 'к' 10: 2, # 'л' 14: 2, # 'м' 6: 3, # 'н' 4: 2, # 'о' 13: 1, # 'п' 7: 2, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 1, # 'у' 29: 2, # 'ф' 25: 1, # 'х' 22: 2, # 'ц' 21: 2, # 'ч' 27: 1, # 'ш' 24: 1, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 12: { # 'к' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 1, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 1, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 3, # 'в' 20: 2, # 'г' 11: 1, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 2, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 3, # 'л' 14: 2, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 1, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 3, # 'у' 29: 1, # 'ф' 25: 1, # 'х' 22: 3, # 'ц' 21: 2, # 'ч' 27: 1, # 'ш' 24: 0, # 'щ' 17: 3, # 'ъ' 52: 1, # 'ь' 42: 2, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 10: { # 'л' 63: 1, # 'e' 45: 1, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 1, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 3, # 'г' 11: 2, # 'д' 3: 3, # 'е' 23: 3, # 'ж' 15: 2, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 3, # 'к' 10: 1, # 'л' 14: 2, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 2, # 'п' 7: 2, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 3, # 'у' 29: 2, # 'ф' 25: 2, # 'х' 22: 2, # 'ц' 21: 2, # 'ч' 27: 2, # 'ш' 24: 1, # 'щ' 17: 3, # 'ъ' 52: 2, # 'ь' 42: 3, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 14: { # 'м' 63: 1, # 'e' 45: 0, # '\xad' 31: 1, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 1, # 'г' 11: 1, # 'д' 3: 3, # 'е' 23: 1, # 'ж' 15: 1, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 2, # 'к' 10: 3, # 'л' 14: 1, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 3, # 'п' 7: 2, # 'р' 8: 2, # 'с' 5: 1, # 'т' 19: 3, # 'у' 29: 2, # 'ф' 25: 1, # 'х' 22: 2, # 'ц' 21: 2, # 'ч' 27: 2, # 'ш' 24: 1, # 'щ' 17: 3, # 'ъ' 52: 1, # 'ь' 42: 2, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 6: { # 'н' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 1, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 2, # 'б' 9: 2, # 'в' 20: 3, # 'г' 11: 3, # 'д' 3: 3, # 'е' 23: 2, # 'ж' 15: 2, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 3, # 'к' 10: 2, # 'л' 14: 1, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 1, # 'п' 7: 2, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 3, # 'у' 29: 3, # 'ф' 25: 2, # 'х' 22: 3, # 'ц' 21: 3, # 'ч' 27: 2, # 'ш' 24: 1, # 'щ' 17: 3, # 'ъ' 52: 2, # 'ь' 42: 2, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 4: { # 'о' 63: 0, # 'e' 45: 1, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 2, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 3, # 'г' 11: 3, # 'д' 3: 3, # 'е' 23: 3, # 'ж' 15: 3, # 'з' 2: 3, # 'и' 26: 3, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 3, # 'м' 6: 3, # 'н' 4: 2, # 'о' 13: 3, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 2, # 'у' 29: 3, # 'ф' 25: 3, # 'х' 22: 3, # 'ц' 21: 3, # 'ч' 27: 3, # 'ш' 24: 3, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 13: { # 'п' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 2, # 'в' 20: 1, # 'г' 11: 1, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 1, # 'з' 2: 3, # 'и' 26: 1, # 'й' 12: 2, # 'к' 10: 3, # 'л' 14: 1, # 'м' 6: 2, # 'н' 4: 3, # 'о' 13: 1, # 'п' 7: 3, # 'р' 8: 2, # 'с' 5: 2, # 'т' 19: 3, # 'у' 29: 1, # 'ф' 25: 1, # 'х' 22: 2, # 'ц' 21: 2, # 'ч' 27: 1, # 'ш' 24: 1, # 'щ' 17: 3, # 'ъ' 52: 1, # 'ь' 42: 2, # 'ю' 16: 2, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 7: { # 'р' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 3, # 'г' 11: 3, # 'д' 3: 3, # 'е' 23: 3, # 'ж' 15: 2, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 3, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 2, # 'п' 7: 1, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 3, # 'у' 29: 2, # 'ф' 25: 3, # 'х' 22: 3, # 'ц' 21: 2, # 'ч' 27: 3, # 'ш' 24: 1, # 'щ' 17: 3, # 'ъ' 52: 1, # 'ь' 42: 2, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 8: { # 'с' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 2, # 'б' 9: 3, # 'в' 20: 2, # 'г' 11: 2, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 1, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 3, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 3, # 'п' 7: 3, # 'р' 8: 1, # 'с' 5: 3, # 'т' 19: 3, # 'у' 29: 2, # 'ф' 25: 2, # 'х' 22: 2, # 'ц' 21: 2, # 'ч' 27: 2, # 'ш' 24: 0, # 'щ' 17: 3, # 'ъ' 52: 2, # 'ь' 42: 2, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 5: { # 'т' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 2, # 'г' 11: 2, # 'д' 3: 3, # 'е' 23: 1, # 'ж' 15: 1, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 2, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 2, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 3, # 'у' 29: 1, # 'ф' 25: 2, # 'х' 22: 2, # 'ц' 21: 2, # 'ч' 27: 1, # 'ш' 24: 1, # 'щ' 17: 3, # 'ъ' 52: 2, # 'ь' 42: 2, # 'ю' 16: 3, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 19: { # 'у' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 3, # 'г' 11: 3, # 'д' 3: 2, # 'е' 23: 3, # 'ж' 15: 3, # 'з' 2: 2, # 'и' 26: 2, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 3, # 'м' 6: 3, # 'н' 4: 2, # 'о' 13: 3, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 1, # 'у' 29: 2, # 'ф' 25: 2, # 'х' 22: 2, # 'ц' 21: 3, # 'ч' 27: 3, # 'ш' 24: 2, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 29: { # 'ф' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 1, # 'в' 20: 1, # 'г' 11: 0, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 2, # 'к' 10: 2, # 'л' 14: 1, # 'м' 6: 1, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 2, # 'р' 8: 2, # 'с' 5: 2, # 'т' 19: 2, # 'у' 29: 0, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 1, # 'ч' 27: 1, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 2, # 'ь' 42: 1, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 25: { # 'х' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 3, # 'в' 20: 0, # 'г' 11: 1, # 'д' 3: 2, # 'е' 23: 0, # 'ж' 15: 1, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 2, # 'л' 14: 2, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 1, # 'п' 7: 3, # 'р' 8: 1, # 'с' 5: 2, # 'т' 19: 3, # 'у' 29: 0, # 'ф' 25: 1, # 'х' 22: 0, # 'ц' 21: 1, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 22: { # 'ц' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 2, # 'в' 20: 1, # 'г' 11: 1, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 1, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 2, # 'к' 10: 1, # 'л' 14: 1, # 'м' 6: 1, # 'н' 4: 2, # 'о' 13: 1, # 'п' 7: 1, # 'р' 8: 1, # 'с' 5: 1, # 'т' 19: 2, # 'у' 29: 1, # 'ф' 25: 1, # 'х' 22: 1, # 'ц' 21: 1, # 'ч' 27: 1, # 'ш' 24: 1, # 'щ' 17: 2, # 'ъ' 52: 1, # 'ь' 42: 0, # 'ю' 16: 2, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 21: { # 'ч' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 1, # 'б' 9: 3, # 'в' 20: 1, # 'г' 11: 0, # 'д' 3: 3, # 'е' 23: 1, # 'ж' 15: 0, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 3, # 'к' 10: 2, # 'л' 14: 2, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 2, # 'р' 8: 0, # 'с' 5: 2, # 'т' 19: 3, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 1, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 27: { # 'ш' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 0, # 'б' 9: 2, # 'в' 20: 0, # 'г' 11: 1, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 3, # 'к' 10: 2, # 'л' 14: 1, # 'м' 6: 3, # 'н' 4: 2, # 'о' 13: 2, # 'п' 7: 1, # 'р' 8: 0, # 'с' 5: 1, # 'т' 19: 2, # 'у' 29: 1, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 1, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 2, # 'ъ' 52: 1, # 'ь' 42: 1, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 24: { # 'щ' 63: 1, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 3, # 'а' 18: 0, # 'б' 9: 1, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 3, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 3, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 2, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 1, # 'р' 8: 0, # 'с' 5: 2, # 'т' 19: 3, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 1, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 2, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 17: { # 'ъ' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 1, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 3, # 'г' 11: 3, # 'д' 3: 2, # 'е' 23: 3, # 'ж' 15: 3, # 'з' 2: 1, # 'и' 26: 2, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 3, # 'м' 6: 3, # 'н' 4: 3, # 'о' 13: 3, # 'п' 7: 3, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 1, # 'у' 29: 1, # 'ф' 25: 2, # 'х' 22: 2, # 'ц' 21: 3, # 'ч' 27: 2, # 'ш' 24: 3, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 2, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 52: { # 'ь' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 0, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 1, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 0, # 'и' 26: 0, # 'й' 12: 1, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 1, # 'н' 4: 3, # 'о' 13: 0, # 'п' 7: 0, # 'р' 8: 0, # 'с' 5: 1, # 'т' 19: 0, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 1, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 1, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 42: { # 'ю' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 1, # 'а' 18: 2, # 'б' 9: 1, # 'в' 20: 2, # 'г' 11: 2, # 'д' 3: 1, # 'е' 23: 2, # 'ж' 15: 2, # 'з' 2: 1, # 'и' 26: 1, # 'й' 12: 2, # 'к' 10: 2, # 'л' 14: 2, # 'м' 6: 2, # 'н' 4: 1, # 'о' 13: 1, # 'п' 7: 2, # 'р' 8: 2, # 'с' 5: 2, # 'т' 19: 1, # 'у' 29: 1, # 'ф' 25: 1, # 'х' 22: 2, # 'ц' 21: 3, # 'ч' 27: 1, # 'ш' 24: 1, # 'щ' 17: 1, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 16: { # 'я' 63: 0, # 'e' 45: 1, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 0, # 'а' 18: 3, # 'б' 9: 3, # 'в' 20: 2, # 'г' 11: 3, # 'д' 3: 2, # 'е' 23: 1, # 'ж' 15: 2, # 'з' 2: 1, # 'и' 26: 2, # 'й' 12: 3, # 'к' 10: 3, # 'л' 14: 3, # 'м' 6: 3, # 'н' 4: 1, # 'о' 13: 2, # 'п' 7: 2, # 'р' 8: 3, # 'с' 5: 3, # 'т' 19: 1, # 'у' 29: 1, # 'ф' 25: 3, # 'х' 22: 2, # 'ц' 21: 1, # 'ч' 27: 1, # 'ш' 24: 2, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 1, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 58: { # 'є' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 0, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 0, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 0, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 0, # 'о' 13: 0, # 'п' 7: 0, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 0, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, 62: { # '№' 63: 0, # 'e' 45: 0, # '\xad' 31: 0, # 'А' 32: 0, # 'Б' 35: 0, # 'В' 43: 0, # 'Г' 37: 0, # 'Д' 44: 0, # 'Е' 55: 0, # 'Ж' 47: 0, # 'З' 40: 0, # 'И' 59: 0, # 'Й' 33: 0, # 'К' 46: 0, # 'Л' 38: 0, # 'М' 36: 0, # 'Н' 41: 0, # 'О' 30: 0, # 'П' 39: 0, # 'Р' 28: 0, # 'С' 34: 0, # 'Т' 51: 0, # 'У' 48: 0, # 'Ф' 49: 0, # 'Х' 53: 0, # 'Ц' 50: 0, # 'Ч' 54: 0, # 'Ш' 57: 0, # 'Щ' 61: 0, # 'Ъ' 60: 0, # 'Ю' 56: 0, # 'Я' 1: 0, # 'а' 18: 0, # 'б' 9: 0, # 'в' 20: 0, # 'г' 11: 0, # 'д' 3: 0, # 'е' 23: 0, # 'ж' 15: 0, # 'з' 2: 0, # 'и' 26: 0, # 'й' 12: 0, # 'к' 10: 0, # 'л' 14: 0, # 'м' 6: 0, # 'н' 4: 0, # 'о' 13: 0, # 'п' 7: 0, # 'р' 8: 0, # 'с' 5: 0, # 'т' 19: 0, # 'у' 29: 0, # 'ф' 25: 0, # 'х' 22: 0, # 'ц' 21: 0, # 'ч' 27: 0, # 'ш' 24: 0, # 'щ' 17: 0, # 'ъ' 52: 0, # 'ь' 42: 0, # 'ю' 16: 0, # 'я' 58: 0, # 'є' 62: 0, # '№' }, } # 255: Undefined characters that did not exist in training text # 254: Carriage/Return # 253: symbol (punctuation) that does not belong to word # 252: 0 - 9 # 251: Control characters # Character Mapping Table(s): ISO_8859_5_BULGARIAN_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 77, # 'A' 66: 90, # 'B' 67: 99, # 'C' 68: 100, # 'D' 69: 72, # 'E' 70: 109, # 'F' 71: 107, # 'G' 72: 101, # 'H' 73: 79, # 'I' 74: 185, # 'J' 75: 81, # 'K' 76: 102, # 'L' 77: 76, # 'M' 78: 94, # 'N' 79: 82, # 'O' 80: 110, # 'P' 81: 186, # 'Q' 82: 108, # 'R' 83: 91, # 'S' 84: 74, # 'T' 85: 119, # 'U' 86: 84, # 'V' 87: 96, # 'W' 88: 111, # 'X' 89: 187, # 'Y' 90: 115, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 65, # 'a' 98: 69, # 'b' 99: 70, # 'c' 100: 66, # 'd' 101: 63, # 'e' 102: 68, # 'f' 103: 112, # 'g' 104: 103, # 'h' 105: 92, # 'i' 106: 194, # 'j' 107: 104, # 'k' 108: 95, # 'l' 109: 86, # 'm' 110: 87, # 'n' 111: 71, # 'o' 112: 116, # 'p' 113: 195, # 'q' 114: 85, # 'r' 115: 93, # 's' 116: 97, # 't' 117: 113, # 'u' 118: 196, # 'v' 119: 197, # 'w' 120: 198, # 'x' 121: 199, # 'y' 122: 200, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 194, # '\x80' 129: 195, # '\x81' 130: 196, # '\x82' 131: 197, # '\x83' 132: 198, # '\x84' 133: 199, # '\x85' 134: 200, # '\x86' 135: 201, # '\x87' 136: 202, # '\x88' 137: 203, # '\x89' 138: 204, # '\x8a' 139: 205, # '\x8b' 140: 206, # '\x8c' 141: 207, # '\x8d' 142: 208, # '\x8e' 143: 209, # '\x8f' 144: 210, # '\x90' 145: 211, # '\x91' 146: 212, # '\x92' 147: 213, # '\x93' 148: 214, # '\x94' 149: 215, # '\x95' 150: 216, # '\x96' 151: 217, # '\x97' 152: 218, # '\x98' 153: 219, # '\x99' 154: 220, # '\x9a' 155: 221, # '\x9b' 156: 222, # '\x9c' 157: 223, # '\x9d' 158: 224, # '\x9e' 159: 225, # '\x9f' 160: 81, # '\xa0' 161: 226, # 'Ё' 162: 227, # 'Ђ' 163: 228, # 'Ѓ' 164: 229, # 'Є' 165: 230, # 'Ѕ' 166: 105, # 'І' 167: 231, # 'Ї' 168: 232, # 'Ј' 169: 233, # 'Љ' 170: 234, # 'Њ' 171: 235, # 'Ћ' 172: 236, # 'Ќ' 173: 45, # '\xad' 174: 237, # 'Ў' 175: 238, # 'Џ' 176: 31, # 'А' 177: 32, # 'Б' 178: 35, # 'В' 179: 43, # 'Г' 180: 37, # 'Д' 181: 44, # 'Е' 182: 55, # 'Ж' 183: 47, # 'З' 184: 40, # 'И' 185: 59, # 'Й' 186: 33, # 'К' 187: 46, # 'Л' 188: 38, # 'М' 189: 36, # 'Н' 190: 41, # 'О' 191: 30, # 'П' 192: 39, # 'Р' 193: 28, # 'С' 194: 34, # 'Т' 195: 51, # 'У' 196: 48, # 'Ф' 197: 49, # 'Х' 198: 53, # 'Ц' 199: 50, # 'Ч' 200: 54, # 'Ш' 201: 57, # 'Щ' 202: 61, # 'Ъ' 203: 239, # 'Ы' 204: 67, # 'Ь' 205: 240, # 'Э' 206: 60, # 'Ю' 207: 56, # 'Я' 208: 1, # 'а' 209: 18, # 'б' 210: 9, # 'в' 211: 20, # 'г' 212: 11, # 'д' 213: 3, # 'е' 214: 23, # 'ж' 215: 15, # 'з' 216: 2, # 'и' 217: 26, # 'й' 218: 12, # 'к' 219: 10, # 'л' 220: 14, # 'м' 221: 6, # 'н' 222: 4, # 'о' 223: 13, # 'п' 224: 7, # 'р' 225: 8, # 'с' 226: 5, # 'т' 227: 19, # 'у' 228: 29, # 'ф' 229: 25, # 'х' 230: 22, # 'ц' 231: 21, # 'ч' 232: 27, # 'ш' 233: 24, # 'щ' 234: 17, # 'ъ' 235: 75, # 'ы' 236: 52, # 'ь' 237: 241, # 'э' 238: 42, # 'ю' 239: 16, # 'я' 240: 62, # '№' 241: 242, # 'ё' 242: 243, # 'ђ' 243: 244, # 'ѓ' 244: 58, # 'є' 245: 245, # 'ѕ' 246: 98, # 'і' 247: 246, # 'ї' 248: 247, # 'ј' 249: 248, # 'љ' 250: 249, # 'њ' 251: 250, # 'ћ' 252: 251, # 'ќ' 253: 91, # '§' 254: 252, # 'ў' 255: 253, # 'џ' } ISO_8859_5_BULGARIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-5', language='Bulgarian', char_to_order_map=ISO_8859_5_BULGARIAN_CHAR_TO_ORDER, language_model=BULGARIAN_LANG_MODEL, typical_positive_ratio=0.969392, keep_ascii_letters=False, alphabet='АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюя') WINDOWS_1251_BULGARIAN_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 77, # 'A' 66: 90, # 'B' 67: 99, # 'C' 68: 100, # 'D' 69: 72, # 'E' 70: 109, # 'F' 71: 107, # 'G' 72: 101, # 'H' 73: 79, # 'I' 74: 185, # 'J' 75: 81, # 'K' 76: 102, # 'L' 77: 76, # 'M' 78: 94, # 'N' 79: 82, # 'O' 80: 110, # 'P' 81: 186, # 'Q' 82: 108, # 'R' 83: 91, # 'S' 84: 74, # 'T' 85: 119, # 'U' 86: 84, # 'V' 87: 96, # 'W' 88: 111, # 'X' 89: 187, # 'Y' 90: 115, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 65, # 'a' 98: 69, # 'b' 99: 70, # 'c' 100: 66, # 'd' 101: 63, # 'e' 102: 68, # 'f' 103: 112, # 'g' 104: 103, # 'h' 105: 92, # 'i' 106: 194, # 'j' 107: 104, # 'k' 108: 95, # 'l' 109: 86, # 'm' 110: 87, # 'n' 111: 71, # 'o' 112: 116, # 'p' 113: 195, # 'q' 114: 85, # 'r' 115: 93, # 's' 116: 97, # 't' 117: 113, # 'u' 118: 196, # 'v' 119: 197, # 'w' 120: 198, # 'x' 121: 199, # 'y' 122: 200, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 206, # 'Ђ' 129: 207, # 'Ѓ' 130: 208, # '‚' 131: 209, # 'ѓ' 132: 210, # '„' 133: 211, # '…' 134: 212, # '†' 135: 213, # '‡' 136: 120, # '€' 137: 214, # '‰' 138: 215, # 'Љ' 139: 216, # '‹' 140: 217, # 'Њ' 141: 218, # 'Ќ' 142: 219, # 'Ћ' 143: 220, # 'Џ' 144: 221, # 'ђ' 145: 78, # '‘' 146: 64, # '’' 147: 83, # '“' 148: 121, # '”' 149: 98, # '•' 150: 117, # '–' 151: 105, # '—' 152: 222, # None 153: 223, # '™' 154: 224, # 'љ' 155: 225, # '›' 156: 226, # 'њ' 157: 227, # 'ќ' 158: 228, # 'ћ' 159: 229, # 'џ' 160: 88, # '\xa0' 161: 230, # 'Ў' 162: 231, # 'ў' 163: 232, # 'Ј' 164: 233, # '¤' 165: 122, # 'Ґ' 166: 89, # '¦' 167: 106, # '§' 168: 234, # 'Ё' 169: 235, # '©' 170: 236, # 'Є' 171: 237, # '«' 172: 238, # '¬' 173: 45, # '\xad' 174: 239, # '®' 175: 240, # 'Ї' 176: 73, # '°' 177: 80, # '±' 178: 118, # 'І' 179: 114, # 'і' 180: 241, # 'ґ' 181: 242, # 'µ' 182: 243, # '¶' 183: 244, # '·' 184: 245, # 'ё' 185: 62, # '№' 186: 58, # 'є' 187: 246, # '»' 188: 247, # 'ј' 189: 248, # 'Ѕ' 190: 249, # 'ѕ' 191: 250, # 'ї' 192: 31, # 'А' 193: 32, # 'Б' 194: 35, # 'В' 195: 43, # 'Г' 196: 37, # 'Д' 197: 44, # 'Е' 198: 55, # 'Ж' 199: 47, # 'З' 200: 40, # 'И' 201: 59, # 'Й' 202: 33, # 'К' 203: 46, # 'Л' 204: 38, # 'М' 205: 36, # 'Н' 206: 41, # 'О' 207: 30, # 'П' 208: 39, # 'Р' 209: 28, # 'С' 210: 34, # 'Т' 211: 51, # 'У' 212: 48, # 'Ф' 213: 49, # 'Х' 214: 53, # 'Ц' 215: 50, # 'Ч' 216: 54, # 'Ш' 217: 57, # 'Щ' 218: 61, # 'Ъ' 219: 251, # 'Ы' 220: 67, # 'Ь' 221: 252, # 'Э' 222: 60, # 'Ю' 223: 56, # 'Я' 224: 1, # 'а' 225: 18, # 'б' 226: 9, # 'в' 227: 20, # 'г' 228: 11, # 'д' 229: 3, # 'е' 230: 23, # 'ж' 231: 15, # 'з' 232: 2, # 'и' 233: 26, # 'й' 234: 12, # 'к' 235: 10, # 'л' 236: 14, # 'м' 237: 6, # 'н' 238: 4, # 'о' 239: 13, # 'п' 240: 7, # 'р' 241: 8, # 'с' 242: 5, # 'т' 243: 19, # 'у' 244: 29, # 'ф' 245: 25, # 'х' 246: 22, # 'ц' 247: 21, # 'ч' 248: 27, # 'ш' 249: 24, # 'щ' 250: 17, # 'ъ' 251: 75, # 'ы' 252: 52, # 'ь' 253: 253, # 'э' 254: 42, # 'ю' 255: 16, # 'я' } WINDOWS_1251_BULGARIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1251', language='Bulgarian', char_to_order_map=WINDOWS_1251_BULGARIAN_CHAR_TO_ORDER, language_model=BULGARIAN_LANG_MODEL, typical_positive_ratio=0.969392, keep_ascii_letters=False, alphabet='АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюя') PKH]pW >python3.10/site-packages/pip/_vendor/chardet/cli/chardetect.pynu[""" Script which takes one or more file paths and reports on their detected encodings Example:: % chardetect somefile someotherfile somefile: windows-1252 with confidence 0.5 someotherfile: ascii with confidence 1.0 If no paths are provided, it takes its input from stdin. """ from __future__ import absolute_import, print_function, unicode_literals import argparse import sys from pip._vendor.chardet import __version__ from pip._vendor.chardet.compat import PY2 from pip._vendor.chardet.universaldetector import UniversalDetector def description_of(lines, name='stdin'): """ Return a string describing the probable encoding of a file or list of strings. :param lines: The lines to get the encoding of. :type lines: Iterable of bytes :param name: Name of file or collection of lines :type name: str """ u = UniversalDetector() for line in lines: line = bytearray(line) u.feed(line) # shortcut out of the loop to save reading further - particularly useful if we read a BOM. if u.done: break u.close() result = u.result if PY2: name = name.decode(sys.getfilesystemencoding(), 'ignore') if result['encoding']: return '{}: {} with confidence {}'.format(name, result['encoding'], result['confidence']) else: return '{}: no result'.format(name) def main(argv=None): """ Handles command line arguments and gets things started. :param argv: List of arguments, as if specified on the command-line. If None, ``sys.argv[1:]`` is used instead. :type argv: list of str """ # Get command line arguments parser = argparse.ArgumentParser( description="Takes one or more file paths and reports their detected \ encodings") parser.add_argument('input', help='File whose encoding we would like to determine. \ (default: stdin)', type=argparse.FileType('rb'), nargs='*', default=[sys.stdin if PY2 else sys.stdin.buffer]) parser.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) args = parser.parse_args(argv) for f in args.input: if f.isatty(): print("You are running chardetect interactively. Press " + "CTRL-D twice at the start of a blank line to signal the " + "end of your input. If you want help, run chardetect " + "--help\n", file=sys.stderr) print(description_of(f, f.name)) if __name__ == '__main__': main() PKH];(Upython3.10/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-310.pycnu[o ai@sdS)Nrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/cli/__init__.pysPKH]p?z Wpython3.10/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-310.pycnu[o ai @svdZddlmZmZmZddlZddlZddlmZddl m Z ddl m Z d dd Z dd d Zed kr9edSdS)a Script which takes one or more file paths and reports on their detected encodings Example:: % chardetect somefile someotherfile somefile: windows-1252 with confidence 0.5 someotherfile: ascii with confidence 1.0 If no paths are provided, it takes its input from stdin. )absolute_importprint_functionunicode_literalsN) __version__)PY2)UniversalDetectorstdincCsvt}|D]}t|}|||jrnq||j}tr'|t d}|dr6d ||d|dSd |S)z Return a string describing the probable encoding of a file or list of strings. :param lines: The lines to get the encoding of. :type lines: Iterable of bytes :param name: Name of file or collection of lines :type name: str ignoreencodingz{}: {} with confidence {} confidencez {}: no result) r bytearrayfeeddonecloseresultrdecodesysgetfilesystemencodingformat)linesnameulinerr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/cli/chardetect.pydescription_ofs     rcCstjdd}|jddtddtrtjntjjgd|jdd d t d | |}|j D]}| r;t d tjd t t||jq.dS)z Handles command line arguments and gets things started. :param argv: List of arguments, as if specified on the command-line. If None, ``sys.argv[1:]`` is used instead. :type argv: list of str zVTakes one or more file paths and reports their detected encodings) descriptioninputz^File whose encoding we would like to determine. (default: stdin)rb*)helptypenargsdefaultz --versionversionz %(prog)s {})actionr$zYou are running chardetect interactively. Press CTRL-D twice at the start of a blank line to signal the end of your input. If you want help, run chardetect --help )fileN)argparseArgumentParser add_argumentFileTyperrrbufferrr parse_argsrisattyprintstderrrr)argvparserargsfrrrmain5s&    r4__main__)r)N)__doc__ __future__rrrr'rpip._vendor.chardetrZpip._vendor.chardet.compatr%pip._vendor.chardet.universaldetectorrrr4__name__rrrrs      PKH]2<python3.10/site-packages/pip/_vendor/chardet/cli/__init__.pynu[ PKH]6uMU U ?python3.10/site-packages/pip/_vendor/chardet/mbcharsetprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Universal charset detector code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 2001 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # Shy Shalom - original C code # Proofpoint, Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .charsetprober import CharSetProber from .enums import ProbingState, MachineState class MultiByteCharSetProber(CharSetProber): """ MultiByteCharSetProber """ def __init__(self, lang_filter=None): super(MultiByteCharSetProber, self).__init__(lang_filter=lang_filter) self.distribution_analyzer = None self.coding_sm = None self._last_char = [0, 0] def reset(self): super(MultiByteCharSetProber, self).reset() if self.coding_sm: self.coding_sm.reset() if self.distribution_analyzer: self.distribution_analyzer.reset() self._last_char = [0, 0] @property def charset_name(self): raise NotImplementedError @property def language(self): raise NotImplementedError def feed(self, byte_str): for i in range(len(byte_str)): coding_state = self.coding_sm.next_state(byte_str[i]) if coding_state == MachineState.ERROR: self.logger.debug('%s %s prober hit error at byte %s', self.charset_name, self.language, i) self._state = ProbingState.NOT_ME break elif coding_state == MachineState.ITS_ME: self._state = ProbingState.FOUND_IT break elif coding_state == MachineState.START: char_len = self.coding_sm.get_current_charlen() if i == 0: self._last_char[1] = byte_str[0] self.distribution_analyzer.feed(self._last_char, char_len) else: self.distribution_analyzer.feed(byte_str[i - 1:i + 1], char_len) self._last_char[0] = byte_str[-1] if self.state == ProbingState.DETECTING: if (self.distribution_analyzer.got_enough_data() and (self.get_confidence() > self.SHORTCUT_THRESHOLD)): self._state = ProbingState.FOUND_IT return self.state def get_confidence(self): return self.distribution_analyzer.get_confidence() PKH]9zz8python3.10/site-packages/pip/_vendor/chardet/big5freq.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Communicator client code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### # Big5 frequency table # by Taiwan's Mandarin Promotion Council # # # 128 --> 0.42261 # 256 --> 0.57851 # 512 --> 0.74851 # 1024 --> 0.89384 # 2048 --> 0.97583 # # Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 # Random Distribution Ration = 512/(5401-512)=0.105 # # Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75 #Char to FreqOrder table BIG5_TABLE_SIZE = 5376 BIG5_CHAR_TO_FREQ_ORDER = ( 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16 3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32 1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64 3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80 4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96 5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160 2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176 1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192 3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224 1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240 3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256 2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288 3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304 1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320 5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352 5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368 1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416 3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432 3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464 2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480 2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528 3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544 1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560 1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576 1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592 2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624 4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640 1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656 5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672 2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752 5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784 1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832 5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848 1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880 3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896 4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912 3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960 1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976 4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992 3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008 3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024 2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040 5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056 3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072 5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088 1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104 2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120 1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152 1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168 4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184 3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248 2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264 5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280 1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296 2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312 1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328 1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344 5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360 5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376 5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392 3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408 4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424 4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440 2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456 5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472 3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504 5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520 5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536 1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552 2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568 3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584 4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600 5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616 3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632 4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648 1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664 1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680 4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696 1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728 1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744 1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760 3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792 5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808 2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824 1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840 1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856 5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888 4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920 2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952 1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968 1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000 4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016 4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032 1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048 3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064 5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080 5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096 1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112 2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128 1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144 3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160 2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176 3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192 2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208 4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224 4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240 3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272 3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304 3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320 4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336 3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352 1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368 5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400 5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416 1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448 4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464 4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496 2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512 2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528 3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544 1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560 4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576 2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592 1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608 1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624 2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640 3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656 1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672 5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688 1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704 4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720 1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752 1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768 4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784 4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800 2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816 1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832 4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864 5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880 2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896 3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912 4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944 5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960 5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976 1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992 4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008 4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024 2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040 3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056 3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072 2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088 1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104 4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120 3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136 3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152 2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168 4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184 5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200 3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216 2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232 3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248 1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264 2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280 3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296 4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312 2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328 2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344 5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360 1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376 2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392 1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408 3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424 4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440 2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456 3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472 3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488 2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504 4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520 2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536 3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552 4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568 5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584 3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616 1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632 4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648 1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664 4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680 5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712 5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728 5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744 2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760 3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776 2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792 2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824 1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840 4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856 3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872 3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904 2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936 2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952 4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968 1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984 4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000 1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016 3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048 3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064 5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080 5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096 3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112 3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128 1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144 2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160 5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176 1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192 1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208 3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240 1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256 4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272 5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288 2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304 3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336 1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352 2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368 2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384 5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400 5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416 5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432 2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448 2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464 1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480 4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496 3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512 3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528 4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544 4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560 2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576 2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592 5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608 4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624 5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640 4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688 1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704 3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720 4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736 1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752 5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768 2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784 2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800 3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816 5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832 1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848 3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864 5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880 1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896 5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912 2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928 3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944 2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960 3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976 3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992 3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008 4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040 2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056 4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072 3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088 5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104 1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120 5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152 1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184 4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200 1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216 4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232 1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264 3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280 4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296 5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328 3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360 2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 ) PKH]`̖VV@python3.10/site-packages/pip/_vendor/chardet/langrussianmodel.pynu[# -*- coding: utf-8 -*- from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel # 3: Positive # 2: Likely # 1: Unlikely # 0: Negative RUSSIAN_LANG_MODEL = { 37: { # 'А' 37: 0, # 'А' 44: 1, # 'Б' 33: 1, # 'В' 46: 1, # 'Г' 41: 1, # 'Д' 48: 1, # 'Е' 56: 1, # 'Ж' 51: 1, # 'З' 42: 1, # 'И' 60: 1, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 2, # 'Н' 34: 1, # 'О' 35: 1, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 1, # 'У' 53: 1, # 'Ф' 55: 1, # 'Х' 58: 1, # 'Ц' 50: 1, # 'Ч' 57: 1, # 'Ш' 63: 1, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 1, # 'Ю' 43: 1, # 'Я' 3: 1, # 'а' 21: 2, # 'б' 10: 2, # 'в' 19: 2, # 'г' 13: 2, # 'д' 2: 0, # 'е' 24: 1, # 'ж' 20: 1, # 'з' 4: 0, # 'и' 23: 1, # 'й' 11: 2, # 'к' 8: 3, # 'л' 12: 2, # 'м' 5: 2, # 'н' 1: 0, # 'о' 15: 2, # 'п' 9: 2, # 'р' 7: 2, # 'с' 6: 2, # 'т' 14: 2, # 'у' 39: 2, # 'ф' 26: 2, # 'х' 28: 0, # 'ц' 22: 1, # 'ч' 25: 2, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 1, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 44: { # 'Б' 37: 1, # 'А' 44: 0, # 'Б' 33: 1, # 'В' 46: 1, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 0, # 'П' 45: 1, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 1, # 'Я' 3: 2, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 0, # 'г' 13: 1, # 'д' 2: 3, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 2, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 2, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 2, # 'ы' 17: 1, # 'ь' 30: 2, # 'э' 27: 1, # 'ю' 16: 1, # 'я' }, 33: { # 'В' 37: 2, # 'А' 44: 0, # 'Б' 33: 1, # 'В' 46: 0, # 'Г' 41: 1, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 1, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 1, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 1, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 1, # 'Я' 3: 2, # 'а' 21: 1, # 'б' 10: 1, # 'в' 19: 1, # 'г' 13: 2, # 'д' 2: 3, # 'е' 24: 0, # 'ж' 20: 2, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 1, # 'к' 8: 2, # 'л' 12: 2, # 'м' 5: 2, # 'н' 1: 3, # 'о' 15: 2, # 'п' 9: 2, # 'р' 7: 3, # 'с' 6: 2, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 1, # 'х' 28: 1, # 'ц' 22: 2, # 'ч' 25: 1, # 'ш' 29: 0, # 'щ' 54: 1, # 'ъ' 18: 3, # 'ы' 17: 1, # 'ь' 30: 2, # 'э' 27: 0, # 'ю' 16: 1, # 'я' }, 46: { # 'Г' 37: 1, # 'А' 44: 1, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 1, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 1, # 'П' 45: 1, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 2, # 'а' 21: 0, # 'б' 10: 1, # 'в' 19: 0, # 'г' 13: 2, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 2, # 'л' 12: 1, # 'м' 5: 1, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 2, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 1, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 0, # 'я' }, 41: { # 'Д' 37: 1, # 'А' 44: 0, # 'Б' 33: 1, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 2, # 'Е' 56: 1, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 0, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 0, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 1, # 'Ц' 50: 1, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 1, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 1, # 'Я' 3: 3, # 'а' 21: 0, # 'б' 10: 2, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 3, # 'ж' 20: 1, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 2, # 'л' 12: 1, # 'м' 5: 1, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 2, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 1, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 1, # 'ы' 17: 1, # 'ь' 30: 2, # 'э' 27: 1, # 'ю' 16: 1, # 'я' }, 48: { # 'Е' 37: 1, # 'А' 44: 1, # 'Б' 33: 1, # 'В' 46: 1, # 'Г' 41: 1, # 'Д' 48: 1, # 'Е' 56: 1, # 'Ж' 51: 1, # 'З' 42: 1, # 'И' 60: 1, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 2, # 'Н' 34: 1, # 'О' 35: 1, # 'П' 45: 2, # 'Р' 32: 2, # 'С' 40: 1, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 1, # 'Х' 58: 1, # 'Ц' 50: 1, # 'Ч' 57: 1, # 'Ш' 63: 1, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 1, # 'Я' 3: 0, # 'а' 21: 0, # 'б' 10: 2, # 'в' 19: 2, # 'г' 13: 2, # 'д' 2: 2, # 'е' 24: 1, # 'ж' 20: 1, # 'з' 4: 0, # 'и' 23: 2, # 'й' 11: 1, # 'к' 8: 2, # 'л' 12: 2, # 'м' 5: 1, # 'н' 1: 0, # 'о' 15: 1, # 'п' 9: 1, # 'р' 7: 3, # 'с' 6: 0, # 'т' 14: 0, # 'у' 39: 1, # 'ф' 26: 1, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 1, # 'ш' 29: 2, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 1, # 'ю' 16: 0, # 'я' }, 56: { # 'Ж' 37: 1, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 1, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 1, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 2, # 'а' 21: 1, # 'б' 10: 0, # 'в' 19: 1, # 'г' 13: 1, # 'д' 2: 2, # 'е' 24: 1, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 0, # 'л' 12: 1, # 'м' 5: 0, # 'н' 1: 2, # 'о' 15: 0, # 'п' 9: 1, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 2, # 'ю' 16: 0, # 'я' }, 51: { # 'З' 37: 1, # 'А' 44: 0, # 'Б' 33: 1, # 'В' 46: 1, # 'Г' 41: 1, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 0, # 'П' 45: 1, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 1, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 1, # 'б' 10: 2, # 'в' 19: 0, # 'г' 13: 2, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 1, # 'л' 12: 1, # 'м' 5: 2, # 'н' 1: 2, # 'о' 15: 0, # 'п' 9: 1, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 1, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 1, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 1, # 'я' }, 42: { # 'И' 37: 1, # 'А' 44: 1, # 'Б' 33: 1, # 'В' 46: 1, # 'Г' 41: 1, # 'Д' 48: 2, # 'Е' 56: 1, # 'Ж' 51: 1, # 'З' 42: 1, # 'И' 60: 1, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 1, # 'П' 45: 1, # 'Р' 32: 2, # 'С' 40: 1, # 'Т' 52: 0, # 'У' 53: 1, # 'Ф' 55: 1, # 'Х' 58: 1, # 'Ц' 50: 1, # 'Ч' 57: 0, # 'Ш' 63: 1, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 1, # 'Ю' 43: 1, # 'Я' 3: 1, # 'а' 21: 2, # 'б' 10: 2, # 'в' 19: 2, # 'г' 13: 2, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 2, # 'з' 4: 1, # 'и' 23: 0, # 'й' 11: 1, # 'к' 8: 2, # 'л' 12: 2, # 'м' 5: 2, # 'н' 1: 1, # 'о' 15: 1, # 'п' 9: 2, # 'р' 7: 2, # 'с' 6: 2, # 'т' 14: 1, # 'у' 39: 1, # 'ф' 26: 2, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 1, # 'ш' 29: 1, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 1, # 'ю' 16: 0, # 'я' }, 60: { # 'Й' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 1, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 1, # 'Х' 58: 1, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 0, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 1, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 0, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 0, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 2, # 'о' 15: 0, # 'п' 9: 0, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 0, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 36: { # 'К' 37: 2, # 'А' 44: 0, # 'Б' 33: 1, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 1, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 1, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 2, # 'О' 35: 1, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 1, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 0, # 'б' 10: 1, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 2, # 'л' 12: 0, # 'м' 5: 1, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 2, # 'р' 7: 2, # 'с' 6: 2, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 1, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 1, # 'ы' 17: 1, # 'ь' 30: 2, # 'э' 27: 1, # 'ю' 16: 0, # 'я' }, 49: { # 'Л' 37: 2, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 1, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 1, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 0, # 'Н' 34: 1, # 'О' 35: 1, # 'П' 45: 0, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 1, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 1, # 'Ь' 47: 0, # 'Э' 59: 1, # 'Ю' 43: 1, # 'Я' 3: 2, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 1, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 1, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 1, # 'л' 12: 0, # 'м' 5: 1, # 'н' 1: 2, # 'о' 15: 0, # 'п' 9: 0, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 1, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 1, # 'ы' 17: 1, # 'ь' 30: 2, # 'э' 27: 2, # 'ю' 16: 1, # 'я' }, 38: { # 'М' 37: 1, # 'А' 44: 1, # 'Б' 33: 1, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 1, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 1, # 'У' 53: 1, # 'Ф' 55: 1, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 0, # 'Ь' 47: 1, # 'Э' 59: 0, # 'Ю' 43: 1, # 'Я' 3: 3, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 1, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 1, # 'л' 12: 1, # 'м' 5: 2, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 1, # 'р' 7: 1, # 'с' 6: 0, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 3, # 'ы' 17: 1, # 'ь' 30: 2, # 'э' 27: 1, # 'ю' 16: 1, # 'я' }, 31: { # 'Н' 37: 2, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 1, # 'Г' 41: 1, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 1, # 'З' 42: 2, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 0, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 1, # 'У' 53: 1, # 'Ф' 55: 1, # 'Х' 58: 1, # 'Ц' 50: 1, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 1, # 'Ь' 47: 1, # 'Э' 59: 0, # 'Ю' 43: 1, # 'Я' 3: 3, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 3, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 0, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 1, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 3, # 'у' 39: 0, # 'ф' 26: 1, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 1, # 'ы' 17: 2, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 1, # 'я' }, 34: { # 'О' 37: 0, # 'А' 44: 1, # 'Б' 33: 1, # 'В' 46: 1, # 'Г' 41: 2, # 'Д' 48: 1, # 'Е' 56: 1, # 'Ж' 51: 1, # 'З' 42: 1, # 'И' 60: 1, # 'Й' 36: 1, # 'К' 49: 2, # 'Л' 38: 1, # 'М' 31: 2, # 'Н' 34: 1, # 'О' 35: 1, # 'П' 45: 2, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 1, # 'У' 53: 1, # 'Ф' 55: 1, # 'Х' 58: 0, # 'Ц' 50: 1, # 'Ч' 57: 1, # 'Ш' 63: 1, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 1, # 'Я' 3: 1, # 'а' 21: 2, # 'б' 10: 1, # 'в' 19: 2, # 'г' 13: 2, # 'д' 2: 0, # 'е' 24: 1, # 'ж' 20: 1, # 'з' 4: 0, # 'и' 23: 1, # 'й' 11: 2, # 'к' 8: 2, # 'л' 12: 1, # 'м' 5: 3, # 'н' 1: 0, # 'о' 15: 2, # 'п' 9: 2, # 'р' 7: 2, # 'с' 6: 2, # 'т' 14: 1, # 'у' 39: 1, # 'ф' 26: 2, # 'х' 28: 1, # 'ц' 22: 2, # 'ч' 25: 2, # 'ш' 29: 1, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 35: { # 'П' 37: 1, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 1, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 1, # 'П' 45: 2, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 1, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 1, # 'Я' 3: 2, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 2, # 'л' 12: 0, # 'м' 5: 1, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 3, # 'р' 7: 1, # 'с' 6: 1, # 'т' 14: 2, # 'у' 39: 1, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 1, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 1, # 'ы' 17: 2, # 'ь' 30: 1, # 'э' 27: 0, # 'ю' 16: 2, # 'я' }, 45: { # 'Р' 37: 2, # 'А' 44: 1, # 'Б' 33: 1, # 'В' 46: 1, # 'Г' 41: 1, # 'Д' 48: 2, # 'Е' 56: 1, # 'Ж' 51: 0, # 'З' 42: 2, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 2, # 'О' 35: 0, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 1, # 'Х' 58: 1, # 'Ц' 50: 1, # 'Ч' 57: 1, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 1, # 'Ь' 47: 1, # 'Э' 59: 1, # 'Ю' 43: 1, # 'Я' 3: 3, # 'а' 21: 0, # 'б' 10: 1, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 1, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 0, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 1, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 2, # 'ы' 17: 0, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 2, # 'я' }, 32: { # 'С' 37: 1, # 'А' 44: 1, # 'Б' 33: 1, # 'В' 46: 1, # 'Г' 41: 1, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 1, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 2, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 1, # 'Х' 58: 1, # 'Ц' 50: 1, # 'Ч' 57: 1, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 1, # 'Ь' 47: 1, # 'Э' 59: 1, # 'Ю' 43: 1, # 'Я' 3: 2, # 'а' 21: 1, # 'б' 10: 2, # 'в' 19: 1, # 'г' 13: 2, # 'д' 2: 3, # 'е' 24: 1, # 'ж' 20: 1, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 2, # 'к' 8: 2, # 'л' 12: 2, # 'м' 5: 2, # 'н' 1: 2, # 'о' 15: 2, # 'п' 9: 2, # 'р' 7: 1, # 'с' 6: 3, # 'т' 14: 2, # 'у' 39: 1, # 'ф' 26: 1, # 'х' 28: 1, # 'ц' 22: 1, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 1, # 'ъ' 18: 1, # 'ы' 17: 1, # 'ь' 30: 2, # 'э' 27: 1, # 'ю' 16: 1, # 'я' }, 40: { # 'Т' 37: 1, # 'А' 44: 0, # 'Б' 33: 1, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 2, # 'О' 35: 0, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 1, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 1, # 'Ь' 47: 1, # 'Э' 59: 1, # 'Ю' 43: 1, # 'Я' 3: 3, # 'а' 21: 1, # 'б' 10: 2, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 3, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 1, # 'к' 8: 1, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 2, # 'р' 7: 1, # 'с' 6: 0, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 1, # 'щ' 54: 0, # 'ъ' 18: 3, # 'ы' 17: 1, # 'ь' 30: 2, # 'э' 27: 1, # 'ю' 16: 1, # 'я' }, 52: { # 'У' 37: 1, # 'А' 44: 1, # 'Б' 33: 1, # 'В' 46: 1, # 'Г' 41: 1, # 'Д' 48: 1, # 'Е' 56: 1, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 1, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 1, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 1, # 'Х' 58: 0, # 'Ц' 50: 1, # 'Ч' 57: 1, # 'Ш' 63: 1, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 1, # 'Ю' 43: 0, # 'Я' 3: 1, # 'а' 21: 2, # 'б' 10: 2, # 'в' 19: 1, # 'г' 13: 2, # 'д' 2: 1, # 'е' 24: 2, # 'ж' 20: 2, # 'з' 4: 2, # 'и' 23: 1, # 'й' 11: 1, # 'к' 8: 2, # 'л' 12: 2, # 'м' 5: 1, # 'н' 1: 2, # 'о' 15: 1, # 'п' 9: 2, # 'р' 7: 2, # 'с' 6: 2, # 'т' 14: 0, # 'у' 39: 1, # 'ф' 26: 1, # 'х' 28: 1, # 'ц' 22: 2, # 'ч' 25: 1, # 'ш' 29: 1, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 2, # 'э' 27: 1, # 'ю' 16: 0, # 'я' }, 53: { # 'Ф' 37: 1, # 'А' 44: 1, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 1, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 1, # 'О' 35: 0, # 'П' 45: 1, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 2, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 2, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 2, # 'о' 15: 0, # 'п' 9: 2, # 'р' 7: 0, # 'с' 6: 1, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 1, # 'ь' 30: 2, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 55: { # 'Х' 37: 1, # 'А' 44: 0, # 'Б' 33: 1, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 2, # 'а' 21: 0, # 'б' 10: 2, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 2, # 'л' 12: 1, # 'м' 5: 0, # 'н' 1: 2, # 'о' 15: 0, # 'п' 9: 2, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 1, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 1, # 'ь' 30: 1, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 58: { # 'Ц' 37: 1, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 1, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 1, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 1, # 'а' 21: 0, # 'б' 10: 1, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 0, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 0, # 'о' 15: 0, # 'п' 9: 0, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 1, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 1, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 1, # 'ю' 16: 0, # 'я' }, 50: { # 'Ч' 37: 1, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 0, # 'О' 35: 1, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 1, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 1, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 2, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 1, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 1, # 'о' 15: 0, # 'п' 9: 1, # 'р' 7: 0, # 'с' 6: 3, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 1, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 57: { # 'Ш' 37: 1, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 1, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 2, # 'а' 21: 0, # 'б' 10: 1, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 1, # 'и' 23: 0, # 'й' 11: 1, # 'к' 8: 2, # 'л' 12: 1, # 'м' 5: 1, # 'н' 1: 2, # 'о' 15: 2, # 'п' 9: 1, # 'р' 7: 0, # 'с' 6: 2, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 1, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 1, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 1, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 63: { # 'Щ' 37: 1, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 1, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 1, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 1, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 1, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 0, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 1, # 'о' 15: 0, # 'п' 9: 0, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 1, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 62: { # 'Ы' 37: 0, # 'А' 44: 0, # 'Б' 33: 1, # 'В' 46: 1, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 1, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 0, # 'О' 35: 1, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 1, # 'Х' 58: 1, # 'Ц' 50: 0, # 'Ч' 57: 1, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 0, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 0, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 0, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 0, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 0, # 'о' 15: 0, # 'п' 9: 0, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 0, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 61: { # 'Ь' 37: 0, # 'А' 44: 1, # 'Б' 33: 1, # 'В' 46: 0, # 'Г' 41: 1, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 0, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 1, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 1, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 1, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 1, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 1, # 'Ю' 43: 1, # 'Я' 3: 0, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 0, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 0, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 0, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 0, # 'о' 15: 0, # 'п' 9: 0, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 0, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 47: { # 'Э' 37: 0, # 'А' 44: 0, # 'Б' 33: 1, # 'В' 46: 0, # 'Г' 41: 1, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 1, # 'Й' 36: 1, # 'К' 49: 1, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 0, # 'О' 35: 1, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 1, # 'а' 21: 1, # 'б' 10: 2, # 'в' 19: 1, # 'г' 13: 2, # 'д' 2: 0, # 'е' 24: 1, # 'ж' 20: 0, # 'з' 4: 0, # 'и' 23: 2, # 'й' 11: 2, # 'к' 8: 2, # 'л' 12: 2, # 'м' 5: 2, # 'н' 1: 0, # 'о' 15: 1, # 'п' 9: 2, # 'р' 7: 1, # 'с' 6: 3, # 'т' 14: 1, # 'у' 39: 1, # 'ф' 26: 1, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 1, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 59: { # 'Ю' 37: 1, # 'А' 44: 1, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 1, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 1, # 'Р' 32: 0, # 'С' 40: 1, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 1, # 'Ч' 57: 0, # 'Ш' 63: 1, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 0, # 'а' 21: 1, # 'б' 10: 0, # 'в' 19: 1, # 'г' 13: 1, # 'д' 2: 0, # 'е' 24: 1, # 'ж' 20: 0, # 'з' 4: 0, # 'и' 23: 0, # 'й' 11: 1, # 'к' 8: 2, # 'л' 12: 1, # 'м' 5: 2, # 'н' 1: 0, # 'о' 15: 1, # 'п' 9: 1, # 'р' 7: 1, # 'с' 6: 0, # 'т' 14: 0, # 'у' 39: 0, # 'ф' 26: 1, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 43: { # 'Я' 37: 0, # 'А' 44: 0, # 'Б' 33: 1, # 'В' 46: 1, # 'Г' 41: 0, # 'Д' 48: 1, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 1, # 'С' 40: 1, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 1, # 'Х' 58: 0, # 'Ц' 50: 1, # 'Ч' 57: 0, # 'Ш' 63: 1, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 1, # 'Ю' 43: 1, # 'Я' 3: 0, # 'а' 21: 1, # 'б' 10: 1, # 'в' 19: 1, # 'г' 13: 1, # 'д' 2: 0, # 'е' 24: 0, # 'ж' 20: 1, # 'з' 4: 0, # 'и' 23: 1, # 'й' 11: 1, # 'к' 8: 1, # 'л' 12: 1, # 'м' 5: 2, # 'н' 1: 0, # 'о' 15: 1, # 'п' 9: 1, # 'р' 7: 1, # 'с' 6: 0, # 'т' 14: 0, # 'у' 39: 0, # 'ф' 26: 1, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 1, # 'ш' 29: 1, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 3: { # 'а' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 1, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 2, # 'а' 21: 3, # 'б' 10: 3, # 'в' 19: 3, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 3, # 'ж' 20: 3, # 'з' 4: 3, # 'и' 23: 3, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 3, # 'м' 5: 3, # 'н' 1: 2, # 'о' 15: 3, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 3, # 'у' 39: 2, # 'ф' 26: 3, # 'х' 28: 3, # 'ц' 22: 3, # 'ч' 25: 3, # 'ш' 29: 3, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 2, # 'э' 27: 3, # 'ю' 16: 3, # 'я' }, 21: { # 'б' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 1, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 2, # 'б' 10: 2, # 'в' 19: 1, # 'г' 13: 2, # 'д' 2: 3, # 'е' 24: 2, # 'ж' 20: 1, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 2, # 'к' 8: 3, # 'л' 12: 2, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 1, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 2, # 'т' 14: 3, # 'у' 39: 0, # 'ф' 26: 2, # 'х' 28: 1, # 'ц' 22: 1, # 'ч' 25: 2, # 'ш' 29: 3, # 'щ' 54: 2, # 'ъ' 18: 3, # 'ы' 17: 2, # 'ь' 30: 1, # 'э' 27: 2, # 'ю' 16: 3, # 'я' }, 10: { # 'в' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 2, # 'б' 10: 2, # 'в' 19: 2, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 1, # 'ж' 20: 3, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 2, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 3, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 3, # 'у' 39: 1, # 'ф' 26: 2, # 'х' 28: 2, # 'ц' 22: 2, # 'ч' 25: 3, # 'ш' 29: 2, # 'щ' 54: 2, # 'ъ' 18: 3, # 'ы' 17: 3, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 3, # 'я' }, 19: { # 'г' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 1, # 'б' 10: 2, # 'в' 19: 1, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 0, # 'ж' 20: 1, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 2, # 'к' 8: 3, # 'л' 12: 2, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 3, # 'р' 7: 2, # 'с' 6: 2, # 'т' 14: 3, # 'у' 39: 1, # 'ф' 26: 1, # 'х' 28: 1, # 'ц' 22: 2, # 'ч' 25: 1, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 1, # 'ы' 17: 1, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 0, # 'я' }, 13: { # 'д' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 2, # 'б' 10: 3, # 'в' 19: 2, # 'г' 13: 2, # 'д' 2: 3, # 'е' 24: 2, # 'ж' 20: 2, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 2, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 2, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 3, # 'у' 39: 1, # 'ф' 26: 2, # 'х' 28: 3, # 'ц' 22: 2, # 'ч' 25: 2, # 'ш' 29: 1, # 'щ' 54: 2, # 'ъ' 18: 3, # 'ы' 17: 3, # 'ь' 30: 1, # 'э' 27: 2, # 'ю' 16: 3, # 'я' }, 2: { # 'е' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 2, # 'а' 21: 3, # 'б' 10: 3, # 'в' 19: 3, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 3, # 'ж' 20: 3, # 'з' 4: 2, # 'и' 23: 3, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 3, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 3, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 2, # 'у' 39: 2, # 'ф' 26: 3, # 'х' 28: 3, # 'ц' 22: 3, # 'ч' 25: 3, # 'ш' 29: 3, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 1, # 'э' 27: 2, # 'ю' 16: 3, # 'я' }, 24: { # 'ж' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 2, # 'б' 10: 1, # 'в' 19: 2, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 2, # 'ж' 20: 1, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 2, # 'к' 8: 2, # 'л' 12: 1, # 'м' 5: 3, # 'н' 1: 2, # 'о' 15: 1, # 'п' 9: 2, # 'р' 7: 2, # 'с' 6: 1, # 'т' 14: 3, # 'у' 39: 1, # 'ф' 26: 0, # 'х' 28: 1, # 'ц' 22: 2, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 1, # 'ы' 17: 2, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 1, # 'я' }, 20: { # 'з' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 3, # 'б' 10: 3, # 'в' 19: 3, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 2, # 'ж' 20: 2, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 3, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 3, # 'р' 7: 2, # 'с' 6: 2, # 'т' 14: 3, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 1, # 'ц' 22: 2, # 'ч' 25: 1, # 'ш' 29: 0, # 'щ' 54: 2, # 'ъ' 18: 3, # 'ы' 17: 2, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 3, # 'я' }, 4: { # 'и' 37: 1, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 1, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 3, # 'б' 10: 3, # 'в' 19: 3, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 3, # 'ж' 20: 3, # 'з' 4: 3, # 'и' 23: 3, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 3, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 3, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 2, # 'у' 39: 2, # 'ф' 26: 3, # 'х' 28: 3, # 'ц' 22: 3, # 'ч' 25: 3, # 'ш' 29: 3, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 2, # 'э' 27: 3, # 'ю' 16: 3, # 'я' }, 23: { # 'й' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 1, # 'а' 21: 1, # 'б' 10: 1, # 'в' 19: 2, # 'г' 13: 3, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 2, # 'з' 4: 1, # 'и' 23: 0, # 'й' 11: 2, # 'к' 8: 2, # 'л' 12: 2, # 'м' 5: 3, # 'н' 1: 2, # 'о' 15: 1, # 'п' 9: 2, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 1, # 'у' 39: 2, # 'ф' 26: 1, # 'х' 28: 2, # 'ц' 22: 3, # 'ч' 25: 2, # 'ш' 29: 1, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 2, # 'я' }, 11: { # 'к' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 1, # 'б' 10: 3, # 'в' 19: 1, # 'г' 13: 1, # 'д' 2: 3, # 'е' 24: 2, # 'ж' 20: 2, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 2, # 'к' 8: 3, # 'л' 12: 1, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 3, # 'у' 39: 1, # 'ф' 26: 2, # 'х' 28: 2, # 'ц' 22: 1, # 'ч' 25: 2, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 1, # 'ы' 17: 1, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 1, # 'я' }, 8: { # 'л' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 2, # 'б' 10: 2, # 'в' 19: 3, # 'г' 13: 2, # 'д' 2: 3, # 'е' 24: 3, # 'ж' 20: 2, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 2, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 2, # 'п' 9: 1, # 'р' 7: 3, # 'с' 6: 2, # 'т' 14: 3, # 'у' 39: 2, # 'ф' 26: 2, # 'х' 28: 1, # 'ц' 22: 3, # 'ч' 25: 2, # 'ш' 29: 1, # 'щ' 54: 0, # 'ъ' 18: 3, # 'ы' 17: 3, # 'ь' 30: 1, # 'э' 27: 3, # 'ю' 16: 3, # 'я' }, 12: { # 'м' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 2, # 'б' 10: 2, # 'в' 19: 2, # 'г' 13: 1, # 'д' 2: 3, # 'е' 24: 1, # 'ж' 20: 1, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 2, # 'к' 8: 3, # 'л' 12: 2, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 2, # 'п' 9: 2, # 'р' 7: 3, # 'с' 6: 2, # 'т' 14: 3, # 'у' 39: 2, # 'ф' 26: 2, # 'х' 28: 2, # 'ц' 22: 2, # 'ч' 25: 1, # 'ш' 29: 1, # 'щ' 54: 0, # 'ъ' 18: 3, # 'ы' 17: 2, # 'ь' 30: 2, # 'э' 27: 1, # 'ю' 16: 3, # 'я' }, 5: { # 'н' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 2, # 'б' 10: 2, # 'в' 19: 3, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 2, # 'ж' 20: 2, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 3, # 'к' 8: 2, # 'л' 12: 1, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 1, # 'п' 9: 2, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 3, # 'у' 39: 2, # 'ф' 26: 2, # 'х' 28: 3, # 'ц' 22: 3, # 'ч' 25: 2, # 'ш' 29: 2, # 'щ' 54: 1, # 'ъ' 18: 3, # 'ы' 17: 3, # 'ь' 30: 1, # 'э' 27: 3, # 'ю' 16: 3, # 'я' }, 1: { # 'о' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 2, # 'а' 21: 3, # 'б' 10: 3, # 'в' 19: 3, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 3, # 'ж' 20: 3, # 'з' 4: 3, # 'и' 23: 3, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 3, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 3, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 2, # 'у' 39: 2, # 'ф' 26: 3, # 'х' 28: 2, # 'ц' 22: 3, # 'ч' 25: 3, # 'ш' 29: 3, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 2, # 'э' 27: 3, # 'ю' 16: 3, # 'я' }, 15: { # 'п' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 1, # 'б' 10: 0, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 3, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 2, # 'к' 8: 3, # 'л' 12: 1, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 2, # 'п' 9: 3, # 'р' 7: 2, # 'с' 6: 2, # 'т' 14: 3, # 'у' 39: 1, # 'ф' 26: 0, # 'х' 28: 2, # 'ц' 22: 2, # 'ч' 25: 1, # 'ш' 29: 1, # 'щ' 54: 0, # 'ъ' 18: 3, # 'ы' 17: 2, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 3, # 'я' }, 9: { # 'р' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 2, # 'б' 10: 3, # 'в' 19: 3, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 3, # 'ж' 20: 2, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 3, # 'к' 8: 2, # 'л' 12: 3, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 2, # 'п' 9: 2, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 3, # 'у' 39: 2, # 'ф' 26: 3, # 'х' 28: 2, # 'ц' 22: 2, # 'ч' 25: 3, # 'ш' 29: 2, # 'щ' 54: 0, # 'ъ' 18: 3, # 'ы' 17: 3, # 'ь' 30: 2, # 'э' 27: 2, # 'ю' 16: 3, # 'я' }, 7: { # 'с' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 1, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 2, # 'б' 10: 3, # 'в' 19: 2, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 2, # 'ж' 20: 2, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 3, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 3, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 3, # 'у' 39: 2, # 'ф' 26: 3, # 'х' 28: 2, # 'ц' 22: 3, # 'ч' 25: 2, # 'ш' 29: 1, # 'щ' 54: 2, # 'ъ' 18: 3, # 'ы' 17: 3, # 'ь' 30: 2, # 'э' 27: 3, # 'ю' 16: 3, # 'я' }, 6: { # 'т' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 2, # 'б' 10: 3, # 'в' 19: 2, # 'г' 13: 2, # 'д' 2: 3, # 'е' 24: 1, # 'ж' 20: 1, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 2, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 2, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 2, # 'т' 14: 3, # 'у' 39: 2, # 'ф' 26: 2, # 'х' 28: 2, # 'ц' 22: 2, # 'ч' 25: 2, # 'ш' 29: 2, # 'щ' 54: 2, # 'ъ' 18: 3, # 'ы' 17: 3, # 'ь' 30: 2, # 'э' 27: 2, # 'ю' 16: 3, # 'я' }, 14: { # 'у' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 2, # 'а' 21: 3, # 'б' 10: 3, # 'в' 19: 3, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 3, # 'ж' 20: 3, # 'з' 4: 2, # 'и' 23: 2, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 3, # 'м' 5: 3, # 'н' 1: 2, # 'о' 15: 3, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 1, # 'у' 39: 2, # 'ф' 26: 3, # 'х' 28: 2, # 'ц' 22: 3, # 'ч' 25: 3, # 'ш' 29: 3, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 2, # 'э' 27: 3, # 'ю' 16: 2, # 'я' }, 39: { # 'ф' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 1, # 'б' 10: 0, # 'в' 19: 1, # 'г' 13: 0, # 'д' 2: 3, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 1, # 'к' 8: 2, # 'л' 12: 1, # 'м' 5: 1, # 'н' 1: 3, # 'о' 15: 1, # 'п' 9: 2, # 'р' 7: 2, # 'с' 6: 2, # 'т' 14: 2, # 'у' 39: 2, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 1, # 'ч' 25: 1, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 2, # 'ы' 17: 1, # 'ь' 30: 2, # 'э' 27: 1, # 'ю' 16: 1, # 'я' }, 26: { # 'х' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 0, # 'б' 10: 3, # 'в' 19: 1, # 'г' 13: 1, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 1, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 1, # 'к' 8: 2, # 'л' 12: 2, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 1, # 'п' 9: 3, # 'р' 7: 2, # 'с' 6: 2, # 'т' 14: 2, # 'у' 39: 1, # 'ф' 26: 1, # 'х' 28: 1, # 'ц' 22: 1, # 'ч' 25: 2, # 'ш' 29: 0, # 'щ' 54: 1, # 'ъ' 18: 0, # 'ы' 17: 1, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 0, # 'я' }, 28: { # 'ц' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 1, # 'б' 10: 2, # 'в' 19: 1, # 'г' 13: 1, # 'д' 2: 3, # 'е' 24: 0, # 'ж' 20: 1, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 2, # 'к' 8: 1, # 'л' 12: 1, # 'м' 5: 1, # 'н' 1: 3, # 'о' 15: 0, # 'п' 9: 1, # 'р' 7: 0, # 'с' 6: 1, # 'т' 14: 3, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 1, # 'ц' 22: 0, # 'ч' 25: 1, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 3, # 'ы' 17: 1, # 'ь' 30: 0, # 'э' 27: 1, # 'ю' 16: 0, # 'я' }, 22: { # 'ч' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 1, # 'б' 10: 1, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 3, # 'е' 24: 1, # 'ж' 20: 0, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 3, # 'к' 8: 2, # 'л' 12: 1, # 'м' 5: 3, # 'н' 1: 2, # 'о' 15: 0, # 'п' 9: 2, # 'р' 7: 1, # 'с' 6: 3, # 'т' 14: 3, # 'у' 39: 1, # 'ф' 26: 1, # 'х' 28: 0, # 'ц' 22: 1, # 'ч' 25: 2, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 3, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 25: { # 'ш' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 1, # 'б' 10: 2, # 'в' 19: 1, # 'г' 13: 0, # 'д' 2: 3, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 2, # 'м' 5: 3, # 'н' 1: 3, # 'о' 15: 2, # 'п' 9: 2, # 'р' 7: 1, # 'с' 6: 2, # 'т' 14: 3, # 'у' 39: 2, # 'ф' 26: 1, # 'х' 28: 1, # 'ц' 22: 1, # 'ч' 25: 1, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 3, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 0, # 'я' }, 29: { # 'щ' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 3, # 'а' 21: 0, # 'б' 10: 1, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 3, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 3, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 0, # 'л' 12: 1, # 'м' 5: 2, # 'н' 1: 1, # 'о' 15: 0, # 'п' 9: 2, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 2, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 2, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 0, # 'я' }, 54: { # 'ъ' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 0, # 'а' 21: 0, # 'б' 10: 0, # 'в' 19: 0, # 'г' 13: 0, # 'д' 2: 2, # 'е' 24: 0, # 'ж' 20: 0, # 'з' 4: 0, # 'и' 23: 0, # 'й' 11: 0, # 'к' 8: 0, # 'л' 12: 0, # 'м' 5: 0, # 'н' 1: 0, # 'о' 15: 0, # 'п' 9: 0, # 'р' 7: 0, # 'с' 6: 0, # 'т' 14: 0, # 'у' 39: 0, # 'ф' 26: 0, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 0, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 1, # 'ю' 16: 2, # 'я' }, 18: { # 'ы' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 0, # 'а' 21: 3, # 'б' 10: 3, # 'в' 19: 2, # 'г' 13: 2, # 'д' 2: 3, # 'е' 24: 2, # 'ж' 20: 2, # 'з' 4: 2, # 'и' 23: 3, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 3, # 'м' 5: 3, # 'н' 1: 1, # 'о' 15: 3, # 'п' 9: 3, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 1, # 'у' 39: 0, # 'ф' 26: 3, # 'х' 28: 2, # 'ц' 22: 3, # 'ч' 25: 3, # 'ш' 29: 2, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 0, # 'ю' 16: 2, # 'я' }, 17: { # 'ь' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 0, # 'а' 21: 2, # 'б' 10: 2, # 'в' 19: 2, # 'г' 13: 2, # 'д' 2: 3, # 'е' 24: 1, # 'ж' 20: 3, # 'з' 4: 2, # 'и' 23: 0, # 'й' 11: 3, # 'к' 8: 0, # 'л' 12: 3, # 'м' 5: 3, # 'н' 1: 2, # 'о' 15: 2, # 'п' 9: 1, # 'р' 7: 3, # 'с' 6: 2, # 'т' 14: 0, # 'у' 39: 2, # 'ф' 26: 1, # 'х' 28: 2, # 'ц' 22: 2, # 'ч' 25: 3, # 'ш' 29: 2, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 1, # 'э' 27: 3, # 'ю' 16: 3, # 'я' }, 30: { # 'э' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 1, # 'М' 31: 1, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 1, # 'Р' 32: 1, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 1, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 0, # 'а' 21: 1, # 'б' 10: 1, # 'в' 19: 1, # 'г' 13: 2, # 'д' 2: 1, # 'е' 24: 0, # 'ж' 20: 1, # 'з' 4: 0, # 'и' 23: 2, # 'й' 11: 2, # 'к' 8: 2, # 'л' 12: 2, # 'м' 5: 2, # 'н' 1: 0, # 'о' 15: 2, # 'п' 9: 2, # 'р' 7: 2, # 'с' 6: 3, # 'т' 14: 1, # 'у' 39: 2, # 'ф' 26: 1, # 'х' 28: 0, # 'ц' 22: 0, # 'ч' 25: 1, # 'ш' 29: 0, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 1, # 'э' 27: 1, # 'ю' 16: 1, # 'я' }, 27: { # 'ю' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 2, # 'а' 21: 3, # 'б' 10: 1, # 'в' 19: 2, # 'г' 13: 3, # 'д' 2: 1, # 'е' 24: 2, # 'ж' 20: 2, # 'з' 4: 1, # 'и' 23: 1, # 'й' 11: 2, # 'к' 8: 2, # 'л' 12: 2, # 'м' 5: 2, # 'н' 1: 1, # 'о' 15: 2, # 'п' 9: 2, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 0, # 'у' 39: 1, # 'ф' 26: 2, # 'х' 28: 2, # 'ц' 22: 2, # 'ч' 25: 2, # 'ш' 29: 3, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 1, # 'э' 27: 2, # 'ю' 16: 1, # 'я' }, 16: { # 'я' 37: 0, # 'А' 44: 0, # 'Б' 33: 0, # 'В' 46: 0, # 'Г' 41: 0, # 'Д' 48: 0, # 'Е' 56: 0, # 'Ж' 51: 0, # 'З' 42: 0, # 'И' 60: 0, # 'Й' 36: 0, # 'К' 49: 0, # 'Л' 38: 0, # 'М' 31: 0, # 'Н' 34: 0, # 'О' 35: 0, # 'П' 45: 0, # 'Р' 32: 0, # 'С' 40: 0, # 'Т' 52: 0, # 'У' 53: 0, # 'Ф' 55: 0, # 'Х' 58: 0, # 'Ц' 50: 0, # 'Ч' 57: 0, # 'Ш' 63: 0, # 'Щ' 62: 0, # 'Ы' 61: 0, # 'Ь' 47: 0, # 'Э' 59: 0, # 'Ю' 43: 0, # 'Я' 3: 0, # 'а' 21: 2, # 'б' 10: 3, # 'в' 19: 2, # 'г' 13: 3, # 'д' 2: 3, # 'е' 24: 3, # 'ж' 20: 3, # 'з' 4: 2, # 'и' 23: 2, # 'й' 11: 3, # 'к' 8: 3, # 'л' 12: 3, # 'м' 5: 3, # 'н' 1: 0, # 'о' 15: 2, # 'п' 9: 2, # 'р' 7: 3, # 'с' 6: 3, # 'т' 14: 1, # 'у' 39: 1, # 'ф' 26: 3, # 'х' 28: 2, # 'ц' 22: 2, # 'ч' 25: 2, # 'ш' 29: 3, # 'щ' 54: 0, # 'ъ' 18: 0, # 'ы' 17: 0, # 'ь' 30: 0, # 'э' 27: 2, # 'ю' 16: 2, # 'я' }, } # 255: Undefined characters that did not exist in training text # 254: Carriage/Return # 253: symbol (punctuation) that does not belong to word # 252: 0 - 9 # 251: Control characters # Character Mapping Table(s): IBM866_RUSSIAN_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 142, # 'A' 66: 143, # 'B' 67: 144, # 'C' 68: 145, # 'D' 69: 146, # 'E' 70: 147, # 'F' 71: 148, # 'G' 72: 149, # 'H' 73: 150, # 'I' 74: 151, # 'J' 75: 152, # 'K' 76: 74, # 'L' 77: 153, # 'M' 78: 75, # 'N' 79: 154, # 'O' 80: 155, # 'P' 81: 156, # 'Q' 82: 157, # 'R' 83: 158, # 'S' 84: 159, # 'T' 85: 160, # 'U' 86: 161, # 'V' 87: 162, # 'W' 88: 163, # 'X' 89: 164, # 'Y' 90: 165, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 71, # 'a' 98: 172, # 'b' 99: 66, # 'c' 100: 173, # 'd' 101: 65, # 'e' 102: 174, # 'f' 103: 76, # 'g' 104: 175, # 'h' 105: 64, # 'i' 106: 176, # 'j' 107: 177, # 'k' 108: 77, # 'l' 109: 72, # 'm' 110: 178, # 'n' 111: 69, # 'o' 112: 67, # 'p' 113: 179, # 'q' 114: 78, # 'r' 115: 73, # 's' 116: 180, # 't' 117: 181, # 'u' 118: 79, # 'v' 119: 182, # 'w' 120: 183, # 'x' 121: 184, # 'y' 122: 185, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 37, # 'А' 129: 44, # 'Б' 130: 33, # 'В' 131: 46, # 'Г' 132: 41, # 'Д' 133: 48, # 'Е' 134: 56, # 'Ж' 135: 51, # 'З' 136: 42, # 'И' 137: 60, # 'Й' 138: 36, # 'К' 139: 49, # 'Л' 140: 38, # 'М' 141: 31, # 'Н' 142: 34, # 'О' 143: 35, # 'П' 144: 45, # 'Р' 145: 32, # 'С' 146: 40, # 'Т' 147: 52, # 'У' 148: 53, # 'Ф' 149: 55, # 'Х' 150: 58, # 'Ц' 151: 50, # 'Ч' 152: 57, # 'Ш' 153: 63, # 'Щ' 154: 70, # 'Ъ' 155: 62, # 'Ы' 156: 61, # 'Ь' 157: 47, # 'Э' 158: 59, # 'Ю' 159: 43, # 'Я' 160: 3, # 'а' 161: 21, # 'б' 162: 10, # 'в' 163: 19, # 'г' 164: 13, # 'д' 165: 2, # 'е' 166: 24, # 'ж' 167: 20, # 'з' 168: 4, # 'и' 169: 23, # 'й' 170: 11, # 'к' 171: 8, # 'л' 172: 12, # 'м' 173: 5, # 'н' 174: 1, # 'о' 175: 15, # 'п' 176: 191, # '░' 177: 192, # '▒' 178: 193, # '▓' 179: 194, # '│' 180: 195, # '┤' 181: 196, # '╡' 182: 197, # '╢' 183: 198, # '╖' 184: 199, # '╕' 185: 200, # '╣' 186: 201, # '║' 187: 202, # '╗' 188: 203, # '╝' 189: 204, # '╜' 190: 205, # '╛' 191: 206, # '┐' 192: 207, # '└' 193: 208, # '┴' 194: 209, # '┬' 195: 210, # '├' 196: 211, # '─' 197: 212, # '┼' 198: 213, # '╞' 199: 214, # '╟' 200: 215, # '╚' 201: 216, # '╔' 202: 217, # '╩' 203: 218, # '╦' 204: 219, # '╠' 205: 220, # '═' 206: 221, # '╬' 207: 222, # '╧' 208: 223, # '╨' 209: 224, # '╤' 210: 225, # '╥' 211: 226, # '╙' 212: 227, # '╘' 213: 228, # '╒' 214: 229, # '╓' 215: 230, # '╫' 216: 231, # '╪' 217: 232, # '┘' 218: 233, # '┌' 219: 234, # '█' 220: 235, # '▄' 221: 236, # '▌' 222: 237, # '▐' 223: 238, # '▀' 224: 9, # 'р' 225: 7, # 'с' 226: 6, # 'т' 227: 14, # 'у' 228: 39, # 'ф' 229: 26, # 'х' 230: 28, # 'ц' 231: 22, # 'ч' 232: 25, # 'ш' 233: 29, # 'щ' 234: 54, # 'ъ' 235: 18, # 'ы' 236: 17, # 'ь' 237: 30, # 'э' 238: 27, # 'ю' 239: 16, # 'я' 240: 239, # 'Ё' 241: 68, # 'ё' 242: 240, # 'Є' 243: 241, # 'є' 244: 242, # 'Ї' 245: 243, # 'ї' 246: 244, # 'Ў' 247: 245, # 'ў' 248: 246, # '°' 249: 247, # '∙' 250: 248, # '·' 251: 249, # '√' 252: 250, # '№' 253: 251, # '¤' 254: 252, # '■' 255: 255, # '\xa0' } IBM866_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='IBM866', language='Russian', char_to_order_map=IBM866_RUSSIAN_CHAR_TO_ORDER, language_model=RUSSIAN_LANG_MODEL, typical_positive_ratio=0.976601, keep_ascii_letters=False, alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') WINDOWS_1251_RUSSIAN_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 142, # 'A' 66: 143, # 'B' 67: 144, # 'C' 68: 145, # 'D' 69: 146, # 'E' 70: 147, # 'F' 71: 148, # 'G' 72: 149, # 'H' 73: 150, # 'I' 74: 151, # 'J' 75: 152, # 'K' 76: 74, # 'L' 77: 153, # 'M' 78: 75, # 'N' 79: 154, # 'O' 80: 155, # 'P' 81: 156, # 'Q' 82: 157, # 'R' 83: 158, # 'S' 84: 159, # 'T' 85: 160, # 'U' 86: 161, # 'V' 87: 162, # 'W' 88: 163, # 'X' 89: 164, # 'Y' 90: 165, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 71, # 'a' 98: 172, # 'b' 99: 66, # 'c' 100: 173, # 'd' 101: 65, # 'e' 102: 174, # 'f' 103: 76, # 'g' 104: 175, # 'h' 105: 64, # 'i' 106: 176, # 'j' 107: 177, # 'k' 108: 77, # 'l' 109: 72, # 'm' 110: 178, # 'n' 111: 69, # 'o' 112: 67, # 'p' 113: 179, # 'q' 114: 78, # 'r' 115: 73, # 's' 116: 180, # 't' 117: 181, # 'u' 118: 79, # 'v' 119: 182, # 'w' 120: 183, # 'x' 121: 184, # 'y' 122: 185, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 191, # 'Ђ' 129: 192, # 'Ѓ' 130: 193, # '‚' 131: 194, # 'ѓ' 132: 195, # '„' 133: 196, # '…' 134: 197, # '†' 135: 198, # '‡' 136: 199, # '€' 137: 200, # '‰' 138: 201, # 'Љ' 139: 202, # '‹' 140: 203, # 'Њ' 141: 204, # 'Ќ' 142: 205, # 'Ћ' 143: 206, # 'Џ' 144: 207, # 'ђ' 145: 208, # '‘' 146: 209, # '’' 147: 210, # '“' 148: 211, # '”' 149: 212, # '•' 150: 213, # '–' 151: 214, # '—' 152: 215, # None 153: 216, # '™' 154: 217, # 'љ' 155: 218, # '›' 156: 219, # 'њ' 157: 220, # 'ќ' 158: 221, # 'ћ' 159: 222, # 'џ' 160: 223, # '\xa0' 161: 224, # 'Ў' 162: 225, # 'ў' 163: 226, # 'Ј' 164: 227, # '¤' 165: 228, # 'Ґ' 166: 229, # '¦' 167: 230, # '§' 168: 231, # 'Ё' 169: 232, # '©' 170: 233, # 'Є' 171: 234, # '«' 172: 235, # '¬' 173: 236, # '\xad' 174: 237, # '®' 175: 238, # 'Ї' 176: 239, # '°' 177: 240, # '±' 178: 241, # 'І' 179: 242, # 'і' 180: 243, # 'ґ' 181: 244, # 'µ' 182: 245, # '¶' 183: 246, # '·' 184: 68, # 'ё' 185: 247, # '№' 186: 248, # 'є' 187: 249, # '»' 188: 250, # 'ј' 189: 251, # 'Ѕ' 190: 252, # 'ѕ' 191: 253, # 'ї' 192: 37, # 'А' 193: 44, # 'Б' 194: 33, # 'В' 195: 46, # 'Г' 196: 41, # 'Д' 197: 48, # 'Е' 198: 56, # 'Ж' 199: 51, # 'З' 200: 42, # 'И' 201: 60, # 'Й' 202: 36, # 'К' 203: 49, # 'Л' 204: 38, # 'М' 205: 31, # 'Н' 206: 34, # 'О' 207: 35, # 'П' 208: 45, # 'Р' 209: 32, # 'С' 210: 40, # 'Т' 211: 52, # 'У' 212: 53, # 'Ф' 213: 55, # 'Х' 214: 58, # 'Ц' 215: 50, # 'Ч' 216: 57, # 'Ш' 217: 63, # 'Щ' 218: 70, # 'Ъ' 219: 62, # 'Ы' 220: 61, # 'Ь' 221: 47, # 'Э' 222: 59, # 'Ю' 223: 43, # 'Я' 224: 3, # 'а' 225: 21, # 'б' 226: 10, # 'в' 227: 19, # 'г' 228: 13, # 'д' 229: 2, # 'е' 230: 24, # 'ж' 231: 20, # 'з' 232: 4, # 'и' 233: 23, # 'й' 234: 11, # 'к' 235: 8, # 'л' 236: 12, # 'м' 237: 5, # 'н' 238: 1, # 'о' 239: 15, # 'п' 240: 9, # 'р' 241: 7, # 'с' 242: 6, # 'т' 243: 14, # 'у' 244: 39, # 'ф' 245: 26, # 'х' 246: 28, # 'ц' 247: 22, # 'ч' 248: 25, # 'ш' 249: 29, # 'щ' 250: 54, # 'ъ' 251: 18, # 'ы' 252: 17, # 'ь' 253: 30, # 'э' 254: 27, # 'ю' 255: 16, # 'я' } WINDOWS_1251_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1251', language='Russian', char_to_order_map=WINDOWS_1251_RUSSIAN_CHAR_TO_ORDER, language_model=RUSSIAN_LANG_MODEL, typical_positive_ratio=0.976601, keep_ascii_letters=False, alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') IBM855_RUSSIAN_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 142, # 'A' 66: 143, # 'B' 67: 144, # 'C' 68: 145, # 'D' 69: 146, # 'E' 70: 147, # 'F' 71: 148, # 'G' 72: 149, # 'H' 73: 150, # 'I' 74: 151, # 'J' 75: 152, # 'K' 76: 74, # 'L' 77: 153, # 'M' 78: 75, # 'N' 79: 154, # 'O' 80: 155, # 'P' 81: 156, # 'Q' 82: 157, # 'R' 83: 158, # 'S' 84: 159, # 'T' 85: 160, # 'U' 86: 161, # 'V' 87: 162, # 'W' 88: 163, # 'X' 89: 164, # 'Y' 90: 165, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 71, # 'a' 98: 172, # 'b' 99: 66, # 'c' 100: 173, # 'd' 101: 65, # 'e' 102: 174, # 'f' 103: 76, # 'g' 104: 175, # 'h' 105: 64, # 'i' 106: 176, # 'j' 107: 177, # 'k' 108: 77, # 'l' 109: 72, # 'm' 110: 178, # 'n' 111: 69, # 'o' 112: 67, # 'p' 113: 179, # 'q' 114: 78, # 'r' 115: 73, # 's' 116: 180, # 't' 117: 181, # 'u' 118: 79, # 'v' 119: 182, # 'w' 120: 183, # 'x' 121: 184, # 'y' 122: 185, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 191, # 'ђ' 129: 192, # 'Ђ' 130: 193, # 'ѓ' 131: 194, # 'Ѓ' 132: 68, # 'ё' 133: 195, # 'Ё' 134: 196, # 'є' 135: 197, # 'Є' 136: 198, # 'ѕ' 137: 199, # 'Ѕ' 138: 200, # 'і' 139: 201, # 'І' 140: 202, # 'ї' 141: 203, # 'Ї' 142: 204, # 'ј' 143: 205, # 'Ј' 144: 206, # 'љ' 145: 207, # 'Љ' 146: 208, # 'њ' 147: 209, # 'Њ' 148: 210, # 'ћ' 149: 211, # 'Ћ' 150: 212, # 'ќ' 151: 213, # 'Ќ' 152: 214, # 'ў' 153: 215, # 'Ў' 154: 216, # 'џ' 155: 217, # 'Џ' 156: 27, # 'ю' 157: 59, # 'Ю' 158: 54, # 'ъ' 159: 70, # 'Ъ' 160: 3, # 'а' 161: 37, # 'А' 162: 21, # 'б' 163: 44, # 'Б' 164: 28, # 'ц' 165: 58, # 'Ц' 166: 13, # 'д' 167: 41, # 'Д' 168: 2, # 'е' 169: 48, # 'Е' 170: 39, # 'ф' 171: 53, # 'Ф' 172: 19, # 'г' 173: 46, # 'Г' 174: 218, # '«' 175: 219, # '»' 176: 220, # '░' 177: 221, # '▒' 178: 222, # '▓' 179: 223, # '│' 180: 224, # '┤' 181: 26, # 'х' 182: 55, # 'Х' 183: 4, # 'и' 184: 42, # 'И' 185: 225, # '╣' 186: 226, # '║' 187: 227, # '╗' 188: 228, # '╝' 189: 23, # 'й' 190: 60, # 'Й' 191: 229, # '┐' 192: 230, # '└' 193: 231, # '┴' 194: 232, # '┬' 195: 233, # '├' 196: 234, # '─' 197: 235, # '┼' 198: 11, # 'к' 199: 36, # 'К' 200: 236, # '╚' 201: 237, # '╔' 202: 238, # '╩' 203: 239, # '╦' 204: 240, # '╠' 205: 241, # '═' 206: 242, # '╬' 207: 243, # '¤' 208: 8, # 'л' 209: 49, # 'Л' 210: 12, # 'м' 211: 38, # 'М' 212: 5, # 'н' 213: 31, # 'Н' 214: 1, # 'о' 215: 34, # 'О' 216: 15, # 'п' 217: 244, # '┘' 218: 245, # '┌' 219: 246, # '█' 220: 247, # '▄' 221: 35, # 'П' 222: 16, # 'я' 223: 248, # '▀' 224: 43, # 'Я' 225: 9, # 'р' 226: 45, # 'Р' 227: 7, # 'с' 228: 32, # 'С' 229: 6, # 'т' 230: 40, # 'Т' 231: 14, # 'у' 232: 52, # 'У' 233: 24, # 'ж' 234: 56, # 'Ж' 235: 10, # 'в' 236: 33, # 'В' 237: 17, # 'ь' 238: 61, # 'Ь' 239: 249, # '№' 240: 250, # '\xad' 241: 18, # 'ы' 242: 62, # 'Ы' 243: 20, # 'з' 244: 51, # 'З' 245: 25, # 'ш' 246: 57, # 'Ш' 247: 30, # 'э' 248: 47, # 'Э' 249: 29, # 'щ' 250: 63, # 'Щ' 251: 22, # 'ч' 252: 50, # 'Ч' 253: 251, # '§' 254: 252, # '■' 255: 255, # '\xa0' } IBM855_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='IBM855', language='Russian', char_to_order_map=IBM855_RUSSIAN_CHAR_TO_ORDER, language_model=RUSSIAN_LANG_MODEL, typical_positive_ratio=0.976601, keep_ascii_letters=False, alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') KOI8_R_RUSSIAN_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 142, # 'A' 66: 143, # 'B' 67: 144, # 'C' 68: 145, # 'D' 69: 146, # 'E' 70: 147, # 'F' 71: 148, # 'G' 72: 149, # 'H' 73: 150, # 'I' 74: 151, # 'J' 75: 152, # 'K' 76: 74, # 'L' 77: 153, # 'M' 78: 75, # 'N' 79: 154, # 'O' 80: 155, # 'P' 81: 156, # 'Q' 82: 157, # 'R' 83: 158, # 'S' 84: 159, # 'T' 85: 160, # 'U' 86: 161, # 'V' 87: 162, # 'W' 88: 163, # 'X' 89: 164, # 'Y' 90: 165, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 71, # 'a' 98: 172, # 'b' 99: 66, # 'c' 100: 173, # 'd' 101: 65, # 'e' 102: 174, # 'f' 103: 76, # 'g' 104: 175, # 'h' 105: 64, # 'i' 106: 176, # 'j' 107: 177, # 'k' 108: 77, # 'l' 109: 72, # 'm' 110: 178, # 'n' 111: 69, # 'o' 112: 67, # 'p' 113: 179, # 'q' 114: 78, # 'r' 115: 73, # 's' 116: 180, # 't' 117: 181, # 'u' 118: 79, # 'v' 119: 182, # 'w' 120: 183, # 'x' 121: 184, # 'y' 122: 185, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 191, # '─' 129: 192, # '│' 130: 193, # '┌' 131: 194, # '┐' 132: 195, # '└' 133: 196, # '┘' 134: 197, # '├' 135: 198, # '┤' 136: 199, # '┬' 137: 200, # '┴' 138: 201, # '┼' 139: 202, # '▀' 140: 203, # '▄' 141: 204, # '█' 142: 205, # '▌' 143: 206, # '▐' 144: 207, # '░' 145: 208, # '▒' 146: 209, # '▓' 147: 210, # '⌠' 148: 211, # '■' 149: 212, # '∙' 150: 213, # '√' 151: 214, # '≈' 152: 215, # '≤' 153: 216, # '≥' 154: 217, # '\xa0' 155: 218, # '⌡' 156: 219, # '°' 157: 220, # '²' 158: 221, # '·' 159: 222, # '÷' 160: 223, # '═' 161: 224, # '║' 162: 225, # '╒' 163: 68, # 'ё' 164: 226, # '╓' 165: 227, # '╔' 166: 228, # '╕' 167: 229, # '╖' 168: 230, # '╗' 169: 231, # '╘' 170: 232, # '╙' 171: 233, # '╚' 172: 234, # '╛' 173: 235, # '╜' 174: 236, # '╝' 175: 237, # '╞' 176: 238, # '╟' 177: 239, # '╠' 178: 240, # '╡' 179: 241, # 'Ё' 180: 242, # '╢' 181: 243, # '╣' 182: 244, # '╤' 183: 245, # '╥' 184: 246, # '╦' 185: 247, # '╧' 186: 248, # '╨' 187: 249, # '╩' 188: 250, # '╪' 189: 251, # '╫' 190: 252, # '╬' 191: 253, # '©' 192: 27, # 'ю' 193: 3, # 'а' 194: 21, # 'б' 195: 28, # 'ц' 196: 13, # 'д' 197: 2, # 'е' 198: 39, # 'ф' 199: 19, # 'г' 200: 26, # 'х' 201: 4, # 'и' 202: 23, # 'й' 203: 11, # 'к' 204: 8, # 'л' 205: 12, # 'м' 206: 5, # 'н' 207: 1, # 'о' 208: 15, # 'п' 209: 16, # 'я' 210: 9, # 'р' 211: 7, # 'с' 212: 6, # 'т' 213: 14, # 'у' 214: 24, # 'ж' 215: 10, # 'в' 216: 17, # 'ь' 217: 18, # 'ы' 218: 20, # 'з' 219: 25, # 'ш' 220: 30, # 'э' 221: 29, # 'щ' 222: 22, # 'ч' 223: 54, # 'ъ' 224: 59, # 'Ю' 225: 37, # 'А' 226: 44, # 'Б' 227: 58, # 'Ц' 228: 41, # 'Д' 229: 48, # 'Е' 230: 53, # 'Ф' 231: 46, # 'Г' 232: 55, # 'Х' 233: 42, # 'И' 234: 60, # 'Й' 235: 36, # 'К' 236: 49, # 'Л' 237: 38, # 'М' 238: 31, # 'Н' 239: 34, # 'О' 240: 35, # 'П' 241: 43, # 'Я' 242: 45, # 'Р' 243: 32, # 'С' 244: 40, # 'Т' 245: 52, # 'У' 246: 56, # 'Ж' 247: 33, # 'В' 248: 61, # 'Ь' 249: 62, # 'Ы' 250: 51, # 'З' 251: 57, # 'Ш' 252: 47, # 'Э' 253: 63, # 'Щ' 254: 50, # 'Ч' 255: 70, # 'Ъ' } KOI8_R_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='KOI8-R', language='Russian', char_to_order_map=KOI8_R_RUSSIAN_CHAR_TO_ORDER, language_model=RUSSIAN_LANG_MODEL, typical_positive_ratio=0.976601, keep_ascii_letters=False, alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') MACCYRILLIC_RUSSIAN_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 142, # 'A' 66: 143, # 'B' 67: 144, # 'C' 68: 145, # 'D' 69: 146, # 'E' 70: 147, # 'F' 71: 148, # 'G' 72: 149, # 'H' 73: 150, # 'I' 74: 151, # 'J' 75: 152, # 'K' 76: 74, # 'L' 77: 153, # 'M' 78: 75, # 'N' 79: 154, # 'O' 80: 155, # 'P' 81: 156, # 'Q' 82: 157, # 'R' 83: 158, # 'S' 84: 159, # 'T' 85: 160, # 'U' 86: 161, # 'V' 87: 162, # 'W' 88: 163, # 'X' 89: 164, # 'Y' 90: 165, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 71, # 'a' 98: 172, # 'b' 99: 66, # 'c' 100: 173, # 'd' 101: 65, # 'e' 102: 174, # 'f' 103: 76, # 'g' 104: 175, # 'h' 105: 64, # 'i' 106: 176, # 'j' 107: 177, # 'k' 108: 77, # 'l' 109: 72, # 'm' 110: 178, # 'n' 111: 69, # 'o' 112: 67, # 'p' 113: 179, # 'q' 114: 78, # 'r' 115: 73, # 's' 116: 180, # 't' 117: 181, # 'u' 118: 79, # 'v' 119: 182, # 'w' 120: 183, # 'x' 121: 184, # 'y' 122: 185, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 37, # 'А' 129: 44, # 'Б' 130: 33, # 'В' 131: 46, # 'Г' 132: 41, # 'Д' 133: 48, # 'Е' 134: 56, # 'Ж' 135: 51, # 'З' 136: 42, # 'И' 137: 60, # 'Й' 138: 36, # 'К' 139: 49, # 'Л' 140: 38, # 'М' 141: 31, # 'Н' 142: 34, # 'О' 143: 35, # 'П' 144: 45, # 'Р' 145: 32, # 'С' 146: 40, # 'Т' 147: 52, # 'У' 148: 53, # 'Ф' 149: 55, # 'Х' 150: 58, # 'Ц' 151: 50, # 'Ч' 152: 57, # 'Ш' 153: 63, # 'Щ' 154: 70, # 'Ъ' 155: 62, # 'Ы' 156: 61, # 'Ь' 157: 47, # 'Э' 158: 59, # 'Ю' 159: 43, # 'Я' 160: 191, # '†' 161: 192, # '°' 162: 193, # 'Ґ' 163: 194, # '£' 164: 195, # '§' 165: 196, # '•' 166: 197, # '¶' 167: 198, # 'І' 168: 199, # '®' 169: 200, # '©' 170: 201, # '™' 171: 202, # 'Ђ' 172: 203, # 'ђ' 173: 204, # '≠' 174: 205, # 'Ѓ' 175: 206, # 'ѓ' 176: 207, # '∞' 177: 208, # '±' 178: 209, # '≤' 179: 210, # '≥' 180: 211, # 'і' 181: 212, # 'µ' 182: 213, # 'ґ' 183: 214, # 'Ј' 184: 215, # 'Є' 185: 216, # 'є' 186: 217, # 'Ї' 187: 218, # 'ї' 188: 219, # 'Љ' 189: 220, # 'љ' 190: 221, # 'Њ' 191: 222, # 'њ' 192: 223, # 'ј' 193: 224, # 'Ѕ' 194: 225, # '¬' 195: 226, # '√' 196: 227, # 'ƒ' 197: 228, # '≈' 198: 229, # '∆' 199: 230, # '«' 200: 231, # '»' 201: 232, # '…' 202: 233, # '\xa0' 203: 234, # 'Ћ' 204: 235, # 'ћ' 205: 236, # 'Ќ' 206: 237, # 'ќ' 207: 238, # 'ѕ' 208: 239, # '–' 209: 240, # '—' 210: 241, # '“' 211: 242, # '”' 212: 243, # '‘' 213: 244, # '’' 214: 245, # '÷' 215: 246, # '„' 216: 247, # 'Ў' 217: 248, # 'ў' 218: 249, # 'Џ' 219: 250, # 'џ' 220: 251, # '№' 221: 252, # 'Ё' 222: 68, # 'ё' 223: 16, # 'я' 224: 3, # 'а' 225: 21, # 'б' 226: 10, # 'в' 227: 19, # 'г' 228: 13, # 'д' 229: 2, # 'е' 230: 24, # 'ж' 231: 20, # 'з' 232: 4, # 'и' 233: 23, # 'й' 234: 11, # 'к' 235: 8, # 'л' 236: 12, # 'м' 237: 5, # 'н' 238: 1, # 'о' 239: 15, # 'п' 240: 9, # 'р' 241: 7, # 'с' 242: 6, # 'т' 243: 14, # 'у' 244: 39, # 'ф' 245: 26, # 'х' 246: 28, # 'ц' 247: 22, # 'ч' 248: 25, # 'ш' 249: 29, # 'щ' 250: 54, # 'ъ' 251: 18, # 'ы' 252: 17, # 'ь' 253: 30, # 'э' 254: 27, # 'ю' 255: 255, # '€' } MACCYRILLIC_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='MacCyrillic', language='Russian', char_to_order_map=MACCYRILLIC_RUSSIAN_CHAR_TO_ORDER, language_model=RUSSIAN_LANG_MODEL, typical_positive_ratio=0.976601, keep_ascii_letters=False, alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') ISO_8859_5_RUSSIAN_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 142, # 'A' 66: 143, # 'B' 67: 144, # 'C' 68: 145, # 'D' 69: 146, # 'E' 70: 147, # 'F' 71: 148, # 'G' 72: 149, # 'H' 73: 150, # 'I' 74: 151, # 'J' 75: 152, # 'K' 76: 74, # 'L' 77: 153, # 'M' 78: 75, # 'N' 79: 154, # 'O' 80: 155, # 'P' 81: 156, # 'Q' 82: 157, # 'R' 83: 158, # 'S' 84: 159, # 'T' 85: 160, # 'U' 86: 161, # 'V' 87: 162, # 'W' 88: 163, # 'X' 89: 164, # 'Y' 90: 165, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 71, # 'a' 98: 172, # 'b' 99: 66, # 'c' 100: 173, # 'd' 101: 65, # 'e' 102: 174, # 'f' 103: 76, # 'g' 104: 175, # 'h' 105: 64, # 'i' 106: 176, # 'j' 107: 177, # 'k' 108: 77, # 'l' 109: 72, # 'm' 110: 178, # 'n' 111: 69, # 'o' 112: 67, # 'p' 113: 179, # 'q' 114: 78, # 'r' 115: 73, # 's' 116: 180, # 't' 117: 181, # 'u' 118: 79, # 'v' 119: 182, # 'w' 120: 183, # 'x' 121: 184, # 'y' 122: 185, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 191, # '\x80' 129: 192, # '\x81' 130: 193, # '\x82' 131: 194, # '\x83' 132: 195, # '\x84' 133: 196, # '\x85' 134: 197, # '\x86' 135: 198, # '\x87' 136: 199, # '\x88' 137: 200, # '\x89' 138: 201, # '\x8a' 139: 202, # '\x8b' 140: 203, # '\x8c' 141: 204, # '\x8d' 142: 205, # '\x8e' 143: 206, # '\x8f' 144: 207, # '\x90' 145: 208, # '\x91' 146: 209, # '\x92' 147: 210, # '\x93' 148: 211, # '\x94' 149: 212, # '\x95' 150: 213, # '\x96' 151: 214, # '\x97' 152: 215, # '\x98' 153: 216, # '\x99' 154: 217, # '\x9a' 155: 218, # '\x9b' 156: 219, # '\x9c' 157: 220, # '\x9d' 158: 221, # '\x9e' 159: 222, # '\x9f' 160: 223, # '\xa0' 161: 224, # 'Ё' 162: 225, # 'Ђ' 163: 226, # 'Ѓ' 164: 227, # 'Є' 165: 228, # 'Ѕ' 166: 229, # 'І' 167: 230, # 'Ї' 168: 231, # 'Ј' 169: 232, # 'Љ' 170: 233, # 'Њ' 171: 234, # 'Ћ' 172: 235, # 'Ќ' 173: 236, # '\xad' 174: 237, # 'Ў' 175: 238, # 'Џ' 176: 37, # 'А' 177: 44, # 'Б' 178: 33, # 'В' 179: 46, # 'Г' 180: 41, # 'Д' 181: 48, # 'Е' 182: 56, # 'Ж' 183: 51, # 'З' 184: 42, # 'И' 185: 60, # 'Й' 186: 36, # 'К' 187: 49, # 'Л' 188: 38, # 'М' 189: 31, # 'Н' 190: 34, # 'О' 191: 35, # 'П' 192: 45, # 'Р' 193: 32, # 'С' 194: 40, # 'Т' 195: 52, # 'У' 196: 53, # 'Ф' 197: 55, # 'Х' 198: 58, # 'Ц' 199: 50, # 'Ч' 200: 57, # 'Ш' 201: 63, # 'Щ' 202: 70, # 'Ъ' 203: 62, # 'Ы' 204: 61, # 'Ь' 205: 47, # 'Э' 206: 59, # 'Ю' 207: 43, # 'Я' 208: 3, # 'а' 209: 21, # 'б' 210: 10, # 'в' 211: 19, # 'г' 212: 13, # 'д' 213: 2, # 'е' 214: 24, # 'ж' 215: 20, # 'з' 216: 4, # 'и' 217: 23, # 'й' 218: 11, # 'к' 219: 8, # 'л' 220: 12, # 'м' 221: 5, # 'н' 222: 1, # 'о' 223: 15, # 'п' 224: 9, # 'р' 225: 7, # 'с' 226: 6, # 'т' 227: 14, # 'у' 228: 39, # 'ф' 229: 26, # 'х' 230: 28, # 'ц' 231: 22, # 'ч' 232: 25, # 'ш' 233: 29, # 'щ' 234: 54, # 'ъ' 235: 18, # 'ы' 236: 17, # 'ь' 237: 30, # 'э' 238: 27, # 'ю' 239: 16, # 'я' 240: 239, # '№' 241: 68, # 'ё' 242: 240, # 'ђ' 243: 241, # 'ѓ' 244: 242, # 'є' 245: 243, # 'ѕ' 246: 244, # 'і' 247: 245, # 'ї' 248: 246, # 'ј' 249: 247, # 'љ' 250: 248, # 'њ' 251: 249, # 'ћ' 252: 250, # 'ќ' 253: 251, # '§' 254: 252, # 'ў' 255: 255, # 'џ' } ISO_8859_5_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-5', language='Russian', char_to_order_map=ISO_8859_5_RUSSIAN_CHAR_TO_ORDER, language_model=RUSSIAN_LANG_MODEL, typical_positive_ratio=0.976601, keep_ascii_letters=False, alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') PKH]e,zz=python3.10/site-packages/pip/_vendor/chardet/langthaimodel.pynu[# -*- coding: utf-8 -*- from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel # 3: Positive # 2: Likely # 1: Unlikely # 0: Negative THAI_LANG_MODEL = { 5: { # 'ก' 5: 2, # 'ก' 30: 2, # 'ข' 24: 2, # 'ค' 8: 2, # 'ง' 26: 2, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 3, # 'ฎ' 57: 2, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 2, # 'ณ' 20: 2, # 'ด' 19: 3, # 'ต' 44: 0, # 'ถ' 14: 2, # 'ท' 48: 0, # 'ธ' 3: 2, # 'น' 17: 1, # 'บ' 25: 2, # 'ป' 39: 1, # 'ผ' 62: 1, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 1, # 'ภ' 9: 2, # 'ม' 16: 1, # 'ย' 2: 3, # 'ร' 61: 2, # 'ฤ' 15: 3, # 'ล' 12: 3, # 'ว' 42: 2, # 'ศ' 46: 3, # 'ษ' 18: 2, # 'ส' 21: 2, # 'ห' 4: 3, # 'อ' 63: 1, # 'ฯ' 22: 2, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 3, # 'ำ' 23: 3, # 'ิ' 13: 3, # 'ี' 40: 0, # 'ึ' 27: 2, # 'ื' 32: 2, # 'ุ' 35: 1, # 'ู' 11: 2, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 1, # 'ใ' 33: 2, # 'ไ' 50: 1, # 'ๆ' 37: 3, # '็' 6: 3, # '่' 7: 3, # '้' 38: 2, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 30: { # 'ข' 5: 1, # 'ก' 30: 0, # 'ข' 24: 1, # 'ค' 8: 1, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 2, # 'ณ' 20: 0, # 'ด' 19: 2, # 'ต' 44: 0, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 2, # 'น' 17: 1, # 'บ' 25: 1, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 2, # 'ย' 2: 1, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 2, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 1, # 'ห' 4: 3, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 2, # 'ี' 40: 3, # 'ึ' 27: 1, # 'ื' 32: 1, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 1, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 1, # '็' 6: 2, # '่' 7: 3, # '้' 38: 1, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 24: { # 'ค' 5: 0, # 'ก' 30: 0, # 'ข' 24: 2, # 'ค' 8: 2, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 2, # 'ณ' 20: 2, # 'ด' 19: 2, # 'ต' 44: 0, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 0, # 'บ' 25: 1, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 2, # 'ม' 16: 2, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 3, # 'ล' 12: 3, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 0, # 'ห' 4: 2, # 'อ' 63: 0, # 'ฯ' 22: 2, # 'ะ' 10: 3, # 'ั' 1: 2, # 'า' 36: 3, # 'ำ' 23: 3, # 'ิ' 13: 2, # 'ี' 40: 0, # 'ึ' 27: 3, # 'ื' 32: 3, # 'ุ' 35: 2, # 'ู' 11: 1, # 'เ' 28: 0, # 'แ' 41: 3, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 1, # '็' 6: 3, # '่' 7: 3, # '้' 38: 3, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 8: { # 'ง' 5: 3, # 'ก' 30: 2, # 'ข' 24: 3, # 'ค' 8: 2, # 'ง' 26: 2, # 'จ' 52: 1, # 'ฉ' 34: 2, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 2, # 'ด' 19: 2, # 'ต' 44: 1, # 'ถ' 14: 3, # 'ท' 48: 1, # 'ธ' 3: 3, # 'น' 17: 2, # 'บ' 25: 2, # 'ป' 39: 2, # 'ผ' 62: 1, # 'ฝ' 31: 2, # 'พ' 54: 0, # 'ฟ' 45: 1, # 'ภ' 9: 2, # 'ม' 16: 1, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 2, # 'ว' 42: 2, # 'ศ' 46: 1, # 'ษ' 18: 3, # 'ส' 21: 3, # 'ห' 4: 2, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 1, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 2, # 'ิ' 13: 1, # 'ี' 40: 0, # 'ึ' 27: 1, # 'ื' 32: 1, # 'ุ' 35: 0, # 'ู' 11: 3, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 2, # 'ไ' 50: 3, # 'ๆ' 37: 0, # '็' 6: 2, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 26: { # 'จ' 5: 2, # 'ก' 30: 1, # 'ข' 24: 0, # 'ค' 8: 2, # 'ง' 26: 3, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 2, # 'ด' 19: 1, # 'ต' 44: 1, # 'ถ' 14: 2, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 1, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 1, # 'ม' 16: 1, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 1, # 'ห' 4: 2, # 'อ' 63: 0, # 'ฯ' 22: 3, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 3, # 'ำ' 23: 2, # 'ิ' 13: 1, # 'ี' 40: 3, # 'ึ' 27: 1, # 'ื' 32: 3, # 'ุ' 35: 2, # 'ู' 11: 1, # 'เ' 28: 1, # 'แ' 41: 0, # 'โ' 29: 1, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 2, # '่' 7: 2, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 52: { # 'ฉ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 3, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 3, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 1, # 'ม' 16: 1, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 1, # 'ะ' 10: 1, # 'ั' 1: 1, # 'า' 36: 0, # 'ำ' 23: 1, # 'ิ' 13: 1, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 1, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 34: { # 'ช' 5: 1, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 1, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 1, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 2, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 2, # 'ม' 16: 1, # 'ย' 2: 1, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 2, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 2, # 'ั' 1: 3, # 'า' 36: 1, # 'ำ' 23: 3, # 'ิ' 13: 2, # 'ี' 40: 0, # 'ึ' 27: 3, # 'ื' 32: 3, # 'ุ' 35: 1, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 1, # '็' 6: 3, # '่' 7: 3, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 51: { # 'ซ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 1, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 1, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 0, # 'ห' 4: 2, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 1, # 'ั' 1: 1, # 'า' 36: 0, # 'ำ' 23: 1, # 'ิ' 13: 2, # 'ี' 40: 3, # 'ึ' 27: 2, # 'ื' 32: 1, # 'ุ' 35: 1, # 'ู' 11: 1, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 1, # '็' 6: 1, # '่' 7: 2, # '้' 38: 1, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 47: { # 'ญ' 5: 1, # 'ก' 30: 1, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 0, # 'ซ' 47: 3, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 1, # 'บ' 25: 1, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 1, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 1, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 2, # 'ห' 4: 1, # 'อ' 63: 0, # 'ฯ' 22: 1, # 'ะ' 10: 2, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 1, # 'ิ' 13: 1, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 1, # 'เ' 28: 1, # 'แ' 41: 0, # 'โ' 29: 1, # 'ใ' 33: 0, # 'ไ' 50: 1, # 'ๆ' 37: 0, # '็' 6: 2, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 58: { # 'ฎ' 5: 2, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 1, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 1, # 'ิ' 13: 2, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 57: { # 'ฏ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 3, # 'ิ' 13: 1, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 49: { # 'ฐ' 5: 1, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 2, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 2, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 1, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 1, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 1, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 53: { # 'ฑ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 2, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 3, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 55: { # 'ฒ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 1, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 43: { # 'ณ' 5: 1, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 3, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 3, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 1, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 1, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 3, # 'ะ' 10: 0, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 1, # 'ิ' 13: 2, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 1, # 'เ' 28: 1, # 'แ' 41: 0, # 'โ' 29: 1, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 3, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 20: { # 'ด' 5: 2, # 'ก' 30: 2, # 'ข' 24: 2, # 'ค' 8: 3, # 'ง' 26: 2, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 1, # 'ด' 19: 2, # 'ต' 44: 1, # 'ถ' 14: 2, # 'ท' 48: 0, # 'ธ' 3: 1, # 'น' 17: 1, # 'บ' 25: 1, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 1, # 'ภ' 9: 2, # 'ม' 16: 3, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 2, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 2, # 'ห' 4: 1, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 3, # 'ั' 1: 2, # 'า' 36: 2, # 'ำ' 23: 3, # 'ิ' 13: 3, # 'ี' 40: 1, # 'ึ' 27: 2, # 'ื' 32: 3, # 'ุ' 35: 2, # 'ู' 11: 2, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 2, # 'ไ' 50: 2, # 'ๆ' 37: 2, # '็' 6: 1, # '่' 7: 3, # '้' 38: 1, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 19: { # 'ต' 5: 2, # 'ก' 30: 1, # 'ข' 24: 1, # 'ค' 8: 0, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 1, # 'ด' 19: 1, # 'ต' 44: 2, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 2, # 'น' 17: 1, # 'บ' 25: 1, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 2, # 'ภ' 9: 1, # 'ม' 16: 1, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 3, # 'ส' 21: 0, # 'ห' 4: 3, # 'อ' 63: 1, # 'ฯ' 22: 2, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 2, # 'ำ' 23: 3, # 'ิ' 13: 2, # 'ี' 40: 1, # 'ึ' 27: 1, # 'ื' 32: 3, # 'ุ' 35: 2, # 'ู' 11: 1, # 'เ' 28: 1, # 'แ' 41: 1, # 'โ' 29: 1, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 2, # '็' 6: 3, # '่' 7: 3, # '้' 38: 2, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 44: { # 'ถ' 5: 1, # 'ก' 30: 0, # 'ข' 24: 1, # 'ค' 8: 0, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 1, # 'ต' 44: 0, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 1, # 'น' 17: 2, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 1, # 'ร' 61: 0, # 'ฤ' 15: 1, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 0, # 'ห' 4: 1, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 2, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 2, # 'ิ' 13: 1, # 'ี' 40: 3, # 'ึ' 27: 2, # 'ื' 32: 2, # 'ุ' 35: 3, # 'ู' 11: 1, # 'เ' 28: 1, # 'แ' 41: 0, # 'โ' 29: 1, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 2, # '่' 7: 3, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 14: { # 'ท' 5: 1, # 'ก' 30: 1, # 'ข' 24: 3, # 'ค' 8: 1, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 2, # 'ด' 19: 1, # 'ต' 44: 0, # 'ถ' 14: 1, # 'ท' 48: 3, # 'ธ' 3: 3, # 'น' 17: 2, # 'บ' 25: 2, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 2, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 1, # 'ม' 16: 3, # 'ย' 2: 3, # 'ร' 61: 1, # 'ฤ' 15: 1, # 'ล' 12: 2, # 'ว' 42: 3, # 'ศ' 46: 1, # 'ษ' 18: 1, # 'ส' 21: 0, # 'ห' 4: 2, # 'อ' 63: 0, # 'ฯ' 22: 2, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 3, # 'ำ' 23: 2, # 'ิ' 13: 3, # 'ี' 40: 2, # 'ึ' 27: 1, # 'ื' 32: 3, # 'ุ' 35: 1, # 'ู' 11: 0, # 'เ' 28: 1, # 'แ' 41: 0, # 'โ' 29: 1, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 1, # '็' 6: 3, # '่' 7: 3, # '้' 38: 2, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 48: { # 'ธ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 1, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 1, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 2, # 'า' 36: 0, # 'ำ' 23: 3, # 'ิ' 13: 3, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 2, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 3, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 3: { # 'น' 5: 3, # 'ก' 30: 2, # 'ข' 24: 3, # 'ค' 8: 1, # 'ง' 26: 2, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 1, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 3, # 'ด' 19: 3, # 'ต' 44: 2, # 'ถ' 14: 3, # 'ท' 48: 3, # 'ธ' 3: 2, # 'น' 17: 2, # 'บ' 25: 2, # 'ป' 39: 2, # 'ผ' 62: 0, # 'ฝ' 31: 2, # 'พ' 54: 1, # 'ฟ' 45: 1, # 'ภ' 9: 2, # 'ม' 16: 2, # 'ย' 2: 2, # 'ร' 61: 1, # 'ฤ' 15: 2, # 'ล' 12: 3, # 'ว' 42: 1, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 2, # 'ห' 4: 3, # 'อ' 63: 1, # 'ฯ' 22: 2, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 3, # 'ำ' 23: 3, # 'ิ' 13: 3, # 'ี' 40: 3, # 'ึ' 27: 3, # 'ื' 32: 3, # 'ุ' 35: 2, # 'ู' 11: 3, # 'เ' 28: 2, # 'แ' 41: 3, # 'โ' 29: 3, # 'ใ' 33: 3, # 'ไ' 50: 2, # 'ๆ' 37: 1, # '็' 6: 3, # '่' 7: 3, # '้' 38: 2, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 17: { # 'บ' 5: 3, # 'ก' 30: 2, # 'ข' 24: 2, # 'ค' 8: 1, # 'ง' 26: 1, # 'จ' 52: 1, # 'ฉ' 34: 1, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 1, # 'ด' 19: 2, # 'ต' 44: 1, # 'ถ' 14: 3, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 3, # 'บ' 25: 2, # 'ป' 39: 2, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 1, # 'ฟ' 45: 1, # 'ภ' 9: 1, # 'ม' 16: 0, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 3, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 2, # 'ห' 4: 2, # 'อ' 63: 1, # 'ฯ' 22: 0, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 2, # 'ำ' 23: 2, # 'ิ' 13: 2, # 'ี' 40: 0, # 'ึ' 27: 2, # 'ื' 32: 3, # 'ุ' 35: 2, # 'ู' 11: 2, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 2, # 'ไ' 50: 0, # 'ๆ' 37: 1, # '็' 6: 2, # '่' 7: 2, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 25: { # 'ป' 5: 2, # 'ก' 30: 0, # 'ข' 24: 1, # 'ค' 8: 0, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 1, # 'ฎ' 57: 3, # 'ฏ' 49: 1, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 1, # 'ด' 19: 1, # 'ต' 44: 1, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 2, # 'น' 17: 0, # 'บ' 25: 1, # 'ป' 39: 1, # 'ผ' 62: 1, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 1, # 'ม' 16: 0, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 3, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 1, # 'ษ' 18: 2, # 'ส' 21: 1, # 'ห' 4: 2, # 'อ' 63: 0, # 'ฯ' 22: 1, # 'ะ' 10: 3, # 'ั' 1: 1, # 'า' 36: 0, # 'ำ' 23: 2, # 'ิ' 13: 3, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 1, # 'ุ' 35: 0, # 'ู' 11: 1, # 'เ' 28: 2, # 'แ' 41: 0, # 'โ' 29: 1, # 'ใ' 33: 2, # 'ไ' 50: 0, # 'ๆ' 37: 3, # '็' 6: 1, # '่' 7: 2, # '้' 38: 1, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 39: { # 'ผ' 5: 1, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 1, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 2, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 1, # 'ม' 16: 2, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 3, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 1, # 'ะ' 10: 1, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 2, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 1, # 'ื' 32: 0, # 'ุ' 35: 3, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 3, # '่' 7: 1, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 62: { # 'ฝ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 1, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 1, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 1, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 1, # 'ี' 40: 2, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 2, # '่' 7: 1, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 31: { # 'พ' 5: 1, # 'ก' 30: 1, # 'ข' 24: 1, # 'ค' 8: 1, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 1, # 'ณ' 20: 1, # 'ด' 19: 1, # 'ต' 44: 0, # 'ถ' 14: 2, # 'ท' 48: 1, # 'ธ' 3: 3, # 'น' 17: 2, # 'บ' 25: 0, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 1, # 'ม' 16: 2, # 'ย' 2: 3, # 'ร' 61: 2, # 'ฤ' 15: 2, # 'ล' 12: 2, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 1, # 'ห' 4: 2, # 'อ' 63: 1, # 'ฯ' 22: 0, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 3, # 'ิ' 13: 2, # 'ี' 40: 1, # 'ึ' 27: 3, # 'ื' 32: 1, # 'ุ' 35: 2, # 'ู' 11: 1, # 'เ' 28: 1, # 'แ' 41: 0, # 'โ' 29: 1, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 1, # '็' 6: 0, # '่' 7: 1, # '้' 38: 3, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 54: { # 'ฟ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 1, # 'ต' 44: 0, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 2, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 1, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 0, # 'ห' 4: 1, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 2, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 1, # 'ิ' 13: 1, # 'ี' 40: 0, # 'ึ' 27: 1, # 'ื' 32: 1, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 1, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 2, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 45: { # 'ภ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 1, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 3, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 1, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 1, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 2, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 1, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 9: { # 'ม' 5: 2, # 'ก' 30: 2, # 'ข' 24: 2, # 'ค' 8: 2, # 'ง' 26: 2, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 1, # 'ณ' 20: 2, # 'ด' 19: 2, # 'ต' 44: 1, # 'ถ' 14: 2, # 'ท' 48: 1, # 'ธ' 3: 3, # 'น' 17: 2, # 'บ' 25: 2, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 3, # 'พ' 54: 0, # 'ฟ' 45: 1, # 'ภ' 9: 2, # 'ม' 16: 1, # 'ย' 2: 2, # 'ร' 61: 2, # 'ฤ' 15: 2, # 'ล' 12: 2, # 'ว' 42: 1, # 'ศ' 46: 1, # 'ษ' 18: 3, # 'ส' 21: 3, # 'ห' 4: 3, # 'อ' 63: 0, # 'ฯ' 22: 1, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 3, # 'ิ' 13: 3, # 'ี' 40: 0, # 'ึ' 27: 3, # 'ื' 32: 3, # 'ุ' 35: 3, # 'ู' 11: 2, # 'เ' 28: 2, # 'แ' 41: 2, # 'โ' 29: 2, # 'ใ' 33: 2, # 'ไ' 50: 1, # 'ๆ' 37: 1, # '็' 6: 3, # '่' 7: 2, # '้' 38: 1, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 16: { # 'ย' 5: 3, # 'ก' 30: 1, # 'ข' 24: 2, # 'ค' 8: 3, # 'ง' 26: 2, # 'จ' 52: 0, # 'ฉ' 34: 2, # 'ช' 51: 0, # 'ซ' 47: 2, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 2, # 'ด' 19: 2, # 'ต' 44: 1, # 'ถ' 14: 2, # 'ท' 48: 1, # 'ธ' 3: 3, # 'น' 17: 3, # 'บ' 25: 1, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 1, # 'ภ' 9: 2, # 'ม' 16: 0, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 1, # 'ล' 12: 3, # 'ว' 42: 1, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 1, # 'ห' 4: 2, # 'อ' 63: 0, # 'ฯ' 22: 2, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 2, # 'ิ' 13: 3, # 'ี' 40: 1, # 'ึ' 27: 2, # 'ื' 32: 2, # 'ุ' 35: 3, # 'ู' 11: 2, # 'เ' 28: 1, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 2, # 'ไ' 50: 2, # 'ๆ' 37: 1, # '็' 6: 3, # '่' 7: 2, # '้' 38: 3, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 2: { # 'ร' 5: 3, # 'ก' 30: 2, # 'ข' 24: 2, # 'ค' 8: 3, # 'ง' 26: 2, # 'จ' 52: 0, # 'ฉ' 34: 2, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 3, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 3, # 'ณ' 20: 2, # 'ด' 19: 2, # 'ต' 44: 3, # 'ถ' 14: 3, # 'ท' 48: 1, # 'ธ' 3: 2, # 'น' 17: 2, # 'บ' 25: 3, # 'ป' 39: 2, # 'ผ' 62: 1, # 'ฝ' 31: 2, # 'พ' 54: 1, # 'ฟ' 45: 1, # 'ภ' 9: 3, # 'ม' 16: 2, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 3, # 'ว' 42: 2, # 'ศ' 46: 2, # 'ษ' 18: 2, # 'ส' 21: 2, # 'ห' 4: 3, # 'อ' 63: 1, # 'ฯ' 22: 3, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 3, # 'ิ' 13: 3, # 'ี' 40: 2, # 'ึ' 27: 3, # 'ื' 32: 3, # 'ุ' 35: 3, # 'ู' 11: 3, # 'เ' 28: 3, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 3, # '็' 6: 3, # '่' 7: 3, # '้' 38: 3, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 61: { # 'ฤ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 2, # 'ต' 44: 0, # 'ถ' 14: 2, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 1, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 2, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 15: { # 'ล' 5: 2, # 'ก' 30: 3, # 'ข' 24: 1, # 'ค' 8: 3, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 2, # 'ด' 19: 2, # 'ต' 44: 1, # 'ถ' 14: 2, # 'ท' 48: 0, # 'ธ' 3: 1, # 'น' 17: 2, # 'บ' 25: 2, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 1, # 'ภ' 9: 1, # 'ม' 16: 3, # 'ย' 2: 1, # 'ร' 61: 0, # 'ฤ' 15: 1, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 1, # 'ห' 4: 3, # 'อ' 63: 2, # 'ฯ' 22: 3, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 2, # 'ำ' 23: 3, # 'ิ' 13: 3, # 'ี' 40: 2, # 'ึ' 27: 3, # 'ื' 32: 2, # 'ุ' 35: 3, # 'ู' 11: 2, # 'เ' 28: 1, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 2, # '็' 6: 3, # '่' 7: 3, # '้' 38: 2, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 12: { # 'ว' 5: 3, # 'ก' 30: 2, # 'ข' 24: 1, # 'ค' 8: 3, # 'ง' 26: 2, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 1, # 'ณ' 20: 2, # 'ด' 19: 1, # 'ต' 44: 1, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 2, # 'บ' 25: 1, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 1, # 'ฟ' 45: 0, # 'ภ' 9: 3, # 'ม' 16: 3, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 3, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 2, # 'ห' 4: 2, # 'อ' 63: 0, # 'ฯ' 22: 2, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 3, # 'ิ' 13: 2, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 2, # 'ุ' 35: 0, # 'ู' 11: 3, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 1, # 'ใ' 33: 2, # 'ไ' 50: 1, # 'ๆ' 37: 0, # '็' 6: 3, # '่' 7: 3, # '้' 38: 1, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 42: { # 'ศ' 5: 1, # 'ก' 30: 0, # 'ข' 24: 1, # 'ค' 8: 0, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 1, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 1, # 'ต' 44: 0, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 2, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 2, # 'ว' 42: 1, # 'ศ' 46: 2, # 'ษ' 18: 1, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 2, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 2, # 'ิ' 13: 0, # 'ี' 40: 3, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 2, # 'ู' 11: 0, # 'เ' 28: 1, # 'แ' 41: 0, # 'โ' 29: 1, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 1, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 46: { # 'ษ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 2, # 'ฎ' 57: 1, # 'ฏ' 49: 2, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 3, # 'ณ' 20: 0, # 'ด' 19: 1, # 'ต' 44: 0, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 1, # 'ภ' 9: 1, # 'ม' 16: 2, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 1, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 2, # 'ะ' 10: 2, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 1, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 1, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 2, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 18: { # 'ส' 5: 2, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 2, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 3, # 'ด' 19: 3, # 'ต' 44: 3, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 2, # 'บ' 25: 1, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 2, # 'ภ' 9: 3, # 'ม' 16: 1, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 1, # 'ล' 12: 2, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 2, # 'ห' 4: 3, # 'อ' 63: 0, # 'ฯ' 22: 2, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 3, # 'ำ' 23: 3, # 'ิ' 13: 3, # 'ี' 40: 2, # 'ึ' 27: 3, # 'ื' 32: 3, # 'ุ' 35: 3, # 'ู' 11: 2, # 'เ' 28: 0, # 'แ' 41: 1, # 'โ' 29: 0, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 3, # '่' 7: 1, # '้' 38: 2, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 21: { # 'ห' 5: 3, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 1, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 2, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 1, # 'ด' 19: 3, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 0, # 'บ' 25: 1, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 3, # 'ม' 16: 2, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 3, # 'ล' 12: 2, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 3, # 'อ' 63: 0, # 'ฯ' 22: 1, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 0, # 'ำ' 23: 1, # 'ิ' 13: 1, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 1, # 'ุ' 35: 1, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 3, # '็' 6: 3, # '่' 7: 3, # '้' 38: 2, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 4: { # 'อ' 5: 3, # 'ก' 30: 1, # 'ข' 24: 2, # 'ค' 8: 3, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 3, # 'ด' 19: 2, # 'ต' 44: 1, # 'ถ' 14: 2, # 'ท' 48: 1, # 'ธ' 3: 3, # 'น' 17: 3, # 'บ' 25: 1, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 1, # 'ฟ' 45: 1, # 'ภ' 9: 3, # 'ม' 16: 3, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 2, # 'ว' 42: 1, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 2, # 'ห' 4: 3, # 'อ' 63: 0, # 'ฯ' 22: 2, # 'ะ' 10: 3, # 'ั' 1: 3, # 'า' 36: 2, # 'ำ' 23: 2, # 'ิ' 13: 3, # 'ี' 40: 0, # 'ึ' 27: 3, # 'ื' 32: 3, # 'ุ' 35: 0, # 'ู' 11: 3, # 'เ' 28: 1, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 2, # 'ไ' 50: 1, # 'ๆ' 37: 1, # '็' 6: 2, # '่' 7: 2, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 63: { # 'ฯ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 22: { # 'ะ' 5: 3, # 'ก' 30: 1, # 'ข' 24: 2, # 'ค' 8: 1, # 'ง' 26: 2, # 'จ' 52: 0, # 'ฉ' 34: 3, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 3, # 'ด' 19: 3, # 'ต' 44: 1, # 'ถ' 14: 3, # 'ท' 48: 1, # 'ธ' 3: 2, # 'น' 17: 3, # 'บ' 25: 2, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 2, # 'พ' 54: 0, # 'ฟ' 45: 1, # 'ภ' 9: 3, # 'ม' 16: 2, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 2, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 3, # 'ส' 21: 3, # 'ห' 4: 2, # 'อ' 63: 1, # 'ฯ' 22: 1, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 3, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 2, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 10: { # 'ั' 5: 3, # 'ก' 30: 0, # 'ข' 24: 1, # 'ค' 8: 3, # 'ง' 26: 3, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 0, # 'ซ' 47: 3, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 2, # 'ฐ' 53: 0, # 'ฑ' 55: 3, # 'ฒ' 43: 3, # 'ณ' 20: 3, # 'ด' 19: 3, # 'ต' 44: 0, # 'ถ' 14: 2, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 3, # 'บ' 25: 1, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 2, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 3, # 'ม' 16: 3, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 3, # 'ว' 42: 2, # 'ศ' 46: 0, # 'ษ' 18: 3, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 3, # '่' 7: 3, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 1: { # 'า' 5: 3, # 'ก' 30: 2, # 'ข' 24: 3, # 'ค' 8: 3, # 'ง' 26: 3, # 'จ' 52: 0, # 'ฉ' 34: 3, # 'ช' 51: 1, # 'ซ' 47: 2, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 3, # 'ณ' 20: 3, # 'ด' 19: 3, # 'ต' 44: 1, # 'ถ' 14: 3, # 'ท' 48: 2, # 'ธ' 3: 3, # 'น' 17: 3, # 'บ' 25: 2, # 'ป' 39: 1, # 'ผ' 62: 1, # 'ฝ' 31: 3, # 'พ' 54: 1, # 'ฟ' 45: 1, # 'ภ' 9: 3, # 'ม' 16: 3, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 3, # 'ล' 12: 3, # 'ว' 42: 2, # 'ศ' 46: 3, # 'ษ' 18: 3, # 'ส' 21: 3, # 'ห' 4: 2, # 'อ' 63: 1, # 'ฯ' 22: 3, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 3, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 2, # 'ไ' 50: 1, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 36: { # 'ำ' 5: 2, # 'ก' 30: 1, # 'ข' 24: 3, # 'ค' 8: 2, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 1, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 1, # 'ด' 19: 1, # 'ต' 44: 1, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 1, # 'บ' 25: 1, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 1, # 'ภ' 9: 1, # 'ม' 16: 0, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 3, # 'ห' 4: 1, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 3, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 2, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 23: { # 'ิ' 5: 3, # 'ก' 30: 1, # 'ข' 24: 2, # 'ค' 8: 3, # 'ง' 26: 3, # 'จ' 52: 0, # 'ฉ' 34: 3, # 'ช' 51: 0, # 'ซ' 47: 2, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 3, # 'ด' 19: 3, # 'ต' 44: 1, # 'ถ' 14: 3, # 'ท' 48: 3, # 'ธ' 3: 3, # 'น' 17: 3, # 'บ' 25: 2, # 'ป' 39: 2, # 'ผ' 62: 0, # 'ฝ' 31: 3, # 'พ' 54: 1, # 'ฟ' 45: 2, # 'ภ' 9: 3, # 'ม' 16: 2, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 3, # 'ว' 42: 3, # 'ศ' 46: 2, # 'ษ' 18: 2, # 'ส' 21: 3, # 'ห' 4: 1, # 'อ' 63: 1, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 3, # 'เ' 28: 1, # 'แ' 41: 1, # 'โ' 29: 1, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 3, # '่' 7: 2, # '้' 38: 2, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 13: { # 'ี' 5: 3, # 'ก' 30: 2, # 'ข' 24: 2, # 'ค' 8: 0, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 2, # 'ด' 19: 1, # 'ต' 44: 0, # 'ถ' 14: 2, # 'ท' 48: 0, # 'ธ' 3: 1, # 'น' 17: 2, # 'บ' 25: 2, # 'ป' 39: 1, # 'ผ' 62: 0, # 'ฝ' 31: 2, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 2, # 'ม' 16: 3, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 1, # 'ล' 12: 2, # 'ว' 42: 1, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 1, # 'ห' 4: 2, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 2, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 1, # 'ใ' 33: 1, # 'ไ' 50: 1, # 'ๆ' 37: 0, # '็' 6: 3, # '่' 7: 3, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 40: { # 'ึ' 5: 3, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 3, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 1, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 1, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 3, # '่' 7: 3, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 27: { # 'ื' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 1, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 2, # 'น' 17: 3, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 2, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 3, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 3, # '่' 7: 3, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 32: { # 'ุ' 5: 3, # 'ก' 30: 2, # 'ข' 24: 3, # 'ค' 8: 3, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 2, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 1, # 'ฒ' 43: 3, # 'ณ' 20: 3, # 'ด' 19: 3, # 'ต' 44: 1, # 'ถ' 14: 2, # 'ท' 48: 1, # 'ธ' 3: 2, # 'น' 17: 2, # 'บ' 25: 2, # 'ป' 39: 2, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 1, # 'ภ' 9: 3, # 'ม' 16: 1, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 1, # 'ว' 42: 1, # 'ศ' 46: 2, # 'ษ' 18: 1, # 'ส' 21: 1, # 'ห' 4: 1, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 1, # 'เ' 28: 0, # 'แ' 41: 1, # 'โ' 29: 0, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 3, # '่' 7: 2, # '้' 38: 1, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 35: { # 'ู' 5: 3, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 2, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 2, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 1, # 'ณ' 20: 2, # 'ด' 19: 2, # 'ต' 44: 0, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 2, # 'น' 17: 0, # 'บ' 25: 3, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 2, # 'ม' 16: 0, # 'ย' 2: 1, # 'ร' 61: 0, # 'ฤ' 15: 3, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 1, # 'เ' 28: 1, # 'แ' 41: 1, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 3, # '่' 7: 3, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 11: { # 'เ' 5: 3, # 'ก' 30: 3, # 'ข' 24: 3, # 'ค' 8: 2, # 'ง' 26: 3, # 'จ' 52: 3, # 'ฉ' 34: 3, # 'ช' 51: 2, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 1, # 'ณ' 20: 3, # 'ด' 19: 3, # 'ต' 44: 1, # 'ถ' 14: 3, # 'ท' 48: 1, # 'ธ' 3: 3, # 'น' 17: 3, # 'บ' 25: 3, # 'ป' 39: 2, # 'ผ' 62: 1, # 'ฝ' 31: 3, # 'พ' 54: 1, # 'ฟ' 45: 3, # 'ภ' 9: 3, # 'ม' 16: 2, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 3, # 'ล' 12: 3, # 'ว' 42: 2, # 'ศ' 46: 0, # 'ษ' 18: 3, # 'ส' 21: 3, # 'ห' 4: 3, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 28: { # 'แ' 5: 3, # 'ก' 30: 2, # 'ข' 24: 2, # 'ค' 8: 1, # 'ง' 26: 2, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 2, # 'ด' 19: 3, # 'ต' 44: 2, # 'ถ' 14: 3, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 3, # 'บ' 25: 2, # 'ป' 39: 3, # 'ผ' 62: 0, # 'ฝ' 31: 2, # 'พ' 54: 2, # 'ฟ' 45: 0, # 'ภ' 9: 2, # 'ม' 16: 2, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 3, # 'ล' 12: 2, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 3, # 'ส' 21: 3, # 'ห' 4: 1, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 41: { # 'โ' 5: 2, # 'ก' 30: 1, # 'ข' 24: 2, # 'ค' 8: 0, # 'ง' 26: 1, # 'จ' 52: 1, # 'ฉ' 34: 1, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 3, # 'ด' 19: 2, # 'ต' 44: 0, # 'ถ' 14: 2, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 1, # 'บ' 25: 3, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 1, # 'ฟ' 45: 1, # 'ภ' 9: 1, # 'ม' 16: 2, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 3, # 'ล' 12: 0, # 'ว' 42: 1, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 0, # 'ห' 4: 2, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 29: { # 'ใ' 5: 2, # 'ก' 30: 0, # 'ข' 24: 1, # 'ค' 8: 0, # 'ง' 26: 3, # 'จ' 52: 0, # 'ฉ' 34: 3, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 3, # 'ด' 19: 1, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 2, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 1, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 3, # 'ส' 21: 3, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 33: { # 'ไ' 5: 1, # 'ก' 30: 2, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 3, # 'ด' 19: 1, # 'ต' 44: 0, # 'ถ' 14: 3, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 1, # 'บ' 25: 3, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 2, # 'ฟ' 45: 0, # 'ภ' 9: 3, # 'ม' 16: 0, # 'ย' 2: 3, # 'ร' 61: 0, # 'ฤ' 15: 1, # 'ล' 12: 3, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 2, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 50: { # 'ๆ' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 37: { # '็' 5: 2, # 'ก' 30: 1, # 'ข' 24: 2, # 'ค' 8: 2, # 'ง' 26: 3, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 1, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 1, # 'ด' 19: 2, # 'ต' 44: 0, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 3, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 2, # 'ม' 16: 1, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 2, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 0, # 'ห' 4: 1, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 1, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 6: { # '่' 5: 2, # 'ก' 30: 1, # 'ข' 24: 2, # 'ค' 8: 3, # 'ง' 26: 2, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 1, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 1, # 'ด' 19: 2, # 'ต' 44: 1, # 'ถ' 14: 2, # 'ท' 48: 1, # 'ธ' 3: 3, # 'น' 17: 1, # 'บ' 25: 2, # 'ป' 39: 2, # 'ผ' 62: 1, # 'ฝ' 31: 1, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 3, # 'ม' 16: 3, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 2, # 'ล' 12: 3, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 1, # 'ห' 4: 3, # 'อ' 63: 0, # 'ฯ' 22: 1, # 'ะ' 10: 0, # 'ั' 1: 3, # 'า' 36: 2, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 3, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 2, # 'ไ' 50: 1, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 7: { # '้' 5: 2, # 'ก' 30: 1, # 'ข' 24: 2, # 'ค' 8: 3, # 'ง' 26: 2, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 1, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 1, # 'ด' 19: 2, # 'ต' 44: 1, # 'ถ' 14: 2, # 'ท' 48: 0, # 'ธ' 3: 3, # 'น' 17: 2, # 'บ' 25: 2, # 'ป' 39: 2, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 1, # 'ฟ' 45: 0, # 'ภ' 9: 3, # 'ม' 16: 2, # 'ย' 2: 2, # 'ร' 61: 0, # 'ฤ' 15: 1, # 'ล' 12: 3, # 'ว' 42: 1, # 'ศ' 46: 0, # 'ษ' 18: 2, # 'ส' 21: 2, # 'ห' 4: 3, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 3, # 'า' 36: 2, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 2, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 2, # 'ใ' 33: 2, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 38: { # '์' 5: 2, # 'ก' 30: 1, # 'ข' 24: 1, # 'ค' 8: 0, # 'ง' 26: 1, # 'จ' 52: 0, # 'ฉ' 34: 1, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 2, # 'ด' 19: 1, # 'ต' 44: 1, # 'ถ' 14: 1, # 'ท' 48: 0, # 'ธ' 3: 1, # 'น' 17: 1, # 'บ' 25: 1, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 1, # 'พ' 54: 1, # 'ฟ' 45: 0, # 'ภ' 9: 2, # 'ม' 16: 0, # 'ย' 2: 1, # 'ร' 61: 1, # 'ฤ' 15: 1, # 'ล' 12: 1, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 1, # 'ส' 21: 1, # 'ห' 4: 2, # 'อ' 63: 1, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 2, # 'เ' 28: 2, # 'แ' 41: 1, # 'โ' 29: 1, # 'ใ' 33: 1, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 0, # '๑' 59: 0, # '๒' 60: 0, # '๕' }, 56: { # '๑' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 2, # '๑' 59: 1, # '๒' 60: 1, # '๕' }, 59: { # '๒' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 1, # '๑' 59: 1, # '๒' 60: 3, # '๕' }, 60: { # '๕' 5: 0, # 'ก' 30: 0, # 'ข' 24: 0, # 'ค' 8: 0, # 'ง' 26: 0, # 'จ' 52: 0, # 'ฉ' 34: 0, # 'ช' 51: 0, # 'ซ' 47: 0, # 'ญ' 58: 0, # 'ฎ' 57: 0, # 'ฏ' 49: 0, # 'ฐ' 53: 0, # 'ฑ' 55: 0, # 'ฒ' 43: 0, # 'ณ' 20: 0, # 'ด' 19: 0, # 'ต' 44: 0, # 'ถ' 14: 0, # 'ท' 48: 0, # 'ธ' 3: 0, # 'น' 17: 0, # 'บ' 25: 0, # 'ป' 39: 0, # 'ผ' 62: 0, # 'ฝ' 31: 0, # 'พ' 54: 0, # 'ฟ' 45: 0, # 'ภ' 9: 0, # 'ม' 16: 0, # 'ย' 2: 0, # 'ร' 61: 0, # 'ฤ' 15: 0, # 'ล' 12: 0, # 'ว' 42: 0, # 'ศ' 46: 0, # 'ษ' 18: 0, # 'ส' 21: 0, # 'ห' 4: 0, # 'อ' 63: 0, # 'ฯ' 22: 0, # 'ะ' 10: 0, # 'ั' 1: 0, # 'า' 36: 0, # 'ำ' 23: 0, # 'ิ' 13: 0, # 'ี' 40: 0, # 'ึ' 27: 0, # 'ื' 32: 0, # 'ุ' 35: 0, # 'ู' 11: 0, # 'เ' 28: 0, # 'แ' 41: 0, # 'โ' 29: 0, # 'ใ' 33: 0, # 'ไ' 50: 0, # 'ๆ' 37: 0, # '็' 6: 0, # '่' 7: 0, # '้' 38: 0, # '์' 56: 2, # '๑' 59: 1, # '๒' 60: 0, # '๕' }, } # 255: Undefined characters that did not exist in training text # 254: Carriage/Return # 253: symbol (punctuation) that does not belong to word # 252: 0 - 9 # 251: Control characters # Character Mapping Table(s): TIS_620_THAI_CHAR_TO_ORDER = { 0: 255, # '\x00' 1: 255, # '\x01' 2: 255, # '\x02' 3: 255, # '\x03' 4: 255, # '\x04' 5: 255, # '\x05' 6: 255, # '\x06' 7: 255, # '\x07' 8: 255, # '\x08' 9: 255, # '\t' 10: 254, # '\n' 11: 255, # '\x0b' 12: 255, # '\x0c' 13: 254, # '\r' 14: 255, # '\x0e' 15: 255, # '\x0f' 16: 255, # '\x10' 17: 255, # '\x11' 18: 255, # '\x12' 19: 255, # '\x13' 20: 255, # '\x14' 21: 255, # '\x15' 22: 255, # '\x16' 23: 255, # '\x17' 24: 255, # '\x18' 25: 255, # '\x19' 26: 255, # '\x1a' 27: 255, # '\x1b' 28: 255, # '\x1c' 29: 255, # '\x1d' 30: 255, # '\x1e' 31: 255, # '\x1f' 32: 253, # ' ' 33: 253, # '!' 34: 253, # '"' 35: 253, # '#' 36: 253, # '$' 37: 253, # '%' 38: 253, # '&' 39: 253, # "'" 40: 253, # '(' 41: 253, # ')' 42: 253, # '*' 43: 253, # '+' 44: 253, # ',' 45: 253, # '-' 46: 253, # '.' 47: 253, # '/' 48: 252, # '0' 49: 252, # '1' 50: 252, # '2' 51: 252, # '3' 52: 252, # '4' 53: 252, # '5' 54: 252, # '6' 55: 252, # '7' 56: 252, # '8' 57: 252, # '9' 58: 253, # ':' 59: 253, # ';' 60: 253, # '<' 61: 253, # '=' 62: 253, # '>' 63: 253, # '?' 64: 253, # '@' 65: 182, # 'A' 66: 106, # 'B' 67: 107, # 'C' 68: 100, # 'D' 69: 183, # 'E' 70: 184, # 'F' 71: 185, # 'G' 72: 101, # 'H' 73: 94, # 'I' 74: 186, # 'J' 75: 187, # 'K' 76: 108, # 'L' 77: 109, # 'M' 78: 110, # 'N' 79: 111, # 'O' 80: 188, # 'P' 81: 189, # 'Q' 82: 190, # 'R' 83: 89, # 'S' 84: 95, # 'T' 85: 112, # 'U' 86: 113, # 'V' 87: 191, # 'W' 88: 192, # 'X' 89: 193, # 'Y' 90: 194, # 'Z' 91: 253, # '[' 92: 253, # '\\' 93: 253, # ']' 94: 253, # '^' 95: 253, # '_' 96: 253, # '`' 97: 64, # 'a' 98: 72, # 'b' 99: 73, # 'c' 100: 114, # 'd' 101: 74, # 'e' 102: 115, # 'f' 103: 116, # 'g' 104: 102, # 'h' 105: 81, # 'i' 106: 201, # 'j' 107: 117, # 'k' 108: 90, # 'l' 109: 103, # 'm' 110: 78, # 'n' 111: 82, # 'o' 112: 96, # 'p' 113: 202, # 'q' 114: 91, # 'r' 115: 79, # 's' 116: 84, # 't' 117: 104, # 'u' 118: 105, # 'v' 119: 97, # 'w' 120: 98, # 'x' 121: 92, # 'y' 122: 203, # 'z' 123: 253, # '{' 124: 253, # '|' 125: 253, # '}' 126: 253, # '~' 127: 253, # '\x7f' 128: 209, # '\x80' 129: 210, # '\x81' 130: 211, # '\x82' 131: 212, # '\x83' 132: 213, # '\x84' 133: 88, # '\x85' 134: 214, # '\x86' 135: 215, # '\x87' 136: 216, # '\x88' 137: 217, # '\x89' 138: 218, # '\x8a' 139: 219, # '\x8b' 140: 220, # '\x8c' 141: 118, # '\x8d' 142: 221, # '\x8e' 143: 222, # '\x8f' 144: 223, # '\x90' 145: 224, # '\x91' 146: 99, # '\x92' 147: 85, # '\x93' 148: 83, # '\x94' 149: 225, # '\x95' 150: 226, # '\x96' 151: 227, # '\x97' 152: 228, # '\x98' 153: 229, # '\x99' 154: 230, # '\x9a' 155: 231, # '\x9b' 156: 232, # '\x9c' 157: 233, # '\x9d' 158: 234, # '\x9e' 159: 235, # '\x9f' 160: 236, # None 161: 5, # 'ก' 162: 30, # 'ข' 163: 237, # 'ฃ' 164: 24, # 'ค' 165: 238, # 'ฅ' 166: 75, # 'ฆ' 167: 8, # 'ง' 168: 26, # 'จ' 169: 52, # 'ฉ' 170: 34, # 'ช' 171: 51, # 'ซ' 172: 119, # 'ฌ' 173: 47, # 'ญ' 174: 58, # 'ฎ' 175: 57, # 'ฏ' 176: 49, # 'ฐ' 177: 53, # 'ฑ' 178: 55, # 'ฒ' 179: 43, # 'ณ' 180: 20, # 'ด' 181: 19, # 'ต' 182: 44, # 'ถ' 183: 14, # 'ท' 184: 48, # 'ธ' 185: 3, # 'น' 186: 17, # 'บ' 187: 25, # 'ป' 188: 39, # 'ผ' 189: 62, # 'ฝ' 190: 31, # 'พ' 191: 54, # 'ฟ' 192: 45, # 'ภ' 193: 9, # 'ม' 194: 16, # 'ย' 195: 2, # 'ร' 196: 61, # 'ฤ' 197: 15, # 'ล' 198: 239, # 'ฦ' 199: 12, # 'ว' 200: 42, # 'ศ' 201: 46, # 'ษ' 202: 18, # 'ส' 203: 21, # 'ห' 204: 76, # 'ฬ' 205: 4, # 'อ' 206: 66, # 'ฮ' 207: 63, # 'ฯ' 208: 22, # 'ะ' 209: 10, # 'ั' 210: 1, # 'า' 211: 36, # 'ำ' 212: 23, # 'ิ' 213: 13, # 'ี' 214: 40, # 'ึ' 215: 27, # 'ื' 216: 32, # 'ุ' 217: 35, # 'ู' 218: 86, # 'ฺ' 219: 240, # None 220: 241, # None 221: 242, # None 222: 243, # None 223: 244, # '฿' 224: 11, # 'เ' 225: 28, # 'แ' 226: 41, # 'โ' 227: 29, # 'ใ' 228: 33, # 'ไ' 229: 245, # 'ๅ' 230: 50, # 'ๆ' 231: 37, # '็' 232: 6, # '่' 233: 7, # '้' 234: 67, # '๊' 235: 77, # '๋' 236: 38, # '์' 237: 93, # 'ํ' 238: 246, # '๎' 239: 247, # '๏' 240: 68, # '๐' 241: 56, # '๑' 242: 59, # '๒' 243: 65, # '๓' 244: 69, # '๔' 245: 60, # '๕' 246: 70, # '๖' 247: 80, # '๗' 248: 71, # '๘' 249: 87, # '๙' 250: 248, # '๚' 251: 249, # '๛' 252: 250, # None 253: 251, # None 254: 252, # None 255: 253, # None } TIS_620_THAI_MODEL = SingleByteCharSetModel(charset_name='TIS-620', language='Thai', char_to_order_map=TIS_620_THAI_CHAR_TO_ORDER, language_model=THAI_LANG_MODEL, typical_positive_ratio=0.926386, keep_ascii_letters=False, alphabet='กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛') PKH] )Ӳ66<python3.10/site-packages/pip/_vendor/chardet/hebrewprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Universal charset detector code. # # The Initial Developer of the Original Code is # Shy Shalom # Portions created by the Initial Developer are Copyright (C) 2005 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .charsetprober import CharSetProber from .enums import ProbingState # This prober doesn't actually recognize a language or a charset. # It is a helper prober for the use of the Hebrew model probers ### General ideas of the Hebrew charset recognition ### # # Four main charsets exist in Hebrew: # "ISO-8859-8" - Visual Hebrew # "windows-1255" - Logical Hebrew # "ISO-8859-8-I" - Logical Hebrew # "x-mac-hebrew" - ?? Logical Hebrew ?? # # Both "ISO" charsets use a completely identical set of code points, whereas # "windows-1255" and "x-mac-hebrew" are two different proper supersets of # these code points. windows-1255 defines additional characters in the range # 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific # diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. # x-mac-hebrew defines similar additional code points but with a different # mapping. # # As far as an average Hebrew text with no diacritics is concerned, all four # charsets are identical with respect to code points. Meaning that for the # main Hebrew alphabet, all four map the same values to all 27 Hebrew letters # (including final letters). # # The dominant difference between these charsets is their directionality. # "Visual" directionality means that the text is ordered as if the renderer is # not aware of a BIDI rendering algorithm. The renderer sees the text and # draws it from left to right. The text itself when ordered naturally is read # backwards. A buffer of Visual Hebrew generally looks like so: # "[last word of first line spelled backwards] [whole line ordered backwards # and spelled backwards] [first word of first line spelled backwards] # [end of line] [last word of second line] ... etc' " # adding punctuation marks, numbers and English text to visual text is # naturally also "visual" and from left to right. # # "Logical" directionality means the text is ordered "naturally" according to # the order it is read. It is the responsibility of the renderer to display # the text from right to left. A BIDI algorithm is used to place general # punctuation marks, numbers and English text in the text. # # Texts in x-mac-hebrew are almost impossible to find on the Internet. From # what little evidence I could find, it seems that its general directionality # is Logical. # # To sum up all of the above, the Hebrew probing mechanism knows about two # charsets: # Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are # backwards while line order is natural. For charset recognition purposes # the line order is unimportant (In fact, for this implementation, even # word order is unimportant). # Logical Hebrew - "windows-1255" - normal, naturally ordered text. # # "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be # specifically identified. # "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew # that contain special punctuation marks or diacritics is displayed with # some unconverted characters showing as question marks. This problem might # be corrected using another model prober for x-mac-hebrew. Due to the fact # that x-mac-hebrew texts are so rare, writing another model prober isn't # worth the effort and performance hit. # #### The Prober #### # # The prober is divided between two SBCharSetProbers and a HebrewProber, # all of which are managed, created, fed data, inquired and deleted by the # SBCSGroupProber. The two SBCharSetProbers identify that the text is in # fact some kind of Hebrew, Logical or Visual. The final decision about which # one is it is made by the HebrewProber by combining final-letter scores # with the scores of the two SBCharSetProbers to produce a final answer. # # The SBCSGroupProber is responsible for stripping the original text of HTML # tags, English characters, numbers, low-ASCII punctuation characters, spaces # and new lines. It reduces any sequence of such characters to a single space. # The buffer fed to each prober in the SBCS group prober is pure text in # high-ASCII. # The two SBCharSetProbers (model probers) share the same language model: # Win1255Model. # The first SBCharSetProber uses the model normally as any other # SBCharSetProber does, to recognize windows-1255, upon which this model was # built. The second SBCharSetProber is told to make the pair-of-letter # lookup in the language model backwards. This in practice exactly simulates # a visual Hebrew model using the windows-1255 logical Hebrew model. # # The HebrewProber is not using any language model. All it does is look for # final-letter evidence suggesting the text is either logical Hebrew or visual # Hebrew. Disjointed from the model probers, the results of the HebrewProber # alone are meaningless. HebrewProber always returns 0.00 as confidence # since it never identifies a charset by itself. Instead, the pointer to the # HebrewProber is passed to the model probers as a helper "Name Prober". # When the Group prober receives a positive identification from any prober, # it asks for the name of the charset identified. If the prober queried is a # Hebrew model prober, the model prober forwards the call to the # HebrewProber to make the final decision. In the HebrewProber, the # decision is made according to the final-letters scores maintained and Both # model probers scores. The answer is returned in the form of the name of the # charset identified, either "windows-1255" or "ISO-8859-8". class HebrewProber(CharSetProber): # windows-1255 / ISO-8859-8 code points of interest FINAL_KAF = 0xea NORMAL_KAF = 0xeb FINAL_MEM = 0xed NORMAL_MEM = 0xee FINAL_NUN = 0xef NORMAL_NUN = 0xf0 FINAL_PE = 0xf3 NORMAL_PE = 0xf4 FINAL_TSADI = 0xf5 NORMAL_TSADI = 0xf6 # Minimum Visual vs Logical final letter score difference. # If the difference is below this, don't rely solely on the final letter score # distance. MIN_FINAL_CHAR_DISTANCE = 5 # Minimum Visual vs Logical model score difference. # If the difference is below this, don't rely at all on the model score # distance. MIN_MODEL_DISTANCE = 0.01 VISUAL_HEBREW_NAME = "ISO-8859-8" LOGICAL_HEBREW_NAME = "windows-1255" def __init__(self): super(HebrewProber, self).__init__() self._final_char_logical_score = None self._final_char_visual_score = None self._prev = None self._before_prev = None self._logical_prober = None self._visual_prober = None self.reset() def reset(self): self._final_char_logical_score = 0 self._final_char_visual_score = 0 # The two last characters seen in the previous buffer, # mPrev and mBeforePrev are initialized to space in order to simulate # a word delimiter at the beginning of the data self._prev = ' ' self._before_prev = ' ' # These probers are owned by the group prober. def set_model_probers(self, logicalProber, visualProber): self._logical_prober = logicalProber self._visual_prober = visualProber def is_final(self, c): return c in [self.FINAL_KAF, self.FINAL_MEM, self.FINAL_NUN, self.FINAL_PE, self.FINAL_TSADI] def is_non_final(self, c): # The normal Tsadi is not a good Non-Final letter due to words like # 'lechotet' (to chat) containing an apostrophe after the tsadi. This # apostrophe is converted to a space in FilterWithoutEnglishLetters # causing the Non-Final tsadi to appear at an end of a word even # though this is not the case in the original text. # The letters Pe and Kaf rarely display a related behavior of not being # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' # for example legally end with a Non-Final Pe or Kaf. However, the # benefit of these letters as Non-Final letters outweighs the damage # since these words are quite rare. return c in [self.NORMAL_KAF, self.NORMAL_MEM, self.NORMAL_NUN, self.NORMAL_PE] def feed(self, byte_str): # Final letter analysis for logical-visual decision. # Look for evidence that the received buffer is either logical Hebrew # or visual Hebrew. # The following cases are checked: # 1) A word longer than 1 letter, ending with a final letter. This is # an indication that the text is laid out "naturally" since the # final letter really appears at the end. +1 for logical score. # 2) A word longer than 1 letter, ending with a Non-Final letter. In # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, # should not end with the Non-Final form of that letter. Exceptions # to this rule are mentioned above in isNonFinal(). This is an # indication that the text is laid out backwards. +1 for visual # score # 3) A word longer than 1 letter, starting with a final letter. Final # letters should not appear at the beginning of a word. This is an # indication that the text is laid out backwards. +1 for visual # score. # # The visual score and logical score are accumulated throughout the # text and are finally checked against each other in GetCharSetName(). # No checking for final letters in the middle of words is done since # that case is not an indication for either Logical or Visual text. # # We automatically filter out all 7-bit characters (replace them with # spaces) so the word boundary detection works properly. [MAP] if self.state == ProbingState.NOT_ME: # Both model probers say it's not them. No reason to continue. return ProbingState.NOT_ME byte_str = self.filter_high_byte_only(byte_str) for cur in byte_str: if cur == ' ': # We stand on a space - a word just ended if self._before_prev != ' ': # next-to-last char was not a space so self._prev is not a # 1 letter word if self.is_final(self._prev): # case (1) [-2:not space][-1:final letter][cur:space] self._final_char_logical_score += 1 elif self.is_non_final(self._prev): # case (2) [-2:not space][-1:Non-Final letter][ # cur:space] self._final_char_visual_score += 1 else: # Not standing on a space if ((self._before_prev == ' ') and (self.is_final(self._prev)) and (cur != ' ')): # case (3) [-2:space][-1:final letter][cur:not space] self._final_char_visual_score += 1 self._before_prev = self._prev self._prev = cur # Forever detecting, till the end or until both model probers return # ProbingState.NOT_ME (handled above) return ProbingState.DETECTING @property def charset_name(self): # Make the decision: is it Logical or Visual? # If the final letter score distance is dominant enough, rely on it. finalsub = self._final_char_logical_score - self._final_char_visual_score if finalsub >= self.MIN_FINAL_CHAR_DISTANCE: return self.LOGICAL_HEBREW_NAME if finalsub <= -self.MIN_FINAL_CHAR_DISTANCE: return self.VISUAL_HEBREW_NAME # It's not dominant enough, try to rely on the model scores instead. modelsub = (self._logical_prober.get_confidence() - self._visual_prober.get_confidence()) if modelsub > self.MIN_MODEL_DISTANCE: return self.LOGICAL_HEBREW_NAME if modelsub < -self.MIN_MODEL_DISTANCE: return self.VISUAL_HEBREW_NAME # Still no good, back to final letter distance, maybe it'll save the # day. if finalsub < 0.0: return self.VISUAL_HEBREW_NAME # (finalsub > 0 - Logical) or (don't know what to do) default to # Logical. return self.LOGICAL_HEBREW_NAME @property def language(self): return 'Hebrew' @property def state(self): # Remain active as long as any of the model probers are active. if (self._logical_prober.state == ProbingState.NOT_ME) and \ (self._visual_prober.state == ProbingState.NOT_ME): return ProbingState.NOT_ME return ProbingState.DETECTING PKH] `))5python3.10/site-packages/pip/_vendor/chardet/escsm.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .enums import MachineState HZ_CLS = ( 1,0,0,0,0,0,0,0, # 00 - 07 0,0,0,0,0,0,0,0, # 08 - 0f 0,0,0,0,0,0,0,0, # 10 - 17 0,0,0,1,0,0,0,0, # 18 - 1f 0,0,0,0,0,0,0,0, # 20 - 27 0,0,0,0,0,0,0,0, # 28 - 2f 0,0,0,0,0,0,0,0, # 30 - 37 0,0,0,0,0,0,0,0, # 38 - 3f 0,0,0,0,0,0,0,0, # 40 - 47 0,0,0,0,0,0,0,0, # 48 - 4f 0,0,0,0,0,0,0,0, # 50 - 57 0,0,0,0,0,0,0,0, # 58 - 5f 0,0,0,0,0,0,0,0, # 60 - 67 0,0,0,0,0,0,0,0, # 68 - 6f 0,0,0,0,0,0,0,0, # 70 - 77 0,0,0,4,0,5,2,0, # 78 - 7f 1,1,1,1,1,1,1,1, # 80 - 87 1,1,1,1,1,1,1,1, # 88 - 8f 1,1,1,1,1,1,1,1, # 90 - 97 1,1,1,1,1,1,1,1, # 98 - 9f 1,1,1,1,1,1,1,1, # a0 - a7 1,1,1,1,1,1,1,1, # a8 - af 1,1,1,1,1,1,1,1, # b0 - b7 1,1,1,1,1,1,1,1, # b8 - bf 1,1,1,1,1,1,1,1, # c0 - c7 1,1,1,1,1,1,1,1, # c8 - cf 1,1,1,1,1,1,1,1, # d0 - d7 1,1,1,1,1,1,1,1, # d8 - df 1,1,1,1,1,1,1,1, # e0 - e7 1,1,1,1,1,1,1,1, # e8 - ef 1,1,1,1,1,1,1,1, # f0 - f7 1,1,1,1,1,1,1,1, # f8 - ff ) HZ_ST = ( MachineState.START,MachineState.ERROR, 3,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START, 4,MachineState.ERROR,# 10-17 5,MachineState.ERROR, 6,MachineState.ERROR, 5, 5, 4,MachineState.ERROR,# 18-1f 4,MachineState.ERROR, 4, 4, 4,MachineState.ERROR, 4,MachineState.ERROR,# 20-27 4,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 28-2f ) HZ_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) HZ_SM_MODEL = {'class_table': HZ_CLS, 'class_factor': 6, 'state_table': HZ_ST, 'char_len_table': HZ_CHAR_LEN_TABLE, 'name': "HZ-GB-2312", 'language': 'Chinese'} ISO2022CN_CLS = ( 2,0,0,0,0,0,0,0, # 00 - 07 0,0,0,0,0,0,0,0, # 08 - 0f 0,0,0,0,0,0,0,0, # 10 - 17 0,0,0,1,0,0,0,0, # 18 - 1f 0,0,0,0,0,0,0,0, # 20 - 27 0,3,0,0,0,0,0,0, # 28 - 2f 0,0,0,0,0,0,0,0, # 30 - 37 0,0,0,0,0,0,0,0, # 38 - 3f 0,0,0,4,0,0,0,0, # 40 - 47 0,0,0,0,0,0,0,0, # 48 - 4f 0,0,0,0,0,0,0,0, # 50 - 57 0,0,0,0,0,0,0,0, # 58 - 5f 0,0,0,0,0,0,0,0, # 60 - 67 0,0,0,0,0,0,0,0, # 68 - 6f 0,0,0,0,0,0,0,0, # 70 - 77 0,0,0,0,0,0,0,0, # 78 - 7f 2,2,2,2,2,2,2,2, # 80 - 87 2,2,2,2,2,2,2,2, # 88 - 8f 2,2,2,2,2,2,2,2, # 90 - 97 2,2,2,2,2,2,2,2, # 98 - 9f 2,2,2,2,2,2,2,2, # a0 - a7 2,2,2,2,2,2,2,2, # a8 - af 2,2,2,2,2,2,2,2, # b0 - b7 2,2,2,2,2,2,2,2, # b8 - bf 2,2,2,2,2,2,2,2, # c0 - c7 2,2,2,2,2,2,2,2, # c8 - cf 2,2,2,2,2,2,2,2, # d0 - d7 2,2,2,2,2,2,2,2, # d8 - df 2,2,2,2,2,2,2,2, # e0 - e7 2,2,2,2,2,2,2,2, # e8 - ef 2,2,2,2,2,2,2,2, # f0 - f7 2,2,2,2,2,2,2,2, # f8 - ff ) ISO2022CN_ST = ( MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,# 18-1f MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 20-27 5, 6,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 28-2f MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 30-37 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,# 38-3f ) ISO2022CN_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0) ISO2022CN_SM_MODEL = {'class_table': ISO2022CN_CLS, 'class_factor': 9, 'state_table': ISO2022CN_ST, 'char_len_table': ISO2022CN_CHAR_LEN_TABLE, 'name': "ISO-2022-CN", 'language': 'Chinese'} ISO2022JP_CLS = ( 2,0,0,0,0,0,0,0, # 00 - 07 0,0,0,0,0,0,2,2, # 08 - 0f 0,0,0,0,0,0,0,0, # 10 - 17 0,0,0,1,0,0,0,0, # 18 - 1f 0,0,0,0,7,0,0,0, # 20 - 27 3,0,0,0,0,0,0,0, # 28 - 2f 0,0,0,0,0,0,0,0, # 30 - 37 0,0,0,0,0,0,0,0, # 38 - 3f 6,0,4,0,8,0,0,0, # 40 - 47 0,9,5,0,0,0,0,0, # 48 - 4f 0,0,0,0,0,0,0,0, # 50 - 57 0,0,0,0,0,0,0,0, # 58 - 5f 0,0,0,0,0,0,0,0, # 60 - 67 0,0,0,0,0,0,0,0, # 68 - 6f 0,0,0,0,0,0,0,0, # 70 - 77 0,0,0,0,0,0,0,0, # 78 - 7f 2,2,2,2,2,2,2,2, # 80 - 87 2,2,2,2,2,2,2,2, # 88 - 8f 2,2,2,2,2,2,2,2, # 90 - 97 2,2,2,2,2,2,2,2, # 98 - 9f 2,2,2,2,2,2,2,2, # a0 - a7 2,2,2,2,2,2,2,2, # a8 - af 2,2,2,2,2,2,2,2, # b0 - b7 2,2,2,2,2,2,2,2, # b8 - bf 2,2,2,2,2,2,2,2, # c0 - c7 2,2,2,2,2,2,2,2, # c8 - cf 2,2,2,2,2,2,2,2, # d0 - d7 2,2,2,2,2,2,2,2, # d8 - df 2,2,2,2,2,2,2,2, # e0 - e7 2,2,2,2,2,2,2,2, # e8 - ef 2,2,2,2,2,2,2,2, # f0 - f7 2,2,2,2,2,2,2,2, # f8 - ff ) ISO2022JP_ST = ( MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,# 18-1f MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 20-27 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 6,MachineState.ITS_ME,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,# 28-2f MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,# 30-37 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 38-3f MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.START,# 40-47 ) ISO2022JP_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ISO2022JP_SM_MODEL = {'class_table': ISO2022JP_CLS, 'class_factor': 10, 'state_table': ISO2022JP_ST, 'char_len_table': ISO2022JP_CHAR_LEN_TABLE, 'name': "ISO-2022-JP", 'language': 'Japanese'} ISO2022KR_CLS = ( 2,0,0,0,0,0,0,0, # 00 - 07 0,0,0,0,0,0,0,0, # 08 - 0f 0,0,0,0,0,0,0,0, # 10 - 17 0,0,0,1,0,0,0,0, # 18 - 1f 0,0,0,0,3,0,0,0, # 20 - 27 0,4,0,0,0,0,0,0, # 28 - 2f 0,0,0,0,0,0,0,0, # 30 - 37 0,0,0,0,0,0,0,0, # 38 - 3f 0,0,0,5,0,0,0,0, # 40 - 47 0,0,0,0,0,0,0,0, # 48 - 4f 0,0,0,0,0,0,0,0, # 50 - 57 0,0,0,0,0,0,0,0, # 58 - 5f 0,0,0,0,0,0,0,0, # 60 - 67 0,0,0,0,0,0,0,0, # 68 - 6f 0,0,0,0,0,0,0,0, # 70 - 77 0,0,0,0,0,0,0,0, # 78 - 7f 2,2,2,2,2,2,2,2, # 80 - 87 2,2,2,2,2,2,2,2, # 88 - 8f 2,2,2,2,2,2,2,2, # 90 - 97 2,2,2,2,2,2,2,2, # 98 - 9f 2,2,2,2,2,2,2,2, # a0 - a7 2,2,2,2,2,2,2,2, # a8 - af 2,2,2,2,2,2,2,2, # b0 - b7 2,2,2,2,2,2,2,2, # b8 - bf 2,2,2,2,2,2,2,2, # c0 - c7 2,2,2,2,2,2,2,2, # c8 - cf 2,2,2,2,2,2,2,2, # d0 - d7 2,2,2,2,2,2,2,2, # d8 - df 2,2,2,2,2,2,2,2, # e0 - e7 2,2,2,2,2,2,2,2, # e8 - ef 2,2,2,2,2,2,2,2, # f0 - f7 2,2,2,2,2,2,2,2, # f8 - ff ) ISO2022KR_ST = ( MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 10-17 MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 18-1f MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 20-27 ) ISO2022KR_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) ISO2022KR_SM_MODEL = {'class_table': ISO2022KR_CLS, 'class_factor': 6, 'state_table': ISO2022KR_ST, 'char_len_table': ISO2022KR_CHAR_LEN_TABLE, 'name': "ISO-2022-KR", 'language': 'Korean'} PKH]UYtFF[python3.10/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-310.pycnu[o aiK@sbdZddlmZmZddlmZGdddeZidedddgd d d gd d ed ddgdddgd dedddgdddgd dedddddgddgd dedddgd d!d"gd d#ed#d$dd%d&gd'd(gd d)ed)d*dd+d,gd-d.gd d/ed/d0dd%d&gd1gd2d3ed3d4dd5gd6d7gd d8ed8d9dgd d:d;gd dd?d@gd dAedAdBdgd dCdDgd dEedEdFdgd dGdHdIgd dJedJdKddLdMgdNdOgd dPedPdQdddgdRdSgd dTedTdUdddgdVdWgd dXedXdYdgd dZd[gd ed\d]dgd^d_d`gd edadbdgd^dcddgd ededfdgdgdhdigd edjdkdd%d&gdlgd2edmdndddgdodpgd edqdrdgd dsdtgd edudvdddgdwdxgd edydzdgd{d|d}gd ed~ddddgddgd edddddgddgd edddgdgdgdedddgdddgd edddgdddgd eddddgddgd dZdS)z Metadata about languages used by our model training code for our SingleByteCharSetProbers. Could be used for other things in the future. This code is based on the language metadata from the uchardet project. )absolute_importprint_function) ascii_letterscs.eZdZdZ  dfdd ZddZZS) LanguageaMetadata about a language useful for training models :ivar name: The human name for the language, in English. :type name: str :ivar iso_code: 2-letter ISO 639-1 if possible, 3-letter ISO code otherwise, or use another catalog as a last resort. :type iso_code: str :ivar use_ascii: Whether or not ASCII letters should be included in trained models. :type use_ascii: bool :ivar charsets: The charsets we want to support and create data for. :type charsets: list of str :ivar alphabet: The characters in the language's alphabet. If `use_ascii` is `True`, you only need to add those not in the ASCII set. :type alphabet: str :ivar wiki_start_pages: The Wikipedia pages to start from if we're crawling Wikipedia for training data. :type wiki_start_pages: list of str NTcsrtt|||_||_||_||_|jr |r|t7}n t}n|s&td|r1d t t |nd|_ ||_ dS)Nz*Must supply alphabet if use_ascii is False)superr__init__nameiso_code use_asciicharsetsr ValueErrorjoinsortedsetalphabetwiki_start_pages)selfr r r r rr __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/metadata/languages.pyr#s  zLanguage.__init__cCs&d|jjddd|jDS)Nz{}({})z, css*|]\}}|dsd||VqdS)_z{}={!r}N) startswithformat).0kvrrr 6s z$Language.__repr__..)rr__name__r__dict__items)rrrr__repr__4s  zLanguage.__repr__)NNTNNN)r __module__ __qualname____doc__rr" __classcell__rrrrrs rArabicarF)z ISO-8859-6z WINDOWS-1256ZCP720ZCP864ubءآأؤإئابةتثجحخدذرزسشصضطظعغػؼؽؾؿـفقكلمنهوىيًٌٍَُِّuالصفحة_الرئيسية)r r r r rrZ Belarusianbe) ISO-8859-5 WINDOWS-1251IBM866 MacCyrillicuАБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШЫЬЭЮЯабвгдеёжзійклмнопрстуўфхцчшыьэюяʼu!Галоўная_старонка Bulgarianbg)r*r+IBM855uxАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюяuНачална_страницаZCzechczTz ISO-8859-2z WINDOWS-1250u<áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽuHlavní_stranaZDanishda) ISO-8859-1z ISO-8859-15 WINDOWS-1252u æøåÆØÅZForsideZGermander3r4uäöüßÄÖÜzWikipedia:HauptseiteGreekelz ISO-8859-7z WINDOWS-1253uαβγδεζηθικλμνξοπρσςτυφχψωάέήίόύώΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΣΤΥΦΧΨΩΆΈΉΊΌΎΏuΠύλη:ΚύριαZEnglishenZ Main_Page)r r r r rZ Esperantoeo ISO-8859-3uDabcĉdefgĝhĥijĵklmnoprsŝtuŭvzABCĈDEFGĜHĤIJĴKLMNOPRSŜTUŬVZuVikipedio:ĈefpaĝoZSpanishesuñáéíóúüÑÁÉÍÓÚÜzWikipedia:PortadaZEstonianet) ISO-8859-4 ISO-8859-13 WINDOWS-1257u6ABDEGHIJKLMNOPRSTUVÕÄÖÜabdeghijklmnoprstuvõäöüZEsilehtZFinnishfiuÅÄÖŠŽåäöšžzWikipedia:EtusivuZFrenchfru,œàâçèéîïùûêŒÀÂÇÈÉÎÏÙÛÊuWikipédia:Accueil_principaluBœuf (animal)Hebrewhez ISO-8859-8z WINDOWS-1255u<אבגדהוזחטיךכלםמןנסעףפץצקרשתװױײuעמוד_ראשיZCroatianhru@abcčćdđefghijklmnoprsštuvzžABCČĆDĐEFGHIJKLMNOPRSŠTUVZŽZGlavna_stranicaZ HungarianhuuPabcdefghijklmnoprstuvzáéíóöőúüűABCDEFGHIJKLMNOPRSTUVZÁÉÍÓÖŐÚÜŰu KezdőlapZItalianituÀÈÉÌÒÓÙàèéìòóùZPagina_principale Lithuanianlt)r>r?r=uRAĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽaąbcčdeęėfghiįyjklmnoprsštuųūvzžZPagrindinis_puslapisLatvianlvuXAĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽaābcčdeēfgģhiījkķlļmnņoprsštuūvzžu Sākumlapa Macedonianmk)r*r+r-r0u|АБВГДЃЕЖЗЅИЈКЛЉМНЊОПРСТЌУФХЦЧЏШабвгдѓежзѕијклљмнњопрстќуфхцчџшuГлавна_страницаDutchnlZ HoofdpaginaPolishpluRAĄBCĆDEĘFGHIJKLŁMNŃOÓPRSŚTUWYZŹŻaąbcćdeęfghijklłmnńoóprsśtuwyzźżuWikipedia:Strona_główna Portugueseptu0ÁÂÃÀÇÉÊÍÓÔÕÚáâãàçéêíóôõúuWikipédia:Página_principalRomanianrouăâîșțĂÂÎȘȚuPagina_principalăRussianru)r*r+zKOI8-Rr-r,r0uабвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯu#Заглавная_страницаSlovakskuDáäčďéíĺľňóôŕšťúýžÁÄČĎÉÍĹĽŇÓÔŔŠŤÚÝŽuHlavná_stránkaSloveneslu8abcčdefghijklmnoprsštuvzžABCČDEFGHIJKLMNOPRSŠTUVZŽZ Glavna_stranSerbiansruxАБВГДЂЕЖЗИЈКЛЉМНЊОПРСТЋУФХЦЧЏШабвгдђежзијклљмнњопрстћуфхцчџшuГлавна_страна)r r rr rThaith)z ISO-8859-11zTIS-620ZCP874uกขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛uหน้าหลักTurkishtr)r:z ISO-8859-9z WINDOWS-1254uRabcçdefgğhıijklmnoöprsştuüvyzâîûABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZÂÎÛZ Ana_Sayfa Vietnameseviz WINDOWS-1258uHaăâbcdđeêghiklmnoôơpqrstuưvxyAĂÂBCDĐEÊGHIKLMNOÔƠPQRSTUƯVXYuChữ_Quốc_ngữ)rGrIrKrMrOrQrSrUrWrYr[r]r_raN) r% __future__rrstringrobjectrZ LANGUAGESrrrrs , !(.5:BISZbhpx      PKH]Zpython3.10/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-310.pycnu[o ai@sdS)Nrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/chardet/metadata/__init__.pysPKH]zgCKKBpython3.10/site-packages/pip/_vendor/chardet/metadata/languages.pynu[# -*- coding: utf-8 -*- """ Metadata about languages used by our model training code for our SingleByteCharSetProbers. Could be used for other things in the future. This code is based on the language metadata from the uchardet project. """ from __future__ import absolute_import, print_function from string import ascii_letters # TODO: Add Ukranian (KOI8-U) class Language(object): """Metadata about a language useful for training models :ivar name: The human name for the language, in English. :type name: str :ivar iso_code: 2-letter ISO 639-1 if possible, 3-letter ISO code otherwise, or use another catalog as a last resort. :type iso_code: str :ivar use_ascii: Whether or not ASCII letters should be included in trained models. :type use_ascii: bool :ivar charsets: The charsets we want to support and create data for. :type charsets: list of str :ivar alphabet: The characters in the language's alphabet. If `use_ascii` is `True`, you only need to add those not in the ASCII set. :type alphabet: str :ivar wiki_start_pages: The Wikipedia pages to start from if we're crawling Wikipedia for training data. :type wiki_start_pages: list of str """ def __init__(self, name=None, iso_code=None, use_ascii=True, charsets=None, alphabet=None, wiki_start_pages=None): super(Language, self).__init__() self.name = name self.iso_code = iso_code self.use_ascii = use_ascii self.charsets = charsets if self.use_ascii: if alphabet: alphabet += ascii_letters else: alphabet = ascii_letters elif not alphabet: raise ValueError('Must supply alphabet if use_ascii is False') self.alphabet = ''.join(sorted(set(alphabet))) if alphabet else None self.wiki_start_pages = wiki_start_pages def __repr__(self): return '{}({})'.format(self.__class__.__name__, ', '.join('{}={!r}'.format(k, v) for k, v in self.__dict__.items() if not k.startswith('_'))) LANGUAGES = {'Arabic': Language(name='Arabic', iso_code='ar', use_ascii=False, # We only support encodings that use isolated # forms, because the current recommendation is # that the rendering system handles presentation # forms. This means we purposefully skip IBM864. charsets=['ISO-8859-6', 'WINDOWS-1256', 'CP720', 'CP864'], alphabet=u'ءآأؤإئابةتثجحخدذرزسشصضطظعغػؼؽؾؿـفقكلمنهوىيًٌٍَُِّ', wiki_start_pages=[u'الصفحة_الرئيسية']), 'Belarusian': Language(name='Belarusian', iso_code='be', use_ascii=False, charsets=['ISO-8859-5', 'WINDOWS-1251', 'IBM866', 'MacCyrillic'], alphabet=(u'АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШЫЬЭЮЯ' u'абвгдеёжзійклмнопрстуўфхцчшыьэюяʼ'), wiki_start_pages=[u'Галоўная_старонка']), 'Bulgarian': Language(name='Bulgarian', iso_code='bg', use_ascii=False, charsets=['ISO-8859-5', 'WINDOWS-1251', 'IBM855'], alphabet=(u'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯ' u'абвгдежзийклмнопрстуфхцчшщъьюя'), wiki_start_pages=[u'Начална_страница']), 'Czech': Language(name='Czech', iso_code='cz', use_ascii=True, charsets=['ISO-8859-2', 'WINDOWS-1250'], alphabet=u'áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ', wiki_start_pages=[u'Hlavní_strana']), 'Danish': Language(name='Danish', iso_code='da', use_ascii=True, charsets=['ISO-8859-1', 'ISO-8859-15', 'WINDOWS-1252'], alphabet=u'æøåÆØÅ', wiki_start_pages=[u'Forside']), 'German': Language(name='German', iso_code='de', use_ascii=True, charsets=['ISO-8859-1', 'WINDOWS-1252'], alphabet=u'äöüßÄÖÜ', wiki_start_pages=[u'Wikipedia:Hauptseite']), 'Greek': Language(name='Greek', iso_code='el', use_ascii=False, charsets=['ISO-8859-7', 'WINDOWS-1253'], alphabet=(u'αβγδεζηθικλμνξοπρσςτυφχψωάέήίόύώ' u'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΣΤΥΦΧΨΩΆΈΉΊΌΎΏ'), wiki_start_pages=[u'Πύλη:Κύρια']), 'English': Language(name='English', iso_code='en', use_ascii=True, charsets=['ISO-8859-1', 'WINDOWS-1252'], wiki_start_pages=[u'Main_Page']), 'Esperanto': Language(name='Esperanto', iso_code='eo', # Q, W, X, and Y not used at all use_ascii=False, charsets=['ISO-8859-3'], alphabet=(u'abcĉdefgĝhĥijĵklmnoprsŝtuŭvz' u'ABCĈDEFGĜHĤIJĴKLMNOPRSŜTUŬVZ'), wiki_start_pages=[u'Vikipedio:Ĉefpaĝo']), 'Spanish': Language(name='Spanish', iso_code='es', use_ascii=True, charsets=['ISO-8859-1', 'ISO-8859-15', 'WINDOWS-1252'], alphabet=u'ñáéíóúüÑÁÉÍÓÚÜ', wiki_start_pages=[u'Wikipedia:Portada']), 'Estonian': Language(name='Estonian', iso_code='et', use_ascii=False, charsets=['ISO-8859-4', 'ISO-8859-13', 'WINDOWS-1257'], # C, F, Š, Q, W, X, Y, Z, Ž are only for # loanwords alphabet=(u'ABDEGHIJKLMNOPRSTUVÕÄÖÜ' u'abdeghijklmnoprstuvõäöü'), wiki_start_pages=[u'Esileht']), 'Finnish': Language(name='Finnish', iso_code='fi', use_ascii=True, charsets=['ISO-8859-1', 'ISO-8859-15', 'WINDOWS-1252'], alphabet=u'ÅÄÖŠŽåäöšž', wiki_start_pages=[u'Wikipedia:Etusivu']), 'French': Language(name='French', iso_code='fr', use_ascii=True, charsets=['ISO-8859-1', 'ISO-8859-15', 'WINDOWS-1252'], alphabet=u'œàâçèéîïùûêŒÀÂÇÈÉÎÏÙÛÊ', wiki_start_pages=[u'Wikipédia:Accueil_principal', u'Bœuf (animal)']), 'Hebrew': Language(name='Hebrew', iso_code='he', use_ascii=False, charsets=['ISO-8859-8', 'WINDOWS-1255'], alphabet=u'אבגדהוזחטיךכלםמןנסעףפץצקרשתװױײ', wiki_start_pages=[u'עמוד_ראשי']), 'Croatian': Language(name='Croatian', iso_code='hr', # Q, W, X, Y are only used for foreign words. use_ascii=False, charsets=['ISO-8859-2', 'WINDOWS-1250'], alphabet=(u'abcčćdđefghijklmnoprsštuvzž' u'ABCČĆDĐEFGHIJKLMNOPRSŠTUVZŽ'), wiki_start_pages=[u'Glavna_stranica']), 'Hungarian': Language(name='Hungarian', iso_code='hu', # Q, W, X, Y are only used for foreign words. use_ascii=False, charsets=['ISO-8859-2', 'WINDOWS-1250'], alphabet=(u'abcdefghijklmnoprstuvzáéíóöőúüű' u'ABCDEFGHIJKLMNOPRSTUVZÁÉÍÓÖŐÚÜŰ'), wiki_start_pages=[u'Kezdőlap']), 'Italian': Language(name='Italian', iso_code='it', use_ascii=True, charsets=['ISO-8859-1', 'ISO-8859-15', 'WINDOWS-1252'], alphabet=u'ÀÈÉÌÒÓÙàèéìòóù', wiki_start_pages=[u'Pagina_principale']), 'Lithuanian': Language(name='Lithuanian', iso_code='lt', use_ascii=False, charsets=['ISO-8859-13', 'WINDOWS-1257', 'ISO-8859-4'], # Q, W, and X not used at all alphabet=(u'AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ' u'aąbcčdeęėfghiįyjklmnoprsštuųūvzž'), wiki_start_pages=[u'Pagrindinis_puslapis']), 'Latvian': Language(name='Latvian', iso_code='lv', use_ascii=False, charsets=['ISO-8859-13', 'WINDOWS-1257', 'ISO-8859-4'], # Q, W, X, Y are only for loanwords alphabet=(u'AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ' u'aābcčdeēfgģhiījkķlļmnņoprsštuūvzž'), wiki_start_pages=[u'Sākumlapa']), 'Macedonian': Language(name='Macedonian', iso_code='mk', use_ascii=False, charsets=['ISO-8859-5', 'WINDOWS-1251', 'MacCyrillic', 'IBM855'], alphabet=(u'АБВГДЃЕЖЗЅИЈКЛЉМНЊОПРСТЌУФХЦЧЏШ' u'абвгдѓежзѕијклљмнњопрстќуфхцчџш'), wiki_start_pages=[u'Главна_страница']), 'Dutch': Language(name='Dutch', iso_code='nl', use_ascii=True, charsets=['ISO-8859-1', 'WINDOWS-1252'], wiki_start_pages=[u'Hoofdpagina']), 'Polish': Language(name='Polish', iso_code='pl', # Q and X are only used for foreign words. use_ascii=False, charsets=['ISO-8859-2', 'WINDOWS-1250'], alphabet=(u'AĄBCĆDEĘFGHIJKLŁMNŃOÓPRSŚTUWYZŹŻ' u'aąbcćdeęfghijklłmnńoóprsśtuwyzźż'), wiki_start_pages=[u'Wikipedia:Strona_główna']), 'Portuguese': Language(name='Portuguese', iso_code='pt', use_ascii=True, charsets=['ISO-8859-1', 'ISO-8859-15', 'WINDOWS-1252'], alphabet=u'ÁÂÃÀÇÉÊÍÓÔÕÚáâãàçéêíóôõú', wiki_start_pages=[u'Wikipédia:Página_principal']), 'Romanian': Language(name='Romanian', iso_code='ro', use_ascii=True, charsets=['ISO-8859-2', 'WINDOWS-1250'], alphabet=u'ăâîșțĂÂÎȘȚ', wiki_start_pages=[u'Pagina_principală']), 'Russian': Language(name='Russian', iso_code='ru', use_ascii=False, charsets=['ISO-8859-5', 'WINDOWS-1251', 'KOI8-R', 'MacCyrillic', 'IBM866', 'IBM855'], alphabet=(u'абвгдеёжзийклмнопрстуфхцчшщъыьэюя' u'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'), wiki_start_pages=[u'Заглавная_страница']), 'Slovak': Language(name='Slovak', iso_code='sk', use_ascii=True, charsets=['ISO-8859-2', 'WINDOWS-1250'], alphabet=u'áäčďéíĺľňóôŕšťúýžÁÄČĎÉÍĹĽŇÓÔŔŠŤÚÝŽ', wiki_start_pages=[u'Hlavná_stránka']), 'Slovene': Language(name='Slovene', iso_code='sl', # Q, W, X, Y are only used for foreign words. use_ascii=False, charsets=['ISO-8859-2', 'WINDOWS-1250'], alphabet=(u'abcčdefghijklmnoprsštuvzž' u'ABCČDEFGHIJKLMNOPRSŠTUVZŽ'), wiki_start_pages=[u'Glavna_stran']), # Serbian can be written in both Latin and Cyrillic, but there's no # simple way to get the Latin alphabet pages from Wikipedia through # the API, so for now we just support Cyrillic. 'Serbian': Language(name='Serbian', iso_code='sr', alphabet=(u'АБВГДЂЕЖЗИЈКЛЉМНЊОПРСТЋУФХЦЧЏШ' u'абвгдђежзијклљмнњопрстћуфхцчџш'), charsets=['ISO-8859-5', 'WINDOWS-1251', 'MacCyrillic', 'IBM855'], wiki_start_pages=[u'Главна_страна']), 'Thai': Language(name='Thai', iso_code='th', use_ascii=False, charsets=['ISO-8859-11', 'TIS-620', 'CP874'], alphabet=u'กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛', wiki_start_pages=[u'หน้าหลัก']), 'Turkish': Language(name='Turkish', iso_code='tr', # Q, W, and X are not used by Turkish use_ascii=False, charsets=['ISO-8859-3', 'ISO-8859-9', 'WINDOWS-1254'], alphabet=(u'abcçdefgğhıijklmnoöprsştuüvyzâîû' u'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZÂÎÛ'), wiki_start_pages=[u'Ana_Sayfa']), 'Vietnamese': Language(name='Vietnamese', iso_code='vi', use_ascii=False, # Windows-1258 is the only common 8-bit # Vietnamese encoding supported by Python. # From Wikipedia: # For systems that lack support for Unicode, # dozens of 8-bit Vietnamese code pages are # available.[1] The most common are VISCII # (TCVN 5712:1993), VPS, and Windows-1258.[3] # Where ASCII is required, such as when # ensuring readability in plain text e-mail, # Vietnamese letters are often encoded # according to Vietnamese Quoted-Readable # (VIQR) or VSCII Mnemonic (VSCII-MNEM),[4] # though usage of either variable-width # scheme has declined dramatically following # the adoption of Unicode on the World Wide # Web. charsets=['WINDOWS-1258'], alphabet=(u'aăâbcdđeêghiklmnoôơpqrstuưvxy' u'AĂÂBCDĐEÊGHIKLMNOÔƠPQRSTUƯVXY'), wiki_start_pages=[u'Chữ_Quốc_ngữ']), } PKH]Apython3.10/site-packages/pip/_vendor/chardet/metadata/__init__.pynu[PKH]9add7python3.10/site-packages/pip/_vendor/chardet/jisfreq.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Communicator client code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### # Sampling from about 20M text materials include literature and computer technology # # Japanese frequency table, applied to both S-JIS and EUC-JP # They are sorted in order. # 128 --> 0.77094 # 256 --> 0.85710 # 512 --> 0.92635 # 1024 --> 0.97130 # 2048 --> 0.99431 # # Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 # Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 # # Typical Distribution Ratio, 25% of IDR JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0 # Char to FreqOrder table , JIS_TABLE_SIZE = 4368 JIS_CHAR_TO_FREQ_ORDER = ( 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16 3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32 1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48 2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64 2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80 5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96 1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112 5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128 5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144 5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160 5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176 5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192 5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208 1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224 1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240 1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256 2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272 3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288 3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336 1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368 5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464 5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480 5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496 5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512 4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528 5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544 5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560 5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576 5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592 5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608 5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624 5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640 5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656 5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672 3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688 5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704 5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720 5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736 5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752 5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768 5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784 5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800 5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816 5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832 5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848 5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864 5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880 5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896 5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912 5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928 5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944 5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960 5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976 5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992 5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008 5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024 5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040 5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056 5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072 5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088 5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104 5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120 5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136 5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152 5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168 5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184 5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200 5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216 5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232 5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248 5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264 5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280 5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296 6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312 6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328 6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344 6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360 6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376 6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392 6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408 6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424 4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472 1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488 1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520 3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536 3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568 3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584 3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616 2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648 3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664 1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696 1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728 2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744 2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760 2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776 2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792 1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808 1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824 1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840 1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856 2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872 1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888 2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904 1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920 1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936 1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952 1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968 1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984 1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032 1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048 2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064 2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080 2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096 3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112 3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144 3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160 1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192 2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208 1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240 3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256 4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272 2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288 1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304 2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320 1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368 1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384 2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400 2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416 2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432 3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448 1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464 2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528 1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544 2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576 1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592 1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624 1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640 1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656 1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688 2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720 2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736 3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752 2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768 1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784 6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800 1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816 2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832 1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880 3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896 3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912 1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928 1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944 1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960 1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008 2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040 3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056 2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088 1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104 2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136 1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168 4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184 2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200 1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232 1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248 2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280 6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296 1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312 1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328 2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344 3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376 3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392 1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424 1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456 3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488 2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520 4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536 2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552 1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568 1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584 1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616 1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632 3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648 1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664 3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728 2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744 1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776 1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808 1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872 1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888 1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904 2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920 4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952 1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984 1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000 3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016 1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032 2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048 2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064 1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080 1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096 2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128 2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144 1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160 1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176 1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192 1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208 3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224 2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240 2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272 3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288 3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304 1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320 2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336 1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352 2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512 ) PKH]\7HBpython3.10/site-packages/pip/_vendor/chardet/codingstatemachine.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### import logging from .enums import MachineState class CodingStateMachine(object): """ A state machine to verify a byte sequence for a particular encoding. For each byte the detector receives, it will feed that byte to every active state machine available, one byte at a time. The state machine changes its state based on its previous state and the byte it receives. There are 3 states in a state machine that are of interest to an auto-detector: START state: This is the state to start with, or a legal byte sequence (i.e. a valid code point) for character has been identified. ME state: This indicates that the state machine identified a byte sequence that is specific to the charset it is designed for and that there is no other possible encoding which can contain this byte sequence. This will to lead to an immediate positive answer for the detector. ERROR state: This indicates the state machine identified an illegal byte sequence for that encoding. This will lead to an immediate negative answer for this encoding. Detector will exclude this encoding from consideration from here on. """ def __init__(self, sm): self._model = sm self._curr_byte_pos = 0 self._curr_char_len = 0 self._curr_state = None self.logger = logging.getLogger(__name__) self.reset() def reset(self): self._curr_state = MachineState.START def next_state(self, c): # for each byte we get its class # if it is first byte, we also get byte length byte_class = self._model['class_table'][c] if self._curr_state == MachineState.START: self._curr_byte_pos = 0 self._curr_char_len = self._model['char_len_table'][byte_class] # from byte's class and state_table, we get its next state curr_state = (self._curr_state * self._model['class_factor'] + byte_class) self._curr_state = self._model['state_table'][curr_state] self._curr_byte_pos += 1 return self._curr_state def get_current_charlen(self): return self._curr_char_len def get_coding_state_machine(self): return self._model['name'] @property def language(self): return self._model['language'] PKH]f 8python3.10/site-packages/pip/_vendor/chardet/__init__.pynu[######################## BEGIN LICENSE BLOCK ######################## # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .universaldetector import UniversalDetector from .enums import InputState from .version import __version__, VERSION __all__ = ['UniversalDetector', 'detect', 'detect_all', '__version__', 'VERSION'] def detect(byte_str): """ Detect the encoding of the given byte string. :param byte_str: The byte sequence to examine. :type byte_str: ``bytes`` or ``bytearray`` """ if not isinstance(byte_str, bytearray): if not isinstance(byte_str, bytes): raise TypeError('Expected object of type bytes or bytearray, got: ' '{}'.format(type(byte_str))) else: byte_str = bytearray(byte_str) detector = UniversalDetector() detector.feed(byte_str) return detector.close() def detect_all(byte_str): """ Detect all the possible encodings of the given byte string. :param byte_str: The byte sequence to examine. :type byte_str: ``bytes`` or ``bytearray`` """ if not isinstance(byte_str, bytearray): if not isinstance(byte_str, bytes): raise TypeError('Expected object of type bytes or bytearray, got: ' '{}'.format(type(byte_str))) else: byte_str = bytearray(byte_str) detector = UniversalDetector() detector.feed(byte_str) detector.close() if detector._input_state == InputState.HIGH_BYTE: results = [] for prober in detector._charset_probers: if prober.get_confidence() > detector.MINIMUM_THRESHOLD: charset_name = prober.charset_name lower_charset_name = prober.charset_name.lower() # Use Windows encoding name instead of ISO-8859 if we saw any # extra Windows-specific bytes if lower_charset_name.startswith('iso-8859'): if detector._has_win_bytes: charset_name = detector.ISO_WIN_MAP.get(lower_charset_name, charset_name) results.append({ 'encoding': charset_name, 'confidence': prober.get_confidence(), 'language': prober.language, }) if len(results) > 0: return sorted(results, key=lambda result: -result['confidence']) return [detector.result] PKH]EPP:python3.10/site-packages/pip/_vendor/chardet/gb2312freq.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Communicator client code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### # GB2312 most frequently used character table # # Char to FreqOrder table , from hz6763 # 512 --> 0.79 -- 0.79 # 1024 --> 0.92 -- 0.13 # 2048 --> 0.98 -- 0.06 # 6768 --> 1.00 -- 0.02 # # Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79 # Random Distribution Ration = 512 / (3755 - 512) = 0.157 # # Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9 GB2312_TABLE_SIZE = 3760 GB2312_CHAR_TO_FREQ_ORDER = ( 1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, 2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, 2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, 1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, 1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, 1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, 2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, 3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, 1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, 2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, 2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, 1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, 3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, 1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, 2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, 1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, 3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, 1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, 2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, 1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, 3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, 3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, 3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, 1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, 3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, 2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, 1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, 1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, 4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, 3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, 3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, 1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, 2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, 1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, 1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, 3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, 3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, 4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, 3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, 1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, 1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, 4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, 3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, 1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, 1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, 2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, 3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, 4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, 3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, 2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, 2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, 2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, 2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, 3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, 2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, 2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, 1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, 2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, 1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, 1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, 1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, 2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, 3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, 2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, 2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, 2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, 3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, 1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, 1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, 2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, 1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, 3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, 1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, 1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, 3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, 2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, 1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, 4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, 1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, 1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, 3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, 1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, 1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, 1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, 1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, 3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, 4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, 3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, 2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, 2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, 1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, 3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, 2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, 1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, 1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, 2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, 2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, 3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, 4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, 3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, 3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, 2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, 1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, 3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, 4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, 2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, 1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, 1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, 1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, 3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, 1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, 1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, 2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, 2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, 2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, 1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, 1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, 2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, 1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, 1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, 2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, 2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, 3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, 1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, 4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, 3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, 1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, 3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, 1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, 4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, 1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, 2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, 1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, 1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, 3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, 2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, 1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, 1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, 1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, 3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, 2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, 3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, 3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, 3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, 2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, 2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, 1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, 1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, 3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, 3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, 1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, 1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, 3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, 2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, 2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, 1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, 3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, 4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, 1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, 2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, 3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, 3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, 1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, 2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, 1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, 1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, 1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, 1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, 1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, 1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, #last 512 ) PKH]UZ?python3.10/site-packages/pip/_vendor/chardet/sbcsgroupprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Universal charset detector code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 2001 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # Shy Shalom - original C code # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .charsetgroupprober import CharSetGroupProber from .hebrewprober import HebrewProber from .langbulgarianmodel import (ISO_8859_5_BULGARIAN_MODEL, WINDOWS_1251_BULGARIAN_MODEL) from .langgreekmodel import ISO_8859_7_GREEK_MODEL, WINDOWS_1253_GREEK_MODEL from .langhebrewmodel import WINDOWS_1255_HEBREW_MODEL # from .langhungarianmodel import (ISO_8859_2_HUNGARIAN_MODEL, # WINDOWS_1250_HUNGARIAN_MODEL) from .langrussianmodel import (IBM855_RUSSIAN_MODEL, IBM866_RUSSIAN_MODEL, ISO_8859_5_RUSSIAN_MODEL, KOI8_R_RUSSIAN_MODEL, MACCYRILLIC_RUSSIAN_MODEL, WINDOWS_1251_RUSSIAN_MODEL) from .langthaimodel import TIS_620_THAI_MODEL from .langturkishmodel import ISO_8859_9_TURKISH_MODEL from .sbcharsetprober import SingleByteCharSetProber class SBCSGroupProber(CharSetGroupProber): def __init__(self): super(SBCSGroupProber, self).__init__() hebrew_prober = HebrewProber() logical_hebrew_prober = SingleByteCharSetProber(WINDOWS_1255_HEBREW_MODEL, False, hebrew_prober) # TODO: See if using ISO-8859-8 Hebrew model works better here, since # it's actually the visual one visual_hebrew_prober = SingleByteCharSetProber(WINDOWS_1255_HEBREW_MODEL, True, hebrew_prober) hebrew_prober.set_model_probers(logical_hebrew_prober, visual_hebrew_prober) # TODO: ORDER MATTERS HERE. I changed the order vs what was in master # and several tests failed that did not before. Some thought # should be put into the ordering, and we should consider making # order not matter here, because that is very counter-intuitive. self.probers = [ SingleByteCharSetProber(WINDOWS_1251_RUSSIAN_MODEL), SingleByteCharSetProber(KOI8_R_RUSSIAN_MODEL), SingleByteCharSetProber(ISO_8859_5_RUSSIAN_MODEL), SingleByteCharSetProber(MACCYRILLIC_RUSSIAN_MODEL), SingleByteCharSetProber(IBM866_RUSSIAN_MODEL), SingleByteCharSetProber(IBM855_RUSSIAN_MODEL), SingleByteCharSetProber(ISO_8859_7_GREEK_MODEL), SingleByteCharSetProber(WINDOWS_1253_GREEK_MODEL), SingleByteCharSetProber(ISO_8859_5_BULGARIAN_MODEL), SingleByteCharSetProber(WINDOWS_1251_BULGARIAN_MODEL), # TODO: Restore Hungarian encodings (iso-8859-2 and windows-1250) # after we retrain model. # SingleByteCharSetProber(ISO_8859_2_HUNGARIAN_MODEL), # SingleByteCharSetProber(WINDOWS_1250_HUNGARIAN_MODEL), SingleByteCharSetProber(TIS_620_THAI_MODEL), SingleByteCharSetProber(ISO_8859_9_TURKISH_MODEL), hebrew_prober, logical_hebrew_prober, visual_hebrew_prober, ] self.reset() PKH]Ay449python3.10/site-packages/pip/_vendor/chardet/euckrfreq.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Communicator client code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### # Sampling from about 20M text materials include literature and computer technology # 128 --> 0.79 # 256 --> 0.92 # 512 --> 0.986 # 1024 --> 0.99944 # 2048 --> 0.99999 # # Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 # Random Distribution Ration = 512 / (2350-512) = 0.279. # # Typical Distribution Ratio EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0 EUCKR_TABLE_SIZE = 2352 # Char to FreqOrder table , EUCKR_CHAR_TO_FREQ_ORDER = ( 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, 1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, 1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, 1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, 1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, 1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, 1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, 1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, 1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, 1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, 1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, 1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, 1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, 1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, 1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, 1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, 1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, 1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, 1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, 1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, 1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, 1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, 1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, 1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, 1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, 1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, 1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, 1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, 1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, 2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, 2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, 2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, 2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, 2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, 1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, 2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, 1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, 2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, 2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, 1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, 2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, 2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, 2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, 1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, 2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, 2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, 2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, 2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, 2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, 2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, 1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, 2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, 2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, 2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, 2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, 2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, 1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, 1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, 2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, 1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, 2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, 1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, 2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, 2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, 2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, 2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, 2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, 1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, 1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, 2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, 1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, 2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, 2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, 1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, 2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, 1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, 2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, 1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, 2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, 2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, 1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, 1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, 2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, 2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, 2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, 2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, 2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, 2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, 1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, 2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, 2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, 2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, 2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, 2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, 2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, 1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, 2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256 ) PKH]aZ=python3.10/site-packages/pip/_vendor/chardet/charsetprober.pynu[######################## BEGIN LICENSE BLOCK ######################## # The Original Code is Mozilla Universal charset detector code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 2001 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Mark Pilgrim - port to Python # Shy Shalom - original C code # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### import logging import re from .enums import ProbingState class CharSetProber(object): SHORTCUT_THRESHOLD = 0.95 def __init__(self, lang_filter=None): self._state = None self.lang_filter = lang_filter self.logger = logging.getLogger(__name__) def reset(self): self._state = ProbingState.DETECTING @property def charset_name(self): return None def feed(self, buf): pass @property def state(self): return self._state def get_confidence(self): return 0.0 @staticmethod def filter_high_byte_only(buf): buf = re.sub(b'([\x00-\x7F])+', b' ', buf) return buf @staticmethod def filter_international_words(buf): """ We define three types of bytes: alphabet: english alphabets [a-zA-Z] international: international characters [\x80-\xFF] marker: everything else [^a-zA-Z\x80-\xFF] The input buffer can be thought to contain a series of words delimited by markers. This function works to filter all words that contain at least one international character. All contiguous sequences of markers are replaced by a single space ascii character. This filter applies to all scripts which do not use English characters. """ filtered = bytearray() # This regex expression filters out only words that have at-least one # international character. The word may include one marker character at # the end. words = re.findall(b'[a-zA-Z]*[\x80-\xFF]+[a-zA-Z]*[^a-zA-Z\x80-\xFF]?', buf) for word in words: filtered.extend(word[:-1]) # If the last character in the word is a marker, replace it with a # space as markers shouldn't affect our analysis (they are used # similarly across all languages and may thus have similar # frequencies). last_char = word[-1:] if not last_char.isalpha() and last_char < b'\x80': last_char = b' ' filtered.extend(last_char) return filtered @staticmethod def filter_with_english_letters(buf): """ Returns a copy of ``buf`` that retains only the sequences of English alphabet and high byte characters that are not between <> characters. Also retains English alphabet and high byte characters immediately before occurrences of >. This filter can be applied to all scripts which contain both English characters and extended ASCII characters, but is currently only used by ``Latin1Prober``. """ filtered = bytearray() in_tag = False prev = 0 for curr in range(len(buf)): # Slice here to get bytes instead of an int with Python 3 buf_char = buf[curr:curr + 1] # Check if we're coming out of or entering an HTML tag if buf_char == b'>': in_tag = False elif buf_char == b'<': in_tag = True # If current character is not extended-ASCII and not alphabetic... if buf_char < b'\x80' and not buf_char.isalpha(): # ...and we're not in a tag if curr > prev and not in_tag: # Keep everything after last non-extended-ASCII, # non-alphabetic character filtered.extend(buf[prev:curr]) # Output a space to delimit stretch we kept filtered.extend(b' ') prev = curr + 1 # If we're not in a tag... if not in_tag: # Keep everything after last non-extended-ASCII, non-alphabetic # character filtered.extend(buf[prev:]) return filtered PKH]!]Qpython3.10/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-310.pycnu[o ai&@s@ddlmZGdddeZGdddeZGdddeZdS) )win32c@s,eZdZdZdZdZdZdZdZdZ dZ d S) WinColorrN) __name__ __module__ __qualname__BLACKBLUEGREENCYANREDMAGENTAYELLOWGREYrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/colorama/winterm.pyrsrc@seZdZdZdZdZdS)WinStylerN)r r r NORMALBRIGHTBRIGHT_BACKGROUNDrrrrrsrc@seZdZddZddZddZd dd Zd!d d Zd!d dZd"ddZ d"ddZ ddZ d"ddZ d#ddZ d$ddZd$ddZddZdS)%WinTermcCs>ttjj|_||j|j|_|j|_ |j |_ d|_ dS)Nr) rGetConsoleScreenBufferInfoSTDOUT wAttributes_default set_attrs_fore _default_fore_back _default_back_style_default_style_lightselfrrr__init__s   zWinTerm.__init__cCs|j|jd|j|jBS)N)r$r&r(r*r+rrr get_attrs$szWinTerm.get_attrscCs.|d@|_|d?d@|_|tjtjB@|_dS)Nr r)r$r&rrrr()r,valuerrrr#'s zWinTerm.set_attrsNcCs$||j|j|jdd|_dS)N)attrsr)r#r" set_consoler*)r, on_stderrrrr reset_all,s  zWinTerm.reset_allFcCL|dur|j}||_|r|jtjO_n |jtjM_|j|ddSN)r3)r%r$r*rrr2)r,forelightr3rrrr71z WinTerm.forecCr5r6)r'r&r*rrr2)r,backr8r3rrrr:<r9z WinTerm.backcCs$|dur|j}||_|j|ddSr6)r)r(r2)r,styler3rrrr;Gsz WinTerm.stylecCs0|dur|}tj}|rtj}t||dSN)r/rr STDERRSetConsoleTextAttribute)r,r1r3handlerrrr2Ms zWinTerm.set_consolecCs,t|j}|jd7_|jd7_|S)Nr)rrdwCursorPositionXY)r,r?positionrrr get_positionUs zWinTerm.get_positioncCs,|durdStj}|rtj}t||dSr<)rr r=SetConsoleCursorPosition)r,rCr3r?rrrset_cursor_position]s zWinTerm.set_cursor_positioncCsBtj}|rtj}||}|j||j|f}tj||dddS)NF)adjust)rr r=rDrBrArE)r,xyr3r?rCadjusted_positionrrr cursor_adjustgs  zWinTerm.cursor_adjustrc Cstj}|rtj}t|}|jj|jj}|jj|jj|jj}|dkr-|j}||}n|dkr:tdd}|}n|dkrGtdd}|}ndSt |d||t || |||dkrgt |ddSdS)Nrrr )rr) rr r=rdwSizerArBr@COORDFillConsoleOutputCharacterFillConsoleOutputAttributer/rE) r,moder3r?csbicells_in_screencells_before_cursor from_coordcells_to_eraserrr erase_screenos*    zWinTerm.erase_screencCstj}|rtj}t|}|dkr|j}|jj|jj}n$|dkr.td|jj}|jj}n|dkr?td|jj}|jj}ndSt |d||t || ||dS)NrrrrL) rr r=rr@rMrArNrBrOrPr/)r,rQr3r?rRrUrVrrr erase_lines    zWinTerm.erase_linecCst|dSr<)rSetConsoleTitle)r,titlerrr set_titleszWinTerm.set_titler<)NFF)NF)F)rF)r r r r-r/r#r4r7r:r;r2rDrFrKrWrXr[rrrrrs       rN)robjectrrrrrrrs  PKH]i?Opython3.10/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-310.pycnu[o ai @sdZdZzddlZddlmZeejZddlmZWneefy1dZddZ ddZ YdSwdd lm Z m Z m Z mZejZGd d d e ZejjZejge_eje_ejjZejeege_eje_ejj Zejejge_eje_ejjZejege_eje_ejj Z!eje ejeeejge!_eje!_ejj"Z#ejejejeeejge#_eje#_ejj$Z%ej&ge%_eje%_d d Z'ddZ efddZddZ dddZddZ(ddZ"ddZ)dS)iiN) LibraryLoader)wintypescGdSN_rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/colorama/win32.pyr cGrrrrrrr r r )byref Structurec_charPOINTERc@s>eZdZdZdefdefdejfdejfdefgZddZ d S) CONSOLE_SCREEN_BUFFER_INFOzstruct in wincon.h.dwSizedwCursorPosition wAttributessrWindowdwMaximumWindowSizec CsHd|jj|jj|jj|jj|j|jj|jj|jj|jj |j j|j jf S)Nz"(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)) rYXrrrTopLeftZBottomZRightr)selfrrr __str__s   z"CONSOLE_SCREEN_BUFFER_INFO.__str__N) __name__ __module__ __qualname____doc__COORDrWORDZ SMALL_RECT_fields_rrrrr rs rcCst}t|t|}t|Sr)r_GetConsoleScreenBufferInfor bool)handlecsbisuccessrrr _winapi_test\s r(cCstddttttfDS)Ncss|]}t|VqdSr)r().0hrrr cszwinapi_test..)any _GetStdHandleSTDOUTSTDERRrrrr winapi_testbsr0cCs t|}t}t|t|}|Sr)r-rr#r ) stream_idr%r&r'rrr GetConsoleScreenBufferInfofs r2cCst|}t||Sr)r-_SetConsoleTextAttribute)r1attrsr%rrr SetConsoleTextAttributems r5TcCsvt|}|jdks|jdkrdSt|jd|jd}|r2ttj}|j|j7_|j|j7_t|}t ||S)Nr) r rrr2r.rrrr-_SetConsoleCursorPosition)r1positionadjustadjusted_positionsrr%rrr SetConsoleCursorPositionqs  r<cCsBt|}t|}t|}td}t||||t|}|jS)Nr)r-rencoderDWORD_FillConsoleOutputCharacterAr value)r1charlengthstartr% num_writtenr'rrr FillConsoleOutputCharacters   rEcCs:t|}t|}t|}td}t||||t|S)za FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )r)r-rr!r>_FillConsoleOutputAttributer )r1attrrBrCr% attributerDrrr FillConsoleOutputAttributes   rIcCst|Sr)_SetConsoleTitleW)titlerrr SetConsoleTitlesrL)T)*r.r/ctypesrZWinDLLwindllrAttributeError ImportErrorr5r0r r rrZ_COORDr rZkernel32Z GetStdHandler-r>argtypesZHANDLErestyper2r#ZBOOLr3r!r<r7ZFillConsoleOutputCharacterAr?rIrFZSetConsoleTitleWrJZLPCWSTRr(rErLrrrr s|     PKH]+~] Npython3.10/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-310.pycnu[o ai @sdZdZdZdZddZddZdd d Zdd d ZGd ddeZ GdddeZ Gddde Z Gddde Z Gddde Z e Ze Ze Ze ZdS)z This module generates ANSI character codes to printing colors to terminals. See: http://en.wikipedia.org/wiki/ANSI_escape_code z]cCtt|dS)NmCSIstr)coder/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/colorama/ansi.py code_to_chars r cCstd|tS)Nz2;)OSCBEL)titlerrr set_titler rcCr)NJrmoderrr clear_screenr rcCr)NKrrrrr clear_liner rc@seZdZddZdS) AnsiCodescCs6t|D]}|dst||}t||t|qdS)N_)dir startswithgetattrsetattrr )selfnamevaluerrr __init__s   zAnsiCodes.__init__N)__name__ __module__ __qualname__r rrrr rs rc@s>eZdZd ddZd ddZd ddZd dd Zdd d Zd S) AnsiCursorcCtt|dS)NArrnrrr UP%r z AnsiCursor.UPcCr&)NBrr(rrr DOWN'r zAnsiCursor.DOWNcCr&)NCrr(rrr FORWARD)r zAnsiCursor.FORWARDcCr&)NDrr(rrr BACK+r zAnsiCursor.BACKcCstt|dt|dS)N;Hr)rxyrrr POS-szAnsiCursor.POSN)r%)r%r%)r!r"r#r*r,r.r0r5rrrr r$$s     r$c@PeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdS)AnsiFore !"#$%'Z[\]^_`aNr!r"r#BLACKREDGREENYELLOWBLUEMAGENTACYANWHITERESET LIGHTBLACK_EX LIGHTRED_EX LIGHTGREEN_EXLIGHTYELLOW_EX LIGHTBLUE_EXLIGHTMAGENTA_EX LIGHTCYAN_EX LIGHTWHITE_EXrrrr r71$r7c@r6)AnsiBack()*+,-./1defghijkNrIrrrr r\Gr[r\c@seZdZdZdZdZdZdS) AnsiStyler%rN)r!r"r#BRIGHTDIMNORMAL RESET_ALLrrrr rn]s rnN)r)__doc__rr r r rrrobjectrr$r7r\rnForeBackStyleCursorrrrr s"     PKH]cD\Rpython3.10/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-310.pycnu[o ai@sDddlmZmZmZmZddlmZmZmZm Z ddl m Z dZ dS))initdeinitreinit colorama_text)ForeBackStyleCursor) AnsiToWin32z0.4.4N) initialiserrrransirrrr ansitowin32r __version__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/colorama/__init__.pys PKH]JTpython3.10/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-310.pycnu[o ai{@stddlZddlZddlZddlmZdadadadada ddZ ddd Z d d Z ej d d ZddZddZdS)N) AnsiToWin32FcCstdur ttdSdSN)r orig_stdout reset_allrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/colorama/initialise.pyrsrTcCs|s t|||gr tdtjatjatjdurdan tt||||t_atjdur.da n tt||||t_a t sDt t da dSdS)Nz,wrap=False conflicts with any other arg=TrueT)any ValueErrorsysstdoutrstderr orig_stderrwrapped_stdout wrap_streamwrapped_stderr atexit_doneatexitregisterr) autoresetconvertstripwraprrrinits    rcC$tdurtt_tdurtt_dSdSr)rr r rr rrrrdeinit3  rcos,t|i|z dVWtdStwr)rr)argskwargsrrr colorama_text:s rcCrr)rr r rr rrrrreinitCrr cCs&|rt||||d}|r|j}|S)N)rrr)r should_wrapstream)r"rrrrwrapperrrrrJsr)FNNT)r contextlibr ansitowin32rrrrrrrrrcontextmanagerrr rrrrrs     PKH]G8  Upython3.10/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-310.pycnu[o ai)@sddlZddlZddlZddlmZmZmZmZmZddl m Z m Z m Z ddl mZmZdZ edur5e Z GdddeZGdd d eZdS) N)AnsiForeAnsiBack AnsiStyleStyleBEL)WinTermWinColorWinStyle)windll winapi_testc@sLeZdZdZddZddZddZdd Zd d Zd d Z e ddZ dS) StreamWrapperz Wraps a stream (such as stdout), acting as a transparent proxy for all attribute access apart from method 'write()', which is delegated to our Converter instance. cCs||_||_dSN)_StreamWrapper__wrapped_StreamWrapper__convertor)selfwrapped converterr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/colorama/ansitowin32.py__init__s zStreamWrapper.__init__cCs t|j|Sr)getattrr)rnamerrr __getattr__s zStreamWrapper.__getattr__cO|jj|i|Sr)r __enter__rargskwargsrrrrszStreamWrapper.__enter__cOrr)r__exit__rrrrr%szStreamWrapper.__exit__cCs|j|dSr)rwritertextrrrr (szStreamWrapper.writecCsT|j}dtjvr|dur|tjus|tjurdSz|j}W|Sty)YdSw)NPYCHARM_HOSTEDTF)rosenvironsys __stdout__ __stderr__isattyAttributeError)rstream stream_isattyrrrr)+s  zStreamWrapper.isattycCs$|j}z|jWStyYdSwNT)rclosedr*)rr+rrrr.7s  zStreamWrapper.closedN) __name__ __module__ __qualname____doc__rrrrr r)propertyr.rrrrr s r c@s~eZdZdZedZedZdddZdd Z d d Z d d Z ddZ ddZ ddZddZddZddZddZdS) AnsiToWin32z Implements a 'write()' method which, on Windows, will strip ANSI character sequences from the text, and if outputting to a tty, will convert them into win32 function calls. z?\[((?:\d|;)*)([a-zA-Z])?z?\]([^]*)()?NFcCs||_||_t|||_tjdk}|ot}|dur'|p&|jj o&|j }||_ |dur:|o9|jj o9|j}||_ | |_ |jt ju|_dS)Nnt)r autoresetr r+r$rr r.r)stripconvertget_win32_calls win32_callsr&stderr on_stderr)rrr8r7r6 on_windowsconversion_supportedrrrrIs    zAnsiToWin32.__init__cCs|jp|jp|jS)aj True if this class is actually needed. If false, then the output stream will not be affected, nor will win32 calls be issued, so wrapping stdout is not actually required. This will generally be False on non-Windows platforms, unless optional functionality like autoreset has been requested using kwargs to init() )r8r7r6rrrr should_wrapjszAnsiToWin32.should_wrapc Cs|jrCtrCitjtjftjtjtjftjtjtj ftj tjtj ft j tj t j ft jtj t jft jtj t jft jtj t jft jtj t jft jtj t jft jtj t jft jtj t jft jtj ft jtj t j dft jtj t jdft jtj t jdft jtj t jdfit jtj t jdft jtj t jdft jtj t jdft jtj t jdftj tj t j ftjtj t jftjtj t jftjtj t jftjtj t jftjtj t jftjtj t jftjtj t jftjtj ftjtj t j dftjtj t jdftjtj t jdftjtj t jdftjtj t jdftjtj t jdftjtj t jdftjtj t jdfiSt!Sr-)"r8wintermr RESET_ALL reset_allBRIGHTstyler DIMNORMALrBLACKforer REDGREENYELLOWBLUEMAGENTACYANWHITEGREYRESET LIGHTBLACK_EX LIGHTRED_EX LIGHTGREEN_EXLIGHTYELLOW_EX LIGHTBLUE_EXLIGHTMAGENTA_EX LIGHTCYAN_EX LIGHTWHITE_EXrbackdictr?rrrr9ts        !"#(zAnsiToWin32.get_win32_callscCsD|js|jr ||n |j||j|jr |dSdSr)r7r8write_and_convertrr flushr6rCr!rrrr s     zAnsiToWin32.writecCs>|jr |dddS|js|jjs|jtjdSdSdS)Nmr) r8 call_win32r7r+r.rr rrBr?rrrrCs zAnsiToWin32.reset_allcCsbd}||}|j|D]}|\}}|||||j||}q |||t|dS)z Write the given text to our wrapped stream, stripping any ANSI sequences from the text, and optionally converting them into win32 calls. rN) convert_osc ANSI_CSI_REfinditerspanwrite_plain_text convert_ansigroupslen)rr"cursormatchstartendrrrr]s  zAnsiToWin32.write_and_convertcCs.||kr|j||||jdSdSr)rr r^)rr"rlrmrrrrfszAnsiToWin32.write_plain_textcCs&|jr|||}|||dSdSr)r8extract_paramsra)r paramstringcommandparamsrrrrgs zAnsiToWin32.convert_ansicCs|dvr"tdd|dD}t|dkr |d}t|dks|Stdd|dD}t|dkrB|d vrs&z-AnsiToWin32.extract_params..;)rcss$|] }t|dkrt|VqdS)rNrsrurrrrxs"rJKmr`ABCD)tuplesplitri)rrprorqrrrrns    zAnsiToWin32.extract_paramsc Cs|dkr,|D]#}||jvr)|j|}|d}|dd}t|jd}||i|qdS|dvrs0PKH]oEr{{;python3.10/site-packages/pip/_vendor/colorama/initialise.pynu[# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. import atexit import contextlib import sys from .ansitowin32 import AnsiToWin32 orig_stdout = None orig_stderr = None wrapped_stdout = None wrapped_stderr = None atexit_done = False def reset_all(): if AnsiToWin32 is not None: # Issue #74: objects might become None at exit AnsiToWin32(orig_stdout).reset_all() def init(autoreset=False, convert=None, strip=None, wrap=True): if not wrap and any([autoreset, convert, strip]): raise ValueError('wrap=False conflicts with any other arg=True') global wrapped_stdout, wrapped_stderr global orig_stdout, orig_stderr orig_stdout = sys.stdout orig_stderr = sys.stderr if sys.stdout is None: wrapped_stdout = None else: sys.stdout = wrapped_stdout = \ wrap_stream(orig_stdout, convert, strip, autoreset, wrap) if sys.stderr is None: wrapped_stderr = None else: sys.stderr = wrapped_stderr = \ wrap_stream(orig_stderr, convert, strip, autoreset, wrap) global atexit_done if not atexit_done: atexit.register(reset_all) atexit_done = True def deinit(): if orig_stdout is not None: sys.stdout = orig_stdout if orig_stderr is not None: sys.stderr = orig_stderr @contextlib.contextmanager def colorama_text(*args, **kwargs): init(*args, **kwargs) try: yield finally: deinit() def reinit(): if wrapped_stdout is not None: sys.stdout = wrapped_stdout if wrapped_stderr is not None: sys.stderr = wrapped_stderr def wrap_stream(stream, convert, strip, autoreset, wrap): if wrap: wrapper = AnsiToWin32(stream, convert=convert, strip=strip, autoreset=autoreset) if wrapper.should_wrap(): stream = wrapper.stream return stream PKH](&&8python3.10/site-packages/pip/_vendor/colorama/winterm.pynu[# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. from . import win32 # from wincon.h class WinColor(object): BLACK = 0 BLUE = 1 GREEN = 2 CYAN = 3 RED = 4 MAGENTA = 5 YELLOW = 6 GREY = 7 # from wincon.h class WinStyle(object): NORMAL = 0x00 # dim text, dim background BRIGHT = 0x08 # bright text, dim background BRIGHT_BACKGROUND = 0x80 # dim text, bright background class WinTerm(object): def __init__(self): self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes self.set_attrs(self._default) self._default_fore = self._fore self._default_back = self._back self._default_style = self._style # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. # So that LIGHT_EX colors and BRIGHT style do not clobber each other, # we track them separately, since LIGHT_EX is overwritten by Fore/Back # and BRIGHT is overwritten by Style codes. self._light = 0 def get_attrs(self): return self._fore + self._back * 16 + (self._style | self._light) def set_attrs(self, value): self._fore = value & 7 self._back = (value >> 4) & 7 self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) def reset_all(self, on_stderr=None): self.set_attrs(self._default) self.set_console(attrs=self._default) self._light = 0 def fore(self, fore=None, light=False, on_stderr=False): if fore is None: fore = self._default_fore self._fore = fore # Emulate LIGHT_EX with BRIGHT Style if light: self._light |= WinStyle.BRIGHT else: self._light &= ~WinStyle.BRIGHT self.set_console(on_stderr=on_stderr) def back(self, back=None, light=False, on_stderr=False): if back is None: back = self._default_back self._back = back # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style if light: self._light |= WinStyle.BRIGHT_BACKGROUND else: self._light &= ~WinStyle.BRIGHT_BACKGROUND self.set_console(on_stderr=on_stderr) def style(self, style=None, on_stderr=False): if style is None: style = self._default_style self._style = style self.set_console(on_stderr=on_stderr) def set_console(self, attrs=None, on_stderr=False): if attrs is None: attrs = self.get_attrs() handle = win32.STDOUT if on_stderr: handle = win32.STDERR win32.SetConsoleTextAttribute(handle, attrs) def get_position(self, handle): position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition # Because Windows coordinates are 0-based, # and win32.SetConsoleCursorPosition expects 1-based. position.X += 1 position.Y += 1 return position def set_cursor_position(self, position=None, on_stderr=False): if position is None: # I'm not currently tracking the position, so there is no default. # position = self.get_position() return handle = win32.STDOUT if on_stderr: handle = win32.STDERR win32.SetConsoleCursorPosition(handle, position) def cursor_adjust(self, x, y, on_stderr=False): handle = win32.STDOUT if on_stderr: handle = win32.STDERR position = self.get_position(handle) adjusted_position = (position.Y + y, position.X + x) win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) def erase_screen(self, mode=0, on_stderr=False): # 0 should clear from the cursor to the end of the screen. # 1 should clear from the cursor to the beginning of the screen. # 2 should clear the entire screen, and move cursor to (1,1) handle = win32.STDOUT if on_stderr: handle = win32.STDERR csbi = win32.GetConsoleScreenBufferInfo(handle) # get the number of character cells in the current buffer cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y # get number of character cells before current cursor position cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X if mode == 0: from_coord = csbi.dwCursorPosition cells_to_erase = cells_in_screen - cells_before_cursor elif mode == 1: from_coord = win32.COORD(0, 0) cells_to_erase = cells_before_cursor elif mode == 2: from_coord = win32.COORD(0, 0) cells_to_erase = cells_in_screen else: # invalid mode return # fill the entire screen with blanks win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) # now set the buffer's attributes accordingly win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) if mode == 2: # put the cursor where needed win32.SetConsoleCursorPosition(handle, (1, 1)) def erase_line(self, mode=0, on_stderr=False): # 0 should clear from the cursor to the end of the line. # 1 should clear from the cursor to the beginning of the line. # 2 should clear the entire line. handle = win32.STDOUT if on_stderr: handle = win32.STDERR csbi = win32.GetConsoleScreenBufferInfo(handle) if mode == 0: from_coord = csbi.dwCursorPosition cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X elif mode == 1: from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) cells_to_erase = csbi.dwCursorPosition.X elif mode == 2: from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) cells_to_erase = csbi.dwSize.X else: # invalid mode return # fill the entire screen with blanks win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) # now set the buffer's attributes accordingly win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) def set_title(self, title): win32.SetConsoleTitle(title) PKH]R٭ 5python3.10/site-packages/pip/_vendor/colorama/ansi.pynu[# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. ''' This module generates ANSI character codes to printing colors to terminals. See: http://en.wikipedia.org/wiki/ANSI_escape_code ''' CSI = '\033[' OSC = '\033]' BEL = '\a' def code_to_chars(code): return CSI + str(code) + 'm' def set_title(title): return OSC + '2;' + title + BEL def clear_screen(mode=2): return CSI + str(mode) + 'J' def clear_line(mode=2): return CSI + str(mode) + 'K' class AnsiCodes(object): def __init__(self): # the subclasses declare class attributes which are numbers. # Upon instantiation we define instance attributes, which are the same # as the class attributes but wrapped with the ANSI escape sequence for name in dir(self): if not name.startswith('_'): value = getattr(self, name) setattr(self, name, code_to_chars(value)) class AnsiCursor(object): def UP(self, n=1): return CSI + str(n) + 'A' def DOWN(self, n=1): return CSI + str(n) + 'B' def FORWARD(self, n=1): return CSI + str(n) + 'C' def BACK(self, n=1): return CSI + str(n) + 'D' def POS(self, x=1, y=1): return CSI + str(y) + ';' + str(x) + 'H' class AnsiFore(AnsiCodes): BLACK = 30 RED = 31 GREEN = 32 YELLOW = 33 BLUE = 34 MAGENTA = 35 CYAN = 36 WHITE = 37 RESET = 39 # These are fairly well supported, but not part of the standard. LIGHTBLACK_EX = 90 LIGHTRED_EX = 91 LIGHTGREEN_EX = 92 LIGHTYELLOW_EX = 93 LIGHTBLUE_EX = 94 LIGHTMAGENTA_EX = 95 LIGHTCYAN_EX = 96 LIGHTWHITE_EX = 97 class AnsiBack(AnsiCodes): BLACK = 40 RED = 41 GREEN = 42 YELLOW = 43 BLUE = 44 MAGENTA = 45 CYAN = 46 WHITE = 47 RESET = 49 # These are fairly well supported, but not part of the standard. LIGHTBLACK_EX = 100 LIGHTRED_EX = 101 LIGHTGREEN_EX = 102 LIGHTYELLOW_EX = 103 LIGHTBLUE_EX = 104 LIGHTMAGENTA_EX = 105 LIGHTCYAN_EX = 106 LIGHTWHITE_EX = 107 class AnsiStyle(AnsiCodes): BRIGHT = 1 DIM = 2 NORMAL = 22 RESET_ALL = 0 Fore = AnsiFore() Back = AnsiBack() Style = AnsiStyle() Cursor = AnsiCursor() PKH]))<python3.10/site-packages/pip/_vendor/colorama/ansitowin32.pynu[# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. import re import sys import os from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style, BEL from .winterm import WinTerm, WinColor, WinStyle from .win32 import windll, winapi_test winterm = None if windll is not None: winterm = WinTerm() class StreamWrapper(object): ''' Wraps a stream (such as stdout), acting as a transparent proxy for all attribute access apart from method 'write()', which is delegated to our Converter instance. ''' def __init__(self, wrapped, converter): # double-underscore everything to prevent clashes with names of # attributes on the wrapped stream object. self.__wrapped = wrapped self.__convertor = converter def __getattr__(self, name): return getattr(self.__wrapped, name) def __enter__(self, *args, **kwargs): # special method lookup bypasses __getattr__/__getattribute__, see # https://stackoverflow.com/questions/12632894/why-doesnt-getattr-work-with-exit # thus, contextlib magic methods are not proxied via __getattr__ return self.__wrapped.__enter__(*args, **kwargs) def __exit__(self, *args, **kwargs): return self.__wrapped.__exit__(*args, **kwargs) def write(self, text): self.__convertor.write(text) def isatty(self): stream = self.__wrapped if 'PYCHARM_HOSTED' in os.environ: if stream is not None and (stream is sys.__stdout__ or stream is sys.__stderr__): return True try: stream_isatty = stream.isatty except AttributeError: return False else: return stream_isatty() @property def closed(self): stream = self.__wrapped try: return stream.closed except AttributeError: return True class AnsiToWin32(object): ''' Implements a 'write()' method which, on Windows, will strip ANSI character sequences from the text, and if outputting to a tty, will convert them into win32 function calls. ''' ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer ANSI_OSC_RE = re.compile('\001?\033\\]([^\a]*)(\a)\002?') # Operating System Command def __init__(self, wrapped, convert=None, strip=None, autoreset=False): # The wrapped stream (normally sys.stdout or sys.stderr) self.wrapped = wrapped # should we reset colors to defaults after every .write() self.autoreset = autoreset # create the proxy wrapping our output stream self.stream = StreamWrapper(wrapped, self) on_windows = os.name == 'nt' # We test if the WinAPI works, because even if we are on Windows # we may be using a terminal that doesn't support the WinAPI # (e.g. Cygwin Terminal). In this case it's up to the terminal # to support the ANSI codes. conversion_supported = on_windows and winapi_test() # should we strip ANSI sequences from our output? if strip is None: strip = conversion_supported or (not self.stream.closed and not self.stream.isatty()) self.strip = strip # should we should convert ANSI sequences into win32 calls? if convert is None: convert = conversion_supported and not self.stream.closed and self.stream.isatty() self.convert = convert # dict of ansi codes to win32 functions and parameters self.win32_calls = self.get_win32_calls() # are we wrapping stderr? self.on_stderr = self.wrapped is sys.stderr def should_wrap(self): ''' True if this class is actually needed. If false, then the output stream will not be affected, nor will win32 calls be issued, so wrapping stdout is not actually required. This will generally be False on non-Windows platforms, unless optional functionality like autoreset has been requested using kwargs to init() ''' return self.convert or self.strip or self.autoreset def get_win32_calls(self): if self.convert and winterm: return { AnsiStyle.RESET_ALL: (winterm.reset_all, ), AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), AnsiFore.RED: (winterm.fore, WinColor.RED), AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), AnsiFore.WHITE: (winterm.fore, WinColor.GREY), AnsiFore.RESET: (winterm.fore, ), AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), AnsiBack.BLACK: (winterm.back, WinColor.BLACK), AnsiBack.RED: (winterm.back, WinColor.RED), AnsiBack.GREEN: (winterm.back, WinColor.GREEN), AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), AnsiBack.BLUE: (winterm.back, WinColor.BLUE), AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), AnsiBack.CYAN: (winterm.back, WinColor.CYAN), AnsiBack.WHITE: (winterm.back, WinColor.GREY), AnsiBack.RESET: (winterm.back, ), AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), } return dict() def write(self, text): if self.strip or self.convert: self.write_and_convert(text) else: self.wrapped.write(text) self.wrapped.flush() if self.autoreset: self.reset_all() def reset_all(self): if self.convert: self.call_win32('m', (0,)) elif not self.strip and not self.stream.closed: self.wrapped.write(Style.RESET_ALL) def write_and_convert(self, text): ''' Write the given text to our wrapped stream, stripping any ANSI sequences from the text, and optionally converting them into win32 calls. ''' cursor = 0 text = self.convert_osc(text) for match in self.ANSI_CSI_RE.finditer(text): start, end = match.span() self.write_plain_text(text, cursor, start) self.convert_ansi(*match.groups()) cursor = end self.write_plain_text(text, cursor, len(text)) def write_plain_text(self, text, start, end): if start < end: self.wrapped.write(text[start:end]) self.wrapped.flush() def convert_ansi(self, paramstring, command): if self.convert: params = self.extract_params(command, paramstring) self.call_win32(command, params) def extract_params(self, command, paramstring): if command in 'Hf': params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) while len(params) < 2: # defaults: params = params + (1,) else: params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) if len(params) == 0: # defaults: if command in 'JKm': params = (0,) elif command in 'ABCD': params = (1,) return params def call_win32(self, command, params): if command == 'm': for param in params: if param in self.win32_calls: func_args = self.win32_calls[param] func = func_args[0] args = func_args[1:] kwargs = dict(on_stderr=self.on_stderr) func(*args, **kwargs) elif command in 'J': winterm.erase_screen(params[0], on_stderr=self.on_stderr) elif command in 'K': winterm.erase_line(params[0], on_stderr=self.on_stderr) elif command in 'Hf': # cursor position - absolute winterm.set_cursor_position(params, on_stderr=self.on_stderr) elif command in 'ABCD': # cursor position - relative n = params[0] # A - up, B - down, C - forward, D - back x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) def convert_osc(self, text): for match in self.ANSI_OSC_RE.finditer(text): start, end = match.span() text = text[:start] + text[end:] paramstring, command = match.groups() if command == BEL: if paramstring.count(";") == 1: params = paramstring.split(";") # 0 - change title and icon (we will only change title) # 1 - change icon (we don't support this) # 2 - change title if params[0] in '02': winterm.set_title(params[1]) return text PKH] 6python3.10/site-packages/pip/_vendor/colorama/win32.pynu[# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. # from winbase.h STDOUT = -11 STDERR = -12 try: import ctypes from ctypes import LibraryLoader windll = LibraryLoader(ctypes.WinDLL) from ctypes import wintypes except (AttributeError, ImportError): windll = None SetConsoleTextAttribute = lambda *_: None winapi_test = lambda *_: None else: from ctypes import byref, Structure, c_char, POINTER COORD = wintypes._COORD class CONSOLE_SCREEN_BUFFER_INFO(Structure): """struct in wincon.h.""" _fields_ = [ ("dwSize", COORD), ("dwCursorPosition", COORD), ("wAttributes", wintypes.WORD), ("srWindow", wintypes.SMALL_RECT), ("dwMaximumWindowSize", COORD), ] def __str__(self): return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( self.dwSize.Y, self.dwSize.X , self.dwCursorPosition.Y, self.dwCursorPosition.X , self.wAttributes , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X ) _GetStdHandle = windll.kernel32.GetStdHandle _GetStdHandle.argtypes = [ wintypes.DWORD, ] _GetStdHandle.restype = wintypes.HANDLE _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo _GetConsoleScreenBufferInfo.argtypes = [ wintypes.HANDLE, POINTER(CONSOLE_SCREEN_BUFFER_INFO), ] _GetConsoleScreenBufferInfo.restype = wintypes.BOOL _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute _SetConsoleTextAttribute.argtypes = [ wintypes.HANDLE, wintypes.WORD, ] _SetConsoleTextAttribute.restype = wintypes.BOOL _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition _SetConsoleCursorPosition.argtypes = [ wintypes.HANDLE, COORD, ] _SetConsoleCursorPosition.restype = wintypes.BOOL _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA _FillConsoleOutputCharacterA.argtypes = [ wintypes.HANDLE, c_char, wintypes.DWORD, COORD, POINTER(wintypes.DWORD), ] _FillConsoleOutputCharacterA.restype = wintypes.BOOL _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute _FillConsoleOutputAttribute.argtypes = [ wintypes.HANDLE, wintypes.WORD, wintypes.DWORD, COORD, POINTER(wintypes.DWORD), ] _FillConsoleOutputAttribute.restype = wintypes.BOOL _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW _SetConsoleTitleW.argtypes = [ wintypes.LPCWSTR ] _SetConsoleTitleW.restype = wintypes.BOOL def _winapi_test(handle): csbi = CONSOLE_SCREEN_BUFFER_INFO() success = _GetConsoleScreenBufferInfo( handle, byref(csbi)) return bool(success) def winapi_test(): return any(_winapi_test(h) for h in (_GetStdHandle(STDOUT), _GetStdHandle(STDERR))) def GetConsoleScreenBufferInfo(stream_id=STDOUT): handle = _GetStdHandle(stream_id) csbi = CONSOLE_SCREEN_BUFFER_INFO() success = _GetConsoleScreenBufferInfo( handle, byref(csbi)) return csbi def SetConsoleTextAttribute(stream_id, attrs): handle = _GetStdHandle(stream_id) return _SetConsoleTextAttribute(handle, attrs) def SetConsoleCursorPosition(stream_id, position, adjust=True): position = COORD(*position) # If the position is out of range, do nothing. if position.Y <= 0 or position.X <= 0: return # Adjust for Windows' SetConsoleCursorPosition: # 1. being 0-based, while ANSI is 1-based. # 2. expecting (x,y), while ANSI uses (y,x). adjusted_position = COORD(position.Y - 1, position.X - 1) if adjust: # Adjust for viewport's scroll position sr = GetConsoleScreenBufferInfo(STDOUT).srWindow adjusted_position.Y += sr.Top adjusted_position.X += sr.Left # Resume normal processing handle = _GetStdHandle(stream_id) return _SetConsoleCursorPosition(handle, adjusted_position) def FillConsoleOutputCharacter(stream_id, char, length, start): handle = _GetStdHandle(stream_id) char = c_char(char.encode()) length = wintypes.DWORD(length) num_written = wintypes.DWORD(0) # Note that this is hard-coded for ANSI (vs wide) bytes. success = _FillConsoleOutputCharacterA( handle, char, length, start, byref(num_written)) return num_written.value def FillConsoleOutputAttribute(stream_id, attr, length, start): ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' handle = _GetStdHandle(stream_id) attribute = wintypes.WORD(attr) length = wintypes.DWORD(length) num_written = wintypes.DWORD(0) # Note that this is hard-coded for ANSI (vs wide) bytes. return _FillConsoleOutputAttribute( handle, attribute, length, start, byref(num_written)) def SetConsoleTitle(title): return _SetConsoleTitleW(title) PKH]k9python3.10/site-packages/pip/_vendor/colorama/__init__.pynu[# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. from .initialise import init, deinit, reinit, colorama_text from .ansi import Fore, Back, Style, Cursor from .ansitowin32 import AnsiToWin32 __version__ = '0.4.4' PKH]=< /python3.10/site-packages/pip/_vendor/vendor.txtnu[CacheControl==0.12.6 # Make sure to update the license in pyproject.toml for this. colorama==0.4.4 distlib==0.3.3 distro==1.6.0 html5lib==1.1 msgpack==1.0.2 packaging==21.0 pep517==0.12.0 platformdirs==2.4.0 progress==1.6 pyparsing==2.4.7 requests==2.26.0 certifi==2021.05.30 chardet==4.0.0 idna==3.2 urllib3==1.26.7 resolvelib==0.8.0 setuptools==44.0.0 six==1.16.0 tenacity==8.0.1 tomli==1.0.3 webencodings==0.5.1 PKH]܉Opython3.10/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-310.pycnu[o ai @sfddlZddlmZejrddlZddlmZdddZ dd d d ed edej dgdffddZ dS)N)_utils)RetryCallState retry_staterreturncCsdS)z&After call strategy that does nothing.Nrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tenacity/after.py after_nothingsr %0.3floggerzlogging.Logger log_level sec_formatcsdfdd }|S)zBAfter call strategy that logs to some logger the finished attempt.rrrNc s:dt|jd|jdt|jddS)NzFinished call to 'z' after z(s), this was the z time calling it.)logrget_callback_namefnseconds_since_start to_ordinalattempt_numberrr r r rrlog_it&s zafter_log..log_itrrrNr)r r r rrrr after_logsrr)r ) typingpip._vendor.tenacityr TYPE_CHECKINGloggingrr intstrCallablerrrrrs    PKH]nTpython3.10/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-310.pycnu[o aia@s|ddlZddlZddlmZddlmZddlmZddlmZddlmZej r/ddl m Z e dZ Gd d d eZdS) N) BaseRetrying) DoAttempt)DoSleep)RetryCallState)gen)Future_RetValTc sVeZdZejfdddejddffdd Zejdd d ejdejdd fd d Z Z S)TornadoRetryingsleepz&typing.Callable[[float], Future[None]]kwargsreturnNc stjdi|||_dS)N)super__init__r )selfr r  __class__r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tenacity/tornadoweb.pyr s zTornadoRetrying.__init__fnzhtyping.Callable[..., typing.Union[typing.Generator[typing.Any, typing.Any, _RetValT], Future[_RetValT]]]argsz2typing.Generator[typing.Any, typing.Any, _RetValT]cos|t||||d} |j|d}t|tr:z ||i|V}Wnty3|tYnw| |nt|t rJ| | |Vnt |q)N) retry_objectrrr T) retry_state)beginriter isinstancer BaseException set_exceptionsysexc_info set_resultrprepare_for_next_attemptr rReturn)rrrr rdoresultr r r__call__$s"      zTornadoRetrying.__call__) __name__ __module__ __qualname__rr typingAnyr coroutiner$ __classcell__r r rrr s"r )rr(pip._vendor.tenacityrrrrtornador TYPE_CHECKINGZtornado.concurrentrTypeVarrr r r r rs       PKH] x !!Opython3.10/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-310.pycnu[o ai@s ddlZddlZddlZejrddlmZGdddejZGdddeZeZ GdddeZ e Z Gd d d eZ Gd d d e Z Gd dde ZGddde ZGdddeZGdddeZGddde ZGdddeZGdddeZGdddeZdS)N)RetryCallStatec@s<eZdZdZejdddefddZdd d Zdd d Z dS) retry_basez)Abstract base class for retry strategies. retry_staterreturncCsdSNselfrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tenacity/retry.py__call__szretry_base.__call__other retry_allcC t||Sr)r r r rrr __and__  zretry_base.__and__ retry_anycCrr)rrrrr __or__#rzretry_base.__or__N)r rrr )r rrr) __name__ __module__ __qualname____doc__abcabstractmethodboolr rrrrrr rs  rc@"eZdZdZdddefddZdS) _retry_neverz-Retry strategy that never rejects any result.rrrcCdSNFrrrrr r *z_retry_never.__call__Nrrrrrr rrrr r'rc@r) _retry_alwaysz.Retry strategy that always rejects any result.rrrcCrNTrrrrr r 4rz_retry_always.__call__Nr rrrr r"1r!r"c@s@eZdZdZdejegefddfddZdddefd d Z dS) retry_if_exceptionzARetry strategy that retries if an exception verifies a predicate. predicaterNcC ||_dSrr%r r%rrr __init__>rzretry_if_exception.__init__rrcCs|jjr ||jSdSroutcomefailedr% exceptionrrrr r Azretry_if_exception.__call__) rrrrtypingCallable BaseExceptionrr)r rrrr r$;sr$cNeZdZdZefdejejeej ejedffddffdd Z Z S)retry_if_exception_typez=Retries if an exception has been raised of one or more types.exception_types.rNc|_tfdddS)Ncs t|Sr isinstanceer4rr Ss z2retry_if_exception_type.__init__..r4superr)r r4 __class__r:r r)Kz retry_if_exception_type.__init__ rrrr Exceptionr/UnionTyper1Tupler) __classcell__rrr?r r3Hr3cr2)retry_if_not_exception_typezARetries except an exception has been raised of one or more types.r4.rNcr5)Nc t| Srr6r8r:rr r;a z6retry_if_not_exception_type.__init__..r<r>r?r:r r)YrAz$retry_if_not_exception_type.__init__rBrrr?r rIVrHrIcs`eZdZdZefdejejeej ejedffddffdd Z dd de fd d Z Z S) retry_unless_exception_typez:Retries until an exception is raised of one or more types.r4.rNcr5)NcrJrr6r8r:rr r;orKz6retry_unless_exception_type.__init__..r<r>r?r:r r)grAz$retry_unless_exception_type.__init__rrcC|jjsdS||jSr#r*rrrr r qsz$retry_unless_exception_type.__call__)rrrrrCr/rDrEr1rFr)rr rGrrr?r rLds rLc@BeZdZdZdejejgefddfddZdddefd d Z dS) retry_if_resultz+Retries if the result verifies a predicate.r%rNcCr&rr'r(rrr r){rzretry_if_result.__init__rrcCs|jjs ||jSdSrr+r,r%resultrrrr r ~r.zretry_if_result.__call__ rrrrr/r0Anyrr)r rrrr rOx rOc@rN) retry_if_not_resultz*Retries if the result refutes a predicate.r%rNcCr&rr'r(rrr r)rzretry_if_not_result.__init__rrcCs|jjs ||j SdSrrPrrrr r szretry_if_not_result.__call__rRrrrr rUrTrUcs@eZdZdZ  ddejedejeddffdd ZZS) retry_if_exception_messagez2Retries if an exception message equals or matches.Nmessagematchrcsr |r t|jjdrdtdtffdd }|}n|r2t|dtdtffdd }|}n t|jjdt|dS) Nz.() takes either 'message' or 'match', not bothr-rcs t|kSr)strr-)rWrr message_fncs z8retry_if_exception_message.__init__..message_fnccstt|Sr)rrXrYrZ)progrr match_fncsz6retry_if_exception_message.__init__..match_fncz3() missing 1 required argument 'message' or 'match') TypeErrorr@rr1rrecompiler=r))r rWrXr[r%r]r?)rWr\r r)s z#retry_if_exception_message.__init__NN) rrrrr/OptionalrYr)rGrrr?r rVsrVcsReZdZdZ  d dejedejeddffdd Zdd defd d Z Z S) retry_if_not_exception_messagez5Retries until an exception message equals or matches.NrWrXrcs&t|||jfdd|_dS)Ncs|i| Srr)args_kwargs_ if_predicaterr r;sz9retry_if_not_exception_message.__init__..)r=r)r%)r rWrXr?rfr r)sz'retry_if_not_exception_message.__init__rrcCrMr#r*rrrr r sz'retry_if_not_exception_message.__call__ra) rrrrr/rbrYr)rr rGrrr?r rcs rcc@4eZdZdZdeddfddZdddefd d ZdS) rz1Retries if any of the retries condition is valid.retriesrNcGr&rrir rirrr r)rzretry_any.__init__rrctfdd|jDS)Nc3|]}|VqdSrr.0rrrr z%retry_any.__call__..)anyrirrrqr r zretry_any.__call__rrrrrr)rr rrrr rrc@rh) r z/Retries if all the retries condition are valid.rirNcGr&rrjrkrrr r)rzretry_all.__init__rrcrl)Nc3rmrrrnrqrr rrrsz%retry_all.__call__..)allrirrrqr r ruzretry_all.__call__rvrrrr r rwr )rr_r/ TYPE_CHECKINGpip._vendor.tenacityrABCrr retry_neverr" retry_alwaysr$r3rIrLrOrUrVrcrr rrrr s(     PKH]%n"@"@Rpython3.10/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-310.pycnu[o aiQG @sddlZddlZddlZddlZddlZddlZddlmZm Z ddl m Z ddl m Z ddlmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z ddlm!Z!ddlm"Z"ddlm#Z#ddlm$Z$ddlm%Z%ddl&m'Z'ddl&m(Z(ddl&m)Z)ddl&m*Z*ddl&m+Z+dd l&m,Z,dd!l&m-Z-dd"l&m.Z.dd"l&m.Z/dd#l0m1Z1dd$l0m2Z2dd%l3m4Z4dd&l3m5Z5dd'l6m7Z7dd(l6m8Z8dZ9ej:rddl;Z;dd)l&md+ej?d,Z@e>d-ZAejBd.e@d/e@fd0d1ZejBd2ejCd3ejCd/ej?e@ge@ffd4d1Zd2ejCd3ejCd/ejDe@ej?e@ge@fffd5d1ZGd6d7d7eEZFeGZHGd8d9d9ZIGd:d;d;eJZKGdd?d?eLZMeGZNd@ejDejCeGfdAejCd/ejCfdBdCZOGdDdEdEeEZPGdFdGdGZQGdHdIdIeZRGdJdKdKeRZSGdLdMdMe jTZTGdNdOdOZUddPlVmWZWe9rddQlXmYZYdSdS)RN)ABCabstractmethod)futures)iscoroutinefunction) retry_base) retry_all) retry_always) retry_any)retry_if_exception)retry_if_exception_type)retry_if_not_exception_type)retry_if_not_result)retry_if_result) retry_never)retry_unless_exception_type)retry_if_exception_message)retry_if_not_exception_messagesleep)sleep_using_event)stop_after_attempt)stop_after_delay)stop_all)stop_any) stop_never)stop_when_event_set) wait_chain) wait_combine)wait_exponential) wait_fixed)wait_incrementing) wait_none) wait_random)wait_random_exponential) before_log)before_nothing) after_log) after_nothing)before_sleep_log)before_sleep_nothing) wait_base) stop_base WrappedFn)bound_RetValTfnreturncCdSN)r0r4r4/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tenacity/__init__.pyretryar6dargsdkwcOr2r3r4r8r9r4r4r5r6fr7csBtdkrtdrtdSdtdtffdd }|S)zWrap a function with a new `Retrying` object. :param dargs: positional arguments passed to Retrying object :param dkw: keyword arguments passed to the Retrying object rrfr1cst|trtd|jjd|jjdt|r!ti}ntr7t tj dr7tj |r7t i}nt i}||S)NzGot retry_base instance (zQ) as callable argument, this will probably hang indefinitely (did you mean retry=z(...)?)is_coroutine_function) isinstancerwarningswarn __class____name__r AsyncRetryingtornadohasattrgenr<TornadoRetryingRetryingwraps)r;rr:r4r5wrapvs   zretry..wrap)lencallabler6r-)r8r9rJr4r:r5r6ksc@seZdZdZdS)TryAgainz/Always retry the executed function when raised.N)rA __module__ __qualname____doc__r4r4r4r5rMsrMc@ eZdZdS) DoAttemptNrArNrOr4r4r4r5rRrRc@rQ)DoSleepNrSr4r4r4r5rUrTrUc@sReZdZUdZdZejeed<dZ ej eed<defddZ defd d Z dS) BaseActiona5Base class for representing actions to take by retry object. Concrete implementations must define: - __init__: to initialize all necessary fields - REPR_FIELDS: class variable specifying attributes to include in repr(self) - NAME: for identification in retry object methods and callbacks r4 REPR_FIELDSNNAMEr1cs.dfddjD}jjd|dS)Nz, c3s$|] }|dt|VqdS)=N)getattr).0fieldselfr4r5 s"z&BaseAction.__repr__..())joinrWr@rA)r^ state_strr4r]r5__repr__szBaseAction.__repr__cCst|Sr3)reprr]r4r4r5__str__szBaseAction.__str__) rArNrOrPrWtSequencestr__annotations__rXOptionalrdrfr4r4r4r5rVs rVc@s(eZdZdZdZdejddfddZdS) RetryActionrr6rr1NcCst||_dSr3)floatr)r^rr4r4r5__init__szRetryAction.__init__)rArNrOrWrXrg SupportsFloatrnr4r4r4r5rlsrlfirstsecondcCs|tur|S|Sr3)_unset)rprqr4r4r5 _first_setsrscs:eZdZdZd fdd Zdd d Zdefd d ZZS) RetryErrorz>Encapsulates the last attempt instance right before giving up. last_attemptFuturer1Ncs||_t|dSr3)rusuperrn)r^rur@r4r5rnszRetryError.__init__ t.NoReturncCs|jjr |j|r3)rufailedresultr]r4r4r5reraises zRetryError.reraisecCs|jjd|jdS)N[])r@rArur]r4r4r5rfzRetryError.__str__)rurvr1N)r1ry) rArNrOrPrnr|rirf __classcell__r4r4rxr5rts  rtc @s\eZdZdZdddZddd Zd ejeje d eje d ejd deje fddZ dS)AttemptManagerzManage attempt context. retry_stateRetryCallStatecCs ||_dSr3r)r^rr4r4r5rns zAttemptManager.__init__r1NcCr2r3r4r]r4r4r5 __enter__szAttemptManager.__enter__exc_type exc_value tracebacktypes.TracebackTypecCs0t|tr|j|||fdS|jddS)NT)r= BaseExceptionr set_exception set_result)r^rrrr4r4r5__exit__s  zAttemptManager.__exit__)rrr1N) rArNrOrPrnrrgrkTyperboolrr4r4r4r5rs  rc@sjeZdZeeeeeedde df de j e j e efgdfddddded e j d gdfd e j d gdfd e je j d gdfd ede je de je j d ge jffddZeeeeeeeeeef de j e j e j e efgdfefde j defde j defde j eefd e j e j d gdfefd e j e j d gdfefd e j e je j d gdfefd e j eefde j e je efde j e je j d ge jfefddfddZdefddZede jee jffddZdedefddZd)ddZdd de j e e!e jffdd Z"de j#e$ddffd!d"Z%e&d#e j d$e'fd%e jd&e jde'fd'd(Z(dS)* BaseRetryingNFrstopr,waitr+r6beforerafter before_sleepr|retry_error_clsretry_error_callbackc CsJ||_||_||_||_||_||_||_||_t |_ | |_ | |_ dSr3) rrrr6rrrr| threadinglocal_localrr r^rrrr6rrrr|rrr4r4r5rns   zBaseRetrying.__init__r1c Csn|jt||jt||jt||jt||jt||jt||jt||jt||j t| |j t| |j d S)z8Copy this object with some parameters changed if needed.) rrrr6rrrr|rr) r@rsrrrr6rrrr|rrrr4r4r5copys          zBaseRetrying.copycCsLd|jjdt|dd|jd|jd|jd|jd|jd |jd S) N) r@rAidrrrr6rrr]r4r4r5rdszBaseRetrying.__repr__cCs.z|jjWStyi|j_|jjYSw)aSReturn a dictionary of runtime statistics. This dictionary will be empty when the controller has never been ran. When it is running or has ran previously it should have (but may not) have useful and/or informational keys and values when running is underway and/or completed. .. warning:: The keys in this dictionary **should** be some what stable (not changing), but there existence **may** change between major releases as new statistics are gathered or removed so before accessing keys ensure that they actually exist and handle when they do not. .. note:: The values in this dictionary are local to the thread running call (so if multiple threads share the same retrying object - either directly or indirectly) they will each have there own view of statistics they have collected (in the future we may provide a way to aggregate the various statistics from each thread). )r statisticsAttributeErrorr]r4r4r5r"s    zBaseRetrying.statisticsr;cs\tdtjdtjdtjffdd }dtjdtjdtffdd }|_||_|S) z[Wrap a function for retrying. :param f: A function to wraps for retrying. argskwr1csg|Ri|Sr3r4)rrr;r^r4r5 wrapped_fDsz%BaseRetrying.wraps..wrapped_fkwargscsj|i|Sr3)rrH)rrrr4r5 retry_withHrz&BaseRetrying.wraps..retry_with) functoolsrHrgAnyr-r6r)r^r;rrr4rr5rH>s $ zBaseRetrying.wrapscCs0|jt|jd<d|jd<d|jd<dS)N start_timerattempt_numberridle_for)rcleartime monotonicr]r4r4r5beginPs  zBaseRetrying.beginrcCs&|j}|dur|jdur||tS|jjot|jt}|s,|j|ds,|S|j dur6| ||j |j d<|j |dr[|j rJ| |S||}|jrV||||jre|j|d}nd}t||_|j|7_|j d|7<|j dd7<|jdur||t|S)Nrdelay_since_first_attemptrrr)outcomerrRrzr= exceptionrMr6r{rseconds_since_startrrrrr|rrl next_actionrrrU)r^rfutis_explicit_retry retry_excrr4r4r5iterVs8            zBaseRetrying.iterccsd|t|ddid} |j|d}t|tr t|dVnt|tr/|||ndSq)Nr4)r0rrTr) rrrr=rRrrUprepare_for_next_attemptr)r^rdor4r4r5__iter__{s    zBaseRetrying.__iter__r0.rrcOr2r3r4)r^r0rrr4r4r5__call__r7zBaseRetrying.__call__r))rArNrOrrr"r r&r(rtrgCallableUnionintrmrrkrrrrnrrobjectrrirdpropertyDictrr-rHrrRrUr Generatorrrrr/rr4r4r4r5rs   "          %.rc@s8eZdZdZdejdefdejdejdefddZd S) rGzRetrying controller.r0.rrr1cOs|t||||d} |j|d}t|tr8z ||i|}Wnty1|tYnw| |nt|t rG| | |n|Sq )N) retry_objectr0rrTr) rrrr=rRrrsysexc_inforrUrr)r^r0rrrrr{r4r4r5rs       zRetrying.__call__N) rArNrOrPrgrr/rrr4r4r4r5rGs,rGc s\eZdZdZdeddffdd ZedefddZe ded e j d eddfd d Z Z S) rvzDEncapsulates a (future or past) attempted call to a target function.rr1Ncst||_dSr3)rwrnr)r^rrxr4r5rns  zFuture.__init__cCs |duS)z8Return whether a exception is being held in this future.N)rr]r4r4r5rzs z Future.failedvalue has_exceptioncCs(||}|r |||S|||S)zConstruct a new Future object.)rr)clsrrrrr4r4r5 constructs   zFuture.construct)rArNrOrPrrnrrrz classmethodrgrrrr4r4rxr5rvs&rvc @seZdZdZdedejedejdejddf dd Z e deje fd d Z dd d Z dejddfddZdejejeedfddfddZddZdS)rz5State related to a single call wrapped with Retrying.rr0rrr1NcCsDt|_||_||_||_||_d|_d|_d|_ d|_ d|_ dS)Nrr) rrrrr0rrrroutcome_timestamprr)r^rr0rrr4r4r5rns  zRetryCallState.__init__cCs|jdurdS|j|jSr3)rrr]r4r4r5rs  z"RetryCallState.seconds_since_startcCs$d|_d|_|jd7_d|_dSNr)rrrrr]r4r4r5rs z'RetryCallState.prepare_for_next_attemptvalcCs.t}t|j}|||||_|_dSr3)rrrvrrrr)r^rtsrr4r4r5rs  zRetryCallState.set_resultrrcCs2t}t|j}||d|||_|_dSr)rrrvrrrr)r^rrrr4r4r5rs zRetryCallState.set_exceptionc Cs|jdurd}n|jjr|j}d|jjd|d}nd|j}tt|jd}|jj}d|dt |d|j d |d |d S) Nznone yetzfailed ( raz returned rz : attempt #z ; slept for z; last result: >) rrzrr@rAr{rmroundrrr)r^r{rsleptclsnamer4r4r5rds  *zRetryCallState.__repr__r)rArNrOrPrrgrkr-rrnrrmrrrTuplerrrrdr4r4r4r5rs&  $ r)rB)rF)Zrrrrtypingrgr>abcrr concurrentrinspectrr6rrr r r r r rrrrrrnaprrrrrrrrrrrrrr r!r"r#r$wait_full_jitterrr%r&rr'r(rr)r*rC TYPE_CHECKINGtypesr+r,TypeVarrr-r/overloadrr ExceptionrMr NO_RESULTrRrmrUrVrlrrrsrtrrrGrvrpip._vendor.tenacity._asynciorBZpip._vendor.tenacity.tornadowebrFr4r4r4r5s                                         (0&- FPKH] NVpython3.10/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-310.pycnu[o ait @sfddlZddlmZejrddlZddlmZdddZ dd d d ed edej dgdffddZ dS)N)_utils)RetryCallState retry_staterreturncCsdS)z'Before call strategy that does nothing.N)rrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tenacity/before_sleep.pybefore_sleep_nothingsrFloggerzlogging.Logger log_levelexc_infocsdfdd }|S)z:Before call strategy that logs to some logger the attempt.rrrNc s|jjr |j}d|jjd|}}r|j}n d}n d|j}}d}jdt|j d|j j d|d|d |d dS) Nraisedz: Freturnedz Retrying z in z seconds as it  .)r ) outcomefailed exception __class____name__resultlogrget_callback_namefn next_actionsleep)rexverbvaluelocal_exc_infor r r rrlog_it&s&   z before_sleep_log..log_itrrrNr)r r r r rrrbefore_sleep_logsr"r!)F) typingpip._vendor.tenacityr TYPE_CHECKINGloggingrrintboolCallabler"rrrrs    PKH]1Ppython3.10/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-310.pycnu[o ai`@s^ddlZddlmZejrddlZddlmZdddZd d d edejdgdffd d Z dS)N)_utils)RetryCallState retry_staterreturncCsdS)z'Before call strategy that does nothing.Nrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tenacity/before.pybefore_nothingsr loggerzlogging.Logger log_levelcsdfdd }|S)z:Before call strategy that logs to some logger the attempt.rrrNc s.dt|jdt|jddS)NzStarting call to 'z', this is the z time calling it.)logrget_callback_namefn to_ordinalattempt_numberrr r rrlog_it"s  zbefore_log..log_itrrrNr)r r rrrr before_logsrr) typingpip._vendor.tenacityr TYPE_CHECKINGloggingrr intCallablerrrrrs   &PKH]/Zb b Rpython3.10/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-310.pycnu[o ai @sddlZddlZddlZddlmZddlmZddlmZddlmZddlm Z ddlm Z ej dej d Z e d ZGd d d eZdS) N)sleep)AttemptManager) BaseRetrying) DoAttempt)DoSleep)RetryCallState WrappedFn)bound_RetValTcseZdZefdejegejfdejddffdd Z dejdeje fd ejdejde fd d Z dd d Z dej eejffddZdedeffdd ZZS) AsyncRetryingrkwargsreturnNc stjdi|||_dS)N)super__init__r)selfrr  __class__r/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tenacity/_asyncio.pyr"s zAsyncRetrying.__init__fn.argscs|t||||d} |j|d}t|trszAsyncRetrying.__aiter__cs` |j|jd}|durtt|trt|jdSt|tr-|j||IdHn|Sq)NTr) rr&StopAsyncIterationrrrrr"r)rr#rrr __anext__Cs    zAsyncRetrying.__anext__csJttdtjdtjdtjffdd }j|_j|_|S)Nrr r cs|i|IdHS)Nr)rr rrr async_wrappedTsz*AsyncRetrying.wraps..async_wrapped)rwraps functoolstypingAnyretry retry_with)rrr+rr*rr,Ps "zAsyncRetrying.wraps)r r )__name__ __module__ __qualname__rr.Callablefloat Awaitabler/rr r%r'Unionrr)rr, __classcell__rrrrr !s.  r )r-rr.asynciorpip._vendor.tenacityrrrrrTypeVarr5rr r rrrrs       PKH]Npython3.10/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-310.pycnu[o ai @sddlZddlZejrddlZddlmZGdddejZGdddeZGdddeZ Gd d d eZ e Z Gd d d eZ Gd ddeZ GdddeZdS)N)RetryCallStatec@s<eZdZdZejdddefddZdd d Zdd d Z dS) stop_basez(Abstract base class for stop strategies. retry_staterreturncCsdSNselfrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tenacity/stop.py__call__szstop_base.__call__otherstop_allcC t||Sr)r r r rrr __and__  zstop_base.__and__stop_anycCrr)rrrrr __or__#rzstop_base.__or__N)r rrr )r rrr) __name__ __module__ __qualname____doc__abcabstractmethodboolr rrrrrr rs  rc@4eZdZdZdeddfddZdddefd d ZdS) rz+Stop if any of the stop condition is valid.stopsrNcG ||_dSrrr rrrr __init__*rzstop_any.__init__rrctfdd|jDS)Nc3|]}|VqdSrr.0xrrr .z$stop_any.__call__..)anyrrrr&r r -zstop_any.__call__rrrrrr rr rrrr r'rc@r) r z*Stop if all the stop conditions are valid.rrNcGrrrrrrr r 4rzstop_all.__init__rrcr!)Nc3r"rrr#r&rr r'8r(z$stop_all.__call__..)allrrrr&r r 7r*zstop_all.__call__r+rrrr r 1r,r c@s"eZdZdZdddefddZdS) _stop_neverz Never stop.rrrcCsdS)NFrrrrr r >sz_stop_never.__call__N)rrrrrr rrrr r.;sr.c@s,eZdZdZd ddZdd defd d ZdS) stop_when_event_setz!Stop when the given event is set.eventthreading.EventrNcCrr)r0)r r0rrr r Hrzstop_when_event_set.__init__rrcCs |jSr)r0is_setrrrr r Krzstop_when_event_set.__call__)r0r1rN)rrrrr rr rrrr r/Es r/c@r) stop_after_attemptz.Stop when the previous attempt >= max_attempt.max_attempt_numberrNcCrr)r4)r r4rrr r Rrzstop_after_attempt.__init__rrcC |j|jkSr)attempt_numberr4rrrr r U zstop_after_attempt.__call__)rrrrintr rr rrrr r3Or,r3c@r) stop_after_delayz3Stop when the time from the first attempt >= limit. max_delayrNcCrr)r:)r r:rrr r \rzstop_after_delay.__init__rrcCr5r)seconds_since_startr:rrrr r _r7zstop_after_delay.__call__)rrrrfloatr rr rrrr r9Yr,r9)rtyping TYPE_CHECKING threadingpip._vendor.tenacityrABCrrr r. stop_neverr/r3r9rrrr s     PKH]Mpython3.10/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-310.pycnu[o aig@sBddlZddlZejrddlZdeddfddZGdddZdS)NsecondsreturncCst|dS)z Sleep strategy that delays execution for a given number of seconds. This is the default strategy, and may be mocked out for unit testing. N)timesleep)rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tenacity/nap.pyrsrc@s2eZdZdZd ddZdejeddfd d ZdS) sleep_using_eventz0Sleep strategy that waits on an event to be set.eventthreading.EventrNcCs ||_dS)N)r )selfr rrr__init__%s zsleep_using_event.__init__timeoutcCs|jj|ddS)N)r )r wait)r r rrr__call__(szsleep_using_event.__call__)r r rN) __name__ __module__ __qualname____doc__r typingOptionalfloatrrrrrr"s r)rr TYPE_CHECKING threadingrrrrrrrs  PKH]aKEENpython3.10/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-310.pycnu[o ai#@sddlZddlZddlZddlmZejrddlmZGdddejZGdddeZ Gdd d e Z Gd d d eZ Gd d d eZ GdddeZ GdddeZGdddeZGdddeZdS)N)_utils)RetryCallStatec@sJeZdZdZejdddefddZdd d Zddde j d fd d Z dS) wait_basez(Abstract base class for wait strategies. retry_staterreturncCsdSNselfrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tenacity/wait.py__call__szwait_base.__call__other wait_combinecCs t||Sr)rr r rrr __add__" zwait_base.__add__)rrcCs|dkr|S||SNr)rrrrr __radd__%s zwait_base.__radd__N)r rrr) __name__ __module__ __qualname____doc__abcabstractmethodfloatr rtypingUnionrrrrr rs  rc@s4eZdZdZdeddfddZdddefd d ZdS) wait_fixedzCWait strategy that waits a fixed amount of time between each retry.waitrNcC ||_dSrr)r rrrr __init__/rzwait_fixed.__init__rrcCs|jSrr r rrr r 2szwait_fixed.__call__)rrrrrr!r rrrr r,rcs"eZdZdZdfdd ZZS) wait_nonez7Wait strategy that doesn't wait at all before retrying.rNcstddSr)superr!)r  __class__rr r!9szwait_none.__init__)rN)rrrrr! __classcell__rrr%r r#6sr#c@sNeZdZdZddejeefdejeefddfdd Zd d defd d Z dS) wait_randomzAWait strategy that waits a random amount of time between min/max.rminmaxrNcCs||_||_dSr)wait_random_minwait_random_max)r r*r+rrr r!@s zwait_random.__init__rrcCs|jt|j|jSr)r,randomr-r rrr r Dszwait_random.__call__)rr)) rrrrrrintrr!r rrrr r(=s,r(c@4eZdZdZdeddfddZdddefd d ZdS) rz#Combine several waiting strategies. strategiesrNcGrr) wait_funcsr r1rrr r!Krzwait_combine.__init__rrcstfdd|jDS)Nc3s|]}|dVqdS)rNr).0xr4rr Osz(wait_combine.__call__..)sumr2r rr4r r Nszwait_combine.__call__rrrrrr!rr rrrr rHr"rc@r0) wait_chainaChain two or more waiting strategies. If all strategies are exhausted, the very last strategy is used thereafter. For example:: @retry(wait=wait_chain(*[wait_fixed(1) for i in range(3)] + [wait_fixed(2) for j in range(5)] + [wait_fixed(5) for k in range(4))) def wait_chained(): print("Wait 1s for 3 attempts, 2s for 5 attempts and 5s thereafter.") r1rNcGrr)r1r3rrr r!brzwait_chain.__init__rrcCs0tt|jdt|j}|j|d}||dS)Nr)r4)r*r+attempt_numberlenr1)r r wait_func_no wait_funcrrr r es zwait_chain.__call__r9rrrr r:Rsr:c @sdeZdZdZddejfdejee fdejee fdejee fddfd d Z d d de fd dZ dS)wait_incrementingzWait an incremental amount of time after each attempt. Starting at a starting value and incrementing by a value for each attempt (and restricting the upper limit to some maximum value). rdstart incrementr+rNcCs||_||_||_dSr)rArBr+)r rArBr+rrr r!rs zwait_incrementing.__init__rrcCs(|j|j|jd}tdt||jSNr)r)rArBr;r+r*)r rresultrrr r |szwait_incrementing.__call__ rrrrrMAX_WAITrrr/rr!r rrrr r?ks     r?c @steZdZdZdejddfdejee fdejee fdejee fdejee fd d f d d Z d dd e fddZ d S)wait_exponentialaWait strategy that applies exponential backoff. It allows for a customized multiplier and an ability to restrict the upper and lower limits to some maximum and minimum value. The intervals are fixed (i.e. there is no jitter), so this strategy is suitable for balancing retries against latency when a required resource is unavailable for an unknown duration, but *not* suitable for resolving contention between multiple processes for a shared resource. Use wait_random_exponential for the latter case. r)r multiplierr+exp_baser*rNcCs||_||_||_||_dSr)rIr*r+rJ)r rIr+rJr*rrr r!s zwait_exponential.__init__rrcCsRz|j|jd}|j|}Wn ty|jYSwttd|jt||jSrC)rJr;rI OverflowErrorr+r*)r rexprDrrr r s  zwait_exponential.__call__rErrrr rGs$      rGcs*eZdZdZdddeffdd ZZS)wait_random_exponentialaRandom wait with exponentially widening window. An exponential backoff strategy used to mediate contention between multiple uncoordinated processes for a shared resource in distributed systems. This is the sense in which "exponential backoff" is meant in e.g. Ethernet networking, and corresponds to the "Full Jitter" algorithm described in this blog post: https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ Each retry occurs at a random time in a geometrically expanding interval. It allows for a custom multiplier and an ability to restrict the upper limit of the random interval to some maximum value. Example:: wait_random_exponential(multiplier=0.5, # initial window 0.5s max=60) # max 60s timeout When waiting for an unavailable resource to become available again, as opposed to trying to resolve contention for a shared resource, the wait_exponential strategy (which uses a fixed interval) may be preferable. rrrcstj|d}td|S)Nr4r)r$r r.uniform)r rhighr%rr r s z wait_random_exponential.__call__)rrrrrr r'rrr%r rMsrM)rr.rpip._vendor.tenacityr TYPE_CHECKINGrABCrrr#r(rr:r?rGrMrrrr s     "PKH]NxPpython3.10/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-310.pycnu[o ai@s`ddlZddlZejdZdedefddZdedefddZd ejd ej fdefd d Z dS) Npos_numreturncCsT|dkrdS|dkr dS|dkrdS|dkrdSd |kr#d kr$dSt|d S) Nrthstrndrd  find_ordinalrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tenacity/_utils.pyrs rcCs|t|S)Nrrrrr to_ordinal*srcb.c Csg}z||jWnty%z||jWn ty"YnwYnw|s,t|Sz |jr7|d|jWn tyAYnwd|S)znGet a callback fully-qualified name. If no name can be produced ``repr(cb)`` is called and returned. r.)append __qualname__AttributeError__name__repr __module__insertjoin)rsegmentsrrrget_callback_name.s*    r) systypingmaxsizeMAX_WAITintstrrrCallableAnyrrrrrs  "PKH]"9aa;python3.10/site-packages/pip/_vendor/tenacity/tornadoweb.pynu[# Copyright 2017 Elisey Zanko # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import sys import typing from pip._vendor.tenacity import BaseRetrying from pip._vendor.tenacity import DoAttempt from pip._vendor.tenacity import DoSleep from pip._vendor.tenacity import RetryCallState from tornado import gen if typing.TYPE_CHECKING: from tornado.concurrent import Future _RetValT = typing.TypeVar("_RetValT") class TornadoRetrying(BaseRetrying): def __init__(self, sleep: "typing.Callable[[float], Future[None]]" = gen.sleep, **kwargs: typing.Any) -> None: super().__init__(**kwargs) self.sleep = sleep @gen.coroutine def __call__( # type: ignore # Change signature from supertype self, fn: "typing.Callable[..., typing.Union[typing.Generator[typing.Any, typing.Any, _RetValT], Future[_RetValT]]]", *args: typing.Any, **kwargs: typing.Any, ) -> "typing.Generator[typing.Any, typing.Any, _RetValT]": self.begin() retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs) while True: do = self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): try: result = yield fn(*args, **kwargs) except BaseException: # noqa: B902 retry_state.set_exception(sys.exc_info()) else: retry_state.set_result(result) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() yield self.sleep(do) else: raise gen.Return(do) PKH]lgg4python3.10/site-packages/pip/_vendor/tenacity/nap.pynu[# Copyright 2016 Étienne Bersac # Copyright 2016 Julien Danjou # Copyright 2016 Joshua Harlow # Copyright 2013-2014 Ray Holder # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import time import typing if typing.TYPE_CHECKING: import threading def sleep(seconds: float) -> None: """ Sleep strategy that delays execution for a given number of seconds. This is the default strategy, and may be mocked out for unit testing. """ time.sleep(seconds) class sleep_using_event: """Sleep strategy that waits on an event to be set.""" def __init__(self, event: "threading.Event") -> None: self.event = event def __call__(self, timeout: typing.Optional[float]) -> None: # NOTE(harlowja): this may *not* actually wait for timeout # seconds if the event is set (ie this may eject out early). self.event.wait(timeout=timeout) PKH]ml 9python3.10/site-packages/pip/_vendor/tenacity/_asyncio.pynu[# Copyright 2016 Étienne Bersac # Copyright 2016 Julien Danjou # Copyright 2016 Joshua Harlow # Copyright 2013-2014 Ray Holder # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import functools import sys import typing from asyncio import sleep from pip._vendor.tenacity import AttemptManager from pip._vendor.tenacity import BaseRetrying from pip._vendor.tenacity import DoAttempt from pip._vendor.tenacity import DoSleep from pip._vendor.tenacity import RetryCallState WrappedFn = typing.TypeVar("WrappedFn", bound=typing.Callable) _RetValT = typing.TypeVar("_RetValT") class AsyncRetrying(BaseRetrying): def __init__(self, sleep: typing.Callable[[float], typing.Awaitable] = sleep, **kwargs: typing.Any) -> None: super().__init__(**kwargs) self.sleep = sleep async def __call__( # type: ignore # Change signature from supertype self, fn: typing.Callable[..., typing.Awaitable[_RetValT]], *args: typing.Any, **kwargs: typing.Any, ) -> _RetValT: self.begin() retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs) while True: do = self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): try: result = await fn(*args, **kwargs) except BaseException: # noqa: B902 retry_state.set_exception(sys.exc_info()) else: retry_state.set_result(result) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do def __aiter__(self) -> "AsyncRetrying": self.begin() self._retry_state = RetryCallState(self, fn=None, args=(), kwargs={}) return self async def __anext__(self) -> typing.Union[AttemptManager, typing.Any]: while True: do = self.iter(retry_state=self._retry_state) if do is None: raise StopAsyncIteration elif isinstance(do, DoAttempt): return AttemptManager(retry_state=self._retry_state) elif isinstance(do, DoSleep): self._retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do def wraps(self, fn: WrappedFn) -> WrappedFn: fn = super().wraps(fn) # Ensure wrapper is recognized as a coroutine function. @functools.wraps(fn) async def async_wrapped(*args: typing.Any, **kwargs: typing.Any) -> typing.Any: return await fn(*args, **kwargs) # Preserve attributes async_wrapped.retry = fn.retry async_wrapped.retry_with = fn.retry_with return async_wrapped PKH]6python3.10/site-packages/pip/_vendor/tenacity/after.pynu[# Copyright 2016 Julien Danjou # Copyright 2016 Joshua Harlow # Copyright 2013-2014 Ray Holder # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import typing from pip._vendor.tenacity import _utils if typing.TYPE_CHECKING: import logging from pip._vendor.tenacity import RetryCallState def after_nothing(retry_state: "RetryCallState") -> None: """After call strategy that does nothing.""" def after_log( logger: "logging.Logger", log_level: int, sec_format: str = "%0.3f", ) -> typing.Callable[["RetryCallState"], None]: """After call strategy that logs to some logger the finished attempt.""" def log_it(retry_state: "RetryCallState") -> None: logger.log( log_level, f"Finished call to '{_utils.get_callback_name(retry_state.fn)}' " f"after {sec_format % retry_state.seconds_since_start}(s), " f"this was the {_utils.to_ordinal(retry_state.attempt_number)} time calling it.", ) return log_it PKH]Vu 5python3.10/site-packages/pip/_vendor/tenacity/stop.pynu[# Copyright 2016–2021 Julien Danjou # Copyright 2016 Joshua Harlow # Copyright 2013-2014 Ray Holder # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import abc import typing if typing.TYPE_CHECKING: import threading from pip._vendor.tenacity import RetryCallState class stop_base(abc.ABC): """Abstract base class for stop strategies.""" @abc.abstractmethod def __call__(self, retry_state: "RetryCallState") -> bool: pass def __and__(self, other: "stop_base") -> "stop_all": return stop_all(self, other) def __or__(self, other: "stop_base") -> "stop_any": return stop_any(self, other) class stop_any(stop_base): """Stop if any of the stop condition is valid.""" def __init__(self, *stops: stop_base) -> None: self.stops = stops def __call__(self, retry_state: "RetryCallState") -> bool: return any(x(retry_state) for x in self.stops) class stop_all(stop_base): """Stop if all the stop conditions are valid.""" def __init__(self, *stops: stop_base) -> None: self.stops = stops def __call__(self, retry_state: "RetryCallState") -> bool: return all(x(retry_state) for x in self.stops) class _stop_never(stop_base): """Never stop.""" def __call__(self, retry_state: "RetryCallState") -> bool: return False stop_never = _stop_never() class stop_when_event_set(stop_base): """Stop when the given event is set.""" def __init__(self, event: "threading.Event") -> None: self.event = event def __call__(self, retry_state: "RetryCallState") -> bool: return self.event.is_set() class stop_after_attempt(stop_base): """Stop when the previous attempt >= max_attempt.""" def __init__(self, max_attempt_number: int) -> None: self.max_attempt_number = max_attempt_number def __call__(self, retry_state: "RetryCallState") -> bool: return retry_state.attempt_number >= self.max_attempt_number class stop_after_delay(stop_base): """Stop when the time from the first attempt >= limit.""" def __init__(self, max_delay: float) -> None: self.max_delay = max_delay def __call__(self, retry_state: "RetryCallState") -> bool: return retry_state.seconds_since_start >= self.max_delay PKH] ktt=python3.10/site-packages/pip/_vendor/tenacity/before_sleep.pynu[# Copyright 2016 Julien Danjou # Copyright 2016 Joshua Harlow # Copyright 2013-2014 Ray Holder # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import typing from pip._vendor.tenacity import _utils if typing.TYPE_CHECKING: import logging from pip._vendor.tenacity import RetryCallState def before_sleep_nothing(retry_state: "RetryCallState") -> None: """Before call strategy that does nothing.""" def before_sleep_log( logger: "logging.Logger", log_level: int, exc_info: bool = False, ) -> typing.Callable[["RetryCallState"], None]: """Before call strategy that logs to some logger the attempt.""" def log_it(retry_state: "RetryCallState") -> None: if retry_state.outcome.failed: ex = retry_state.outcome.exception() verb, value = "raised", f"{ex.__class__.__name__}: {ex}" if exc_info: local_exc_info = retry_state.outcome.exception() else: local_exc_info = False else: verb, value = "returned", retry_state.outcome.result() local_exc_info = False # exc_info does not apply when no exception logger.log( log_level, f"Retrying {_utils.get_callback_name(retry_state.fn)} " f"in {retry_state.next_action.sleep} seconds as it {verb} {value}.", exc_info=local_exc_info, ) return log_it PKH]}``7python3.10/site-packages/pip/_vendor/tenacity/before.pynu[# Copyright 2016 Julien Danjou # Copyright 2016 Joshua Harlow # Copyright 2013-2014 Ray Holder # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import typing from pip._vendor.tenacity import _utils if typing.TYPE_CHECKING: import logging from pip._vendor.tenacity import RetryCallState def before_nothing(retry_state: "RetryCallState") -> None: """Before call strategy that does nothing.""" def before_log(logger: "logging.Logger", log_level: int) -> typing.Callable[["RetryCallState"], None]: """Before call strategy that logs to some logger the attempt.""" def log_it(retry_state: "RetryCallState") -> None: logger.log( log_level, f"Starting call to '{_utils.get_callback_name(retry_state.fn)}', " f"this is the {_utils.to_ordinal(retry_state.attempt_number)} time calling it.", ) return log_it PKH]U str: # See: https://en.wikipedia.org/wiki/English_numerals#Ordinal_numbers if pos_num == 0: return "th" elif pos_num == 1: return "st" elif pos_num == 2: return "nd" elif pos_num == 3: return "rd" elif 4 <= pos_num <= 20: return "th" else: return find_ordinal(pos_num % 10) def to_ordinal(pos_num: int) -> str: return f"{pos_num}{find_ordinal(pos_num)}" def get_callback_name(cb: typing.Callable[..., typing.Any]) -> str: """Get a callback fully-qualified name. If no name can be produced ``repr(cb)`` is called and returned. """ segments = [] try: segments.append(cb.__qualname__) except AttributeError: try: segments.append(cb.__name__) except AttributeError: pass if not segments: return repr(cb) else: try: # When running under sphinx it appears this can be none? if cb.__module__: segments.insert(0, cb.__module__) except AttributeError: pass return ".".join(segments) PKH]R-6python3.10/site-packages/pip/_vendor/tenacity/retry.pynu[# Copyright 2016–2021 Julien Danjou # Copyright 2016 Joshua Harlow # Copyright 2013-2014 Ray Holder # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import abc import re import typing if typing.TYPE_CHECKING: from pip._vendor.tenacity import RetryCallState class retry_base(abc.ABC): """Abstract base class for retry strategies.""" @abc.abstractmethod def __call__(self, retry_state: "RetryCallState") -> bool: pass def __and__(self, other: "retry_base") -> "retry_all": return retry_all(self, other) def __or__(self, other: "retry_base") -> "retry_any": return retry_any(self, other) class _retry_never(retry_base): """Retry strategy that never rejects any result.""" def __call__(self, retry_state: "RetryCallState") -> bool: return False retry_never = _retry_never() class _retry_always(retry_base): """Retry strategy that always rejects any result.""" def __call__(self, retry_state: "RetryCallState") -> bool: return True retry_always = _retry_always() class retry_if_exception(retry_base): """Retry strategy that retries if an exception verifies a predicate.""" def __init__(self, predicate: typing.Callable[[BaseException], bool]) -> None: self.predicate = predicate def __call__(self, retry_state: "RetryCallState") -> bool: if retry_state.outcome.failed: return self.predicate(retry_state.outcome.exception()) else: return False class retry_if_exception_type(retry_if_exception): """Retries if an exception has been raised of one or more types.""" def __init__( self, exception_types: typing.Union[ typing.Type[BaseException], typing.Tuple[typing.Type[BaseException], ...], ] = Exception, ) -> None: self.exception_types = exception_types super().__init__(lambda e: isinstance(e, exception_types)) class retry_if_not_exception_type(retry_if_exception): """Retries except an exception has been raised of one or more types.""" def __init__( self, exception_types: typing.Union[ typing.Type[BaseException], typing.Tuple[typing.Type[BaseException], ...], ] = Exception, ) -> None: self.exception_types = exception_types super().__init__(lambda e: not isinstance(e, exception_types)) class retry_unless_exception_type(retry_if_exception): """Retries until an exception is raised of one or more types.""" def __init__( self, exception_types: typing.Union[ typing.Type[BaseException], typing.Tuple[typing.Type[BaseException], ...], ] = Exception, ) -> None: self.exception_types = exception_types super().__init__(lambda e: not isinstance(e, exception_types)) def __call__(self, retry_state: "RetryCallState") -> bool: # always retry if no exception was raised if not retry_state.outcome.failed: return True return self.predicate(retry_state.outcome.exception()) class retry_if_result(retry_base): """Retries if the result verifies a predicate.""" def __init__(self, predicate: typing.Callable[[typing.Any], bool]) -> None: self.predicate = predicate def __call__(self, retry_state: "RetryCallState") -> bool: if not retry_state.outcome.failed: return self.predicate(retry_state.outcome.result()) else: return False class retry_if_not_result(retry_base): """Retries if the result refutes a predicate.""" def __init__(self, predicate: typing.Callable[[typing.Any], bool]) -> None: self.predicate = predicate def __call__(self, retry_state: "RetryCallState") -> bool: if not retry_state.outcome.failed: return not self.predicate(retry_state.outcome.result()) else: return False class retry_if_exception_message(retry_if_exception): """Retries if an exception message equals or matches.""" def __init__( self, message: typing.Optional[str] = None, match: typing.Optional[str] = None, ) -> None: if message and match: raise TypeError(f"{self.__class__.__name__}() takes either 'message' or 'match', not both") # set predicate if message: def message_fnc(exception: BaseException) -> bool: return message == str(exception) predicate = message_fnc elif match: prog = re.compile(match) def match_fnc(exception: BaseException) -> bool: return bool(prog.match(str(exception))) predicate = match_fnc else: raise TypeError(f"{self.__class__.__name__}() missing 1 required argument 'message' or 'match'") super().__init__(predicate) class retry_if_not_exception_message(retry_if_exception_message): """Retries until an exception message equals or matches.""" def __init__( self, message: typing.Optional[str] = None, match: typing.Optional[str] = None, ) -> None: super().__init__(message, match) # invert predicate if_predicate = self.predicate self.predicate = lambda *args_, **kwargs_: not if_predicate(*args_, **kwargs_) def __call__(self, retry_state: "RetryCallState") -> bool: if not retry_state.outcome.failed: return True return self.predicate(retry_state.outcome.exception()) class retry_any(retry_base): """Retries if any of the retries condition is valid.""" def __init__(self, *retries: retry_base) -> None: self.retries = retries def __call__(self, retry_state: "RetryCallState") -> bool: return any(r(retry_state) for r in self.retries) class retry_all(retry_base): """Retries if all the retries condition are valid.""" def __init__(self, *retries: retry_base) -> None: self.retries = retries def __call__(self, retry_state: "RetryCallState") -> bool: return all(r(retry_state) for r in self.retries) PKH]QGQG9python3.10/site-packages/pip/_vendor/tenacity/__init__.pynu[# Copyright 2016-2018 Julien Danjou # Copyright 2017 Elisey Zanko # Copyright 2016 Étienne Bersac # Copyright 2016 Joshua Harlow # Copyright 2013-2014 Ray Holder # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import functools import sys import threading import time import typing as t import warnings from abc import ABC, abstractmethod from concurrent import futures from inspect import iscoroutinefunction # Import all built-in retry strategies for easier usage. from .retry import retry_base # noqa from .retry import retry_all # noqa from .retry import retry_always # noqa from .retry import retry_any # noqa from .retry import retry_if_exception # noqa from .retry import retry_if_exception_type # noqa from .retry import retry_if_not_exception_type # noqa from .retry import retry_if_not_result # noqa from .retry import retry_if_result # noqa from .retry import retry_never # noqa from .retry import retry_unless_exception_type # noqa from .retry import retry_if_exception_message # noqa from .retry import retry_if_not_exception_message # noqa # Import all nap strategies for easier usage. from .nap import sleep # noqa from .nap import sleep_using_event # noqa # Import all built-in stop strategies for easier usage. from .stop import stop_after_attempt # noqa from .stop import stop_after_delay # noqa from .stop import stop_all # noqa from .stop import stop_any # noqa from .stop import stop_never # noqa from .stop import stop_when_event_set # noqa # Import all built-in wait strategies for easier usage. from .wait import wait_chain # noqa from .wait import wait_combine # noqa from .wait import wait_exponential # noqa from .wait import wait_fixed # noqa from .wait import wait_incrementing # noqa from .wait import wait_none # noqa from .wait import wait_random # noqa from .wait import wait_random_exponential # noqa from .wait import wait_random_exponential as wait_full_jitter # noqa # Import all built-in before strategies for easier usage. from .before import before_log # noqa from .before import before_nothing # noqa # Import all built-in after strategies for easier usage. from .after import after_log # noqa from .after import after_nothing # noqa # Import all built-in after strategies for easier usage. from .before_sleep import before_sleep_log # noqa from .before_sleep import before_sleep_nothing # noqa # Replace a conditional import with a hard-coded None so that pip does # not attempt to use tornado even if it is present in the environment. # If tornado is non-None, tenacity will attempt to execute some code # that is sensitive to the version of tornado, which could break pip # if an old version is found. tornado = None # type: ignore if t.TYPE_CHECKING: import types from .wait import wait_base from .stop import stop_base WrappedFn = t.TypeVar("WrappedFn", bound=t.Callable) _RetValT = t.TypeVar("_RetValT") @t.overload def retry(fn: WrappedFn) -> WrappedFn: pass @t.overload def retry(*dargs: t.Any, **dkw: t.Any) -> t.Callable[[WrappedFn], WrappedFn]: # noqa pass def retry(*dargs: t.Any, **dkw: t.Any) -> t.Union[WrappedFn, t.Callable[[WrappedFn], WrappedFn]]: # noqa """Wrap a function with a new `Retrying` object. :param dargs: positional arguments passed to Retrying object :param dkw: keyword arguments passed to the Retrying object """ # support both @retry and @retry() as valid syntax if len(dargs) == 1 and callable(dargs[0]): return retry()(dargs[0]) else: def wrap(f: WrappedFn) -> WrappedFn: if isinstance(f, retry_base): warnings.warn( f"Got retry_base instance ({f.__class__.__name__}) as callable argument, " f"this will probably hang indefinitely (did you mean retry={f.__class__.__name__}(...)?)" ) if iscoroutinefunction(f): r: "BaseRetrying" = AsyncRetrying(*dargs, **dkw) elif tornado and hasattr(tornado.gen, "is_coroutine_function") and tornado.gen.is_coroutine_function(f): r = TornadoRetrying(*dargs, **dkw) else: r = Retrying(*dargs, **dkw) return r.wraps(f) return wrap class TryAgain(Exception): """Always retry the executed function when raised.""" NO_RESULT = object() class DoAttempt: pass class DoSleep(float): pass class BaseAction: """Base class for representing actions to take by retry object. Concrete implementations must define: - __init__: to initialize all necessary fields - REPR_FIELDS: class variable specifying attributes to include in repr(self) - NAME: for identification in retry object methods and callbacks """ REPR_FIELDS: t.Sequence[str] = () NAME: t.Optional[str] = None def __repr__(self) -> str: state_str = ", ".join(f"{field}={getattr(self, field)!r}" for field in self.REPR_FIELDS) return f"{self.__class__.__name__}({state_str})" def __str__(self) -> str: return repr(self) class RetryAction(BaseAction): REPR_FIELDS = ("sleep",) NAME = "retry" def __init__(self, sleep: t.SupportsFloat) -> None: self.sleep = float(sleep) _unset = object() def _first_set(first: t.Union[t.Any, object], second: t.Any) -> t.Any: return second if first is _unset else first class RetryError(Exception): """Encapsulates the last attempt instance right before giving up.""" def __init__(self, last_attempt: "Future") -> None: self.last_attempt = last_attempt super().__init__(last_attempt) def reraise(self) -> "t.NoReturn": if self.last_attempt.failed: raise self.last_attempt.result() raise self def __str__(self) -> str: return f"{self.__class__.__name__}[{self.last_attempt}]" class AttemptManager: """Manage attempt context.""" def __init__(self, retry_state: "RetryCallState"): self.retry_state = retry_state def __enter__(self) -> None: pass def __exit__( self, exc_type: t.Optional[t.Type[BaseException]], exc_value: t.Optional[BaseException], traceback: t.Optional["types.TracebackType"], ) -> t.Optional[bool]: if isinstance(exc_value, BaseException): self.retry_state.set_exception((exc_type, exc_value, traceback)) return True # Swallow exception. else: # We don't have the result, actually. self.retry_state.set_result(None) return None class BaseRetrying(ABC): def __init__( self, sleep: t.Callable[[t.Union[int, float]], None] = sleep, stop: "stop_base" = stop_never, wait: "wait_base" = wait_none(), retry: retry_base = retry_if_exception_type(), before: t.Callable[["RetryCallState"], None] = before_nothing, after: t.Callable[["RetryCallState"], None] = after_nothing, before_sleep: t.Optional[t.Callable[["RetryCallState"], None]] = None, reraise: bool = False, retry_error_cls: t.Type[RetryError] = RetryError, retry_error_callback: t.Optional[t.Callable[["RetryCallState"], t.Any]] = None, ): self.sleep = sleep self.stop = stop self.wait = wait self.retry = retry self.before = before self.after = after self.before_sleep = before_sleep self.reraise = reraise self._local = threading.local() self.retry_error_cls = retry_error_cls self.retry_error_callback = retry_error_callback def copy( self, sleep: t.Union[t.Callable[[t.Union[int, float]], None], object] = _unset, stop: t.Union["stop_base", object] = _unset, wait: t.Union["wait_base", object] = _unset, retry: t.Union[retry_base, object] = _unset, before: t.Union[t.Callable[["RetryCallState"], None], object] = _unset, after: t.Union[t.Callable[["RetryCallState"], None], object] = _unset, before_sleep: t.Union[t.Optional[t.Callable[["RetryCallState"], None]], object] = _unset, reraise: t.Union[bool, object] = _unset, retry_error_cls: t.Union[t.Type[RetryError], object] = _unset, retry_error_callback: t.Union[t.Optional[t.Callable[["RetryCallState"], t.Any]], object] = _unset, ) -> "BaseRetrying": """Copy this object with some parameters changed if needed.""" return self.__class__( sleep=_first_set(sleep, self.sleep), stop=_first_set(stop, self.stop), wait=_first_set(wait, self.wait), retry=_first_set(retry, self.retry), before=_first_set(before, self.before), after=_first_set(after, self.after), before_sleep=_first_set(before_sleep, self.before_sleep), reraise=_first_set(reraise, self.reraise), retry_error_cls=_first_set(retry_error_cls, self.retry_error_cls), retry_error_callback=_first_set(retry_error_callback, self.retry_error_callback), ) def __repr__(self) -> str: return ( f"<{self.__class__.__name__} object at 0x{id(self):x} (" f"stop={self.stop}, " f"wait={self.wait}, " f"sleep={self.sleep}, " f"retry={self.retry}, " f"before={self.before}, " f"after={self.after})>" ) @property def statistics(self) -> t.Dict[str, t.Any]: """Return a dictionary of runtime statistics. This dictionary will be empty when the controller has never been ran. When it is running or has ran previously it should have (but may not) have useful and/or informational keys and values when running is underway and/or completed. .. warning:: The keys in this dictionary **should** be some what stable (not changing), but there existence **may** change between major releases as new statistics are gathered or removed so before accessing keys ensure that they actually exist and handle when they do not. .. note:: The values in this dictionary are local to the thread running call (so if multiple threads share the same retrying object - either directly or indirectly) they will each have there own view of statistics they have collected (in the future we may provide a way to aggregate the various statistics from each thread). """ try: return self._local.statistics except AttributeError: self._local.statistics = {} return self._local.statistics def wraps(self, f: WrappedFn) -> WrappedFn: """Wrap a function for retrying. :param f: A function to wraps for retrying. """ @functools.wraps(f) def wrapped_f(*args: t.Any, **kw: t.Any) -> t.Any: return self(f, *args, **kw) def retry_with(*args: t.Any, **kwargs: t.Any) -> WrappedFn: return self.copy(*args, **kwargs).wraps(f) wrapped_f.retry = self wrapped_f.retry_with = retry_with return wrapped_f def begin(self) -> None: self.statistics.clear() self.statistics["start_time"] = time.monotonic() self.statistics["attempt_number"] = 1 self.statistics["idle_for"] = 0 def iter(self, retry_state: "RetryCallState") -> t.Union[DoAttempt, DoSleep, t.Any]: # noqa fut = retry_state.outcome if fut is None: if self.before is not None: self.before(retry_state) return DoAttempt() is_explicit_retry = retry_state.outcome.failed and isinstance(retry_state.outcome.exception(), TryAgain) if not (is_explicit_retry or self.retry(retry_state=retry_state)): return fut.result() if self.after is not None: self.after(retry_state) self.statistics["delay_since_first_attempt"] = retry_state.seconds_since_start if self.stop(retry_state=retry_state): if self.retry_error_callback: return self.retry_error_callback(retry_state) retry_exc = self.retry_error_cls(fut) if self.reraise: raise retry_exc.reraise() raise retry_exc from fut.exception() if self.wait: sleep = self.wait(retry_state=retry_state) else: sleep = 0.0 retry_state.next_action = RetryAction(sleep) retry_state.idle_for += sleep self.statistics["idle_for"] += sleep self.statistics["attempt_number"] += 1 if self.before_sleep is not None: self.before_sleep(retry_state) return DoSleep(sleep) def __iter__(self) -> t.Generator[AttemptManager, None, None]: self.begin() retry_state = RetryCallState(self, fn=None, args=(), kwargs={}) while True: do = self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): yield AttemptManager(retry_state=retry_state) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() self.sleep(do) else: break @abstractmethod def __call__(self, fn: t.Callable[..., _RetValT], *args: t.Any, **kwargs: t.Any) -> _RetValT: pass class Retrying(BaseRetrying): """Retrying controller.""" def __call__(self, fn: t.Callable[..., _RetValT], *args: t.Any, **kwargs: t.Any) -> _RetValT: self.begin() retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs) while True: do = self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): try: result = fn(*args, **kwargs) except BaseException: # noqa: B902 retry_state.set_exception(sys.exc_info()) else: retry_state.set_result(result) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() self.sleep(do) else: return do class Future(futures.Future): """Encapsulates a (future or past) attempted call to a target function.""" def __init__(self, attempt_number: int) -> None: super().__init__() self.attempt_number = attempt_number @property def failed(self) -> bool: """Return whether a exception is being held in this future.""" return self.exception() is not None @classmethod def construct(cls, attempt_number: int, value: t.Any, has_exception: bool) -> "Future": """Construct a new Future object.""" fut = cls(attempt_number) if has_exception: fut.set_exception(value) else: fut.set_result(value) return fut class RetryCallState: """State related to a single call wrapped with Retrying.""" def __init__( self, retry_object: BaseRetrying, fn: t.Optional[WrappedFn], args: t.Any, kwargs: t.Any, ) -> None: #: Retry call start timestamp self.start_time = time.monotonic() #: Retry manager object self.retry_object = retry_object #: Function wrapped by this retry call self.fn = fn #: Arguments of the function wrapped by this retry call self.args = args #: Keyword arguments of the function wrapped by this retry call self.kwargs = kwargs #: The number of the current attempt self.attempt_number: int = 1 #: Last outcome (result or exception) produced by the function self.outcome: t.Optional[Future] = None #: Timestamp of the last outcome self.outcome_timestamp: t.Optional[float] = None #: Time spent sleeping in retries self.idle_for: float = 0.0 #: Next action as decided by the retry manager self.next_action: t.Optional[RetryAction] = None @property def seconds_since_start(self) -> t.Optional[float]: if self.outcome_timestamp is None: return None return self.outcome_timestamp - self.start_time def prepare_for_next_attempt(self) -> None: self.outcome = None self.outcome_timestamp = None self.attempt_number += 1 self.next_action = None def set_result(self, val: t.Any) -> None: ts = time.monotonic() fut = Future(self.attempt_number) fut.set_result(val) self.outcome, self.outcome_timestamp = fut, ts def set_exception(self, exc_info: t.Tuple[t.Type[BaseException], BaseException, "types.TracebackType"]) -> None: ts = time.monotonic() fut = Future(self.attempt_number) fut.set_exception(exc_info[1]) self.outcome, self.outcome_timestamp = fut, ts def __repr__(self): if self.outcome is None: result = "none yet" elif self.outcome.failed: exception = self.outcome.exception() result = f"failed ({exception.__class__.__name__} {exception})" else: result = f"returned {self.outcome.result()}" slept = float(round(self.idle_for, 2)) clsname = self.__class__.__name__ return f"<{clsname} {id(self)}: attempt #{self.attempt_number}; slept for {slept}; last result: {result}>" from pip._vendor.tenacity._asyncio import AsyncRetrying # noqa:E402,I100 if tornado: from pip._vendor.tenacity.tornadoweb import TornadoRetrying PKH]ZeY##5python3.10/site-packages/pip/_vendor/tenacity/wait.pynu[# Copyright 2016–2021 Julien Danjou # Copyright 2016 Joshua Harlow # Copyright 2013-2014 Ray Holder # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import abc import random import typing from pip._vendor.tenacity import _utils if typing.TYPE_CHECKING: from pip._vendor.tenacity import RetryCallState class wait_base(abc.ABC): """Abstract base class for wait strategies.""" @abc.abstractmethod def __call__(self, retry_state: "RetryCallState") -> float: pass def __add__(self, other: "wait_base") -> "wait_combine": return wait_combine(self, other) def __radd__(self, other: "wait_base") -> typing.Union["wait_combine", "wait_base"]: # make it possible to use multiple waits with the built-in sum function if other == 0: return self return self.__add__(other) class wait_fixed(wait_base): """Wait strategy that waits a fixed amount of time between each retry.""" def __init__(self, wait: float) -> None: self.wait_fixed = wait def __call__(self, retry_state: "RetryCallState") -> float: return self.wait_fixed class wait_none(wait_fixed): """Wait strategy that doesn't wait at all before retrying.""" def __init__(self) -> None: super().__init__(0) class wait_random(wait_base): """Wait strategy that waits a random amount of time between min/max.""" def __init__(self, min: typing.Union[int, float] = 0, max: typing.Union[int, float] = 1) -> None: # noqa self.wait_random_min = min self.wait_random_max = max def __call__(self, retry_state: "RetryCallState") -> float: return self.wait_random_min + (random.random() * (self.wait_random_max - self.wait_random_min)) class wait_combine(wait_base): """Combine several waiting strategies.""" def __init__(self, *strategies: wait_base) -> None: self.wait_funcs = strategies def __call__(self, retry_state: "RetryCallState") -> float: return sum(x(retry_state=retry_state) for x in self.wait_funcs) class wait_chain(wait_base): """Chain two or more waiting strategies. If all strategies are exhausted, the very last strategy is used thereafter. For example:: @retry(wait=wait_chain(*[wait_fixed(1) for i in range(3)] + [wait_fixed(2) for j in range(5)] + [wait_fixed(5) for k in range(4))) def wait_chained(): print("Wait 1s for 3 attempts, 2s for 5 attempts and 5s thereafter.") """ def __init__(self, *strategies: wait_base) -> None: self.strategies = strategies def __call__(self, retry_state: "RetryCallState") -> float: wait_func_no = min(max(retry_state.attempt_number, 1), len(self.strategies)) wait_func = self.strategies[wait_func_no - 1] return wait_func(retry_state=retry_state) class wait_incrementing(wait_base): """Wait an incremental amount of time after each attempt. Starting at a starting value and incrementing by a value for each attempt (and restricting the upper limit to some maximum value). """ def __init__( self, start: typing.Union[int, float] = 0, increment: typing.Union[int, float] = 100, max: typing.Union[int, float] = _utils.MAX_WAIT, # noqa ) -> None: self.start = start self.increment = increment self.max = max def __call__(self, retry_state: "RetryCallState") -> float: result = self.start + (self.increment * (retry_state.attempt_number - 1)) return max(0, min(result, self.max)) class wait_exponential(wait_base): """Wait strategy that applies exponential backoff. It allows for a customized multiplier and an ability to restrict the upper and lower limits to some maximum and minimum value. The intervals are fixed (i.e. there is no jitter), so this strategy is suitable for balancing retries against latency when a required resource is unavailable for an unknown duration, but *not* suitable for resolving contention between multiple processes for a shared resource. Use wait_random_exponential for the latter case. """ def __init__( self, multiplier: typing.Union[int, float] = 1, max: typing.Union[int, float] = _utils.MAX_WAIT, # noqa exp_base: typing.Union[int, float] = 2, min: typing.Union[int, float] = 0, # noqa ) -> None: self.multiplier = multiplier self.min = min self.max = max self.exp_base = exp_base def __call__(self, retry_state: "RetryCallState") -> float: try: exp = self.exp_base ** (retry_state.attempt_number - 1) result = self.multiplier * exp except OverflowError: return self.max return max(max(0, self.min), min(result, self.max)) class wait_random_exponential(wait_exponential): """Random wait with exponentially widening window. An exponential backoff strategy used to mediate contention between multiple uncoordinated processes for a shared resource in distributed systems. This is the sense in which "exponential backoff" is meant in e.g. Ethernet networking, and corresponds to the "Full Jitter" algorithm described in this blog post: https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ Each retry occurs at a random time in a geometrically expanding interval. It allows for a custom multiplier and an ability to restrict the upper limit of the random interval to some maximum value. Example:: wait_random_exponential(multiplier=0.5, # initial window 0.5s max=60) # max 60s timeout When waiting for an unavailable resource to become available again, as opposed to trying to resolve contention for a shared resource, the wait_exponential strategy (which uses a fixed interval) may be preferable. """ def __call__(self, retry_state: "RetryCallState") -> float: high = super().__call__(retry_state=retry_state) return random.uniform(0, high) PKH]Մ# Jpython3.10/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-310.pycnu[o aiy @sddlmZmZmZmZmZmZddlZddlmZm Z m Z m Z er.ddlm Z ddl mZdZedZedZed Zed ZeeZed ed d Zddde eeffddZdddefddZddddde fddZdS))datedatetimetime timedeltatimezonetzinfoN) TYPE_CHECKINGAnyOptionalUnion)Match) ParseFloatz7([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?z[0-9A-Fa-f](?:_?[0-9A-Fa-f])*z[01](?:_?[01])*z[0-7](?:_?[0-7])*zS[+-]?(?:0|[1-9](?:_?[0-9])*)(?:\.[0-9](?:_?[0-9])*)?(?:[eE][+-]?[0-9](?:_?[0-9])*)?z>([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[01])(?:[T ]z.(?:(Z)|([+-])([01][0-9]|2[0-3]):([0-5][0-9]))?z)?matchr returnc Cs|\ }}}}}}}}} } } t|t|t|} } }|dur't| | |St|t|t|}}}|rGt|ddddddnd}| rd| dkrQdnd}tt|t| |t| d}n|rjtj}nd}t| | ||||||d S) zConvert a `RE_DATETIME` match to `datetime.datetime` or `datetime.date`. Raises ValueError if the match does not correspond to a valid date or datetime. N0r+)hoursminutes)r)groupsintrljustrrutcr)ryear_str month_strday_strhour_str minute_strsec_str micros_str zulu_timeoffset_dir_stroffset_hour_stroffset_minute_stryearmonthdayhourminutesecmicros offset_dirtzr//builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tomli/_re.pymatch_to_datetime"s< (  r1cCsR|\}}}}|rt|ddddddnd}tt|t|t||S)Nrrrr)rrrr)rrrr r!r,r/r/r0match_to_localtimeIs(r2 parse_floatr cCs0|}d|vsd|vsd|vr||St|S)N.eE)groupr)rr3 match_strr/r/r0match_to_numberOsr9)rrrrrrretypingrr r r r pip._vendor.tomli._parserr _TIME_RE_STRcompileRE_HEXRE_BINRE_OCT RE_NUMBER RE_LOCALTIME RE_DATETIMEr1r2r9r/r/r/r0s4        'PKH]T7Opython3.10/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-310.pycnu[o ai@s$dZdZdZddlmZmZmZdS)zA lil' TOML parser.)loadsloadTOMLDecodeErrorz1.0.3)rrrN)__doc____all__ __version__pip._vendor.tomli._parserrrrr r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tomli/__init__.pysPKH]z??Npython3.10/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-310.pycnu[o aiW @sxddlZddlmZddlmZmZmZmZmZm Z m Z m Z m Z ddl mZmZmZmZmZmZmZmZmZer>ddlmZeddedDeed BZeed Zeed ZeZeed Z eZ!ed Z"e"edBZ#eej$ej%dZ&e&edBZ'edd ddddddZ(ee)gefZ*e e)dfZ+e,Z-Gddde.Z/e0dde de*dee)effddZ1e0dd e)de*dee)effd!d"Z2Gd#d$d$Z3Gd%d&d&Z4Gd'd(d(Z5d)e)d*e-d+e e)de-fd,d-Z6d)e)d*e-d.e)d/ee)d0e7de-f d1d2Z8d)e)d*e-de-fd3d4Z9d)e)d*e-de-fd5d6Z:d)e)d*e-d7e3de-fd8d9Z;d)e)d*e-d7e3de-fd:d;Zd?Z>d)e)d*e-de e-e+ffd@dAZ?d)e)d*e-de e-e)ffdBdCZ@d)e)d*e-de e-e)ffdDdEZAd)e)d*e-de*de e-eBffdFdGZCd)e)d*e-de*de e-eDffdHdIZEdJdKd)e)d*e-dLe7de e-e)ffdMdNZFd)e)d*e-de e-e)ffdOdPZGd)e)d*e-dQe,de e-e)ffdRdSZHd)e)d*e-de e-e)ffdTdUZId)e)d*e-dVe7de e-e)ffdWdXZJd)e)d*e-dLe7de e-e)ffdYdZZKd)e)d*e-d[d\de e-e)ffd]d^ZLd)e)d*e-de*de e-effd_d`ZMd)e)d*e-dae)de/fdbdcZNdde,de7fdedfZOdS)gN)MappingProxyType) TYPE_CHECKINGAnyCallableDict FrozenSetIterableOptionalTextIOTuple) RE_BIN RE_DATETIMERE_HEX RE_LOCALTIME RE_NUMBERRE_OCTmatch_to_datetimematch_to_localtimematch_to_number)Patternccs|]}t|VqdSN)chr).0ir/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/tomli/_parser.py sr  z z z  z-_z"'  "\)z\bz\tz\nz\fz\rz\"z\\.c@seZdZdZdS)TOMLDecodeErrorz0An error raised if a document is not valid TOML.N)__name__ __module__ __qualname____doc__rrrrr&Bsr& parse_floatfpr,returncCs|}t||dS)zParse TOML from a file object.r+)readloads)r-r,srrrloadFs r2r1cCsB|dd}d}t} t||t}z||}Wn ty$Y|j j Sw|dkr.|d7}q |tvr@t||||}t||t}n:|dkrpz||d}Wn tyWd}Ynw|dkrct|||}nt|||}t||t}n |dkrzt ||d t ||}z||}Wn tyY|j j Sw|dkrt ||d |d7}q ) zParse TOML from a string.z r rT[N#zInvalid statementz5Expected newline or end of document after a statement) replaceState skip_charsTOML_WS IndexErrorKEY_INITIAL_CHARSkey_value_rulecreate_list_rulecreate_dict_rule suffixed_err skip_commentoutdict)r1r,srcposstatechar second_charrrrr0LsT    "      r0c@seZdZdddZdS)r7r.NcCst|_t|_d|_dS)Nr) NestedDictrAFlagsflagsheader_namespaceselfrrr__init__s zState.__init__r.N)r'r(r)rNrrrrr7sr7c@s~eZdZdZdZdZdddZdeddfd d Zd ed ed e ddfddZ ded e de ddfddZ ded e de fddZ dS)rIz)Flags that map to parsed keys/namespaces.rr3r.NcC i|_dSr_flagsrLrrrrNs zFlags.__init__keycCsF|j}|ddD]}||vrdS||d}q ||dddS)Nnested)rRpop)rMrScontkrrr unset_alls zFlags.unset_allhead_keyrel_keyflagcCs|j}|D]}||vrttid||<||d}q|D] }||vr.||d|n |htid||<||d}qdS)NrJrecursive_flagsrUrUrJrRsetadd)rMrZr[r\rWrXrrrset_for_relative_keyszFlags.set_for_relative_key recursivecCs|j}|dd|d}}|D]}||vr ttid||<||d}q||vr5ttid||<|||r*s     r>cCs|d7}t||t}t||\}}|j|tjr"t||d||j||jj |tj ddz|j |Wn t yGt||dw||_|||d}|dkrat||d|d|dS) N#Can not mutate immutable namespace Frrz]]zFound "z3" at the end of an array declaration. Expected "]]")r8r9rrJrgrIrhr?rYr`rirArvrqrK)rCrDrErS end_markerrrrr==s*     r=c Cst|||\}}}|dd|d}}|j|}|j|tjr*t||d||j|j|tjz|j |} Wn t yIt||dw|| vrTt||dt |t tfrj|j|} |jj| tjdd|| |<|S)NrTrrTr)parse_key_value_pairrKrJrgrIrhr?rbrirArrrqrorBrpr`) rCrDrEr,rSvaluerdreabs_key_parentnestabs_keyrrrr<Ys(      r<cCstt||\}}z||}Wn tyd}Ynw|dkr#t||d|d7}t||t}t|||\}}|||fS)N=z,Expected "=" after a key in a key/value pairr3)rr:r?r8r9 parse_value)rCrDr,rSrFrrrrrrs     rcCst||\}}|g}t||t} z||}Wn ty"d}Ynw|dkr-|t|fS|d7}t||t}t||\}}||t||t}q)NT.r3)parse_key_partr8r9r:tuplers)rCrDkey_partrSrFrrrrs"       rcCs|z||}Wn tyd}Ynw|tvr&|}t||t}||||fS|dkr/t||S|dkr8t||St||d)N'r$z(Invalid initial character for a key part)r:BARE_KEY_CHARSr8parse_literal_strparse_one_line_basic_strr?)rCrDrF start_posrrrrs      rcCs|d7}t||ddS)Nr3F multiline)parse_basic_strrCrDrrrrsrcCs|d7}g}t||}|||ddkr|d|fS t|||\}}||t||}|||d}|dkr@|d|fS|dkrJt||d|d7}t||}|||ddkrc|d|fSq)Nr3rT,zUnclosed array)rrrsr?)rCrDr,arrayvalcrrr parse_arrays&        rc CsZ|d7}t}t}t||t}|||ddkr!|d|jfS t|||\}}}|dd|d}}||tjrFt||d|z |j |dd} Wn t y\t||dw|| vrkt||d |d || |<t||t}|||d} | dkr|d|jfS| d krt||d t |tt fr|j |tjdd |d7}t||t}q")Nr3}TrTrFrmrzDuplicate inline table key "r$rzUnclosed inline tabler)rHrIr8r9rBrrgrhr?rrrqrorpr`) rCrDr, nested_dictrJrSrrdrerrrrrparse_inline_tables<      rFrrcCs|||d}|d7}|rB|dvrB|dkr8t||t}|||d}|s*|dfS|dkr4t||d|d7}t||t}|dfS|dkrLt||d S|d krVt||d Sz|t|fWStyvt|dkrpt||d t||dw) Nr>z\ z\ \ rr3r zUnescaped "\" in a stringz\uz\UUnterminated string)r8r9r?rparse_hex_charBASIC_STR_ESCAPE_REPLACEMENTSrqr})rCrDr escape_idrFrrrparse_basic_str_escapes0          rcCst||ddS)NTr)rrrrr parse_basic_str_escape_multilinesrhex_lencCsl||||}t||kstdd|Drt||d||7}t|d}t|s0t||d|t|fS)Ncss|]}|tjvVqdSr)string hexdigits)rrrrrrsz!parse_hex_char..zInvalid hex valuez/Escaped character is not a Unicode scalar value)r}anyr?rkis_unicode_scalar_valuer)rCrDrhex_strhex_intrrrrs    rcCs2|d7}|}t||dtdd}|d|||fS)Nr3rTr)rILLEGAL_LITERAL_STR_CHARS)rCrDrrrrrs  rliteralcCs|d7}|||ddkr|d7}|r*d}t||dtdd}|||}|d}n d}t||dd \}}|||d|krC||fS|d7}|||d|krW|||fS|d7}|||d fS) Nr3r rz'''Trr$rr)r#ILLEGAL_MULTILINE_LITERAL_STR_CHARSr)rCrDrdelimend_posresultrrrparse_multiline_strs.   rc Cs|rt}t}nt}t}d}|} z||}Wn ty#t||dw|dkrS|s6|d||||fS||d|ddkrN|d||||fS|d7}q|dkrm||||7}|||\}}||7}|}q||vr{t||d |d|d7}q) NrTrr$r3r""r%zIllegal character ")!ILLEGAL_MULTILINE_BASIC_STR_CHARSrILLEGAL_BASIC_STR_CHARSrr:r?) rCrDrry parse_escapesrrrF parsed_escaperrrr6s<   rregexrcCs,|||}|st||d||fS)NzUnexpected sequence)matchr?endgroup)rCrDrrrrr parse_regexVs  rcCsz||}Wn tyd}Ynw|dkr.||d|ddkr)t||ddSt||S|dkrJ||d|ddkrEt||d dSt||S|d kr`||d|d d kr`|d d fS|d krv||d|ddkrv|ddfSt||}|rzt|}Wn tyt||dw| |fSt ||}|r| t |fS|dkr||d|d}|dkrt ||dt \}}|t|dfS|dkrt ||dt\}} |t| dfS|dkrt ||dt\}} |t| dfSt||} | r| t| |fS|dkrt|||S|dkrt|||S|||d} | dvr2|d|| fS|||d } | dvrG|d || fSt||d)Nr$r3rrF)rrz''TtrruefalsezInvalid date or datetime0rxrorbr4{>naninf>z-infz+infz-nanz+nanz Invalid value)r:rrrr rrr|r?rrrrrrkrr rrrr)rCrDr,rFdatetime_match datetime_objlocaltime_matchrGroct_strbin_str number_match first_three first_fourrrrr]sn                    rmsgcCs0dtdtdtfdd}t|d|||dS)zZReturn a `TOMLDecodeError` where error message is suffixed with coordinates in source.rCrDr.cSsV|t|krdS|dd|d}|dkr|d}n ||dd|}d|d|S)Nzend of documentr rr3zline z , column )r}countrindex)rCrDlinecolumnrrr coord_reprs  z suffixed_err..coord_reprz (at ))strPosr&)rCrDrrrrrr?s r? codepointcCs0d|ko dknpd|kodkSS)Nriiir)rrrrrs0r)Prtypesrtypingrrrrrrr r r pip._vendor.tomli._rer r rrrrrrrrer frozensetranger ASCII_CTRLrrrrrr9r ascii_lettersdigitsrr;rr ParseFloatrjrkrr|r&floatr2r0r7rIrHr8rlrr@rr>r=r<rrrrrprrBrrrrrrrrrr?rrrrrs ,,  "      $$? >"      ""!  " " ""   PPKH]WW5python3.10/site-packages/pip/_vendor/tomli/_parser.pynu[import string from types import MappingProxyType from typing import ( TYPE_CHECKING, Any, Callable, Dict, FrozenSet, Iterable, Optional, TextIO, Tuple, ) from pip._vendor.tomli._re import ( RE_BIN, RE_DATETIME, RE_HEX, RE_LOCALTIME, RE_NUMBER, RE_OCT, match_to_datetime, match_to_localtime, match_to_number, ) if TYPE_CHECKING: from re import Pattern ASCII_CTRL = frozenset(chr(i) for i in range(32)) | frozenset(chr(127)) # Neither of these sets include quotation mark or backslash. They are # currently handled as separate cases in the parser functions. ILLEGAL_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t") ILLEGAL_MULTILINE_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t\n\r") ILLEGAL_LITERAL_STR_CHARS = ILLEGAL_BASIC_STR_CHARS ILLEGAL_MULTILINE_LITERAL_STR_CHARS = ASCII_CTRL - frozenset("\t\n") ILLEGAL_COMMENT_CHARS = ILLEGAL_BASIC_STR_CHARS TOML_WS = frozenset(" \t") TOML_WS_AND_NEWLINE = TOML_WS | frozenset("\n") BARE_KEY_CHARS = frozenset(string.ascii_letters + string.digits + "-_") KEY_INITIAL_CHARS = BARE_KEY_CHARS | frozenset("\"'") BASIC_STR_ESCAPE_REPLACEMENTS = MappingProxyType( { "\\b": "\u0008", # backspace "\\t": "\u0009", # tab "\\n": "\u000A", # linefeed "\\f": "\u000C", # form feed "\\r": "\u000D", # carriage return '\\"': "\u0022", # quote "\\\\": "\u005C", # backslash } ) # Type annotations ParseFloat = Callable[[str], Any] Key = Tuple[str, ...] Pos = int class TOMLDecodeError(ValueError): """An error raised if a document is not valid TOML.""" def load(fp: TextIO, *, parse_float: ParseFloat = float) -> Dict[str, Any]: """Parse TOML from a file object.""" s = fp.read() return loads(s, parse_float=parse_float) def loads(s: str, *, parse_float: ParseFloat = float) -> Dict[str, Any]: # noqa: C901 """Parse TOML from a string.""" # The spec allows converting "\r\n" to "\n", even in string # literals. Let's do so to simplify parsing. src = s.replace("\r\n", "\n") pos = 0 state = State() # Parse one statement at a time # (typically means one line in TOML source) while True: # 1. Skip line leading whitespace pos = skip_chars(src, pos, TOML_WS) # 2. Parse rules. Expect one of the following: # - end of file # - end of line # - comment # - key/value pair # - append dict to list (and move to its namespace) # - create dict (and move to its namespace) # Skip trailing whitespace when applicable. try: char = src[pos] except IndexError: break if char == "\n": pos += 1 continue if char in KEY_INITIAL_CHARS: pos = key_value_rule(src, pos, state, parse_float) pos = skip_chars(src, pos, TOML_WS) elif char == "[": try: second_char: Optional[str] = src[pos + 1] except IndexError: second_char = None if second_char == "[": pos = create_list_rule(src, pos, state) else: pos = create_dict_rule(src, pos, state) pos = skip_chars(src, pos, TOML_WS) elif char != "#": raise suffixed_err(src, pos, "Invalid statement") # 3. Skip comment pos = skip_comment(src, pos) # 4. Expect end of line or end of file try: char = src[pos] except IndexError: break if char != "\n": raise suffixed_err( src, pos, "Expected newline or end of document after a statement" ) pos += 1 return state.out.dict class State: def __init__(self) -> None: # Mutable, read-only self.out = NestedDict() self.flags = Flags() # Immutable, read and write self.header_namespace: Key = () class Flags: """Flags that map to parsed keys/namespaces.""" # Marks an immutable namespace (inline array or inline table). FROZEN = 0 # Marks a nest that has been explicitly created and can no longer # be opened using the "[table]" syntax. EXPLICIT_NEST = 1 def __init__(self) -> None: self._flags: Dict[str, dict] = {} def unset_all(self, key: Key) -> None: cont = self._flags for k in key[:-1]: if k not in cont: return cont = cont[k]["nested"] cont.pop(key[-1], None) def set_for_relative_key(self, head_key: Key, rel_key: Key, flag: int) -> None: cont = self._flags for k in head_key: if k not in cont: cont[k] = {"flags": set(), "recursive_flags": set(), "nested": {}} cont = cont[k]["nested"] for k in rel_key: if k in cont: cont[k]["flags"].add(flag) else: cont[k] = {"flags": {flag}, "recursive_flags": set(), "nested": {}} cont = cont[k]["nested"] def set(self, key: Key, flag: int, *, recursive: bool) -> None: # noqa: A003 cont = self._flags key_parent, key_stem = key[:-1], key[-1] for k in key_parent: if k not in cont: cont[k] = {"flags": set(), "recursive_flags": set(), "nested": {}} cont = cont[k]["nested"] if key_stem not in cont: cont[key_stem] = {"flags": set(), "recursive_flags": set(), "nested": {}} cont[key_stem]["recursive_flags" if recursive else "flags"].add(flag) def is_(self, key: Key, flag: int) -> bool: if not key: return False # document root has no flags cont = self._flags for k in key[:-1]: if k not in cont: return False inner_cont = cont[k] if flag in inner_cont["recursive_flags"]: return True cont = inner_cont["nested"] key_stem = key[-1] if key_stem in cont: cont = cont[key_stem] return flag in cont["flags"] or flag in cont["recursive_flags"] return False class NestedDict: def __init__(self) -> None: # The parsed content of the TOML document self.dict: Dict[str, Any] = {} def get_or_create_nest( self, key: Key, *, access_lists: bool = True, ) -> dict: cont: Any = self.dict for k in key: if k not in cont: cont[k] = {} cont = cont[k] if access_lists and isinstance(cont, list): cont = cont[-1] if not isinstance(cont, dict): raise KeyError("There is no nest behind this key") return cont def append_nest_to_list(self, key: Key) -> None: cont = self.get_or_create_nest(key[:-1]) last_key = key[-1] if last_key in cont: list_ = cont[last_key] if not isinstance(list_, list): raise KeyError("An object other than list found behind this key") list_.append({}) else: cont[last_key] = [{}] def skip_chars(src: str, pos: Pos, chars: Iterable[str]) -> Pos: try: while src[pos] in chars: pos += 1 except IndexError: pass return pos def skip_until( src: str, pos: Pos, expect: str, *, error_on: FrozenSet[str], error_on_eof: bool, ) -> Pos: try: new_pos = src.index(expect, pos) except ValueError: new_pos = len(src) if error_on_eof: raise suffixed_err(src, new_pos, f'Expected "{expect!r}"') bad_chars = error_on.intersection(src[pos:new_pos]) if bad_chars: bad_char = next(iter(bad_chars)) bad_pos = src.index(bad_char, pos) raise suffixed_err(src, bad_pos, f'Found invalid character "{bad_char!r}"') return new_pos def skip_comment(src: str, pos: Pos) -> Pos: try: char: Optional[str] = src[pos] except IndexError: char = None if char == "#": return skip_until( src, pos + 1, "\n", error_on=ILLEGAL_COMMENT_CHARS, error_on_eof=False ) return pos def skip_comments_and_array_ws(src: str, pos: Pos) -> Pos: while True: pos_before_skip = pos pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE) pos = skip_comment(src, pos) if pos == pos_before_skip: return pos def create_dict_rule(src: str, pos: Pos, state: State) -> Pos: pos += 1 # Skip "[" pos = skip_chars(src, pos, TOML_WS) pos, key = parse_key(src, pos) if state.flags.is_(key, Flags.EXPLICIT_NEST) or state.flags.is_(key, Flags.FROZEN): raise suffixed_err(src, pos, f"Can not declare {key} twice") state.flags.set(key, Flags.EXPLICIT_NEST, recursive=False) try: state.out.get_or_create_nest(key) except KeyError: raise suffixed_err(src, pos, "Can not overwrite a value") state.header_namespace = key if src[pos : pos + 1] != "]": raise suffixed_err(src, pos, 'Expected "]" at the end of a table declaration') return pos + 1 def create_list_rule(src: str, pos: Pos, state: State) -> Pos: pos += 2 # Skip "[[" pos = skip_chars(src, pos, TOML_WS) pos, key = parse_key(src, pos) if state.flags.is_(key, Flags.FROZEN): raise suffixed_err(src, pos, f"Can not mutate immutable namespace {key}") # Free the namespace now that it points to another empty list item... state.flags.unset_all(key) # ...but this key precisely is still prohibited from table declaration state.flags.set(key, Flags.EXPLICIT_NEST, recursive=False) try: state.out.append_nest_to_list(key) except KeyError: raise suffixed_err(src, pos, "Can not overwrite a value") state.header_namespace = key end_marker = src[pos : pos + 2] if end_marker != "]]": raise suffixed_err( src, pos, f'Found "{end_marker!r}" at the end of an array declaration.' ' Expected "]]"', ) return pos + 2 def key_value_rule(src: str, pos: Pos, state: State, parse_float: ParseFloat) -> Pos: pos, key, value = parse_key_value_pair(src, pos, parse_float) key_parent, key_stem = key[:-1], key[-1] abs_key_parent = state.header_namespace + key_parent if state.flags.is_(abs_key_parent, Flags.FROZEN): raise suffixed_err( src, pos, f"Can not mutate immutable namespace {abs_key_parent}" ) # Containers in the relative path can't be opened with the table syntax after this state.flags.set_for_relative_key(state.header_namespace, key, Flags.EXPLICIT_NEST) try: nest = state.out.get_or_create_nest(abs_key_parent) except KeyError: raise suffixed_err(src, pos, "Can not overwrite a value") if key_stem in nest: raise suffixed_err(src, pos, "Can not overwrite a value") # Mark inline table and array namespaces recursively immutable if isinstance(value, (dict, list)): abs_key = state.header_namespace + key state.flags.set(abs_key, Flags.FROZEN, recursive=True) nest[key_stem] = value return pos def parse_key_value_pair( src: str, pos: Pos, parse_float: ParseFloat ) -> Tuple[Pos, Key, Any]: pos, key = parse_key(src, pos) try: char: Optional[str] = src[pos] except IndexError: char = None if char != "=": raise suffixed_err(src, pos, 'Expected "=" after a key in a key/value pair') pos += 1 pos = skip_chars(src, pos, TOML_WS) pos, value = parse_value(src, pos, parse_float) return pos, key, value def parse_key(src: str, pos: Pos) -> Tuple[Pos, Key]: pos, key_part = parse_key_part(src, pos) key = [key_part] pos = skip_chars(src, pos, TOML_WS) while True: try: char: Optional[str] = src[pos] except IndexError: char = None if char != ".": return pos, tuple(key) pos += 1 pos = skip_chars(src, pos, TOML_WS) pos, key_part = parse_key_part(src, pos) key.append(key_part) pos = skip_chars(src, pos, TOML_WS) def parse_key_part(src: str, pos: Pos) -> Tuple[Pos, str]: try: char: Optional[str] = src[pos] except IndexError: char = None if char in BARE_KEY_CHARS: start_pos = pos pos = skip_chars(src, pos, BARE_KEY_CHARS) return pos, src[start_pos:pos] if char == "'": return parse_literal_str(src, pos) if char == '"': return parse_one_line_basic_str(src, pos) raise suffixed_err(src, pos, "Invalid initial character for a key part") def parse_one_line_basic_str(src: str, pos: Pos) -> Tuple[Pos, str]: pos += 1 return parse_basic_str(src, pos, multiline=False) def parse_array(src: str, pos: Pos, parse_float: ParseFloat) -> Tuple[Pos, list]: pos += 1 array: list = [] pos = skip_comments_and_array_ws(src, pos) if src[pos : pos + 1] == "]": return pos + 1, array while True: pos, val = parse_value(src, pos, parse_float) array.append(val) pos = skip_comments_and_array_ws(src, pos) c = src[pos : pos + 1] if c == "]": return pos + 1, array if c != ",": raise suffixed_err(src, pos, "Unclosed array") pos += 1 pos = skip_comments_and_array_ws(src, pos) if src[pos : pos + 1] == "]": return pos + 1, array def parse_inline_table(src: str, pos: Pos, parse_float: ParseFloat) -> Tuple[Pos, dict]: pos += 1 nested_dict = NestedDict() flags = Flags() pos = skip_chars(src, pos, TOML_WS) if src[pos : pos + 1] == "}": return pos + 1, nested_dict.dict while True: pos, key, value = parse_key_value_pair(src, pos, parse_float) key_parent, key_stem = key[:-1], key[-1] if flags.is_(key, Flags.FROZEN): raise suffixed_err(src, pos, f"Can not mutate immutable namespace {key}") try: nest = nested_dict.get_or_create_nest(key_parent, access_lists=False) except KeyError: raise suffixed_err(src, pos, "Can not overwrite a value") if key_stem in nest: raise suffixed_err(src, pos, f'Duplicate inline table key "{key_stem}"') nest[key_stem] = value pos = skip_chars(src, pos, TOML_WS) c = src[pos : pos + 1] if c == "}": return pos + 1, nested_dict.dict if c != ",": raise suffixed_err(src, pos, "Unclosed inline table") if isinstance(value, (dict, list)): flags.set(key, Flags.FROZEN, recursive=True) pos += 1 pos = skip_chars(src, pos, TOML_WS) def parse_basic_str_escape( src: str, pos: Pos, *, multiline: bool = False ) -> Tuple[Pos, str]: escape_id = src[pos : pos + 2] pos += 2 if multiline and escape_id in {"\\ ", "\\\t", "\\\n"}: # Skip whitespace until next non-whitespace character or end of # the doc. Error if non-whitespace is found before newline. if escape_id != "\\\n": pos = skip_chars(src, pos, TOML_WS) char = src[pos : pos + 1] if not char: return pos, "" if char != "\n": raise suffixed_err(src, pos, 'Unescaped "\\" in a string') pos += 1 pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE) return pos, "" if escape_id == "\\u": return parse_hex_char(src, pos, 4) if escape_id == "\\U": return parse_hex_char(src, pos, 8) try: return pos, BASIC_STR_ESCAPE_REPLACEMENTS[escape_id] except KeyError: if len(escape_id) != 2: raise suffixed_err(src, pos, "Unterminated string") raise suffixed_err(src, pos, 'Unescaped "\\" in a string') def parse_basic_str_escape_multiline(src: str, pos: Pos) -> Tuple[Pos, str]: return parse_basic_str_escape(src, pos, multiline=True) def parse_hex_char(src: str, pos: Pos, hex_len: int) -> Tuple[Pos, str]: hex_str = src[pos : pos + hex_len] if len(hex_str) != hex_len or any(c not in string.hexdigits for c in hex_str): raise suffixed_err(src, pos, "Invalid hex value") pos += hex_len hex_int = int(hex_str, 16) if not is_unicode_scalar_value(hex_int): raise suffixed_err(src, pos, "Escaped character is not a Unicode scalar value") return pos, chr(hex_int) def parse_literal_str(src: str, pos: Pos) -> Tuple[Pos, str]: pos += 1 # Skip starting apostrophe start_pos = pos pos = skip_until( src, pos, "'", error_on=ILLEGAL_LITERAL_STR_CHARS, error_on_eof=True ) return pos + 1, src[start_pos:pos] # Skip ending apostrophe def parse_multiline_str(src: str, pos: Pos, *, literal: bool) -> Tuple[Pos, str]: pos += 3 if src[pos : pos + 1] == "\n": pos += 1 if literal: delim = "'" end_pos = skip_until( src, pos, "'''", error_on=ILLEGAL_MULTILINE_LITERAL_STR_CHARS, error_on_eof=True, ) result = src[pos:end_pos] pos = end_pos + 3 else: delim = '"' pos, result = parse_basic_str(src, pos, multiline=True) # Add at maximum two extra apostrophes/quotes if the end sequence # is 4 or 5 chars long instead of just 3. if src[pos : pos + 1] != delim: return pos, result pos += 1 if src[pos : pos + 1] != delim: return pos, result + delim pos += 1 return pos, result + (delim * 2) def parse_basic_str(src: str, pos: Pos, *, multiline: bool) -> Tuple[Pos, str]: if multiline: error_on = ILLEGAL_MULTILINE_BASIC_STR_CHARS parse_escapes = parse_basic_str_escape_multiline else: error_on = ILLEGAL_BASIC_STR_CHARS parse_escapes = parse_basic_str_escape result = "" start_pos = pos while True: try: char = src[pos] except IndexError: raise suffixed_err(src, pos, "Unterminated string") if char == '"': if not multiline: return pos + 1, result + src[start_pos:pos] if src[pos + 1 : pos + 3] == '""': return pos + 3, result + src[start_pos:pos] pos += 1 continue if char == "\\": result += src[start_pos:pos] pos, parsed_escape = parse_escapes(src, pos) result += parsed_escape start_pos = pos continue if char in error_on: raise suffixed_err(src, pos, f'Illegal character "{char!r}"') pos += 1 def parse_regex(src: str, pos: Pos, regex: "Pattern") -> Tuple[Pos, str]: match = regex.match(src, pos) if not match: raise suffixed_err(src, pos, "Unexpected sequence") return match.end(), match.group() def parse_value( # noqa: C901 src: str, pos: Pos, parse_float: ParseFloat ) -> Tuple[Pos, Any]: try: char: Optional[str] = src[pos] except IndexError: char = None # Basic strings if char == '"': if src[pos + 1 : pos + 3] == '""': return parse_multiline_str(src, pos, literal=False) return parse_one_line_basic_str(src, pos) # Literal strings if char == "'": if src[pos + 1 : pos + 3] == "''": return parse_multiline_str(src, pos, literal=True) return parse_literal_str(src, pos) # Booleans if char == "t": if src[pos + 1 : pos + 4] == "rue": return pos + 4, True if char == "f": if src[pos + 1 : pos + 5] == "alse": return pos + 5, False # Dates and times datetime_match = RE_DATETIME.match(src, pos) if datetime_match: try: datetime_obj = match_to_datetime(datetime_match) except ValueError: raise suffixed_err(src, pos, "Invalid date or datetime") return datetime_match.end(), datetime_obj localtime_match = RE_LOCALTIME.match(src, pos) if localtime_match: return localtime_match.end(), match_to_localtime(localtime_match) # Non-decimal integers if char == "0": second_char = src[pos + 1 : pos + 2] if second_char == "x": pos, hex_str = parse_regex(src, pos + 2, RE_HEX) return pos, int(hex_str, 16) if second_char == "o": pos, oct_str = parse_regex(src, pos + 2, RE_OCT) return pos, int(oct_str, 8) if second_char == "b": pos, bin_str = parse_regex(src, pos + 2, RE_BIN) return pos, int(bin_str, 2) # Decimal integers and "normal" floats. # The regex will greedily match any type starting with a decimal # char, so needs to be located after handling of non-decimal ints, # and dates and times. number_match = RE_NUMBER.match(src, pos) if number_match: return number_match.end(), match_to_number(number_match, parse_float) # Arrays if char == "[": return parse_array(src, pos, parse_float) # Inline tables if char == "{": return parse_inline_table(src, pos, parse_float) # Special floats first_three = src[pos : pos + 3] if first_three in {"inf", "nan"}: return pos + 3, parse_float(first_three) first_four = src[pos : pos + 4] if first_four in {"-inf", "+inf", "-nan", "+nan"}: return pos + 4, parse_float(first_four) raise suffixed_err(src, pos, "Invalid value") def suffixed_err(src: str, pos: Pos, msg: str) -> TOMLDecodeError: """Return a `TOMLDecodeError` where error message is suffixed with coordinates in source.""" def coord_repr(src: str, pos: Pos) -> str: if pos >= len(src): return "end of document" line = src.count("\n", 0, pos) + 1 if line == 1: column = pos + 1 else: column = pos - src.rindex("\n", 0, pos) return f"line {line}, column {column}" return TOMLDecodeError(f"{msg} (at {coord_repr(src, pos)})") def is_unicode_scalar_value(codepoint: int) -> bool: return (0 <= codepoint <= 55295) or (57344 <= codepoint <= 1114111) PKH]1y y 1python3.10/site-packages/pip/_vendor/tomli/_re.pynu[from datetime import date, datetime, time, timedelta, timezone, tzinfo import re from typing import TYPE_CHECKING, Any, Optional, Union if TYPE_CHECKING: from re import Match from pip._vendor.tomli._parser import ParseFloat # E.g. # - 00:32:00.999999 # - 00:32:00 _TIME_RE_STR = r"([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?" RE_HEX = re.compile(r"[0-9A-Fa-f](?:_?[0-9A-Fa-f])*") RE_BIN = re.compile(r"[01](?:_?[01])*") RE_OCT = re.compile(r"[0-7](?:_?[0-7])*") RE_NUMBER = re.compile( r"[+-]?(?:0|[1-9](?:_?[0-9])*)" # integer + r"(?:\.[0-9](?:_?[0-9])*)?" # optional fractional part + r"(?:[eE][+-]?[0-9](?:_?[0-9])*)?" # optional exponent part ) RE_LOCALTIME = re.compile(_TIME_RE_STR) RE_DATETIME = re.compile( r"([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[01])" # date, e.g. 1988-10-27 + r"(?:" + r"[T ]" + _TIME_RE_STR + r"(?:(Z)|([+-])([01][0-9]|2[0-3]):([0-5][0-9]))?" # time offset + r")?" ) def match_to_datetime(match: "Match") -> Union[datetime, date]: """Convert a `RE_DATETIME` match to `datetime.datetime` or `datetime.date`. Raises ValueError if the match does not correspond to a valid date or datetime. """ ( year_str, month_str, day_str, hour_str, minute_str, sec_str, micros_str, zulu_time, offset_dir_str, offset_hour_str, offset_minute_str, ) = match.groups() year, month, day = int(year_str), int(month_str), int(day_str) if hour_str is None: return date(year, month, day) hour, minute, sec = int(hour_str), int(minute_str), int(sec_str) micros = int(micros_str[1:].ljust(6, "0")[:6]) if micros_str else 0 if offset_dir_str: offset_dir = 1 if offset_dir_str == "+" else -1 tz: Optional[tzinfo] = timezone( timedelta( hours=offset_dir * int(offset_hour_str), minutes=offset_dir * int(offset_minute_str), ) ) elif zulu_time: tz = timezone.utc else: # local date-time tz = None return datetime(year, month, day, hour, minute, sec, micros, tzinfo=tz) def match_to_localtime(match: "Match") -> time: hour_str, minute_str, sec_str, micros_str = match.groups() micros = int(micros_str[1:].ljust(6, "0")[:6]) if micros_str else 0 return time(int(hour_str), int(minute_str), int(sec_str), micros) def match_to_number(match: "Match", parse_float: "ParseFloat") -> Any: match_str = match.group() if "." in match_str or "e" in match_str or "E" in match_str: return parse_float(match_str) return int(match_str) PKH]Ы6python3.10/site-packages/pip/_vendor/tomli/__init__.pynu["""A lil' TOML parser.""" __all__ = ("loads", "load", "TOMLDecodeError") __version__ = "1.0.3" # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY DO IT from pip._vendor.tomli._parser import TOMLDecodeError, load, loads PKH]2HQQ5python3.10/site-packages/pip/_vendor/distlib/index.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2013 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # import hashlib import logging import os import shutil import subprocess import tempfile try: from threading import Thread except ImportError: from dummy_threading import Thread from . import DistlibException from .compat import (HTTPBasicAuthHandler, Request, HTTPPasswordMgr, urlparse, build_opener, string_types) from .util import zip_dir, ServerProxy logger = logging.getLogger(__name__) DEFAULT_INDEX = 'https://pypi.org/pypi' DEFAULT_REALM = 'pypi' class PackageIndex(object): """ This class represents a package index compatible with PyPI, the Python Package Index. """ boundary = b'----------ThIs_Is_tHe_distlib_index_bouNdaRY_$' def __init__(self, url=None): """ Initialise an instance. :param url: The URL of the index. If not specified, the URL for PyPI is used. """ self.url = url or DEFAULT_INDEX self.read_configuration() scheme, netloc, path, params, query, frag = urlparse(self.url) if params or query or frag or scheme not in ('http', 'https'): raise DistlibException('invalid repository: %s' % self.url) self.password_handler = None self.ssl_verifier = None self.gpg = None self.gpg_home = None with open(os.devnull, 'w') as sink: # Use gpg by default rather than gpg2, as gpg2 insists on # prompting for passwords for s in ('gpg', 'gpg2'): try: rc = subprocess.check_call([s, '--version'], stdout=sink, stderr=sink) if rc == 0: self.gpg = s break except OSError: pass def _get_pypirc_command(self): """ Get the distutils command for interacting with PyPI configurations. :return: the command. """ from .util import _get_pypirc_command as cmd return cmd() def read_configuration(self): """ Read the PyPI access configuration as supported by distutils. This populates ``username``, ``password``, ``realm`` and ``url`` attributes from the configuration. """ from .util import _load_pypirc cfg = _load_pypirc(self) self.username = cfg.get('username') self.password = cfg.get('password') self.realm = cfg.get('realm', 'pypi') self.url = cfg.get('repository', self.url) def save_configuration(self): """ Save the PyPI access configuration. You must have set ``username`` and ``password`` attributes before calling this method. """ self.check_credentials() from .util import _store_pypirc _store_pypirc(self) def check_credentials(self): """ Check that ``username`` and ``password`` have been set, and raise an exception if not. """ if self.username is None or self.password is None: raise DistlibException('username and password must be set') pm = HTTPPasswordMgr() _, netloc, _, _, _, _ = urlparse(self.url) pm.add_password(self.realm, netloc, self.username, self.password) self.password_handler = HTTPBasicAuthHandler(pm) def register(self, metadata): """ Register a distribution on PyPI, using the provided metadata. :param metadata: A :class:`Metadata` instance defining at least a name and version number for the distribution to be registered. :return: The HTTP response received from PyPI upon submission of the request. """ self.check_credentials() metadata.validate() d = metadata.todict() d[':action'] = 'verify' request = self.encode_request(d.items(), []) response = self.send_request(request) d[':action'] = 'submit' request = self.encode_request(d.items(), []) return self.send_request(request) def _reader(self, name, stream, outbuf): """ Thread runner for reading lines of from a subprocess into a buffer. :param name: The logical name of the stream (used for logging only). :param stream: The stream to read from. This will typically a pipe connected to the output stream of a subprocess. :param outbuf: The list to append the read lines to. """ while True: s = stream.readline() if not s: break s = s.decode('utf-8').rstrip() outbuf.append(s) logger.debug('%s: %s' % (name, s)) stream.close() def get_sign_command(self, filename, signer, sign_password, keystore=None): """ Return a suitable command for signing a file. :param filename: The pathname to the file to be signed. :param signer: The identifier of the signer of the file. :param sign_password: The passphrase for the signer's private key used for signing. :param keystore: The path to a directory which contains the keys used in verification. If not specified, the instance's ``gpg_home`` attribute is used instead. :return: The signing command as a list suitable to be passed to :class:`subprocess.Popen`. """ cmd = [self.gpg, '--status-fd', '2', '--no-tty'] if keystore is None: keystore = self.gpg_home if keystore: cmd.extend(['--homedir', keystore]) if sign_password is not None: cmd.extend(['--batch', '--passphrase-fd', '0']) td = tempfile.mkdtemp() sf = os.path.join(td, os.path.basename(filename) + '.asc') cmd.extend(['--detach-sign', '--armor', '--local-user', signer, '--output', sf, filename]) logger.debug('invoking: %s', ' '.join(cmd)) return cmd, sf def run_command(self, cmd, input_data=None): """ Run a command in a child process , passing it any input data specified. :param cmd: The command to run. :param input_data: If specified, this must be a byte string containing data to be sent to the child process. :return: A tuple consisting of the subprocess' exit code, a list of lines read from the subprocess' ``stdout``, and a list of lines read from the subprocess' ``stderr``. """ kwargs = { 'stdout': subprocess.PIPE, 'stderr': subprocess.PIPE, } if input_data is not None: kwargs['stdin'] = subprocess.PIPE stdout = [] stderr = [] p = subprocess.Popen(cmd, **kwargs) # We don't use communicate() here because we may need to # get clever with interacting with the command t1 = Thread(target=self._reader, args=('stdout', p.stdout, stdout)) t1.start() t2 = Thread(target=self._reader, args=('stderr', p.stderr, stderr)) t2.start() if input_data is not None: p.stdin.write(input_data) p.stdin.close() p.wait() t1.join() t2.join() return p.returncode, stdout, stderr def sign_file(self, filename, signer, sign_password, keystore=None): """ Sign a file. :param filename: The pathname to the file to be signed. :param signer: The identifier of the signer of the file. :param sign_password: The passphrase for the signer's private key used for signing. :param keystore: The path to a directory which contains the keys used in signing. If not specified, the instance's ``gpg_home`` attribute is used instead. :return: The absolute pathname of the file where the signature is stored. """ cmd, sig_file = self.get_sign_command(filename, signer, sign_password, keystore) rc, stdout, stderr = self.run_command(cmd, sign_password.encode('utf-8')) if rc != 0: raise DistlibException('sign command failed with error ' 'code %s' % rc) return sig_file def upload_file(self, metadata, filename, signer=None, sign_password=None, filetype='sdist', pyversion='source', keystore=None): """ Upload a release file to the index. :param metadata: A :class:`Metadata` instance defining at least a name and version number for the file to be uploaded. :param filename: The pathname of the file to be uploaded. :param signer: The identifier of the signer of the file. :param sign_password: The passphrase for the signer's private key used for signing. :param filetype: The type of the file being uploaded. This is the distutils command which produced that file, e.g. ``sdist`` or ``bdist_wheel``. :param pyversion: The version of Python which the release relates to. For code compatible with any Python, this would be ``source``, otherwise it would be e.g. ``3.2``. :param keystore: The path to a directory which contains the keys used in signing. If not specified, the instance's ``gpg_home`` attribute is used instead. :return: The HTTP response received from PyPI upon submission of the request. """ self.check_credentials() if not os.path.exists(filename): raise DistlibException('not found: %s' % filename) metadata.validate() d = metadata.todict() sig_file = None if signer: if not self.gpg: logger.warning('no signing program available - not signed') else: sig_file = self.sign_file(filename, signer, sign_password, keystore) with open(filename, 'rb') as f: file_data = f.read() md5_digest = hashlib.md5(file_data).hexdigest() sha256_digest = hashlib.sha256(file_data).hexdigest() d.update({ ':action': 'file_upload', 'protocol_version': '1', 'filetype': filetype, 'pyversion': pyversion, 'md5_digest': md5_digest, 'sha256_digest': sha256_digest, }) files = [('content', os.path.basename(filename), file_data)] if sig_file: with open(sig_file, 'rb') as f: sig_data = f.read() files.append(('gpg_signature', os.path.basename(sig_file), sig_data)) shutil.rmtree(os.path.dirname(sig_file)) request = self.encode_request(d.items(), files) return self.send_request(request) def upload_documentation(self, metadata, doc_dir): """ Upload documentation to the index. :param metadata: A :class:`Metadata` instance defining at least a name and version number for the documentation to be uploaded. :param doc_dir: The pathname of the directory which contains the documentation. This should be the directory that contains the ``index.html`` for the documentation. :return: The HTTP response received from PyPI upon submission of the request. """ self.check_credentials() if not os.path.isdir(doc_dir): raise DistlibException('not a directory: %r' % doc_dir) fn = os.path.join(doc_dir, 'index.html') if not os.path.exists(fn): raise DistlibException('not found: %r' % fn) metadata.validate() name, version = metadata.name, metadata.version zip_data = zip_dir(doc_dir).getvalue() fields = [(':action', 'doc_upload'), ('name', name), ('version', version)] files = [('content', name, zip_data)] request = self.encode_request(fields, files) return self.send_request(request) def get_verify_command(self, signature_filename, data_filename, keystore=None): """ Return a suitable command for verifying a file. :param signature_filename: The pathname to the file containing the signature. :param data_filename: The pathname to the file containing the signed data. :param keystore: The path to a directory which contains the keys used in verification. If not specified, the instance's ``gpg_home`` attribute is used instead. :return: The verifying command as a list suitable to be passed to :class:`subprocess.Popen`. """ cmd = [self.gpg, '--status-fd', '2', '--no-tty'] if keystore is None: keystore = self.gpg_home if keystore: cmd.extend(['--homedir', keystore]) cmd.extend(['--verify', signature_filename, data_filename]) logger.debug('invoking: %s', ' '.join(cmd)) return cmd def verify_signature(self, signature_filename, data_filename, keystore=None): """ Verify a signature for a file. :param signature_filename: The pathname to the file containing the signature. :param data_filename: The pathname to the file containing the signed data. :param keystore: The path to a directory which contains the keys used in verification. If not specified, the instance's ``gpg_home`` attribute is used instead. :return: True if the signature was verified, else False. """ if not self.gpg: raise DistlibException('verification unavailable because gpg ' 'unavailable') cmd = self.get_verify_command(signature_filename, data_filename, keystore) rc, stdout, stderr = self.run_command(cmd) if rc not in (0, 1): raise DistlibException('verify command failed with error ' 'code %s' % rc) return rc == 0 def download_file(self, url, destfile, digest=None, reporthook=None): """ This is a convenience method for downloading a file from an URL. Normally, this will be a file from the index, though currently no check is made for this (i.e. a file can be downloaded from anywhere). The method is just like the :func:`urlretrieve` function in the standard library, except that it allows digest computation to be done during download and checking that the downloaded data matched any expected value. :param url: The URL of the file to be downloaded (assumed to be available via an HTTP GET request). :param destfile: The pathname where the downloaded file is to be saved. :param digest: If specified, this must be a (hasher, value) tuple, where hasher is the algorithm used (e.g. ``'md5'``) and ``value`` is the expected value. :param reporthook: The same as for :func:`urlretrieve` in the standard library. """ if digest is None: digester = None logger.debug('No digest specified') else: if isinstance(digest, (list, tuple)): hasher, digest = digest else: hasher = 'md5' digester = getattr(hashlib, hasher)() logger.debug('Digest specified: %s' % digest) # The following code is equivalent to urlretrieve. # We need to do it this way so that we can compute the # digest of the file as we go. with open(destfile, 'wb') as dfp: # addinfourl is not a context manager on 2.x # so we have to use try/finally sfp = self.send_request(Request(url)) try: headers = sfp.info() blocksize = 8192 size = -1 read = 0 blocknum = 0 if "content-length" in headers: size = int(headers["Content-Length"]) if reporthook: reporthook(blocknum, blocksize, size) while True: block = sfp.read(blocksize) if not block: break read += len(block) dfp.write(block) if digester: digester.update(block) blocknum += 1 if reporthook: reporthook(blocknum, blocksize, size) finally: sfp.close() # check that we got the whole file, if we can if size >= 0 and read < size: raise DistlibException( 'retrieval incomplete: got only %d out of %d bytes' % (read, size)) # if we have a digest, it must match. if digester: actual = digester.hexdigest() if digest != actual: raise DistlibException('%s digest mismatch for %s: expected ' '%s, got %s' % (hasher, destfile, digest, actual)) logger.debug('Digest verified: %s', digest) def send_request(self, req): """ Send a standard library :class:`Request` to PyPI and return its response. :param req: The request to send. :return: The HTTP response from PyPI (a standard library HTTPResponse). """ handlers = [] if self.password_handler: handlers.append(self.password_handler) if self.ssl_verifier: handlers.append(self.ssl_verifier) opener = build_opener(*handlers) return opener.open(req) def encode_request(self, fields, files): """ Encode fields and files for posting to an HTTP server. :param fields: The fields to send as a list of (fieldname, value) tuples. :param files: The files to send as a list of (fieldname, filename, file_bytes) tuple. """ # Adapted from packaging, which in turn was adapted from # http://code.activestate.com/recipes/146306 parts = [] boundary = self.boundary for k, values in fields: if not isinstance(values, (list, tuple)): values = [values] for v in values: parts.extend(( b'--' + boundary, ('Content-Disposition: form-data; name="%s"' % k).encode('utf-8'), b'', v.encode('utf-8'))) for key, filename, value in files: parts.extend(( b'--' + boundary, ('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename)).encode('utf-8'), b'', value)) parts.extend((b'--' + boundary + b'--', b'')) body = b'\r\n'.join(parts) ct = b'multipart/form-data; boundary=' + boundary headers = { 'Content-type': ct, 'Content-length': str(len(body)) } return Request(self.url, body, headers) def search(self, terms, operator=None): if isinstance(terms, string_types): terms = {'name': terms} rpc_proxy = ServerProxy(self.url, timeout=3.0) try: return rpc_proxy.search(terms, operator or 'and') finally: rpc_proxy('close')() PKH]x5g998python3.10/site-packages/pip/_vendor/distlib/manifest.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2012-2013 Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # """ Class representing the list of files in a distribution. Equivalent to distutils.filelist, but fixes some problems. """ import fnmatch import logging import os import re import sys from . import DistlibException from .compat import fsdecode from .util import convert_path __all__ = ['Manifest'] logger = logging.getLogger(__name__) # a \ followed by some spaces + EOL _COLLAPSE_PATTERN = re.compile('\\\\w*\n', re.M) _COMMENTED_LINE = re.compile('#.*?(?=\n)|\n(?=$)', re.M | re.S) # # Due to the different results returned by fnmatch.translate, we need # to do slightly different processing for Python 2.7 and 3.2 ... this needed # to be brought in for Python 3.6 onwards. # _PYTHON_VERSION = sys.version_info[:2] class Manifest(object): """A list of files built by on exploring the filesystem and filtered by applying various patterns to what we find there. """ def __init__(self, base=None): """ Initialise an instance. :param base: The base directory to explore under. """ self.base = os.path.abspath(os.path.normpath(base or os.getcwd())) self.prefix = self.base + os.sep self.allfiles = None self.files = set() # # Public API # def findall(self): """Find all files under the base and set ``allfiles`` to the absolute pathnames of files found. """ from stat import S_ISREG, S_ISDIR, S_ISLNK self.allfiles = allfiles = [] root = self.base stack = [root] pop = stack.pop push = stack.append while stack: root = pop() names = os.listdir(root) for name in names: fullname = os.path.join(root, name) # Avoid excess stat calls -- just one will do, thank you! stat = os.stat(fullname) mode = stat.st_mode if S_ISREG(mode): allfiles.append(fsdecode(fullname)) elif S_ISDIR(mode) and not S_ISLNK(mode): push(fullname) def add(self, item): """ Add a file to the manifest. :param item: The pathname to add. This can be relative to the base. """ if not item.startswith(self.prefix): item = os.path.join(self.base, item) self.files.add(os.path.normpath(item)) def add_many(self, items): """ Add a list of files to the manifest. :param items: The pathnames to add. These can be relative to the base. """ for item in items: self.add(item) def sorted(self, wantdirs=False): """ Return sorted files in directory order """ def add_dir(dirs, d): dirs.add(d) logger.debug('add_dir added %s', d) if d != self.base: parent, _ = os.path.split(d) assert parent not in ('', '/') add_dir(dirs, parent) result = set(self.files) # make a copy! if wantdirs: dirs = set() for f in result: add_dir(dirs, os.path.dirname(f)) result |= dirs return [os.path.join(*path_tuple) for path_tuple in sorted(os.path.split(path) for path in result)] def clear(self): """Clear all collected files.""" self.files = set() self.allfiles = [] def process_directive(self, directive): """ Process a directive which either adds some files from ``allfiles`` to ``files``, or removes some files from ``files``. :param directive: The directive to process. This should be in a format compatible with distutils ``MANIFEST.in`` files: http://docs.python.org/distutils/sourcedist.html#commands """ # Parse the line: split it up, make sure the right number of words # is there, and return the relevant words. 'action' is always # defined: it's the first word of the line. Which of the other # three are defined depends on the action; it'll be either # patterns, (dir and patterns), or (dirpattern). action, patterns, thedir, dirpattern = self._parse_directive(directive) # OK, now we know that the action is valid and we have the # right number of words on the line for that action -- so we # can proceed with minimal error-checking. if action == 'include': for pattern in patterns: if not self._include_pattern(pattern, anchor=True): logger.warning('no files found matching %r', pattern) elif action == 'exclude': for pattern in patterns: found = self._exclude_pattern(pattern, anchor=True) #if not found: # logger.warning('no previously-included files ' # 'found matching %r', pattern) elif action == 'global-include': for pattern in patterns: if not self._include_pattern(pattern, anchor=False): logger.warning('no files found matching %r ' 'anywhere in distribution', pattern) elif action == 'global-exclude': for pattern in patterns: found = self._exclude_pattern(pattern, anchor=False) #if not found: # logger.warning('no previously-included files ' # 'matching %r found anywhere in ' # 'distribution', pattern) elif action == 'recursive-include': for pattern in patterns: if not self._include_pattern(pattern, prefix=thedir): logger.warning('no files found matching %r ' 'under directory %r', pattern, thedir) elif action == 'recursive-exclude': for pattern in patterns: found = self._exclude_pattern(pattern, prefix=thedir) #if not found: # logger.warning('no previously-included files ' # 'matching %r found under directory %r', # pattern, thedir) elif action == 'graft': if not self._include_pattern(None, prefix=dirpattern): logger.warning('no directories found matching %r', dirpattern) elif action == 'prune': if not self._exclude_pattern(None, prefix=dirpattern): logger.warning('no previously-included directories found ' 'matching %r', dirpattern) else: # pragma: no cover # This should never happen, as it should be caught in # _parse_template_line raise DistlibException( 'invalid action %r' % action) # # Private API # def _parse_directive(self, directive): """ Validate a directive. :param directive: The directive to validate. :return: A tuple of action, patterns, thedir, dir_patterns """ words = directive.split() if len(words) == 1 and words[0] not in ('include', 'exclude', 'global-include', 'global-exclude', 'recursive-include', 'recursive-exclude', 'graft', 'prune'): # no action given, let's use the default 'include' words.insert(0, 'include') action = words[0] patterns = thedir = dir_pattern = None if action in ('include', 'exclude', 'global-include', 'global-exclude'): if len(words) < 2: raise DistlibException( '%r expects ...' % action) patterns = [convert_path(word) for word in words[1:]] elif action in ('recursive-include', 'recursive-exclude'): if len(words) < 3: raise DistlibException( '%r expects ...' % action) thedir = convert_path(words[1]) patterns = [convert_path(word) for word in words[2:]] elif action in ('graft', 'prune'): if len(words) != 2: raise DistlibException( '%r expects a single ' % action) dir_pattern = convert_path(words[1]) else: raise DistlibException('unknown action %r' % action) return action, patterns, thedir, dir_pattern def _include_pattern(self, pattern, anchor=True, prefix=None, is_regex=False): """Select strings (presumably filenames) from 'self.files' that match 'pattern', a Unix-style wildcard (glob) pattern. Patterns are not quite the same as implemented by the 'fnmatch' module: '*' and '?' match non-special characters, where "special" is platform-dependent: slash on Unix; colon, slash, and backslash on DOS/Windows; and colon on Mac OS. If 'anchor' is true (the default), then the pattern match is more stringent: "*.py" will match "foo.py" but not "foo/bar.py". If 'anchor' is false, both of these will match. If 'prefix' is supplied, then only filenames starting with 'prefix' (itself a pattern) and ending with 'pattern', with anything in between them, will match. 'anchor' is ignored in this case. If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and 'pattern' is assumed to be either a string containing a regex or a regex object -- no translation is done, the regex is just compiled and used as-is. Selected strings will be added to self.files. Return True if files are found. """ # XXX docstring lying about what the special chars are? found = False pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) # delayed loading of allfiles list if self.allfiles is None: self.findall() for name in self.allfiles: if pattern_re.search(name): self.files.add(name) found = True return found def _exclude_pattern(self, pattern, anchor=True, prefix=None, is_regex=False): """Remove strings (presumably filenames) from 'files' that match 'pattern'. Other parameters are the same as for 'include_pattern()', above. The list 'self.files' is modified in place. Return True if files are found. This API is public to allow e.g. exclusion of SCM subdirs, e.g. when packaging source distributions """ found = False pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) for f in list(self.files): if pattern_re.search(f): self.files.remove(f) found = True return found def _translate_pattern(self, pattern, anchor=True, prefix=None, is_regex=False): """Translate a shell-like wildcard pattern to a compiled regular expression. Return the compiled regex. If 'is_regex' true, then 'pattern' is directly compiled to a regex (if it's a string) or just returned as-is (assumes it's a regex object). """ if is_regex: if isinstance(pattern, str): return re.compile(pattern) else: return pattern if _PYTHON_VERSION > (3, 2): # ditch start and end characters start, _, end = self._glob_to_re('_').partition('_') if pattern: pattern_re = self._glob_to_re(pattern) if _PYTHON_VERSION > (3, 2): assert pattern_re.startswith(start) and pattern_re.endswith(end) else: pattern_re = '' base = re.escape(os.path.join(self.base, '')) if prefix is not None: # ditch end of pattern character if _PYTHON_VERSION <= (3, 2): empty_pattern = self._glob_to_re('') prefix_re = self._glob_to_re(prefix)[:-len(empty_pattern)] else: prefix_re = self._glob_to_re(prefix) assert prefix_re.startswith(start) and prefix_re.endswith(end) prefix_re = prefix_re[len(start): len(prefix_re) - len(end)] sep = os.sep if os.sep == '\\': sep = r'\\' if _PYTHON_VERSION <= (3, 2): pattern_re = '^' + base + sep.join((prefix_re, '.*' + pattern_re)) else: pattern_re = pattern_re[len(start): len(pattern_re) - len(end)] pattern_re = r'%s%s%s%s.*%s%s' % (start, base, prefix_re, sep, pattern_re, end) else: # no prefix -- respect anchor flag if anchor: if _PYTHON_VERSION <= (3, 2): pattern_re = '^' + base + pattern_re else: pattern_re = r'%s%s%s' % (start, base, pattern_re[len(start):]) return re.compile(pattern_re) def _glob_to_re(self, pattern): """Translate a shell-like glob pattern to a regular expression. Return a string containing the regex. Differs from 'fnmatch.translate()' in that '*' does not match "special characters" (which are platform-specific). """ pattern_re = fnmatch.translate(pattern) # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, # and by extension they shouldn't match such "special characters" under # any OS. So change all non-escaped dots in the RE to match any # character except the special characters (currently: just os.sep). sep = os.sep if os.sep == '\\': # we're using a regex to manipulate a regex, so we need # to escape the backslash twice sep = r'\\\\' escaped = r'\1[^%s]' % sep pattern_re = re.sub(r'((?Z#d?d@Z$GdAdBdBeZ%GdCdDdDeZ&GdEdFdFe Z'e'eeee'ee!dGdHe'e$e&edIZ(e(dJe(dK<dLdMZ)dS)Nz~ Implementation of a flexible versioning scheme providing support for PEP-440, setuptools-compatible and semantic versioning. N) string_typesparse_requirement)NormalizedVersionNormalizedMatcher LegacyVersion LegacyMatcherSemanticVersionSemanticMatcherUnsupportedVersionError get_schemec@seZdZdZdS)r zThis is an unsupported version.N)__name__ __module__ __qualname____doc__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/version.pyr sr c@sxeZdZddZddZddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZeddZdS)VersioncCs@||_}|||_}t|tsJt|dksJdS)Nr)strip_stringparse_parts isinstancetuplelen)selfspartsrrr__init__szVersion.__init__cCtd)Nzplease implement in a subclassNotImplementedErrorrrrrrr%z Version.parsecCs$t|t|krtd||fdS)Nzcannot compare %r and %r)type TypeErrorrotherrrr_check_compatible(szVersion._check_compatiblecCs|||j|jkSNr)rr'rrr__eq__,  zVersion.__eq__cC || Sr*r,r'rrr__ne__0 zVersion.__ne__cCs|||j|jkSr*r+r'rrr__lt__3r-zVersion.__lt__cCs||p || Sr*r2r,r'rrr__gt__7szVersion.__gt__cC||p ||Sr*r3r'rrr__le__:zVersion.__le__cCr5r*)r4r,r'rrr__ge__=r7zVersion.__ge__cCs t|jSr*)hashrrrrr__hash__A zVersion.__hash__cCd|jj|jfS)Nz%s('%s') __class__rrr:rrr__repr__DzVersion.__repr__cC|jSr*rr:rrr__str__GzVersion.__str__cCr )NzPlease implement in subclasses.r!r:rrr is_prereleaseJszVersion.is_prereleaseN)rrrrrr)r,r0r2r4r6r8r;r@rDpropertyrFrrrrrsrc @seZdZdZddddddddddddd dd dd Zd d ZddZddZeddZ ddZ ddZ ddZ ddZ ddZddZdS) MatcherNcCs||kSr*rvcprrrTzMatcher.cCs||kSr*rrIrrrrMUrNcCs||kp||kSr*rrIrrrrMVcC||kp||kSr*rrIrrrrMWrOcC||kSr*rrIrrrrMXrNcCrQr*rrIrrrrMYrNcCrPr*rrIrrrrM[rOcCs||kSr*rrIrrrrM\rN)<><=>======~=!=cCt|Sr*rr#rrrrar$zMatcher.parse_requirementcCs|jdur td||_}||}|std||j|_|j|_g}|jrb|jD]2\}}| drQ|dvrBtd||ddd}}||n||d}}| |||fq/t ||_ dS) NzPlease specify a version classz Not valid: %rz.*)rVrYz#'.*' not allowed for %r constraintsTF) version_class ValueErrorrrrnamelowerkey constraintsendswithappendrr)rrrZclistopZvnprefixrrrrds*      zMatcher.__init__cCsxt|tr ||}|jD],\}}}|j|}t|tr"t||}|s0d||jjf}t |||||s9dSq dS)z Check if the provided version matches the constraints. :param version: The version to match against this instance. :type version: String or :class:`Version` instance. z%r not implemented for %sFT) rrr\r _operatorsgetgetattrr?rr")rversionoperator constraintrffmsgrrrmatchs       z Matcher.matchcCs6d}t|jdkr|jdddvr|jdd}|S)Nrr)rVrW)rr)rresultrrr exact_versions zMatcher.exact_versioncCs0t|t|ks|j|jkrtd||fdS)Nzcannot compare %s and %s)r%r^r&r'rrrr)szMatcher._check_compatiblecCs"|||j|jko|j|jkSr*)r)r`rr'rrrr,s zMatcher.__eq__cCr.r*r/r'rrrr0r1zMatcher.__ne__cCst|jt|jSr*)r9r`rr:rrrr;r7zMatcher.__hash__cCr=)Nz%s(%r)r>r:rrrr@rAzMatcher.__repr__cCrBr*rCr:rrrrDrEzMatcher.__str__)rrrr\rgrrrorGrqr)r,r0r;r@rDrrrrrHOs,  rHzk^v?(\d+!)?(\d+(\.\d+)*)((a|b|c|rc)(\d+))?(\.(post)(\d+))?(\.(dev)(\d+))?(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$c Cs|}t|}|std||}tdd|ddD}t|dkrA|ddkrA|dd}t|dkrA|ddks/|dsHd}n t|ddd}|dd }|d d }|d d }|d}|dkrod}n |dt|df}|dkrd}n |dt|df}|dkrd}n |dt|df}|durd}n"g} |dD]} | rdt| f} nd| f} | | qt| }|s|s|rd}nd}|sd}|sd}||||||fS)NzNot a valid version: %scs|]}t|VqdSr*int.0rJrrr z_pep_440_key..r.r )NNr)arz)z)_)final) rPEP440_VERSION_REror groupsrsplitrrtisdigitrc) rmrnumsepochprepostdevlocalrpartrrr _pep_440_keysV       rc@s0eZdZdZddZegdZeddZdS)raIA rational version. Good: 1.2 # equivalent to "1.2.0" 1.2.0 1.2a1 1.2.3a2 1.2.3b1 1.2.3c1 1.2.3.4 TODO: fill this out Bad: 1 # minimum two numbers 1.2a # release level must have a release serial 1.2.3b cCs<t|}t|}|}tdd|ddD|_|S)Ncsrrr*rsrurrrrwrxz*NormalizedVersion.parse..rry)_normalized_keyrrorrr_release_clause)rrrprrrrrr s  zNormalizedVersion.parse)rbrKrcrcstfddjDS)Nc3s"|] }|r|djvVqdS)rN) PREREL_TAGS)rvtr:rrrws z2NormalizedVersion.is_prerelease..)anyrr:rr:rrFszNormalizedVersion.is_prereleaseN) rrrrrsetrrGrFrrrrrs  rcCs>t|}t|}||krdS||sdSt|}||dkS)NTFry)str startswithr)xynrrr _match_prefixs  rc @sneZdZeZddddddddd Zd d Zd d ZddZddZ ddZ ddZ ddZ ddZ ddZdS)r_match_compatible _match_lt _match_gt _match_le _match_ge _match_eq_match_arbitrary _match_ne)rXrRrSrTrUrVrWrYcCsV|r d|vo |jd}n |jd o|jd}|r'|jddd}||}||fS)N+rzrr)rrrr\)rrjrlrfZ strip_localrrrr _adjust_local6s zNormalizedMatcher._adjust_localcCsD||||\}}||krdS|j}ddd|D}t|| S)NFrycSg|]}t|qSrrrvirrr Iz/NormalizedMatcher._match_lt..rrjoinrrrjrlrfZrelease_clausepfxrrrrD  zNormalizedMatcher._match_ltcCsD||||\}}||krdS|j}ddd|D}t|| S)NFrycSrrrrrrrrQrz/NormalizedMatcher._match_gt..rrrrrrLrzNormalizedMatcher._match_gtcCs||||\}}||kSr*rrrjrlrfrrrrTzNormalizedMatcher._match_lecCs||||\}}||kSr*rrrrrrXrzNormalizedMatcher._match_gecCs0||||\}}|s||k}|St||}|Sr*rrrrjrlrfrprrrr\s  zNormalizedMatcher._match_eqcCst|t|kSr*rrrrrrdsz"NormalizedMatcher._match_arbitrarycCs2||||\}}|s||k}|St|| }|Sr*rrrrrrgs  zNormalizedMatcher._match_necCsf||||\}}||krdS||krdS|j}t|dkr$|dd}ddd|D}t||S)NTFrrzrycSrrrrrrrrzrz7NormalizedMatcher._match_compatible..)rrrrrrrrrros   z#NormalizedMatcher._match_compatibleN)rrrrr\rgrrrrrrrrrrrrrr's(  rz[.+-]$z^[.](\d)z0.\1z^[.-]z ^\((.*)\)$\1z^v(ersion)?\s*(\d+)z\2z^r(ev)?\s*(\d+)z[.]{2,}ryz\b(alfa|apha)\balphaz\b(pre-alpha|prealpha)\bz pre.alphaz \(beta\)$betaz ^[:~._+-]+z [,*")([\]]z[~:+_ -]z\.$z (\d+(\.\d+)*)cCsN|}tD] \}}|||}q|sd}t|}|s#d}|}nZ|dd}dd|D}t|dkrD| dt|dks9t|dkrS|| d}nd dd|ddD|| d}|dd}d d d|D}|}|rt D] \}}|||}q|s|}nd |vrd nd }|||}t |sd}|S) z Try to suggest a semantic form for a version for which _suggest_normalized_version couldn't come up with anything. z0.0.0rrycSrrrsrrrrrrz-_suggest_semantic_version..NcSrrrrrrrrrcSrrrrrrrrrr-r)rr_ _REPLACEMENTSsub_NUMERIC_PREFIXrorrrrcendr_SUFFIX_REPLACEMENTS is_semver)rrppatreplrrfsuffixseprrr_suggest_semantic_versions<      ,   rcCsbzt||WStyYnw|}dD] \}}|||}qtdd|}tdd|}tdd|}tdd |}td d |}|d rP|d d}tdd |}tdd|}tdd|}tdd|}tdd|}tdd|}tdd|}tdd|}tdd|}tdd|}tdd |}zt|W|Styd}Y|Sw)!aSuggest a normalized version close to the given version string. If you have a version string that isn't rational (i.e. NormalizedVersion doesn't like it) then you might be able to get an equivalent (or close) rational version from this function. This does a number of simple normalizations to the given string, based on observation of versions currently in use on PyPI. Given a dump of those version during PyCon 2009, 4287 of them: - 2312 (53.93%) match NormalizedVersion without change with the automatic suggestion - 3474 (81.04%) match when using this suggestion method @param s {str} An irrational version string. @returns A rational version string, or None, if couldn't determine one. ))z-alphar)z-betar)rr)rr)rrK)z-finalr)z-prerK)z-releaser)z.releaser)z-stabler)rry)rry) r)z.finalr)rrzpre$Zpre0zdev$Zdev0z([abc]|rc)[\-\.](\d+)$z\1\2z[\-\.](dev)[\-\.]?r?(\d+)$z.\1\2z[.~]?([abc])\.?rrJrNz\b0+(\d+)(?!\d)z (\d+[abc])$z\g<1>0z\.?(dev-r|dev\.r)\.?(\d+)$z.dev\2z-(a|b|c)(\d+)$z[\.\-](dev|devel)$z.dev0z(?![\.\-])dev$z(final|stable)$rz\.?(r|-|-r)\.?(\d+)$z.post\2z\.?(dev|git|bzr)\.?(\d+)$z\.?(pre|preview|-c)(\d+)$zc\g<2>zp(\d+)$z.post\1)rr r_replacererr)rrsorigrrrr_suggest_normalized_versionsD       rz([a-z]+|\d+|[\.-])rKzfinal-@)rpreviewrrrrrycCsdd}g}||D]8}|dr=|dkr)|r)|ddkr)||r)|ddks|r=|ddkr=||r=|ddks1||q t|S)NcSstg}t|D])}t||}|r2d|ddkr!dkr)nn|d}nd|}||q |d|S)N0r9**final) _VERSION_PARTrr__VERSION_REPLACErhzfillrc)rrprLrrr get_partsCs     z_legacy_key..get_partsrrrzz*final-00000000)rpoprcr)rrrprLrrr _legacy_keyBs   rc@ eZdZddZeddZdS)rcCrZr*)rr#rrrr]r$zLegacyVersion.parsecCs:d}|jD]}t|tr|dr|dkrd}|Sq|S)NFrrT)rrrr)rrprrrrrF`s zLegacyVersion.is_prereleaseNrrrrrGrFrrrrr\rc@s4eZdZeZeejZded<e dZ ddZ dS)r rrXz^(\d+(\.\d+)*)cCs`||krdS|jt|}|std||dS|d}d|vr+|ddd}t||S)NFzACannot compute compatible match for version %s and constraint %sTrryr) numeric_rerorloggerwarningrrsplitr)rrjrlrfrrrrrrss  zLegacyMatcher._match_compatibleN) rrrrr\dictrHrgrcompilerrrrrrr ks    r zN^(\d+)\.(\d+)\.(\d+)(-[a-z0-9]+(\.[a-z0-9-]+)*)?(\+[a-z0-9]+(\.[a-z0-9-]+)*)?$cCs t|Sr*) _SEMVER_REro)rrrrrr<rc Csndd}t|}|st||}dd|ddD\}}}||dd||dd}}|||f||fS) NcSs:|dur |f}|S|ddd}tdd|D}|S)NrrycSs"g|] }|r |dn|qS)r)rr)rvrLrrrrs"z5_semantic_key..make_tuple..)rr)rZabsentrprrrr make_tuples z!_semantic_key..make_tuplecSrrrsrrrrrrz!_semantic_key..r|r)rr r) rrrrmajorminorpatchrbuildrrr _semantic_keys rc@r)r cCrZr*)rr#rrrrr$zSemanticVersion.parsecCs|jdddkS)Nrrr)rr:rrrrFszSemanticVersion.is_prereleaseNrrrrrr rr c@seZdZeZdS)r N)rrrr r\rrrrr sr c@s6eZdZd ddZddZddZdd Zd d ZdS) VersionSchemeNcCs||_||_||_dSr*)r`matcher suggester)rr`rrrrrrs zVersionScheme.__init__cCs0z |j|d}W|Styd}Y|SwNTF)rr\r rrrprrris_valid_versions  zVersionScheme.is_valid_versioncCs.z ||d}W|Styd}Y|Swr)rr rrrris_valid_matchers  zVersionScheme.is_valid_matchercCs$|dr |dd}|d|S)z: Used for processing some metadata fields ,Nrzzdummy_name (%s))rbrr#rrris_valid_constraint_lists  z&VersionScheme.is_valid_constraint_listcCs |jdur d}|S||}|Sr*)rrrrrsuggests  zVersionScheme.suggestr*)rrrrrrrrrrrrrs   rcCs|Sr*rr#rrrrMsrM) normalizedlegacyZsemanticrdefaultcCs|tvr td|t|S)Nzunknown scheme name: %r)_SCHEMESr])r^rrrr s r )*rloggingrcompatrutilr__all__ getLoggerrrr]r objectrrHrrrrrrrrrrrrIrrrrr rrrr r rrr rrrrs   1 d=$ W              .r  '  PKH]茫CCNpython3.10/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-310.pycnu[o aiQ@sddlZddlZddlZddlZddlZddlZzddlmZWney/ddl mZYnwddl m Z ddl m Z mZmZmZmZmZddlmZmZeeZdZdZGd d d eZdS) N)Thread)DistlibException)HTTPBasicAuthHandlerRequestHTTPPasswordMgrurlparse build_opener string_types)zip_dir ServerProxyzhttps://pypi.org/pypipypic@seZdZdZdZd*ddZddZdd Zd d Zd d Z ddZ ddZ d*ddZ d*ddZ d*ddZ  d+ddZddZ d*ddZ d*d d!Zd,d"d#Zd$d%Zd&d'Zd*d(d)ZdS)- PackageIndexzc This class represents a package index compatible with PyPI, the Python Package Index. s.----------ThIs_Is_tHe_distlib_index_bouNdaRY_$Nc Cs|pt|_|t|j\}}}}}}|s|s|s|dvr%td|jd|_d|_d|_d|_t t j d5}dD]!} zt j | dg||d} | dkrQ| |_WnWq:ty[Yq:wWddSWddS1sowYdS) z Initialise an instance. :param url: The URL of the index. If not specified, the URL for PyPI is used. )httphttpszinvalid repository: %sNw)gpgZgpg2z --versionstdoutstderrr) DEFAULT_INDEXurlread_configurationrrpassword_handler ssl_verifierrgpg_homeopenosdevnull subprocess check_callOSError) selfrschemenetlocpathparamsqueryfragZsinksrcr+/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/index.py__init__$s4    "zPackageIndex.__init__cCsddlm}|S)zs Get the distutils command for interacting with PyPI configurations. :return: the command. r)_get_pypirc_command)utilr.)r"cmdr+r+r,r.As z PackageIndex._get_pypirc_commandcCsNddlm}||}|d|_|d|_|dd|_|d|j|_dS) z Read the PyPI access configuration as supported by distutils. This populates ``username``, ``password``, ``realm`` and ``url`` attributes from the configuration. r) _load_pypircusernamepasswordrealmr repositoryN)r/r1getr2r3r4r)r"r1cfgr+r+r,rIs   zPackageIndex.read_configurationcCs |ddlm}||dS)z Save the PyPI access configuration. You must have set ``username`` and ``password`` attributes before calling this method. r) _store_pypircN)check_credentialsr/r8)r"r8r+r+r,save_configurationVs  zPackageIndex.save_configurationcCs\|jdus |jdurtdt}t|j\}}}}}}||j||j|jt||_ dS)zp Check that ``username`` and ``password`` have been set, and raise an exception if not. Nz!username and password must be set) r2r3rrrr add_passwordr4rr)r"Zpm_r$r+r+r,r9_s zPackageIndex.check_credentialscCs\|||}d|d<||g}||}d|d<||g}||S)aq Register a distribution on PyPI, using the provided metadata. :param metadata: A :class:`Metadata` instance defining at least a name and version number for the distribution to be registered. :return: The HTTP response received from PyPI upon submission of the request. verify:actionsubmit)r9validatetodictencode_requestitems send_request)r"metadatadrequestresponser+r+r,registerks   zPackageIndex.registercCsH |}|sn|d}||td||fq|dS)ar Thread runner for reading lines of from a subprocess into a buffer. :param name: The logical name of the stream (used for logging only). :param stream: The stream to read from. This will typically a pipe connected to the output stream of a subprocess. :param outbuf: The list to append the read lines to. Tutf-8z%s: %sN)readlinedecoderstripappendloggerdebugclose)r"namestreamZoutbufr)r+r+r,_readers   zPackageIndex._readerc Cs|jdddg}|dur|j}|r|d|g|dur"|gdt}tj|tj|d}|dd d |d ||gt d d |||fS)a Return a suitable command for signing a file. :param filename: The pathname to the file to be signed. :param signer: The identifier of the signer of the file. :param sign_password: The passphrase for the signer's private key used for signing. :param keystore: The path to a directory which contains the keys used in verification. If not specified, the instance's ``gpg_home`` attribute is used instead. :return: The signing command as a list suitable to be passed to :class:`subprocess.Popen`. --status-fd2--no-ttyN --homedir)z--batchz--passphrase-fd0z.ascz --detach-signz--armorz --local-userz--output invoking: %s ) rrextendtempfilemkdtemprr%joinbasenamerOrP)r"filenamesigner sign_passwordkeystorer0tdZsfr+r+r,get_sign_commands zPackageIndex.get_sign_commandc Cstjtjd}|durtj|d<g}g}tj|fi|}t|jd|j|fd}|t|jd|j|fd}||durJ|j ||j | | | |j ||fS)a Run a command in a child process , passing it any input data specified. :param cmd: The command to run. :param input_data: If specified, this must be a byte string containing data to be sent to the child process. :return: A tuple consisting of the subprocess' exit code, a list of lines read from the subprocess' ``stdout``, and a list of lines read from the subprocess' ``stderr``. rNstdinr)targetargsr)rPIPEPopenrrTrstartrrgwriterQwaitr_ returncode) r"r0Z input_datakwargsrrpt1t2r+r+r, run_commands&     zPackageIndex.run_commandc CsD|||||\}}|||d\}}} |dkr td||S)aR Sign a file. :param filename: The pathname to the file to be signed. :param signer: The identifier of the signer of the file. :param sign_password: The passphrase for the signer's private key used for signing. :param keystore: The path to a directory which contains the keys used in signing. If not specified, the instance's ``gpg_home`` attribute is used instead. :return: The absolute pathname of the file where the signature is stored. rJrz&sign command failed with error code %s)rfrtencoder) r"rarbrcrdr0sig_filer*rrr+r+r, sign_files  zPackageIndex.sign_filesdistsourcec CsN|tj|std|||}d} |r-|js%t dn| ||||} t |d } | } Wdn1sAwYt | } t | } |dd||| | ddtj|| fg}| rt | d } | }Wdn1swY|d tj| |fttj| |||}||S) a Upload a release file to the index. :param metadata: A :class:`Metadata` instance defining at least a name and version number for the file to be uploaded. :param filename: The pathname of the file to be uploaded. :param signer: The identifier of the signer of the file. :param sign_password: The passphrase for the signer's private key used for signing. :param filetype: The type of the file being uploaded. This is the distutils command which produced that file, e.g. ``sdist`` or ``bdist_wheel``. :param pyversion: The version of Python which the release relates to. For code compatible with any Python, this would be ``source``, otherwise it would be e.g. ``3.2``. :param keystore: The path to a directory which contains the keys used in signing. If not specified, the instance's ``gpg_home`` attribute is used instead. :return: The HTTP response received from PyPI upon submission of the request. z not found: %sNz)no signing program available - not signedrbZ file_upload1)r>Zprotocol_versionfiletype pyversion md5_digest sha256_digestcontentZ gpg_signature)r9rr%existsrr@rArrOwarningrwrreadhashlibmd5 hexdigestsha256updater`rNshutilrmtreedirnamerBrCrD)r"rErarbrcr|r}rdrFrvfZ file_datar~rfilesZsig_datarGr+r+r, upload_filesH         zPackageIndex.upload_filec Cs|tj|std|tj|d}tj|s#td|||j|j }}t | }dd|fd|fg}d||fg}| ||} | | S)a2 Upload documentation to the index. :param metadata: A :class:`Metadata` instance defining at least a name and version number for the documentation to be uploaded. :param doc_dir: The pathname of the directory which contains the documentation. This should be the directory that contains the ``index.html`` for the documentation. :return: The HTTP response received from PyPI upon submission of the request. znot a directory: %rz index.htmlz not found: %r)r>Z doc_uploadrRversionr)r9rr%isdirrr_rr@rRrr getvaluerBrD) r"rEZdoc_dirfnrRrzip_datafieldsrrGr+r+r,upload_documentation!s         z!PackageIndex.upload_documentationcCsT|jdddg}|dur|j}|r|d|g|d||gtdd||S) a| Return a suitable command for verifying a file. :param signature_filename: The pathname to the file containing the signature. :param data_filename: The pathname to the file containing the signed data. :param keystore: The path to a directory which contains the keys used in verification. If not specified, the instance's ``gpg_home`` attribute is used instead. :return: The verifying command as a list suitable to be passed to :class:`subprocess.Popen`. rUrVrWNrXz--verifyrZr[)rrr\rOrPr_)r"signature_filename data_filenamerdr0r+r+r,get_verify_command=szPackageIndex.get_verify_commandcCsH|jstd||||}||\}}}|dvr td||dkS)a6 Verify a signature for a file. :param signature_filename: The pathname to the file containing the signature. :param data_filename: The pathname to the file containing the signed data. :param keystore: The path to a directory which contains the keys used in verification. If not specified, the instance's ``gpg_home`` attribute is used instead. :return: True if the signature was verified, else False. z0verification unavailable because gpg unavailable)rrz(verify command failed with error code %sr)rrrrt)r"rrrdr0r*rrr+r+r,verify_signatureUszPackageIndex.verify_signaturec Cs|dur d}tdnt|ttfr|\}}nd}tt|}td|t|da}|t |}zL| } d} d} d} d} d | vrKt | d } |rS|| | |  | | }|s\n| t |7} |||rn||| d 7} |rz|| | | qTW|n|wWdn1swY| dkr| | krtd | | f|r|}||krtd||||ftd|dSdS)a This is a convenience method for downloading a file from an URL. Normally, this will be a file from the index, though currently no check is made for this (i.e. a file can be downloaded from anywhere). The method is just like the :func:`urlretrieve` function in the standard library, except that it allows digest computation to be done during download and checking that the downloaded data matched any expected value. :param url: The URL of the file to be downloaded (assumed to be available via an HTTP GET request). :param destfile: The pathname where the downloaded file is to be saved. :param digest: If specified, this must be a (hasher, value) tuple, where hasher is the algorithm used (e.g. ``'md5'``) and ``value`` is the expected value. :param reporthook: The same as for :func:`urlretrieve` in the standard library. NzNo digest specifiedrzDigest specified: %swbi rzcontent-lengthzContent-LengthTrz1retrieval incomplete: got only %d out of %d bytesz.%s digest mismatch for %s: expected %s, got %szDigest verified: %s)rOrP isinstancelisttuplegetattrrrrDrinfointrlenrmrrQrr)r"rdestfiledigest reporthookZdigesterZhasherZdfpZsfpheaders blocksizesizerblocknumblockactualr+r+r, download_filensf            zPackageIndex.download_filecCs:g}|jr ||j|jr||jt|}||S)z Send a standard library :class:`Request` to PyPI and return its response. :param req: The request to send. :return: The HTTP response from PyPI (a standard library HTTPResponse). )rrNrr r)r"reqhandlersopenerr+r+r,rDs   zPackageIndex.send_requestc Csg}|j}|D]&\}}t|ttfs|g}|D]}|d|d|dd|dfqq|D]\}} } |d|d|| fdd| fq0|d|ddfd|} d|} | tt| d} t |j | | S) a& Encode fields and files for posting to an HTTP server. :param fields: The fields to send as a list of (fieldname, value) tuples. :param files: The files to send as a list of (fieldname, filename, file_bytes) tuple. s--z)Content-Disposition: form-data; name="%s"rJz8Content-Disposition: form-data; name="%s"; filename="%s"s smultipart/form-data; boundary=)z Content-typezContent-length) boundaryrrrr\rur_strrrr)r"rrpartsrkvaluesvkeyravaluebodyctrr+r+r,rBsB    zPackageIndex.encode_requestcCsJt|tr d|i}t|jdd}z|||pdW|dS|dw)NrRg@)timeoutandrQ)rr r rsearch)r"ZtermsoperatorZ rpc_proxyr+r+r,rs zPackageIndex.search)N)NNrxryN)NN)__name__ __module__ __qualname____doc__rr-r.rr:r9rIrTrfrtrwrrrrrrDrBrr+r+r+r,rs4      # 9  M+r)rloggingrrrr] threadingr ImportErrorZdummy_threadingrcompatrrrrr r r/r r getLoggerrrOr DEFAULT_REALMobjectrr+r+r+r,s$    PKH]݅Ppython3.10/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-310.pycnu[o ai}@sdZddlZddlZddlZddlZddlmZddlmZm Z ddl m Z dgZ edZd d Zd d ZGd ddeZddZeZ[eZdddZdS)zG Parser for the environment markers micro-language defined in PEP 508. N) string_types)in_venv parse_marker)NormalizedVersion interpretz<((\d+(\.\d+)*\w*)|\'(\d+(\.\d+)*\w*)\'|\"(\d+(\.\d+)*\w*)\")cCst|tr|s dS|ddvS)NFr'") isinstancer)or /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/markers.py _is_literals r cCs2g}t|D] }|t|dqt|S)Nr)_VERSION_PATTERNfinditerappendNVgroupsset)sresultmr r r _get_versions!src @sfeZdZdZddddddddddddd dd dd dd dd dddd ZddZdS) Evaluatorz; This class is used to evaluate marker expessions. cC||kSNr xyr r r -zEvaluator.cCrrr rr r r r.rcC||kp||kSrr rr r r r/cCs||kSrr rr r r r0rcCs||kSrr rr r r r1rcCs||kp||kSrr rr r r r2r!cCs||kSrr rr r r r3rcCr rr rr r r r4r!cCs|o|Srr rr r r r5rcCs|p|Srr rr r r r6rcCs||vSrr rr r r r7rcCs||vSrr rr r r r8r) =====~=!=<<=>>=andorinnot inc Cs"t|tr#|ddvr|dd}|S||vrtd|||}|St|ts*J|d}||jvr9td||d}|d }t|drVt|d rVtd |||f|||}|||}|d ksj|d krw|d vrwt|}t|}n|d kr|d vrt|}t |}|j|||}|S)z Evaluate a marker expression returned by the :func:`parse_requirement` function in the specified context. rrrzunknown variable: %sopzop not implemented: %slhsrhszinvalid comparison: %s %s %spython_version)r&r'r(r)r#r"r%r$)r,r-) r r SyntaxErrordict operationsNotImplementedErrorr evaluaterr) selfexprcontextrr/ZelhsZerhsr0r1r r r r7;s6         zEvaluator.evaluateN)__name__ __module__ __qualname____doc__r5r7r r r r r's  rc Csdd}ttdr|tjj}tjj}nd}d}||tjttt t tt t t t ddtjd }|S)NcSs<d|j|j|jf}|j}|dkr||dt|j7}|S)Nz%s.%s.%sfinalr)majorminormicro releaselevelstrserial)infoversionkindr r r format_full_version^s z,default_context..format_full_versionimplementation0) implementation_nameimplementation_versionos_nameplatform_machineplatform_python_implementationplatform_releaseplatform_systemplatform_versionZplatform_in_venvpython_full_versionr2 sys_platform)hasattrsysrJrGnameosplatformmachinepython_implementationreleasesystemrDrr2)rIrOrNrr r r default_context]s(   rac Cs|zt|\}}Wnty}ztd||fd}~ww|r-|ddkr-td||ftt}|r8||t||S)z Interpret a marker and return a result depending on environment. :param marker: The marker to interpret. :type marker: str :param execution_context: The context used for name lookup. :type execution_context: mapping z)Unable to interpret marker syntax: %s: %sNr#z*unexpected trailing data in marker: %s: %s)r Exceptionr3r4DEFAULT_CONTEXTupdate evaluatorr7)markerZexecution_contextr9rester:r r r rs   r)r>r[rerYr\compatrutilrrrGrr__all__compilerr robjectrrardrfrr r r r s$   6PKH]l"("(Qpython3.10/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-310.pycnu[o ai9@sdZddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z dgZ e eZedejZed ejejBZejdd ZGd ddeZdS) zu Class representing the list of files in a distribution. Equivalent to distutils.filelist, but fixes some problems. N)DistlibException)fsdecode convert_pathManifestz\\w* z#.*?(?= )| (?=$)c@seZdZdZdddZddZddZd d Zdd d ZddZ ddZ ddZ  dddZ  dddZ  dddZddZdS) rz~A list of files built by on exploring the filesystem and filtered by applying various patterns to what we find there. NcCs>tjtj|p t|_|jtj|_d|_t |_ dS)zd Initialise an instance. :param base: The base directory to explore under. N) ospathabspathnormpathgetcwdbasesepprefixallfilessetfiles)selfrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/manifest.py__init__*s zManifest.__init__cCsddlm}m}m}g|_}|j}|g}|j}|j}|rU|}t |} | D])} tj || } t| } | j } || rD|t | q'|| rP|| sP|| q'|sdSdS)zmFind all files under the base and set ``allfiles`` to the absolute pathnames of files found. r)S_ISREGS_ISDIRS_ISLNKN)statrrrrrpopappendr listdirr joinst_moder)rrrrrrootstackrpushnamesnamefullnamermoderrrfindall9s&    zManifest.findallcCs4||jstj|j|}|jtj|dS)zz Add a file to the manifest. :param item: The pathname to add. This can be relative to the base. N) startswithrr r rrraddr )ritemrrrr*Ts z Manifest.addcCs|D]}||qdS)z Add a list of files to the manifest. :param items: The pathnames to add. These can be relative to the base. N)r*)ritemsr+rrradd_many^s zManifest.add_manyFcsbfddtj}|r#t}|D] }|tj|q||O}ddtdd|DDS)z8 Return sorted files in directory order csN||td||jkr%tj|\}}|dvsJ||dSdS)Nzadd_dir added %s)/)r*loggerdebugrr r split)dirsdparent_add_dirrrrr8ls    z Manifest.sorted..add_dircSsg|]}tjj|qSr)r r r).0Z path_tuplerrr zsz#Manifest.sorted..css|] }tj|VqdSN)r r r2)r9r rrr {sz"Manifest.sorted..)rrr r dirnamesorted)rZwantdirsresultr3frr7rr>gs zManifest.sortedcCst|_g|_dS)zClear all collected files.N)rrr)rrrrclear}s zManifest.clearcCsp||\}}}}|dkr!|D]}|j|ddstd|qdS|dkr3|D] }|j|dd}q'dS|dkrK|D]}|j|ddsHtd|q9dS|d kr]|D] }|j|dd}qQdS|d krv|D]}|j||d sstd ||qcdS|d kr|D] }|j||d }q|dS|dkr|jd|d std|dSdS|dkr|jd|d std|dSdStd|)av Process a directive which either adds some files from ``allfiles`` to ``files``, or removes some files from ``files``. :param directive: The directive to process. This should be in a format compatible with distutils ``MANIFEST.in`` files: http://docs.python.org/distutils/sourcedist.html#commands includeT)anchorzno files found matching %rexcludeglobal-includeFz3no files found matching %r anywhere in distributionglobal-excluderecursive-include)rz-no files found matching %r under directory %rrecursive-excludegraftNz no directories found matching %rprunez4no previously-included directories found matching %rzinvalid action %r)_parse_directive_include_patternr0warning_exclude_patternr)r directiveactionpatternsthedirZ dirpatternpatternfoundrrrprocess_directivesd zManifest.process_directivecCs|}t|dkr|ddvr|dd|d}d}}}|dvr ...cSg|]}t|qSrrr9wordrrrr:z-Manifest._parse_directive..)rGrHz*%r expects ...cSrVrrrWrrrr:rY)rIrJz!%r expects a single zunknown action %r)r2leninsertrr)rrOwordsrPrQrRZ dir_patternrrrrKs4        zManifest._parse_directiveTcCsPd}|||||}|jdur||jD]}||r%|j|d}q|S)aSelect strings (presumably filenames) from 'self.files' that match 'pattern', a Unix-style wildcard (glob) pattern. Patterns are not quite the same as implemented by the 'fnmatch' module: '*' and '?' match non-special characters, where "special" is platform-dependent: slash on Unix; colon, slash, and backslash on DOS/Windows; and colon on Mac OS. If 'anchor' is true (the default), then the pattern match is more stringent: "*.py" will match "foo.py" but not "foo/bar.py". If 'anchor' is false, both of these will match. If 'prefix' is supplied, then only filenames starting with 'prefix' (itself a pattern) and ending with 'pattern', with anything in between them, will match. 'anchor' is ignored in this case. If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and 'pattern' is assumed to be either a string containing a regex or a regex object -- no translation is done, the regex is just compiled and used as-is. Selected strings will be added to self.files. Return True if files are found. FNT)_translate_patternrr(searchrr*)rrSrCris_regexrT pattern_rer%rrrrLs    zManifest._include_patterncCsBd}|||||}t|jD]}||r|j|d}q|S)atRemove strings (presumably filenames) from 'files' that match 'pattern'. Other parameters are the same as for 'include_pattern()', above. The list 'self.files' is modified in place. Return True if files are found. This API is public to allow e.g. exclusion of SCM subdirs, e.g. when packaging source distributions FT)r^listrr_remove)rrSrCrr`rTrar@rrrrN)s   zManifest._exclude_patternc Cs|rt|tr t|S|Stdkr|dd\}}}|r5||}tdkr4||r2||s4Jnd}t t j |j d} |durtdkr\|d} ||dt|  } n||} | |rk| |smJ| t|t| t|} t j} t jdkrd} tdkrd| | | d|f}n3|t|t|t|}d || | | ||f}n|rtdkrd| |}n d || |t|df}t|S) aTranslate a shell-like wildcard pattern to a compiled regular expression. Return the compiled regex. If 'is_regex' true, then 'pattern' is directly compiled to a regex (if it's a string) or just returned as-is (assumes it's a regex object). )rZrr6r.N\z\\^z.*z%s%s%s%s.*%s%sz%s%s%s) isinstancestrrecompile_PYTHON_VERSION _glob_to_re partitionr)endswithescaper r rrr[r) rrSrCrr`startr6endrarZ empty_patternZ prefix_rerrrrr^=sH          zManifest._translate_patterncCs8t|}tj}tjdkrd}d|}td||}|S)zTranslate a shell-like glob pattern to a regular expression. Return a string containing the regex. Differs from 'fnmatch.translate()' in that '*' does not match "special characters" (which are platform-specific). rdz\\\\z\1[^%s]z((?rArUrKrLrNr^rkrrrrr%s(  O/ )  7)rxrqloggingr rhsysr.rcompatrutilr__all__ getLoggerrur0riMZ_COLLAPSE_PATTERNSZ_COMMENTED_LINE version_inforjobjectrrrrrs    PKH]O_RRQpython3.10/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-310.pycnu[o aiE@slddlZdZGdddeZzddlmZWney(GdddejZYnweeZ e edS)Nz0.3.3c@s eZdZdS)DistlibExceptionN)__name__ __module__ __qualname__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/__init__.pyr sr) NullHandlerc@s$eZdZddZddZddZdS)rcCdSNrselfrecordrrrhandlezNullHandler.handlecCr r rr rrremitrzNullHandler.emitcCs d|_dSr )lock)r rrr createLocks zNullHandler.createLockN)rrrrrrrrrrrs r) logging __version__ Exceptionrr ImportErrorHandler getLoggerrlogger addHandlerrrrrs  PKH] , ,Ppython3.10/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-310.pycnu[o ai8E@sddlmZddlZddlZddlZddlZddlZddlmZm Z m Z ddl m Z ddl mZmZmZmZmZmZeeZdZedZd Zd d ZeZGd d d eZdS))BytesION) sysconfigdetect_encodingZipFile)finder) FileOperatorget_export_entry convert_pathget_executable get_platformin_venva s^#!.*pythonw?[0-9.]*([ ].*)?$z# -*- coding: utf-8 -*- import re import sys from %(module)s import %(import_name)s if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(%(func)s()) cCsZd|vr+|dr"|dd\}}d|vr |ds d||f}|S|ds+d|}|S)N z /usr/bin/env r"z%s "%s"z"%s") startswithsplit) executableenv _executabler/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/scripts.pyenquote_executable3s   rc@seZdZdZeZdZ  d*ddZddZe j d r#d d Z d d Z ddZd+ddZddZeZddZddZdZddZd,ddZddZed d!Zejd"d!Zejd#kseejd kriejd#krid$d%Zd,d&d'Z d,d(d)Z!dS)- ScriptMakerz_ A class to copy or create scripts from source scripts or callable specifications. NTFcCs||_||_||_d|_d|_tjdkptjdkotjdk|_t d|_ |p)t ||_ tjdkp9tjdko9tjdk|_ tj|_dS)NFposixjava)X.Ynt) source_dir target_dir add_launchersforceclobberosname_nameset_modesetvariantsr_fileop_is_ntsys version_info)selfrrr dry_runfileoprrr__init__Ns   zScriptMaker.__init__cCs@|ddr|jrtj|\}}|dd}tj||}|S)NguiFpythonpythonw)getr*r#pathrreplacejoin)r-roptionsdnfnrrr_get_alternate_executable_s  z%ScriptMaker._get_alternate_executablerc Csdzt|}|ddkWdWS1swYWdSttfy1td|YdSw)zl Determine if the specified executable is a script (contains a #! line) z#!NzFailed to open %sF)openreadOSErrorIOErrorloggerwarning)r-rfprrr _is_shellgs  ( zScriptMaker._is_shellcCsJ||rddl}|jjddkr|Sd|S|dr!|Sd|S)Nrzos.nameLinuxz jython.exez/usr/bin/env %s)rDrlangSystem getPropertylowerendswith)r-rrrrr_fix_jython_executabless z"ScriptMaker._fix_jython_executablecCstjdkrd}nt|t|d}tjdkrd}nd}d|vo#||k}|r0d||d }|Sd }|d ||d 7}|d 7}|S)a Build a shebang line. In the simple case (on Windows, or a shebang line which is not too long or contains spaces) use a simple formulation for the shebang. Otherwise, use /bin/sh as the executable, with a contrived shebang which allows the script to run either under Python or sh, using suitable quoting. Thanks to Harald Nordgren for his input. See also: http://www.in-ulm.de/~mascheck/various/shebang/#length https://hg.mozilla.org/mozilla-central/file/tip/mach rTdarwini s#! s #!/bin/sh s '''exec' s "$0" "$@" s' ''')r#r$lenr+platform)r-r post_interpsimple_shebangshebang_lengthmax_shebang_lengthresultrrr_build_shebangs  zScriptMaker._build_shebangcCsnd}|jr |j}d}nDtst}n %srspythonwrr|) r#r5r7rr rrwr!r)newerrArr=r@r.readlinerB FIRST_LINE_REmatchr6groupclose copy_filer&rrinforseekrkrr>)r-rradjustrf first_linerrSrhlinesrjrrrrr _copy_script?sV       zScriptMaker._copy_scriptcCs|jjSrvr)r.)r-rrrr.rszScriptMaker.dry_runcCs ||j_dSrvr)r-valuerrrr.vs rcCsttddkr d}nd}tdkrdnd}d|||f}td d d }t||}|s7d ||f}t||jS) NPZ64Z32z win-arm64z-armrz %s%s%s.exerlrrz(Unable to find resource %s in package %s) structcalcsizer __name__rsplitrfindrgbytes)r-kindbitsZplatform_suffixr$Zdistlib_packageresourcemsgrrrr~szScriptMaker._get_launchercCs8g}t|}|dur||||S|j|||d|S)a Make a script. :param specification: The specification, which is either a valid export entry specification (to make a script from a callable) or a filename (to make a script by copying from a source location). :param options: A dictionary of options controlling script generation. :return: A list of all absolute pathnames written to. Nr)r rr)r- specificationr8rrtrrrmakes  zScriptMaker.makecCs$g}|D] }||||q|S)z Take a list of specifications and make scripts from them, :param specifications: A list of specifications. :return: A list of all absolute pathnames written to, )extendr)r-specificationsr8rrrrr make_multipleszScriptMaker.make_multiple)TFN)rYNrv)"r __module__ __qualname____doc__SCRIPT_TEMPLATErprr0r;r+rRrrDrKrXrkru_DEFAULT_MANIFESTrxr{rrrrrpropertyr.setterr#r$r%rrrrrrrrEs:    E4 3   r) iorloggingr#rerr+compatrrr resourcesrutilrr r r r r getLoggerrrAstriprcompilerrr_enquote_executableobjectrrrrrs$      PKH]xQpython3.10/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-310.pycnu[o ai@s0ddlZddlmZddlZddlZddlZddlZddlZzddlZWn e y1ddl ZYnwddl Z ddl m Z ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZddlmZm Z m!Z!ddl"m#Z#m$Z$ddl%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-dd l.m/Z/m0Z0dd l1m2Z2m3Z3e4e5Z6e7d Z8e7d ej9Z:e7d Z;dZGddde?Z@Gddde@ZAGddde@ZBGddde?ZCGddde@ZDGddde@ZEGdd d e@ZFGd!d"d"e@ZGGd#d$d$e@ZHeHeFeDd%d&d'd(d)ZIeIjJZJGd*d+d+e?ZKdS)-N)BytesIO)DistlibException)urljoinurlparse urlunparse url2pathname pathname2urlqueuequoteunescape build_openerHTTPRedirectHandler text_typeRequest HTTPErrorURLError) DistributionDistributionPath make_dist)MetadataMetadataInvalidError)cached_property ensure_slashsplit_filenameget_project_dataparse_requirementparse_name_and_version ServerProxynormalize_name) get_schemeUnsupportedVersionError)Wheel is_compatiblez^(\w+)=([a-f0-9]+)z;\s*charset\s*=\s*(.*)\s*$ztext/html|application/x(ht)?mlzhttps://pypi.org/pypicCs:|durt}t|dd}z |W|dS|dw)z Return all distribution names known by an index. :param url: The URL of the index. :return: A list of all known distribution names. N@timeoutclose) DEFAULT_INDEXr list_packages)urlclientr,/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/locators.pyget_all_distribution_names)s  r.c@s$eZdZdZddZeZZZdS)RedirectHandlerzE A class to work around a bug in some Python 3.2.x releases. c Csd}dD] }||vr||}nq|durdSt|}|jdkr7t||}t|dr3|||n|||<t||||||S)N)locationurireplace_header)rschemer get_full_urlhasattrr3BaseRedirectHandlerhttp_error_302) selfreqfpcodemsgheadersnewurlkeyurlpartsr,r,r-r8@s"  zRedirectHandler.http_error_302N)__name__ __module__ __qualname____doc__r8http_error_301http_error_303http_error_307r,r,r,r-r/7sr/c@seZdZdZdZdZdZdZedZd)dd Z d d Z d d Z ddZ ddZ ddZee eZddZddZddZddZddZddZd d!Zd"d#Zd$d%Zd*d'd(ZdS)+LocatorzG A base class for locators - things that locate distributions. )z.tar.gzz.tar.bz2z.tarz.zipz.tgzz.tbz)z.eggz.exe.whl)z.pdfN)rJdefaultcCs,i|_||_tt|_d|_t|_dS)a^ Initialise an instance. :param scheme: Because locators look for most recent versions, they need to know the version scheme to use. This specifies the current PEP-recommended scheme - use ``'legacy'`` if you need to support existing distributions on PyPI. N) _cacher4r r/openermatcherr Queueerrors)r9r4r,r,r-__init__fs  zLocator.__init__cCsXg}|js*z |jd}||Wn |jjyYqw|j|jr|S)z8 Return any errors which have occurred. F)rPemptygetappendEmpty task_done)r9resulter,r,r- get_errorsys    zLocator.get_errorscCs |dS)z> Clear any errors which may have been logged. N)rYr9r,r,r- clear_errorss zLocator.clear_errorscCs|jdSN)rLclearrZr,r,r- clear_cacheszLocator.clear_cachecCs|jSr\_schemerZr,r,r- _get_schemeszLocator._get_schemecCs ||_dSr\r_)r9valuer,r,r- _set_schemes zLocator._set_schemecCtd)a= For a given project, get a dictionary mapping available versions to Distribution instances. This should be implemented in subclasses. If called from a locate() request, self.matcher will be set to a matcher for the requirement to satisfy, otherwise it will be None. Please implement in the subclassNotImplementedError)r9namer,r,r- _get_projects zLocator._get_projectcCrd)J Return all the distribution names known to this locator. rerfrZr,r,r-get_distribution_nameszLocator.get_distribution_namescCsP|jdur ||}|S||jvr|j|}|S|||}||j|<|S)z For a given project, get a dictionary mapping available versions to Distribution instances. This calls _get_project to do all the work, and just implements a caching layer on top. N)rLrir[)r9rhrWr,r,r- get_projects     zLocator.get_projectcCs^t|}t|j}d}|d}||j}|r!tt||j}|j dkd|j v||||fS)zu Give an url a score which can be used to choose preferred URLs for a given project release. TrJhttpszpypi.org) r posixpathbasenamepathendswithdownloadable_extensionsr#r" wheel_tagsr4netloc)r9r*trp compatibleis_wheelZis_downloadabler,r,r- score_urls   zLocator.score_urlcCsT|}|r(||}||}||kr|}||kr!td|||Std|||S)a{ Choose one of two URLs where both are candidates for distribution archives for the same version of a distribution (for example, .tar.gz vs. zip). The current implementation favours https:// URLs over http://, archives from PyPI over those from other locations, wheel compatibility (if a wheel) and then the archive name. zNot replacing %r with %rzReplacing %r with %r)ryloggerdebug)r9url1url2rWs1s2r,r,r- prefer_urls   zLocator.prefer_urlcCs t||S)zZ Attempt to split a filename in project name, version and Python version. )r)r9filename project_namer,r,r-rs zLocator.split_filenamec Csdd}d}t|\}}}}} } | drtd|| t| } | r,| \} } nd\} } |}|r@|ddkr@|dd}|d rz>t |}t ||j sWtd |n+|dur^d }n||j |}|r|j |j |jt||||| d fd dd|jDd}Wnrty}z td|WYd}~n_d}~ww||jstd|nMt|}}|jD]B}||r|dt| }|||}|std|n!|\}}}|r|||r|||t||||| d fd}|r||d<nq|r| r| |d| <|S)a See if a URL is a candidate for a download URL for a project (the URL has typically been scraped from an HTML page). If it is, a dictionary is returned with keys "name", "version", "filename" and "url"; otherwise, None is returned. cSst|t|kSr\)r)Zname1Zname2r,r,r- same_projectsz:Locator.convert_url_to_download_info..same_projectNzegg=z %s: version hint in fragment: %r)NN/rJzWheel not compatible: %sTr2z, cSs"g|] }dt|ddqS).N)joinlist).0vr,r,r- s"z8Locator.convert_url_to_download_info..)rhversionrr*python-versionzinvalid path for wheel: %szNot downloadable: %sz No match for project/version: %s)rhrrr*r %s_digest)rlower startswithrzr{ HASHER_HASHmatchgroupsrrr"r#rtrhrrrrpyver Exceptionwarningrsrorplenr)r9r*rrrWr4rurqparamsqueryfragmalgodigestZorigpathwheelincluderXrextrvrhrrr,r,r-convert_url_to_download_infos~             z$Locator.convert_url_to_download_infocCsjd}d|vr|d}dD]}||vr|||f}nq |s3dD]}d|}||vr2|||f}|Sq|S)z Get a digest from a dictionary by looking at a "digests" dictionary or keys of the form 'algo_digest'. Returns a 2-tuple (algo, digest) if found, else None. Currently looks only for SHA256, then MD5. Ndigests)sha256md5rr,)r9inforWrrr@r,r,r- _get_digest1s"  zLocator._get_digestc Cs|d}|d}||vr||}|j}n t|||jd}|j}|||_}|d}||d|<|j|dkrN||j||_|d|t  |||_ |||<dS)z Update a result dictionary (the final result from _get_project) with a dictionary for a specific version, which typically holds information gleaned from a filename or URL for an archive for the distribution. rhrr4r*rurlsN) popmetadatarr4rr source_urlr setdefaultsetaddlocator) r9rWrrhrdistmdrr*r,r,r-_update_version_dataHs    zLocator._update_version_dataFc Csrd}t|}|durtd|t|j}||j|_}td|t|j | |j }t |dkrg}|j } |D]+} | dvrBq;z|| sIn |sP| | jsU|| Wq;tyftd|| Yq;wt |dkrtt||jd}|rtd ||d } || }|r|jr|j|_|d i| t|_i} |d i} |jD] }|| vr| || |<q| |_d|_|S) a Find the most recent distribution which matches the given requirement. :param requirement: A requirement of the form 'foo (1.0)' or perhaps 'foo (>= 1.0, < 2.0, != 1.3)' :param prereleases: If ``True``, allow pre-release versions to be located. Otherwise, pre-release versions are not returned. :return: A :class:`Distribution` instance, or ``None`` if no such distribution could be located. NzNot a valid requirement: %rzmatcher: %s (%s)rrrzerror matching %s with %rr)r@zsorted list: %srrr)rrr r4rN requirementrzr{typerBrmrhrZ version_classr is_prereleaserTrrsortedr@extrasrSr download_urlsr)r9r prereleasesrWrr4rNversionsslistZvclskrdsdr*r,r,r-locate_sV             zLocator.locate)rK)F)rBrCrDrEsource_extensionsbinary_extensionsexcluded_extensionsrtrsrQrYr[r^rarcpropertyr4rirkrmryrrrrrrr,r,r,r-rIVs0   JrIc0eZdZdZfddZddZddZZS)PyPIRPCLocatorz This locator uses XML-RPC to locate distributions. It therefore cannot be used with simple mirrors (that only mirror file content). c s.tt|jdi|||_t|dd|_dS)z Initialise an instance. :param url: The URL to use for XML-RPC. :param kwargs: Passed to the superclass constructor. r$r%Nr,)superrrQbase_urlrr+r9r*kwargs __class__r,r-rQszPyPIRPCLocator.__init__cCst|jSrj)rr+r)rZr,r,r-rksz%PyPIRPCLocator.get_distribution_namesc Csiid}|j|d}|D]o}|j||}|j||}t|jd}|d|_|d|_|d|_ |dg|_ |d|_ t |}|r}|d } | d |_ || |_||_|||<|D]} | d } || } |d |t| | |d | <q_q|S) NrTrrhrlicensekeywordssummaryrr*rr)r+Zpackage_releasesZ release_urlsZ release_datarr4rhrrSrrrrrrrrrrr) r9rhrWrrrdatarrrr*rr,r,r-ris2         zPyPIRPCLocator._get_projectrBrCrDrErQrkri __classcell__r,r,rr-rs   rcr)PyPIJSONLocatorzw This locator uses PyPI's JSON interface. It's very limited in functionality and probably not worth using. c s$tt|jdi|t||_dS)Nr,)rrrQrrrrr,r-rQszPyPIJSONLocator.__init__cCrdrjzNot available from this locatorrfrZr,r,r-rkrlz&PyPIJSONLocator.get_distribution_namesc Csiid}t|jdt|}z|j|}|}t|}t |j d}|d}|d|_ |d|_ | d|_| dg|_| d |_t|}||_|d } |||j <|d D]*} | d }|j||| |j|<|d |j t||| |d |<q\|d D]N\} } | |j krqt |j d} |j | _ | | _ t| }||_||| <| D])} | d }|j||| |j|<|d | t||| |d |<qqW|Sty}z|jt|td|WYd}~|Sd}~ww)Nrz%s/jsonrrrhrrrrrr*rZreleaseszJSON fetch failed: %s) rrr rMopenreaddecodejsonloadsrr4rhrrSrrrrrrrrrrritemsrrPputrrz exception)r9rhrWr*resprrrrrrrinfosZomdodistrXr,r,r-ris^               zPyPIJSONLocator._get_projectrr,r,rr-rs  rc@s`eZdZdZedejejBejBZ edejejBZ ddZ edejZ e ddZd S) Pagez4 This class represents a scraped HTML page. z (rel\s*=\s*(?:"(?P[^"]*)"|'(?P[^']*)'|(?P[^>\s ]*))\s+)? href\s*=\s*(?:"(?P[^"]*)"|'(?P[^']*)'|(?P[^>\s ]*)) (\s+rel\s*=\s*(?:"(?P[^"]*)"|'(?P[^']*)'|(?P[^>\s ]*)))? z!]+)cCs8||_||_|_|j|j}|r|d|_dSdS)zk Initialise an instance with the Unicode page contents and the URL they came from. rN)rrr*_basesearchgroup)r9rr*rr,r,r-rQ s  z Page.__init__z[^a-z0-9$&+,/:;=?@.#%_\\|-]cCsdd}t}|j|jD]E}|d}|dp,|dp,|dp,|dp,|dp,|d }|d p8|d p8|d }t|j|}t|}|j d d|}| ||fqt |dddd}|S)z Return the URLs of all the links on a page together with information about their "rel" attribute, for determining which ones to treat as downloads and which ones to queue for further scraping. cSs,t|\}}}}}}t||t||||fS)zTidy up an URL.)rrr )r*r4rurqrrrr,r,r-clean4s zPage.links..cleanr2Zrel1Zrel2Zrel3Zrel4Zrel5Zrel6r|r}Zurl3cSsdt|dS)Nz%%%2xr)ordr)rr,r,r-BszPage.links..cSs|dS)Nrr,)rvr,r,r-rFsT)r@reverse) r_hreffinditerr groupdictrrr _clean_resubrr)r9rrWrrrelr*r,r,r-links-s$  z Page.linksN)rBrCrDrErecompileISXrrrQrrrr,r,r,r-rs rcseZdZdZejdddddZdfdd Zd d Zd d Z ddZ e de j ZddZddZddZddZddZe dZddZZS)SimpleScrapingLocatorz A locator which scrapes HTML pages to locate downloads for a distribution. This runs multiple threads to do the I/O; performance is at least as good as pip's PackageFinder, which works in an analogous fashion. cCstjt|dS)N)fileobj)gzipGzipFilerrbr,r,r-rTszSimpleScrapingLocator.cCs|Sr\r,rr,r,r-rUs)deflaternoneN c sptt|jdi|t||_||_i|_t|_t |_ t|_ d|_ ||_t|_t|_d|_dS)a Initialise an instance. :param url: The root URL to use for scraping. :param timeout: The timeout, in seconds, to be applied to requests. This defaults to ``None`` (no timeout specified). :param num_workers: The number of worker threads you want to do I/O, This defaults to 10. :param kwargs: Passed to the superclass. FNr,)rrrQrrr& _page_cacher_seenr rO _to_fetch _bad_hostsskip_externals num_workers threadingRLock_lock_gplockplatform_check)r9r*r&rrrr,r-rQXs     zSimpleScrapingLocator.__init__cCsFg|_t|jD]}tj|jd}|d||j|qdS)z Threads are created only when get_project is called, and terminate before it returns. They are there primarily to parallelise I/O (i.e. fetching web pages). )targetTN) _threadsrangerrThread_fetch setDaemonstartrT)r9irvr,r,r-_prepare_threadsss z&SimpleScrapingLocator._prepare_threadscCs6|jD]}|jdq|jD]}|qg|_dS)zu Tell all the threads to terminate (by sending a sentinel value) and wait for them to do so. N)r rrr)r9rvr,r,r- _wait_threadss    z#SimpleScrapingLocator._wait_threadsc Csiid}|jF||_||_t|jdt|}|j|j| zt d||j ||j W|n|w|`Wd|S1sQwY|S)Nrz%s/z Queueing %s)r rWrrrr rr]rrrzr{rrrr)r9rhrWr*r,r,r-ris$       z"SimpleScrapingLocator._get_projectz<\b(linux_(i\d86|x86_64|arm\w+)|win(32|_amd64)|macosx_?\d+)\bcCs |j|S)zD Does an URL refer to a platform-specific download? )platform_dependentr)r9r*r,r,r-_is_platform_dependents z,SimpleScrapingLocator._is_platform_dependentcCsp|jr ||r d}n|||j}td|||r6|j||j|Wd|S1s1wY|S)a% See if an URL is a suitable download for a project. If it is, register information in the result dictionary (for _get_project) about the specific version it's for. Note that the return value isn't actually used other than as a boolean value. Nzprocess_download: %s -> %s) r rrrrzr{rrrW)r9r*rr,r,r-_process_downloads  z'SimpleScrapingLocator._process_downloadc Cst|\}}}}}}||j|j|jrd}n>|jr%||js%d}n2||js.d}n)|dvr5d}n"|dvr %s) rrrrrrrrrrsplitrrzr{) r9linkZreferrerrr4rurq_rWhostr,r,r- _should_queues.    z#SimpleScrapingLocator._should_queuec Cs |j}zozM|rS||}|durWW|jq|jD]4\}}||jvrRz!|j|||sG||||rGt d|||j |Wqt yQYqwqWnt yn}z|j t|WYd}~nd}~wwW|jn|jw|sdSq)z Get a URL to fetch from the work queue, get the HTML page, examine its links for download candidates and candidates for further scraping. This is a handy method to run in a thread. TNzQueueing %s from %s)rrSget_pagerVrrrrr!rzr{rrrrPr)r9r*pagerrrXr,r,r-rs@          zSimpleScrapingLocator._fetchc Cst|\}}}}}}|dkrtjt|rtt|d}||jvr0|j|}t d|||S| ddd}d}||j vrHt d|||St |d d id }zzlt d ||j j||jd } t d|| } | dd} t| r| } | } | d}|r|j|}|| } d}t| }|r|d}z| |} Wnty| d} Ynwt| | }||j| <Wnity}z|jdkrtd||WYd}~nXd}~wt y }z&td|||j!|j "|Wdn1swYWYd}~n.d}~wt#y&}z td||WYd}~nd}~wwW||j|<|SW||j|<|SW||j|<|SW||j|<|S||j|<w)a Get the HTML for an URL, possibly from an in-memory cache. XXX TODO Note: this cache is never actually cleared. It's assumed that the data won't get stale over the lifetime of a locator instance (not necessarily true for the default_locator). filez index.htmlzReturning %s from cache: %srrrNzSkipping %s due to bad host %szAccept-encodingidentity)r>z Fetching %sr%z Fetched %sz Content-Typer2zContent-Encodingzutf-8zlatin-1izFetch failed: %s: %s)$rosrqisdirrrrrrzr{rrrrMrr&rrSHTML_CONTENT_TYPErgeturlrdecodersCHARSETrrr UnicodeErrorrrr<rrrrr)r9r*r4rurqrrWr r:rr> content_typeZ final_urlrencodingdecoderrrXr,r,r-r"s   * %                 zSimpleScrapingLocator.get_pagez]*>([^<]+)tj||}tddttj |dddf}| |d}|r>| |dq|j sE|Sq |S)rjr$r2Nrh) rr&r9r6r8rqrrr r5rrr4)r9rWr:r;r<r=r*rr,r,r-rkqs$  z'DirectoryLocator.get_distribution_names) rBrCrDrErQr8rirkrr,r,rr-r3Cs  r3c@s eZdZdZddZddZdS) JSONLocatora This locator uses special extended metadata (not available on PyPI) and is the basis of performant dependency resolution in distlib. Other locators require archive downloads before dependencies can be determined! As you might imagine, that can be slow. cCrdrrfrZr,r,r-rkrlz"JSONLocator.get_distribution_namescCsiid}t|}|rk|dgD]Y}|ddks|ddkr qt|d|d|d d |jd }|j}|d |_d |vrH|d rHd|d f|_|di|_|di|_|||j <|d |j t  |d q|S)Nrr<ptypesdistZ pyversionsourcerhrrzPlaceholder for summary)rr4r*rr requirementsexportsr) rrSrr4rrr dependenciesrCrrrr)r9rhrWrrrrr,r,r-ris*    zJSONLocator._get_projectN)rBrCrDrErkrir,r,r,r-r>s r>cs(eZdZdZfddZddZZS)DistPathLocatorz This locator finds installed distributions in a path. It can be useful for adding to an :class:`AggregatingLocator`. c s.tt|jdi|t|tsJ||_dS)zs Initialise an instance. :param distpath: A :class:`DistributionPath` instance to search. Nr,)rrErQ isinstancerdistpath)r9rGrrr,r-rQs zDistPathLocator.__init__cCsR|j|}|duriid}|S|j|d|jt|jgid|jtdgii}|S)Nrrr)rGget_distributionrrr)r9rhrrWr,r,r-ris  zDistPathLocator._get_project)rBrCrDrErQrirr,r,rr-rEs  rEcsReZdZdZfddZfddZddZeej j eZ dd Z d d Z Z S) AggregatingLocatorzI This class allows you to chain and/or merge a list of locators. cs.|dd|_||_tt|jdi|dS)a Initialise an instance. :param locators: The list of locators to search. :param kwargs: Passed to the superclass constructor, except for: * merge - if False (the default), the first successful search from any of the locators is returned. If True, the results from all locators are merged (this can be slow). mergeFNr,)rrJlocatorsrrIrQ)r9rKrrr,r-rQs zAggregatingLocator.__init__cs&tt||jD]}|q dSr\)rrIr^rKr9rrr,r-r^s  zAggregatingLocator.clear_cachecCs||_|jD]}||_qdSr\)r`rKr4)r9rbrr,r,r-rcs zAggregatingLocator._set_schemec Csi}|jD]o}||}|rt|jrT|di}|di}|||d}|rE|rE|D]\}} ||vr@||| O<q/| ||<q/|d} |rS| rS| |q|jdur\d} nd} |D] }|j|rld} nq`| rt|}|Sq|S)NrrTF)rKrmrJrSupdaterrNr) r9rhrWrrr<rZdfrrddfoundr,r,r-ris@           zAggregatingLocator._get_projectc Cs8t}|jD]}z||O}WqtyYqw|Sr)rrKrkrg)r9rWrr,r,r-rks  z)AggregatingLocator.get_distribution_names)rBrCrDrErQr^rcrrIr4fgetrirkrr,r,rr-rIs  ,rIzhttps://pypi.org/simple/r$r%legacyrc@sLeZdZdZdddZddZddZd d Zd d Zd dZ dddZ dS)DependencyFinderz0 Locate dependencies for distributions. NcCs|pt|_t|jj|_dS)zf Initialise an instance, using the specified locator to locate distributions. N)default_locatorrr r4rLr,r,r-rQ/s zDependencyFinder.__init__cCsrtd||j}||j|<||j||jf<|jD]}t|\}}td||||j |t  ||fqdS)z Add a distribution to the finder. This will update internal information about who provides what. :param dist: The distribution to add. zadding distribution %szAdd to provided: %s, %s, %sN) rzr{r@ dists_by_namedistsrprovidesrprovidedrrr)r9rrhprr,r,r-add_distribution7s    z!DependencyFinder.add_distributioncCsxtd||j}|j|=|j||jf=|jD]"}t|\}}td||||j|}| ||f|s9|j|=qdS)z Remove a distribution from the finder. This will update internal information about who provides what. :param dist: The distribution to remove. zremoving distribution %sz Remove from provided: %s, %s, %sN) rzr{r@rTrUrrVrrWremove)r9rrhrXrsr,r,r-remove_distributionFs    z$DependencyFinder.remove_distributioncCs@z |j|}W|Sty|d}|j|}Y|Sw)z Get a version matcher for a requirement. :param reqt: The requirement :type reqt: str :return: A version matcher (an instance of :class:`distlib.version.Matcher`). r)r4rNr!r)r9reqtrNrhr,r,r- get_matcherXs zDependencyFinder.get_matcherc Cst||}|j}t}|j}||vr8||D]!\}}z||}Wn ty,d}Ynw|r7|||Sq|S)z Find the distributions which can fulfill a requirement. :param reqt: The requirement. :type reqt: str :return: A set of distribution which can fulfill the requirement. F)r^r@rrWrr!r) r9r]rNrhrWrWrproviderrr,r,r-find_providershs"   zDependencyFinder.find_providersc Cs|j|}t}|D]}||}||js||q |r.|d||t|fd}|S|||j|=|D] }|j|t|q9| |d}|S)a Attempt to replace one provider with another. This is typically used when resolving dependencies from multiple sources, e.g. A requires (B >= 1.0) while C requires (B >= 1.1). For successful replacement, ``provider`` must meet all the requirements which ``other`` fulfills. :param provider: The provider we are trying to replace with. :param other: The provider we're trying to replace. :param problems: If False is returned, this will contain what problems prevented replacement. This is currently a tuple of the literal string 'cantreplace', ``provider``, ``other`` and the set of requirements that ``provider`` couldn't fulfill. :return: True if we can replace ``other`` with ``provider``, else False. Z cantreplaceFT) reqtsrr^rrr frozensetr\rrY) r9r_otherproblemsZrlist unmatchedr[rNrWr,r,r-try_to_replaces(       zDependencyFinder.try_to_replaceFcCsi|_i|_i|_i|_t|pg}d|vr#|d|tgdO}t|tr3|}}t d|n|j j ||d}}|durGt d|t d|d|_ t}t|g}t|g}|rH|}|j} | |jvrr||n|j| } | |kr||| ||j|jB} |j} t} |r||vrd D]}d |}||vr| t|d |O} q| | B| B}|D]}||}|st d ||j j ||d}|dur|s|j j |dd}|durt d ||d|fn.|j|j}}||f|jvr|||||| vr||vr||t d|j|D]*}|j} | |jvr2|j|t|q|j| } | |krC||| |qq|s`t|j}|D]}||v|_|jrct d|jqQt d|||fS)a Find a distribution and all distributions it depends on. :param requirement: The requirement specifying the distribution to find, or a Distribution instance. :param meta_extras: A list of meta extras such as :test:, :build: and so on. :param prereleases: If ``True``, allow pre-release versions to be returned - otherwise, don't return prereleases unless they're all that's available. Return a set of :class:`Distribution` instances and a set of problems. The distributions returned should be such that they have the :attr:`required` attribute set to ``True`` if they were from the ``requirement`` passed to ``find()``, and they have the :attr:`build_time_dependency` attribute set to ``True`` unless they are post-installation dependencies of the ``requirement``. The problems should be a tuple consisting of the string ``'unsatisfied'`` and the requirement which couldn't be satisfied by any distribution known to the locator. z:*:)z:test:z:build:z:dev:zpassed %s as requirement)rNzUnable to locate %rz located %sT)testbuilddevz:%s:z %s_requireszNo providers found for %rzCannot satisfy %rZ unsatisfiedzAdding %s to install_distsz#%s is a build-time dependency only.zfind done for %s)rWrUrTrarrZrFrrzr{rrr requestedrr@rYrfZ run_requiresZ meta_requiresZbuild_requiresgetattrr`rrZname_and_versionrvaluesZbuild_time_dependency)r9rZ meta_extrasrrrrdtodoZ install_distsrhrcZireqtsZsreqtsZereqtsr@rXZ all_reqtsr providersr_nrrXrUr,r,r-finds                        3  zDependencyFinder.findr\)NF) rBrCrDrErQrYr\r^r`rfrpr,r,r,r-rR*s (rRr\)Lriorrloggingr&rorr ImportErrorZdummy_threadingr1r2rcompatrrrrr r r r r rr7rrrrZdatabaserrrrrrutilrrrrrrrrrr r!rr"r# getLoggerrBrzrrrr+r(r(r.r/objectrIrrrrr3r>rErIrSrrRr,r,r,r-s`     @(    G0E:zA&[PKH]gUQpython3.10/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-310.pycnu[o ais@sdZddlmZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z mZddlmZddlmZmZddlmZmZmZmZdd lmZmZmZmZmZmZm Z gd Z!e"e#Z$d Z%d Z&d eddde%dfZ'dZ(Gddde)Z*Gddde)Z+Gddde)Z,Gddde,Z-Gddde-Z.Gddde-Z/e.Z0e/Z1Gdd d e)Z2d*d"d#Z3d$d%Z4d&d'Z5d(d)Z6dS)+zPEP 376 implementation.)unicode_literalsN)DistlibException resources)StringIO) get_schemeUnsupportedVersionError)MetadataMETADATA_FILENAMEWHEEL_METADATA_FILENAMELEGACY_METADATA_FILENAME)parse_requirementcached_propertyparse_name_and_version read_exports write_exports CSVReader CSVWriter) DistributionBaseInstalledDistributionInstalledDistributionEggInfoDistributionDistributionPathzpydist-exports.jsonzpydist-commands.json INSTALLERRECORD REQUESTED RESOURCESSHAREDz .dist-infoc@s(eZdZdZddZddZddZdS) _CachezL A simple cache mapping names and .dist-info paths to distributions cCsi|_i|_d|_dS)zZ Initialise an instance. There is normally one for each DistributionPath. FN)namepath generatedselfr$/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/database.py__init__1s z_Cache.__init__cCs|j|jd|_dS)zC Clear the cache, setting it to its initial state. FN)rclearr r!r"r$r$r%r'9s   z _Cache.clearcCs6|j|jvr||j|j<|j|jg|dSdS)z` Add a distribution to the cache. :param dist: The distribution to add. N)r r setdefaultkeyappendr#distr$r$r%addAs  z _Cache.addN)__name__ __module__ __qualname____doc__r&r'r-r$r$r$r%r-s  rc@seZdZdZdddZddZdd ZeeeZd d Z d d Z ddZ e ddZ ddZddZdddZddZdddZdS)rzU Represents a set of distributions installed on a path (typically sys.path). NFcCsD|durtj}||_d|_||_t|_t|_d|_td|_ dS)a Create an instance from a path, optionally including legacy (distutils/ setuptools/distribute) distributions. :param path: The path to use, as a list of directories. If not specified, sys.path is used. :param include_egg: If True, this instance will look for and return legacy distributions as well as those based on PEP 376. NTdefault) sysr _include_dist _include_eggr_cache _cache_egg_cache_enabledr_scheme)r#r Z include_eggr$r$r%r&Os zDistributionPath.__init__cCs|jSNr8r"r$r$r%_get_cache_enabledcsz#DistributionPath._get_cache_enabledcCs ||_dSr:r;)r#valuer$r$r%_set_cache_enabledfs z#DistributionPath._set_cache_enabledcCs|j|jdS)z, Clears the internal cache. N)r6r'r7r"r$r$r% clear_cacheks zDistributionPath.clear_cachec csTt}|jD]}t|}|durq|d}|r|jsqt|j}|D]}||}|r3|j|vr4q%|jr|t rt t t g}|D]}t ||} || } | rTnqCq%t| } t| dd} Wdn1snwYtd|j||jt|j| |dVq%|jr|drtd|j||jt|j|Vq%qdS)zD Yield .dist-info and/or .egg(-info) distributions. NlegacyfileobjschemezFound %s)metadataenv) .egg-info.egg)setr rfinder_for_pathfind is_containersortedr4endswith DISTINFO_EXTr r r posixpathjoin contextlibclosing as_streamr loggerdebugr-new_dist_classr5old_dist_class) r#seenr finderrZrsetentryZpossible_filenamesZmetadata_filenameZ metadata_pathZpydiststreamrEr$r$r%_yield_distributionsssR           z%DistributionPath._yield_distributionscCsx|jj }|jo |jj }|s|r8|D]}t|tr#|j|q|j|q|r0d|j_|r:d|j_dSdSdS)zk Scan the path for distributions and populate the cache with those that are found. TN)r6r!r5r7r^ isinstancerr-)r#Zgen_distZgen_eggr,r$r$r%_generate_caches     z DistributionPath._generate_cachecCs|dd}d||gtS)ao The *name* and *version* parameters are converted into their filename-escaped form, i.e. any ``'-'`` characters are replaced with ``'_'`` other than the one in ``'dist-info'`` and the one separating the name from the version number. :parameter name: is converted to a standard distribution name by replacing any runs of non- alphanumeric characters with a single ``'-'``. :type name: string :parameter version: is converted to a standard version string. Spaces become dots, and all other non-alphanumeric characters (except dots) become dashes, with runs of multiple dashes condensed to a single dash. :type version: string :returns: directory name :rtype: string-_)replacerQrO)clsrversionr$r$r%distinfo_dirnames z!DistributionPath.distinfo_dirnameccsf|js|D]}|VqdS||jjD]}|Vq|jr/|jjD]}|Vq)dSdS)a5 Provides an iterator that looks for distributions and returns :class:`InstalledDistribution` or :class:`EggInfoDistribution` instances for each one of them. :rtype: iterator of :class:`InstalledDistribution` and :class:`EggInfoDistribution` instances N)r8r^r`r6r valuesr5r7r+r$r$r%get_distributionss z"DistributionPath.get_distributionscCsd}|}|js|D] }|j|kr|}|Sq |S|||jjvr0|jj|d}|S|jrA||jjvrA|jj|d}|S)a= Looks for a named distribution on the path. This function only returns the first result found, as no more than one value is expected. If nothing is found, ``None`` is returned. :rtype: :class:`InstalledDistribution`, :class:`EggInfoDistribution` or ``None`` Nr) lowerr8r^r)r`r6rr5r7)r#rresultr,r$r$r%get_distributions"     z!DistributionPath.get_distributionc csd}|dur#z |jd||f}Wnty"td||fw|D]8}t|ds5td|q'|j}|D]$}t |\}}|durP||krO|Vnq:||kr^| |r^|Vnq:q'dS)a Iterates over all distributions to find which distributions provide *name*. If a *version* is provided, it will be used to filter the results. This function only returns the first result found, since no more than one values are expected. If the directory is not found, returns ``None``. :parameter version: a version specifier that indicates the version required, conforming to the format in ``PEP-345`` :type name: string :type version: string N%s (%s)zinvalid name or version: %r, %rprovideszNo "provides": %s) r9matcher ValueErrorrrhhasattrrUrVrmrmatch) r#rrernr,providedpp_namep_verr$r$r%provides_distributions4    z&DistributionPath.provides_distributioncCs(||}|durtd|||S)z5 Return the path to a resource file. Nzno distribution named %r found)rk LookupErrorget_resource_path)r#r relative_pathr,r$r$r% get_file_path!s   zDistributionPath.get_file_pathccsZ|D]%}|j}||vr*||}|dur ||vr||Vq|D]}|Vq$qdS)z Return all of the exported entries in a particular category. :param category: The category to search for entries. :param name: If specified, only entries with that name are returned. N)rhexportsrg)r#categoryrr,r[dvr$r$r%get_exported_entries*s   z%DistributionPath.get_exported_entries)NFr:)r.r/r0r1r&r<r>propertyZ cache_enabledr?r^r` classmethodrfrhrkrvrzrr$r$r$r%rKs   ,  ) rc@seZdZdZdZ dZ ddZeddZeZ eddZ ed d Z d d Z ed dZ eddZeddZeddZeddZddZddZddZddZdS) rz A base class for distributions, whether installed or from indexes. Either way, it must have some metadata, so that's all that's needed for construction. FcCsL||_|j|_|j|_|j|_d|_d|_d|_d|_t |_ i|_ dS)z Initialise an instance. :param metadata: The instance of :class:`Metadata` describing this distribution. N) rErrir)relocatordigestextrascontextrIZ download_urlsdigests)r#rEr$r$r%r&Os  zDistribution.__init__cCs|jjS)zH The source archive download URL for this distribution. )rE source_urlr"r$r$r%r`szDistribution.source_urlcCd|j|jfS)zX A utility property which displays the name and version in parentheses. rlrrer"r$r$r%name_and_versioniszDistribution.name_and_versioncCs.|jj}d|j|jf}||vr|||S)z A set of distribution names and versions provided by this distribution. :return: A set of "name (version)" strings. rl)rErmrrer*)r#plistsr$r$r%rmps  zDistribution.providescCs8|j}td|t||}t|j||j|jdS)Nz%Getting requirements from metadata %r)rrF) rErUrVZtodictgetattrrIget_requirementsrr)r#Zreq_attrmdZreqtsr$r$r%_get_requirements|s   zDistribution._get_requirementscC |dS)N run_requiresrr"r$r$r%r zDistribution.run_requirescCr)N meta_requiresrr"r$r$r%rrzDistribution.meta_requirescCr)Nbuild_requiresrr"r$r$r%rrzDistribution.build_requirescCr)N test_requiresrr"r$r$r%rrzDistribution.test_requirescCr)N dev_requiresrr"r$r$r%rrzDistribution.dev_requiresc Cst|}t|jj}z||j}Wnty,td|| d}||}Ynw|j }d}|j D]}t |\}} ||krBq5z | | }W|StyTYq5w|S)z Say if this instance matches (fulfills) a requirement. :param req: The requirement to match. :rtype req: str :return: True if it matches, else False. +could not read version %r - using name onlyrF)r rrErDrn requirementrrUwarningsplitr)rmrrq) r#reqr[rDrnrrjrsrtrur$r$r%matches_requirements2       z Distribution.matches_requirementcCs(|jr d|j}nd}d|j|j|fS)zC Return a textual representation of this instance, z [%s]r@z)rrre)r#suffixr$r$r%__repr__s zDistribution.__repr__cCs@t|t|ur d}|S|j|jko|j|jko|j|jk}|S)a< See if this distribution is the same as another. :param other: The distribution to compare with. To be equal to one another. distributions must have the same type, name, version and source_url. :return: True if it is the same, else False. F)typerrer)r#otherrjr$r$r%__eq__s  zDistribution.__eq__cCst|jt|jt|jS)zH Compute hash in a way which matches the equality test. )hashrrerr"r$r$r%__hash__szDistribution.__hash__N)r.r/r0r1Zbuild_time_dependency requestedr&rr download_urlrrmrrrrrrrrrrr$r$r$r%r=s:         " rcs0eZdZdZdZdfdd ZdddZZS)rz] This is the base class for installed distributions (whether PEP 376 or legacy). Ncs tt||||_||_dS)a Initialise an instance. :param metadata: An instance of :class:`Metadata` which describes the distribution. This will normally have been initialised from a metadata file in the ``path``. :param path: The path of the ``.dist-info`` or ``.egg-info`` directory for the distribution. :param env: This is normally the :class:`DistributionPath` instance where this distribution was found. N)superrr&r dist_path)r#rEr rF __class__r$r%r&s  z"BaseInstalledDistribution.__init__cCsd|dur|j}|durtj}d}n tt|}d|j}||}t|dd}d||fS)a Get the hash of some data, using a particular hash algorithm, if specified. :param data: The data to be hashed. :type data: bytes :param hasher: The name of a hash implementation, supported by hashlib, or ``None``. Examples of valid values are ``'sha1'``, ``'sha224'``, ``'sha384'``, '``sha256'``, ``'md5'`` and ``'sha512'``. If no hasher is specified, the ``hasher`` attribute of the :class:`InstalledDistribution` instance is used. If the hasher is determined to be ``None``, MD5 is used as the hashing algorithm. :returns: The hash of the data. If a hasher was explicitly specified, the returned hash will be prefixed with the specified hasher followed by '='. :rtype: str Nr@z%s==ascii%s%s) hasherhashlibmd5rrbase64urlsafe_b64encoderstripdecode)r#datarprefixrr$r$r%get_hashs    z"BaseInstalledDistribution.get_hashr:)r.r/r0r1rr&r __classcell__r$r$rr%rs rcseZdZdZdZd'fdd ZddZdd Zd d Ze d d Z ddZ ddZ ddZ ddZd(ddZddZe ddZd(ddZdd Zd!d"Zd#d$Zd%d&ZejZZS))ra  Created with the *path* of the ``.dist-info`` directory provided to the constructor. It reads the metadata contained in ``pydist.json`` when it is instantiated., or uses a passed in Metadata instance (useful for when dry-run mode is being used). sha256Nc szg|_t||_}|durtd||r(|jr(||jjvr(|jj|j}nD|durl| t }|dur:| t }|durC| t }|durOtdt |ft |}t|dd}Wdn1sgwYtt|||||r|jr|j|| d}|du|_tj|d}tj|rt|d}|d} Wdn1swY| |_dSdS) Nzfinder unavailable for %szno %s found in %srArBr top_level.txtrbutf-8)modulesrrJrZror8r6r rErKr r r rRrSrTr rrr&r-rosrQexistsopenreadr splitlines) r#r rErFrZr[r]rsfrrr$r%r&s>          zInstalledDistribution.__init__cCd|j|j|jfS)Nz#rrer r"r$r$r%r= zInstalledDistribution.__repr__cCrNz%s %srr"r$r$r%__str__AzInstalledDistribution.__str__c Csg}|d}t|F}t|d(}|D]}ddtt|dD}||\}}} |||| fqWdn1s?wYWd|SWd|S1sWwY|S)a" Get the list of installed files for the distribution :return: A list of tuples of path, hash and size. Note that hash and size might be ``None`` for some entries. The path is exactly as stored in the file (which is as in PEP 376). rr]cSsg|]}dqSr:r$).0ir$r$r% Ssz6InstalledDistribution._get_records..N)get_distinfo_resourcerRrSrTrrangelenr*) r#resultsr[r]Z record_readerrowmissingr checksumsizer$r$r% _get_recordsDs"       z"InstalledDistribution._get_recordscCsi}|t}|r |}|S)a Return the information exported by this distribution. :return: A dictionary of exports, mapping an export category to a dict of :class:`ExportEntry` instances describing the individual export entries, and keyed by name. )rEXPORTS_FILENAMEr)r#rjr[r$r$r%r{[s  zInstalledDistribution.exportscCsNi}|t}|r%t| }t|}Wd|S1s wY|S)z Read exports data from a file in .ini format. :return: A dictionary of exports, mapping an export category to a list of :class:`ExportEntry` instances describing the individual export entries. N)rrrRrSrTr)r#rjr[r]r$r$r%ris   z"InstalledDistribution.read_exportscCsD|t}t|d}t||WddS1swYdS)a Write a dictionary of exports to a file in .ini format. :param exports: A dictionary of exports, mapping an export category to a list of :class:`ExportEntry` instances describing the individual export entries. wN)get_distinfo_filerrr)r#r{rfrr$r$r%rxs   "z#InstalledDistribution.write_exportsc Cs|d}t|:}t|d%}|D]\}}||kr/|WdWdSqWdn1s:wYWdn1sIwYtd|)aW NOTE: This API may change in the future. Return the absolute path to a resource file with the given relative path. :param relative_path: The path, relative to .dist-info, of the resource of interest. :return: The absolute path where the resource is to be found. rrNz3no resource file with relative path %r is installed)rrRrSrTrKeyError)r#ryr[r]Zresources_readerZrelative destinationr$r$r%rxs   z'InstalledDistribution.get_resource_pathccs|D]}|VqdS)z Iterates over the ``RECORD`` entries and returns a tuple ``(path, hash, size)`` for each line. :returns: iterator of (path, hash, size) N)r)r#rjr$r$r%list_installed_filess z*InstalledDistribution.list_installed_filesFc CsPtj|d}tj|j}||}tj|d}|d}td||r)dSt|q}|D]Q}tj |s=| drBd} } n$dtj |} t |d} | | } Wdn1sawY||sr|ry||rytj||}||| | fq0||rtj||}||ddfWd|S1swY|S)z Writes the ``RECORD`` file, using the ``paths`` iterable passed in. Any existing ``RECORD`` file is silently overwritten. prefix is used to determine when to write absolute paths. r@r creating %sNz.pycz.pyoz%dr)rr rQdirname startswithrrUinforisdirrNgetsizerrrrelpathwriterow) r#pathsrdry_runbaseZbase_under_prefix record_pathwriterr hash_valuerfpr$r$r%write_installed_filess8        z+InstalledDistribution.write_installed_filesc Cs*g}tj|j}|d}|D]\}}}tj|s$tj||}||kr)qtj|s9||dddfqtj |rt tj |}|rW||krW||d||fq|rd|vrf| ddd}nd }t |d } || |} | |kr||d || fWd n1swYq|S)  Checks that the hashes and sizes of the files in ``RECORD`` are matched by the files themselves. Returns a (possibly empty) list of mismatches. Each entry in the mismatch list will be a tuple consisting of the path, 'exists', 'size' or 'hash' according to what didn't match (existence is checked first, then size, then hash), the expected value and the actual value. rrTFr=rrNrr)rr rrrisabsrQrr*isfilestrrrrrr) r# mismatchesrrr rrZ actual_sizerrZ actual_hashr$r$r%check_installed_filess4       z+InstalledDistribution.check_installed_filescCsi}tj|jd}tj|rMtj|ddd}|}Wdn1s)wY|D]}|dd\}}|dkrH| |g |q0|||<q0|S) a A dictionary of shared locations whose keys are in the set 'prefix', 'purelib', 'platlib', 'scripts', 'headers', 'data' and 'namespace'. The corresponding value is the absolute path of that category for this distribution, and takes into account any paths selected by the user at installation time (e.g. via command-line arguments). In the case of the 'namespace' key, this would be a list of absolute paths for the roots of namespace packages in this distribution. The first time this property is accessed, the relevant information is read from the SHARED file in the .dist-info directory. rr[rencodingNrr namespace) rr rQrcodecsrrrrr(r*)r#rj shared_pathrlinesliner)r=r$r$r%shared_locationss  z&InstalledDistribution.shared_locationsc Cstj|jd}td||rdSg}dD]}||}tj||r-|d||fq|ddD] }|d|q4tj |d d d }| d |Wd|S1sZwY|S) aa Write shared location information to the SHARED file in .dist-info. :param paths: A dictionary as described in the documentation for :meth:`shared_locations`. :param dry_run: If True, the action is logged but no file is actually written. :return: The path of the file written to. rrN)rlibheadersscriptsrz%s=%srr$z namespace=%srrr ) rr rQrUrrr*getrrwrite) r#rrrrr)r nsrr$r$r%write_shared_locationss$  z,InstalledDistribution.write_shared_locationscCsF|tvr td||jft|j}|durtd|j||S)N+invalid path for a dist-info file: %r at %rzUnable to get a finder for %s) DIST_FILESrr rrJrK)r#r rZr$r$r%rs  z+InstalledDistribution.get_distinfo_resourcecCs~|tjdkr*|tjdd\}}||jtjdkr*td||j|jf|tvr7td||jftj |j|S)a Returns a path located under the ``.dist-info`` directory. Returns a string representing the path. :parameter path: a ``'/'``-separated path relative to the ``.dist-info`` directory or an absolute path; If *path* is an absolute path and doesn't start with the ``.dist-info`` directory path, a :class:`DistlibException` is raised :type path: str :rtype: str rNz;dist-info file %r does not belong to the %r %s distributionr) rKrseprr rrrer rQ)r#r rfr$r$r%r$s z'InstalledDistribution.get_distinfo_fileccsTtj|j}|D]\}}}tj|stj||}||jr'|Vq dS)z Iterates over the ``RECORD`` entries and returns paths for each line if the path is pointing to a file located in the ``.dist-info`` directory or one of its subdirectories. :returns: iterator of paths N)rr rrrrQr)r#rr rrr$r$r%list_distinfo_filesAs  z)InstalledDistribution.list_distinfo_filescCt|to |j|jkSr:)r_rr r#rr$r$r%rQ  zInstalledDistribution.__eq__)NNF)r.r/r0r1rr&rrrrr{rrrxrrrrrrrr robjectrrr$r$rr%rs."    ##   rcsjeZdZdZdZiZdfdd ZddZdd Zd d Z d d Z ddZ dddZ ddZ ejZZS)raCreated with the *path* of the ``.egg-info`` directory or file provided to the constructor. It reads the metadata contained in the file itself, or if the given path happens to be a directory, the metadata is read from the file ``PKG-INFO`` under that directory.TNcsdd}||_||_|r%|jr%||jjvr%|jj|j}|||j|jn||}|||j|j|r=|jr=|j|t t | |||dS)NcSs||_||_||_dSr:)rrir)re)rnr~r$r$r%set_name_and_versioncs  z:EggInfoDistribution.__init__..set_name_and_version) r rr8r7rErre _get_metadatar-rrr&)r#r rFrrErr$r%r&bs   zEggInfoDistribution.__init__csd}ddfdd}d}}|drytj|rBtj|d}tj|d}t|dd }tj|d } tj|d }|| }nht|} t| d  d } t| dd}z| d} | d d}| d}Wn<t yxd}Yn2w|drtj|rtj|d } || }tj|d}tj|d }t|dd }nt d||r| ||dur|durtj|rt|d} |  d}Wdn1swY|sg}n|}||_|S)NcSsg}|}|D]H}|}|drtd||St|}|s)td|q|jr1td|js;||j qd dd|jD}|d|j |fq|S) zCreate a list of dependencies from a requires.txt file. *data*: the contents of a setuptools-produced requires.txt file. [z.Unexpected line: quitting requirement scan: %rz#Not recognised as a requirement: %rz4extra requirements in requires.txt are not supportedz, css|]}d|VqdS)rNr$)rcr$r$r% szQEggInfoDistribution._get_metadata..parse_requires_data..rl) rstriprrUrr r constraintsr*rrQ)rreqsrrr[Zconsr$r$r%parse_requires_datazs*    z>EggInfoDistribution._get_metadata..parse_requires_datacs^g}z"t|dd}|}WdW|S1swYW|Sty.Y|Sw)zCreate a list of dependencies from a requires.txt file. *req_path*: the path to a setuptools-produced requires.txt file. r[rN)rrrIOError)req_pathrrrr$r%parse_requires_paths  z>EggInfoDistribution._get_metadata..parse_requires_pathrHzEGG-INFOzPKG-INFOrA)r rDz requires.txtrzEGG-INFO/PKG-INFOutf8rBzEGG-INFO/requires.txtzEGG-INFO/top_level.txtrrGz,path must end with .egg-info or .egg, got %rr)rNrr rrQr zipimport zipimporterrget_datarrrZadd_requirementsrrrrr)r#r requiresr Ztl_pathZtl_datars meta_pathrErZzipfrCrrr$rr%rws\             z!EggInfoDistribution._get_metadatacCr)Nz!rr"r$r$r%rrzEggInfoDistribution.__repr__cCrrrr"r$r$r%rrzEggInfoDistribution.__str__cCs`g}tj|jd}tj|r.|D]\}}}||krqtj|s-||dddfq|S)rinstalled-files.txtrTF)rr rQrrr*)r#rrr rbr$r$r%rs   z)EggInfoDistribution.check_installed_filescCsdd}dd}tj|jd}g}tj|rqtj|dddA}|D]6}|}tjtj|j|}tj|sGt d || d rGq#tj |sY| |||||fq#Wd n1sdwY| |d d f|S) z Iterates over the ``installed-files.txt`` entries and returns a tuple ``(path, hash, size)`` for each line. :returns: a list of (path, hash, size) cSs8t|d}z |}W|n|wt|S)Nr)rrcloserr hexdigest)r rcontentr$r$r%_md5s  z6EggInfoDistribution.list_installed_files.._md5cSs t|jSr:)rstatst_size)r r$r$r%_sizes z7EggInfoDistribution.list_installed_files.._sizer'r[rrzNon-existent file: %srN) rr rQrrrrnormpathrUrrNrr*)r#r+r.rrjrrrsr$r$r%rs(      z(EggInfoDistribution.list_installed_filesFccstj|jd}tj|rYd}tj|ddd6}|D]*}|}|dkr)d}q|sFtjtj|j|}||jrF|rC|Vq|VqWddS1sRwYdSdS) a  Iterates over the ``installed-files.txt`` entries and returns paths for each line if the path is pointing to a file located in the ``.egg-info`` directory or one of its subdirectories. :parameter absolute: If *absolute* is ``True``, each returned path is transformed into a local absolute path. Otherwise the raw value from ``installed-files.txt`` is returned. :type absolute: boolean :returns: iterator of paths r'Tr[rrz./FN) rr rQrrrrr/r)r#absoluterskiprrrsr$r$r%r s(  "z'EggInfoDistribution.list_distinfo_filescCrr:)r_rr rr$r$r%r.rzEggInfoDistribution.__eq__r:r)r.r/r0r1rrr&rrrrrr rrrrr$r$rr%rYsZ &rc@s^eZdZdZddZddZdddZd d Zd d ZdddZ dddZ ddZ ddZ dS)DependencyGrapha Represents a dependency graph between distributions. The dependency relationships are stored in an ``adjacency_list`` that maps distributions to a list of ``(other, label)`` tuples where ``other`` is a distribution and the edge is labeled with ``label`` (i.e. the version specifier, if such was provided). Also, for more efficient traversal, for every distribution ``x``, a list of predecessors is kept in ``reverse_list[x]``. An edge from distribution ``a`` to distribution ``b`` means that ``a`` depends on ``b``. If any missing dependencies are found, they are stored in ``missing``, which is a dictionary that maps distributions to a list of requirements that were not provided by any other distributions. cCsi|_i|_i|_dSr:)adjacency_list reverse_listrr"r$r$r%r&Is zDependencyGraph.__init__cCsg|j|<g|j|<dS)zAdd the *distribution* to the graph. :type distribution: :class:`distutils2.database.InstalledDistribution` or :class:`distutils2.database.EggInfoDistribution` N)r3r4)r# distributionr$r$r%add_distributionNs z DependencyGraph.add_distributionNcCs:|j|||f||j|vr|j||dSdS)aAdd an edge from distribution *x* to distribution *y* with the given *label*. :type x: :class:`distutils2.database.InstalledDistribution` or :class:`distutils2.database.EggInfoDistribution` :type y: :class:`distutils2.database.InstalledDistribution` or :class:`distutils2.database.EggInfoDistribution` :type label: ``str`` or ``None`` N)r3r*r4)r#xylabelr$r$r%add_edgeXs zDependencyGraph.add_edgecCs&td|||j|g|dS)a Add a missing *requirement* for the given *distribution*. :type distribution: :class:`distutils2.database.InstalledDistribution` or :class:`distutils2.database.EggInfoDistribution` :type requirement: ``str`` z %s missing %rN)rUrVrr(r*)r#r5rr$r$r% add_missinggszDependencyGraph.add_missingcCsd|j|jfSrrr+r$r$r% _repr_distrrzDependencyGraph._repr_distrcCs||g}|j|D]4\}}||}|durd||f}|d|t||||d}|d}||ddq d|S)zPrints only a subgraphNz%s [%s]z rr)r<r3r*r repr_noderextendrQ)r#r,leveloutputrr9Z suboutputsubsr$r$r%r=us     zDependencyGraph.repr_nodeTcCsg}|d|jD]4\}}t|dkr|s|||D] \}}|dur4|d|j|j|fq|d|j|jfqq |sot|dkro|d|d|d|D]}|d |j|d qZ|d |d dS) a9Writes a DOT output for the graph to the provided file *f*. If *skip_disconnected* is set to ``True``, then all distributions that are not dependent on any other distribution are skipped. :type f: has to support ``file``-like operations :type skip_disconnected: ``bool`` zdigraph dependencies { rNz"%s" -> "%s" [label="%s"] z "%s" -> "%s" zsubgraph disconnected { zlabel = "Disconnected" zbgcolor = red z"%s"rz} )rr3itemsrr*r)r#rZskip_disconnected disconnectedr,adjsrr9r$r$r%to_dots*         zDependencyGraph.to_dotcsg}i}|jD] \}}|dd||<q gt|ddD]\}}|s1|||=q#s5n%|D]\}}fdd|D||<q9tdddD|q|t|fS)aa Perform a topological sort of the graph. :return: A tuple, the first element of which is a topologically sorted list of distributions, and the second element of which is a list of distributions that cannot be sorted because they have circular dependencies and so form a cycle. NTcs g|] \}}|vr||fqSr$r$)rr}r[ to_remover$r%rs z4DependencyGraph.topological_sort..zMoving to result: %scSsg|] }d|j|jfqS)rlr)rr}r$r$r%rs)r3rBlistr*rUrVr>keys)r#rjalistkr~r$rFr%topological_sorts*   z DependencyGraph.topological_sortcCs2g}|jD] \}}|||qd|S)zRepresentation of the graphr)r3rBr*r=rQ)r#r@r,rDr$r$r%rs zDependencyGraph.__repr__r:)r)T) r.r/r0r1r&r6r:r;r<r=rErLrr$r$r$r%r29s    r2r2c CsLt|}t}i}|D]&}|||jD]}t|\}}td|||||g||fqq |D]o}|j |j B|j B|j B}|D]^} z| | } Wntygtd| | d}| |} Ynw| j}d} ||vr||D]$\}} z| |} Wn tyd} Ynw| r||| | d} nqu| s||| qDq4|S)a6Makes a dependency graph from the given distributions. :parameter dists: a list of distributions :type dists: list of :class:`distutils2.database.InstalledDistribution` and :class:`distutils2.database.EggInfoDistribution` instances :rtype: a :class:`DependencyGraph` instance zAdd to provided: %s, %s, %srrFT)rr2r6rmrrUrVr(r*rrrrrnrrrr)rqr:r;)distsrDgraphrrr,rsrrer%rrnmatchedproviderrqr$r$r% make_graphsZ        rQcCsx||vr td|jt|}|g}|j|}|r5|}|||j|D] }||vr2||q'|s|d|S)zRecursively generate a list of distributions from *dists* that are dependent on *dist*. :param dists: a list of distributions :param dist: a distribution, member of *dists* for which we are interested 1given distribution %r is not a member of the listr)rrrQr4popr*)rMr,rNdeptodor}succr$r$r%get_dependent_distss"    rWcCsp||vr td|jt|}g}|j|}|r6|d}|||j|D] }||vr3||q(|s|S)zRecursively generate a list of distributions from *dists* that are required by *dist*. :param dists: a list of distributions :param dist: a distribution, member of *dists* for which we are interested rRr)rrrQr3rSr*)rMr,rNrrUr}predr$r$r%get_required_distss     rYcKs8|dd}tdi|}||_||_|pd|_t|S)zO A convenience method for making a dist given just a name and version. summaryzPlaceholder for summaryNr$)rSr rrerZr)rrekwargsrZrr$r$r% make_dist2s  r\)r2)7r1 __future__rrrrRrloggingrrPr3r"r@rrcompatrrerrrEr r r r utilr rrrrrr__all__ getLoggerr.rUrZCOMMANDS_FILENAMEr rOrrrrrrrrWrXr2rQrWrYr\r$r$r$r%sV  $ s7J] 6 PKH]C)H+H+Rpython3.10/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-310.pycnu[o aiD* @s~ddlmZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl m Z mZmZeeZdaGdddeZGdd d eZGd d d eZGd d d eZGdddeZGdddeZedee jeiZz&zddlZWn e yddl!ZYnweeej"<eeej#<eeej$<[Wn e e%fyYnwddZ&iZ'ddZ(e)e*dZ+ddZ,dS))unicode_literalsN)DistlibException)cached_propertyget_cache_baseCachecs.eZdZdfdd ZddZddZZS) ResourceCacheNcs0|durtjttd}tt||dS)Nzresource-cache)ospathjoinrstrsuperr__init__)selfbase __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/resources.pyrszResourceCache.__init__cCsdS)z Is the cache stale for the given resource? :param resource: The :class:`Resource` being cached. :param path: The path of the resource in the cache. :return: True if the cache is stale. Trrresourcer rrris_stale"s zResourceCache.is_stalecCs|j|\}}|dur|}|Stj|j|||}tj|}tj|s-t |tj |s6d}n| ||}|rZt |d}| |jWd|S1sUwY|S)z Get a resource into the cache, :param resource: A :class:`Resource` instance. :return: The pathname of the resource in the cache. NTwb)finderget_cache_infor r r r prefix_to_dirdirnameisdirmakedirsexistsropenwritebytes)rrprefixr resultrstalefrrrget-s$       zResourceCache.getN)__name__ __module__ __qualname__rrr' __classcell__rrrrrs rc@seZdZddZdS) ResourceBasecCs||_||_dSr()rname)rrr.rrrrHs zResourceBase.__init__N)r)r*r+rrrrrr-Gs r-c@s@eZdZdZdZddZeddZeddZed d Z d S) Resourcez A class representing an in-package resource, such as a data file. This is not normally instantiated by user code, but rather by a :class:`ResourceFinder` which manages the resource. FcC |j|S)z Get the resource as a stream. This is not a property to make it obvious that it returns a new stream each time. )r get_streamrrrr as_streamUs zResource.as_streamcCstdurtat|Sr()cacherr'r2rrr file_path^s zResource.file_pathcCr0r()r get_bytesr2rrrr"e zResource.bytescCr0r()rget_sizer2rrrsizeir7z Resource.sizeN) r)r*r+__doc__ is_containerr3rr5r"r9rrrrr/Ms  r/c@seZdZdZeddZdS)ResourceContainerTcCr0r()r get_resourcesr2rrr resourcesqr7zResourceContainer.resourcesN)r)r*r+r;rr>rrrrr<nsr<c@seZdZdZejdrdZndZddZddZ d d Z d d Z d dZ ddZ ddZddZddZddZddZeejjZddZdS)ResourceFinderz4 Resource finder for file system resources. java).pyc.pyoz.class)rArBcCs.||_t|dd|_tjt|dd|_dS)N __loader____file__)modulegetattrloaderr r rr)rrFrrrrszResourceFinder.__init__cC tj|Sr()r r realpathrr rrr _adjust_path zResourceFinder._adjust_pathcCsBt|trd}nd}||}|d|jtjj|}||S)N//r) isinstancer"splitinsertrr r r rL)r resource_nameseppartsr$rrr _make_paths    zResourceFinder._make_pathcCrIr()r r rrKrrr_findrMzResourceFinder._findcCs d|jfSr()r rrrrrrs zResourceFinder.get_cache_infocCsF||}||sd}|S||rt||}nt||}||_|Sr()rVrW _is_directoryr<r/r )rrSr r$rrrfinds    zResourceFinder.findcCs t|jdSNrb)r r rXrrrr1rMzResourceFinder.get_streamcCs8t|jd }|WdS1swYdSr[)r r read)rrr&rrrr6s$zResourceFinder.get_bytescCstj|jSr()r r getsizerXrrrr8zResourceFinder.get_sizecs*fddtfddt|jDS)Ncs|dko |j S)N __pycache__)endswithskipped_extensions)r&r2rralloweds z-ResourceFinder.get_resources..allowedcsg|]}|r|qSrr).0r&)rcrr sz0ResourceFinder.get_resources..)setr listdirr rXr)rcrrr=s zResourceFinder.get_resourcescCs ||jSr()rYr rXrrrr;rMzResourceFinder.is_containerccs||}|durD|g}|rF|d}|V|jr@|j}|jD]}|s'|}nd||g}||}|jr<||q |Vq |sdSdSdS)NrrO)rZpopr;r.r>r append)rrSrtodornamer.new_namechildrrriterators(     zResourceFinder.iteratorN)r)r*r+r:sysplatform startswithrbrrLrVrWrrZr1r6r8r=r; staticmethodr r rrYrnrrrrr?vs$     r?cs`eZdZdZfddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ Z S)ZipResourceFinderz6 Resource finder for resources in .zip files. csZtt|||jj}dt||_t|jdr|jj|_nt j ||_t |j|_ dS)Nr_files) r rsrrHarchivelen prefix_lenhasattrrt zipimport_zip_directory_cachesortedindex)rrFrurrrrs   zZipResourceFinder.__init__cCs|Sr(rrKrrrrLszZipResourceFinder._adjust_pathcCs||jd}||jvrd}n+|r|dtjkr|tj}t|j|}z |j||}Wn ty9d}Ynw|sGt d||j j |St d||j j |S)NTFz_find failed: %r %rz_find worked: %r %r) rwrtr rTbisectr|rq IndexErrorloggerdebugrHr#)rr r$irrrrWs    zZipResourceFinder._findcCs&|jj}|jdt|d}||fS)Nr)rHrur rv)rrr#r rrrrsz ZipResourceFinder.get_cache_infocCs|j|jSr()rHget_datar rXrrrr6r_zZipResourceFinder.get_bytescCst||Sr()ioBytesIOr6rXrrrr1zZipResourceFinder.get_streamcCs|j|jd}|j|dS)N)r rwrtrrrrr8szZipResourceFinder.get_sizecCs|j|jd}|r|dtjkr|tj7}t|}t}t|j|}|t|jkrV|j||s6 |S|j||d}| | tjdd|d7}|t|jks+|S)Nr}rr) r rwr rTrvrfr~r|rqaddrQ)rrr plenr$rsrrrr=s zZipResourceFinder.get_resourcescCsh||jd}|r|dtjkr|tj7}t|j|}z |j||}W|Sty3d}Y|Sw)Nr}F)rwr rTr~r|rqr)rr rr$rrrrYs  zZipResourceFinder._is_directory)r)r*r+r:rrLrWrr6r1r8r=rYr,rrrrrss  rscCs|tt|<dSr()_finder_registrytype)rH finder_makerrrrregister_finder2rrcCs|tvr t|}|S|tjvrt|tj|}t|dd}|dur&tdt|dd}tt|}|dur=td|||}|t|<|S)z Return a resource finder for a package. :param package: The name of the package. :return: A :class:`ResourceFinder` instance for the package. __path__Nz8You cannot get a finder for a module, only for a packagerCzUnable to locate finder for %r) _finder_cacheromodules __import__rGrrr'r)packager$rFr rHrrrrr9s      r __dummy__cCsRd}t|tj|}tt|}|r't}tj |d|_ ||_ ||}|S)z Return a resource finder for a path, which should represent a container. :param path: The path. :return: A :class:`ResourceFinder` instance for the path. NrE) pkgutil get_importerropath_importer_cacher'rr _dummy_moduler r r rDrC)r r$rHrrFrrrfinder_for_pathUs  r)- __future__rr~rloggingr rrotypesryrErutilrrr getLoggerr)rr4robjectr-r/r<r?rsr zipimporterr_frozen_importlib_externalZ_fi ImportError_frozen_importlibSourceFileLoader FileFinderSourcelessFileLoaderAttributeErrorrrr ModuleTyper rrrrrrsP   ,!ZO       PKH]GljjNpython3.10/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-310.pycnu[o ai@sddlmZddlZddlZddlZddlmZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlmZmZddlmZmZmZmZmZddlmZddlmZmZm Z m!Z!dd l"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,dd l-m.Z.m/Z/e 0e1Z2da3e4ed rd Z5nej67d rdZ5n ej6dkrdZ5ndZ5e8dZ9e9sdej:ddZ9de9Z;e5e9Ze8dZ?e?re?7dre?=dd@ddZ?nddZAeAZ?[Ae Bde jCe jDBZEe Bde jCe jDBZFe BdZGe Bd ZHd!ZId"ZJe jKd#krd$d%ZLnd&d%ZLGd'd(d(eMZNeNZOGd)d*d*eMZPd+d,ZQd-d.ZReRZS[Rd1d/d0ZTdS)2)unicode_literalsN)message_from_file) __version__DistlibException) sysconfigZipFilefsdecode text_typefilter)InstalledDistribution)MetadataMETADATA_FILENAMEWHEEL_METADATA_FILENAMELEGACY_METADATA_FILENAME) FileOperator convert_path CSVReader CSVWriterCachecached_propertyget_cache_base read_exportstempdir get_platform)NormalizedVersionUnsupportedVersionErrorpypy_version_infoppjavajycliipcppy_version_nodotz%s%spy-_.SOABIzcpython-cCsRdtg}tdr|dtdr|dtddkr$|dd |S) Nr#Py_DEBUGd WITH_PYMALLOCmPy_UNICODE_SIZEu) VER_SUFFIXrget_config_varappendjoin)partsr8/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/wheel.py _derive_abi<s      r:zz (?P[^-]+) -(?P\d+[^-]*) (-(?P\d+[^-]*))? -(?P\w+\d+(\.\w+\d+)*) -(?P\w+) -(?P\w+(\.\w+)*) \.whl$ z7 (?P[^-]+) -(?P\d+[^-]*) (-(?P\d+[^-]*))?$ s \s*#![^\r\n]*s^(\s*#!("[^"]+"|\S+))\s+(.*)$s#!pythons #!pythonw/cCs|SNr8or8r8r9^sr?cCs|tjdS)Nr;)replaceossepr=r8r8r9r?`sc@s6eZdZddZddZddZd dd Zd d ZdS) MountercCsi|_i|_dSr<) impure_wheelslibsselfr8r8r9__init__ds zMounter.__init__cCs||j|<|j|dSr<)rDrEupdate)rGpathname extensionsr8r8r9addhs z Mounter.addcCs0|j|}|D] \}}||jvr|j|=qdSr<)rDpoprE)rGrJrKkvr8r8r9removels   zMounter.removeNcCs||jvr |}|Sd}|Sr<)rE)rGfullnamepathresultr8r8r9 find_modulers zMounter.find_modulecCsl|tjvr tj|}|S||jvrtd|t||j|}||_|dd}t|dkr4|d|_ |S)Nzunable to find extension for %sr)rr) sysmodulesrE ImportErrorimpZ load_dynamic __loader__rsplitlen __package__)rGrQrSr7r8r8r9 load_moduleys      zMounter.load_moduler<)__name__ __module__ __qualname__rHrLrPrTr]r8r8r8r9rCcs   rCc@seZdZdZdZdZd4ddZedd Zed d Z ed d Z e ddZ ddZ e ddZddZd5ddZddZddZddZd6ddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd7d,d-Zd.d/Zd0d1Zd5d2d3ZdS)8Wheelz@ Class to build and install from Wheel files (PEP 427). )rrsha256NFcCs<||_||_d|_tg|_dg|_dg|_t|_ |dur*d|_ d|_ |j |_ dSt|}|rO|d}|d|_ |dd d |_ |d |_|j |_ dStj|\}}t|}|sdtd ||rmtj||_ ||_ |d}|d|_ |d|_ |d |_|d d|_|dd|_|dd|_dS)zB Initialise an instance using a (valid) filename. r2noneanyNdummyz0.1nmZvnr(r'ZbnzInvalid name or filename: %rr&r)Zbiar)signZ should_verifybuildverPYVERpyverabiarchrAgetcwddirnamenameversionfilename _filenameNAME_VERSION_REmatch groupdictr@rRsplit FILENAME_RErabspath)rGrrrhverifyr.inforor8r8r9rHsD            zWheel.__init__cCs^|jr d|j}nd}d|j}d|j}d|j}|jdd}d|j|||||fS)zJ Build and return a filename from the various components. r'r2r)r(z%s-%s%s-%s-%s-%s.whl)rir6rkrlrmrqr@rp)rGrirkrlrmrqr8r8r9rrs     zWheel.filenamecCstj|j|j}tj|Sr<)rArRr6rorrisfile)rGrRr8r8r9existss z Wheel.existsccs6|jD]}|jD]}|jD]}|||fVqq qdSr<)rkrlrm)rGrkrlrmr8r8r9tagss   z Wheel.tagsc Cs2tj|j|j}d|j|jf}d|}td}t |dp}| |}|d dd}t dd |D}t tg} d} | D]=} z2t|| } || } || }t|d } | rb WdWnWdn1slwYWq>ty{Yq>w| std d | Wd| S1swY| S) N%s-%s %s.dist-infoutf-8r Wheel-Versionr)rcSg|]}t|qSr8int.0ir8r8r9 z"Wheel.metadata..)fileobjz8Invalid wheel, because metadata is missing: looked in %sz, )rArRr6rorrrprqcodecs getreaderrget_wheel_metadatarwtuplerr posixpathopenr KeyError ValueError)rGrJname_verinfo_dirwrapperzfwheel_metadatawv file_versionfnsrSfnmetadata_filenamebfwfr8r8r9metadatasD        zWheel.metadatacCsrd|j|jf}d|}t|d}||}td|}t|}Wdt|S1s0wYt|S)NrrWHEELr) rprqrr6rrrrdict)rGrrrrrrmessager8r8r9rs    zWheel.get_wheel_metadatacCsLtj|j|j}t|d}||}Wd|S1swY|S)Nr)rArRr6rorrrr)rGrJrrSr8r8r9r{s   z Wheel.infoc Cst|}|r?|}|d|||d}}d|vr!t}nt}t|}|r3d|d}nd}||}||}|S|d}|d} |dksQ|| krTd} n|||dd krad } nd} t| |}|S) Nspythonw   rr%s ) SHEBANG_REruendlowerSHEBANG_PYTHONWSHEBANG_PYTHONSHEBANG_DETAIL_REgroupsfind) rGdatar.rshebangZdata_after_shebangZshebang_pythonargsZcrlfZtermr8r8r9process_shebangs.     zWheel.process_shebangcCsb|dur|j}ztt|}Wn tytd|w||}t|d d}||fS)NzUnsupported hash algorithm: %r=ascii) hash_kindgetattrhashlibAttributeErrorrdigestbase64urlsafe_b64encoderstripdecode)rGrrhasherrSr8r8r9get_hash%s   zWheel.get_hashcCslt|}ttj||}||ddft|}|D]}||qWddS1s/wYdS)Nr2)listto_posixrArRrelpathr5rwriterow)rGrecords record_pathbasepwriterrowr8r8r9 write_record0s  "zWheel.write_recordc Csg}|\}}tt|j}|D]2\}} t| d } | } Wdn1s&wYd|| } tj| } | || | fqtj |d} | || |t tj |d}| || fdS)Nrbz%s=%sRECORD) rrrrreadrrArRgetsizer5r6rr)rGr{libdir archive_pathsrdistinforraprfrrsizer8r8r9 write_records8s     zWheel.write_recordscCs\t|dtj}|D]\}}td|||||q WddS1s'wYdS)NwzWrote %s to %s in wheel)rzipfile ZIP_DEFLATEDloggerdebugwrite)rGrJrrrrr8r8r9 build_zipHs  "zWheel.build_zipc" s|duri}ttfdddd}|dkr#d}tg}tg}tg}n d}tg}d g}d g}|d ||_|d ||_|d ||_ |} d|j |j f} d| } d| } g} dD]}|vrbq[|}t j |rt |D]l\}}}|D]d}tt j ||}t j ||}tt j | ||}| ||f|dkr|dst|d }|}Wdn1swY||}t|d }||Wdn1swYqxqqq[| }d}t |D]W\}}}||krt|D]\}}t|}|drt j ||}||=nq|sJd|D]$}t|dr&qt j ||}tt j ||}| ||fqqt |}|D]!}|dvrgtt j ||}tt j | |}| ||fqGd|po|jdtd|g}|jD]\}}}|d|||fq{t j |d}t|d}|d |Wdn 1swYtt j | d}| ||fd!d"} t| | d#} | || f| | t j |j!|j"}!|#|!| |!S)$z Build a wheel from files in specified paths, and use any specified tags when determining the name of the wheel. Ncs|vSr<r8r=pathsr8r9r?VszWheel.build..)purelibplatlibrrfalsetruercrdrkrlrmr%s.datar)rheadersscriptsr.exerwb .dist-infoz(.dist-info directory expected, not found)z.pycz.pyo)r INSTALLERZSHAREDrzWheel-Version: %d.%dzGenerator: distlib %szRoot-Is-Purelib: %sz Tag: %s-%s-%srr cSs*|d}|d}d|vr|d7}||fS)Nrr;ri')count)trnr8r8r9sorters  zWheel.build..sorter)key)$rr IMPVERABIARCHrjgetrkrlrmrprqrArRisdirwalkr r6rrr5endswithrrrr enumeratelistdir wheel_versionrr~sortedrrorrr)"rGrr~rZlibkeyis_pureZ default_pyverZ default_abiZ default_archrrdata_dirrrrrRrootdirsfilesrrrprrrrrdnrrkrlrmrrJr8rr9buildNs             z Wheel.buildcCs |dS)zl Determine whether an archive entry should be skipped when verifying or installing. )r;z /RECORD.jws)r)rGarcnamer8r8r9 skip_entrys zWheel.skip_entrycC KsP|j}|d}|dd}|dd}tj|j|j}d|j|jf} d| } d| } t | t } t | d} t | d }t d }t |d }|| }||}t|}Wd n1scwY|d dd}tdd|D}||jkr|r||j||ddkr|d}n|d}i}||*}t|d}|D] }|d}|||<qWd n1swYWd n1swYt | d}t | d}t | dd}t|d}d|_tj } g}!t}"|"|_d |_zz|D]}#|#j}$t|$tr|$}%n|$d }%| |%rq||%}|dr6t!|#j"|dkr6t#d|%|drr|ddd\}&}'||$ }|$}(Wd n 1sZwY|%|(|&\})}*|*|'krrt#d|$|r|%&||frt'(d |%q|%&|o|%)d! }+|%&|r|%d"d\})},}-tj||,t*|-}.n|%| |fvrqtj|t*|%}.|+sU||$}|+||.Wd n 1swYtjd#krt,|.|#j-d$?d%@|!.|.|s(|dr(t|.d&}|$}(|%|(|&\})}/|/|*krt#d'|.Wd n 1s#wY| rS|.)d(rSz|j/|.|d)}0|!.|0Wqt0yRt'j1d*dd+Yqwqtj2t*|$}1tj|"|1}2||$}|+||2Wd n 1s{wYtj|.\}3}1|3|_|3|1}4|4|4|!5|4q|rt'(d,d }5nMd }6|j6d }|d-kr$t | d.}7zZ||7 }t7|}8Wd n 1swYi}6d/D]9}9d0|9}:|:|8vri|6d1|9<};|8|:8D]}|6d:i}?|>su|?r|dd}@tj>|@st?d;|@|_|>@D]\}:}<|5C||}|r|!.||5D|!|d?||5WWtEF|"Wd St0yt'Gd@|HwtEF|"w1s!wYd S)Aa~ Install a wheel to the specified paths. If kwarg ``warner`` is specified, it should be a callable, which will be called with two tuples indicating the wheel version of this software and the wheel version in the file, if there is a discrepancy in the versions. This can be used to issue any warnings to raise any exceptions. If kwarg ``lib_only`` is True, only the purelib/platlib files are installed, and the headers, scripts, data and dist-info metadata are not written. If kwarg ``bytecode_hashed_invalidation`` is True, written bytecode will try to use file-hash based invalidation (PEP-552) on supported interpreter versions (CPython 2.7+). The return value is a :class:`InstalledDistribution` instance unless ``options.lib_only`` is True, in which case the return value is ``None``. warnerlib_onlyFZbytecode_hashed_invalidationrrrrrrrNrr)rcSrr8rrr8r8r9rrz!Wheel.install..zRoot-Is-Purelibrrrstreamrr2r)dry_runTr%size mismatch for %s=digest mismatch for %szlib_only: skipping %srr;posixirzdigest mismatch on write for %sz.py)hashed_invalidationzByte-compilation failed)exc_infozlib_only: returning Nonez1.0zentry_points.txt)consoleguiz %s_scriptszwrap_%sz%s:%sz [%s],zAUnable to read legacy script metadata, so cannot generate scriptsrKzpython.commandsz8Unable to read JSON metadata, so cannot generate scriptsZ wrap_consoleZwrap_guizValid script path not specifiedz%s = %srlibprefixzinstallation failed.)Ir rrArRr6rorrrprqrrrrrrrrwrrrrrecordrUdont_write_bytecodetempfilemkdtemp source_dir target_dirinfolist isinstancer rrstr file_sizerrr startswithrrrr copy_streamchmod external_attrr5 byte_compile Exceptionwarningbasenamemakeset_executable_modeextendr{rvaluesrsuffixflagsjsonloadrritemsr rZwrite_shared_locationsZwrite_installed_filesshutilrmtree exceptionrollback)CrGrmakerkwargsr r r Zbc_hashed_invalidationrJrrr metadata_namewheel_metadata_name record_namerrbwfrrrrrrrreaderrrZdata_pfxZinfo_pfxZ script_pfxfileopZbcZoutfilesworkdirzinfor u_arcnamekindvaluerr(rZ is_scriptwhereroutfileZ newdigestZpycrZworknamer filenamesdistcommandsepZepdatarrNr,rOsconsole_scripts gui_scriptsZ script_dirscriptoptionsr8r8r9installs                                                            F  z Wheel.installcCs8tdurtjttddtjdd}t|atS)Nz dylib-cachez%s.%sr%) cacherArRr6rr"rU version_infor)rGrr8r8r9_get_dylib_caches zWheel._get_dylib_cachec Cstj|j|j}d|j|jf}d|}t|d}t d}g}t |d}z| |r}||} t | } |} | |} tj| j| } tj| sTt| | D]@\}}tj| t|}tj|snd}nt|j}tj|}||}tj|j}||k}|r||| |||fqXWdn1swYWn tyYn wWd|SWd|S1swY|S)NrrZ EXTENSIONSrrT)rArRr6rorrrprqrrrrrr2r3rT prefix_to_dirrrmakedirsr4rr}statst_mtimedatetime fromtimestampgetinfo date_timeextractr5r)rGrJrrrrrSrrrrKrRrZ cache_baserprdestr]Z file_timer{Z wheel_timer8r8r9_get_extensionssT                 zWheel._get_extensionscCst|S)zM Determine if a wheel is compatible with the running system. ) is_compatiblerFr8r8r9r`szWheel.is_compatiblecCsdS)zP Determine if a wheel is asserted as mountable by its metadata. Tr8rFr8r8r9 is_mountableszWheel.is_mountablecCstjtj|j|j}|sd|}t||s%d|}t||t jvr2t d|dS|r;t j |nt j d||}|r[tt jvrSt j tt||dSdS)Nz)Wheel %s not compatible with this Python.z$Wheel %s is marked as not mountable.z%s already in pathr)rArRryr6rorrr`rrarUrrr5insertr__hook meta_pathrL)rGr5rJmsgrKr8r8r9mounts$   z Wheel.mountcCs|tjtj|j|j}|tjvrtd|dStj ||t j vr*t |t j s:t tj vr.r rr;..invalid entry in wheel: %rr%rrr)rArRr6rorrrprqrrrrrrrrwrrr r!r rrrr"r#rr)rGrJrrrr;r<r=rrr>rrrrrrr?rrrBrrCrDrErr(rr8r8r9rzsn                   $z Wheel.verifyc Ksdd}dd}tj|j|j}d|j|jf}d|}t|d} t} t |dC} i} | D]4} | j}t |t r@|}n| d }|| krJq3d |vrTtd || | | tj| t|}|| |<q3Wd n1srwY|| |\}}|| fi|}|r|| |\}}|r||kr||||d urtjd d| d\}}t|ntj|std|tj||j}t| }tj| |}||f}||| |||||d urt||Wd |SWd |SWd |S1swY|S)a Update the contents of a wheel in a generic way. The modifier should be a callable which expects a dictionary argument: its keys are archive-entry paths, and its values are absolute filesystem paths where the contents the corresponding archive entries can be found. The modifier is free to change the contents of the files pointed to, add new entries and remove entries, before returning. This method will extract the entire contents of the wheel to a temporary location, call the modifier, and then use the passed (and possibly updated) dictionary to write a new wheel. If ``dest_dir`` is specified, the new wheel is written there -- otherwise, the original wheel is overwritten. The modifier should return True if it updated the wheel, else False. This method returns the same value the modifier returns. cSsHd}}d|tf}||vrd|}||vr ||}t|dj}||fS)Nz%s/%sz %s/PKG-INFOrR)rr rq)path_maprrqrRrr8r8r9 get_version`s  z!Wheel.update..get_versioncSsd}z>t|}|d}|dkrd|}n*dd||dddD}|dd7<d |d|dd d |Df}WntyOtd |Ynw|rot|d }||_| t }|j ||dtd||dSdS)Nr'rz%s+1cSrr8r)rrLr8r8r9rrrz8Wheel.update..update_version..rr)rz%s+%scss|]}t|VqdSr<)r"rr8r8r9 usz7Wheel.update..update_version..z0Cannot update non-compliant (PEP-440) version %rrj)rRlegacyzVersion updated from %r to %r) rrrwr6rrrr rqrrr)rqrRupdatedrOrr7Zmdrnr8r8r9update_versionjs4       z$Wheel.update..update_versionrrrrrrhriNz.whlz wheel-update-)r0rdirzNot a directory: %r)rArRr6rorrrprqrrrr r!r rrr]rrmkstempcloserrr4rrr5copyfile)rGmodifierdest_dirr:rlrprJrrr=rArrkrBrrCrRZoriginal_versionr(modifiedcurrent_versionfdnewpathrrr{r8r8r9rIOsr                - - --z Wheel.update)NFFr<)NN)F)r^r_r`__doc__rrrHpropertyrrr}r~rrrr{rrrrrrrrQrTr_r`rarfrgrzrIr8r8r8r9rasB )        tn "  8racCsZddl}|}g}|ddkr+|ddD]}||r#t|ndqt|}|S)Nrglibcrr))platformlibc_verrwr5isdigitrr)r~verrSrLr8r8r9_get_glibc_versions rc CsRtg}td}ttjddddD]}|d|t|gqg}tD]\}}}| dr<|| dddq'| t dkrK| dt |dg}tg}tjd krtd t}|r|\} }}} t|}| g} | d vrz| d | d vr| d| dvr| d| dvr| d| dvr| d|dkr| D]} d| ||| f} | tkr|| q|d8}|dks|D]}|D]} |dt|df|| f|dkrMtj drM| dd} t}t|dkrM|dkr |dt|df|d| f|dkr|dt|df|d| f|dkr5|dt|df|d| f|dt|df|d|d|d| ffqqt|D]&\}}|dt|fddf|dkrx|dt|dfddfqSt|D]&\}}|dd |fddf|dkr|dd |dfddfq~t|S)!zG Return (pyver, abi, arch) tuples compatible with this Python. rrrr2z.abir)r%rcdarwinz(\w+)_(\d+)_(\d+)_(\w+)$)i386ppcfat)rrx86_64Zfat3)ppc64rfat64)rrintel)rrrrr universalz %s_%s_%s_%slinuxZlinux_)r%z manylinux1_%s)r% zmanylinux2010_%s)r%zmanylinux2014_%szmanylinux_%s_%s_%srdr&)r3rangerUrSr5r6r"rXZ get_suffixesr$rwsortrrbrr~rerurr IMP_PREFIXr@rr[rset)versionsmajorminorabisr0r(rSarchesr.rprmmatchesrurLrlr7rrqr8r8r9compatible_tagss                 rcCs^t|ts t|}d}|durt}|D]\}}}||jvr,||jvr,||jvr,d}|Sq|S)NFT)r!raCOMPATIBLE_TAGSrkrlrm)wheelr~rSrrlrmr8r8r9r`s r`r<)U __future__rrrrYemailrrrXr2loggingrArrr5rUrrr2rrcompatrrr r r Zdatabaser rr rrrutilrrrrrrrrrrrqrr getLoggerr^rrRhasattrrr~r$r4r3rSrjrr@rrrwr:compile IGNORECASEVERBOSErxrtrrrrrBrobjectrCrcrarrrr`r8r8r8r9s   0             #1 PPKH]T\{\{Opython3.10/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-310.pycnu[o ai @sddlmZddlZddlZddlZzddlZWn ey#dZYnwejddkrddlmZe fZ e Z ddl mZddlZddlZddlmZddlmZmZmZmZmZdd lmZmZmZm Z m!Z!m"Z"m#Z#d d Zddl$Z$dd l$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-erdd l$m.Z.ddl/Z/ddl0Z0ddl1Z2ddl3m3Z3ddl4Z4e5Z5ddl6m7Z8ddl6m9Z:nddl;mZemZmZmZmZmZmZmZm#Z#ddl?m&Z&mZm%Z%m Z m!Z!m)Z)m*Z*m+Z+m,Z,m-Z-erdd l?m.Z.ddl@m(Z(m'Z'm"Z"ddlAmBZ/ddl?mCZ$ddlDmBZ0ddl2Z2ddlEm3Z3ddlFmGZ4eHZ5ddl6m:Z:e8Z8z ddlmIZImJZJWneybGdddeKZJdbddZLddZIYnwzddl mMZNWney}GdddeOZNYnwzdd lmPZPWneyejQejRBdfd!d"ZPYnwdd#lSmTZUeVeUd$reUZTndd%lSmWZXGd&d'd'eXZWGd(d)d)eUZTzdd*lYmZZZWneyd+d,ZZYnwzddl[Z[Wneydd-lm[Z[Ynwze\Z\Wne]ydd.l^m_Z_d/d0Z\Ynwzej`Z`ejaZaWn#eby3ecpd1Zdedd2kr'd3Zend4Zed5d6Z`d7d8ZaYnwzdd9lfmgZgWn#ey_dd:lhmiZimjZjddlZekd;Zldd?ZgYnwzdd@lnmoZoWneyxdd@lpmoZoYnwejddAdBkre3jqZqnddClnmqZqzddDlrmsZsWn0eyddElrmtZtzddFlumvZwWneydcdHdIZwYnwGdJdKdKetZsYnwzddLlxmyZyWn"eyzddLlzmyZyWneydddMdNZyYnwYnwzddOlrm{Z{WnBey<zddPl|m}Z~WneyddPlm}Z~Ynwz ddQlmZmZmZWn ey1YnwGdRdSdSeZ{Ynwz ddTlmZmZWdSeyekdUejZdVdWZGdXdYdYeZdddZd[ZGd\d]d]eZGd^d_d_eZGd`dadaeOZYdSw)e)absolute_importN)StringIO)FileType)shutil)urlparse urlunparseurljoinurlsplit urlunsplit) urlretrievequoteunquote url2pathname pathname2urlContentTooShortError splittypecCst|tr |d}t|S)Nutf-8) isinstanceunicodeencode_quote)sr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/compat.pyrs  r) RequesturlopenURLError HTTPErrorHTTPBasicAuthHandlerHTTPPasswordMgr HTTPHandlerHTTPRedirectHandler build_opener) HTTPSHandler) HTMLParser)ifilter) ifilterfalse) TextIOWrapper)rr r rrr r r) rr rrrr r!r"r#r$)rrr) filterfalse)match_hostnameCertificateErrorc@s eZdZdS)r,N)__name__ __module__ __qualname__rrrrr,`sr,c Csg}|sdS|d}|d|dd}}|d}||kr'tdt||s1||kS|dkr;|dn|d sE|d rN|t|n |t| d d |D] }|t|q\t d d |dtj } | |S)zpMatching according to RFC 6125, section 6.4.3 http://tools.ietf.org/html/rfc6125#section-6.4.3 F.rrN*z,too many wildcards in certificate DNS name: z[^.]+zxn--z\*z[^.]*z\Az\.z\Z)splitcountr,reprlowerappend startswithreescapereplacecompilejoin IGNORECASEmatch) dnhostname max_wildcardspatspartsleftmost remainder wildcardsfragpatrrr_dnsname_matchds*     rIcCs|stdg}|dd}|D]\}}|dkr%t||r dS||q|sJ|ddD]}|D]\}}|dkrHt||rCdS||q2q.t|dkr^td |d tt|ft|dkrntd ||d ftd )a=Verify that *cert* (in decoded format as returned by SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 rules are followed, but IP addresses are not accepted for *hostname*. CertificateError is raised on failure. On success, the function returns nothing. ztempty or no certificate, match_hostname needs a SSL socket or SSL context with either CERT_OPTIONAL or CERT_REQUIREDsubjectAltNamerDNSNsubject commonNamerz&hostname %r doesn't match either of %s, zhostname %r doesn't match %rrz=no appropriate commonName or subjectAltName fields were found) ValueErrorgetrIr6lenr,r<mapr4)certr@dnsnamessankeyvaluesubrrrr+s8          r+)SimpleNamespacec@eZdZdZddZdS) ContainerzR A generic container for when multiple values need to be returned cKs|j|dSN__dict__update)selfkwargsrrr__init__szContainer.__init__N)r-r.r/__doc__rbrrrrr[s r[)whichc s"dd}tjr||rSdS|durtjdtj}|s#dS|tj}tj dkr^tj |vr:| dtj tjddtj}t fd d |DrTg}n fd d |D}ng}t }|D](}tj|}||vr|||D]} tj|| } || |r| SqyqfdS) aKGiven a command, mode, and a PATH string, return the path which conforms to the given mode on the PATH, or None if there is no such file. `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result of os.environ.get("PATH"), or can be overridden with a custom search path. cSs&tj|ot||otj| Sr\)ospathexistsaccessisdir)fnmoderrr _access_checks zwhich.._access_checkNPATHwin32rPATHEXTc3s"|] }|VqdSr\)r5endswith.0extcmdrr s zwhich..csg|]}|qSrrrrrurr zwhich..)rerfdirnameenvironrPdefpathr2pathsepsysplatformcurdirinsertanysetnormcaseaddr<) rvrkrfrlpathextfilesseendirnormdirthefilenamerrurrds<         rd)ZipFile __enter__) ZipExtFilec@$eZdZddZddZddZdS)rcCs|j|jdSr\r])r`baserrrrbzZipExtFile.__init__cC|Sr\rr`rrrrzZipExtFile.__enter__cG |dSr\closer`exc_inforrr__exit__ zZipExtFile.__exit__N)r-r.r/rbrrrrrrrs rc@r)rcCrr\rrrrrr$rzZipFile.__enter__cGrr\rrrrrr'rzZipFile.__exit__cOs tj|g|Ri|}t|Sr\) BaseZipFileopenr)r`argsrarrrrr+sz ZipFile.openN)r-r.r/rrrrrrrr#s r)python_implementationcCs0dtjvrdStjdkrdStjdrdSdS)z6Return a string identifying the Python implementation.PyPyjavaJython IronPythonCPython)r~versionrerr7rrrrr2s   r) sysconfig)CallablecCs t|tSr\)rr)objrrrcallableF rrmbcsstrictsurrogateescapecC6t|tr|St|tr|ttStdt|jNzexpect bytes or str, not %s) rbytes text_typer _fsencoding _fserrors TypeErrortyper-filenamerrrfsencodeZ   rcCrr) rrrdecoderrrrr-rrrrfsdecodecrr)detect_encoding)BOM_UTF8lookupzcoding[:=]\s*([-\w.]+)cCsH|dddd}|dks|drdS|dvs |dr"d S|S) z(Imitates get_normal_name in tokenizer.c.N _-rzutf-8-)zlatin-1 iso-8859-1z iso-latin-1)zlatin-1-z iso-8859-1-z iso-latin-1-r)r5r:r7)orig_encencrrr_get_normal_nametsrcszjjWn tydYnwdd}d}fdd}fdd}|}|tr7d|d d}d }|s=|gfS||}|rH||gfS|}|sR||gfS||}|r^|||gfS|||gfS) a? The detect_encoding() function is used to detect the encoding that should be used to decode a Python source file. It requires one argument, readline, in the same way as the tokenize() generator. It will call readline a maximum of twice, and return the encoding used (as a string) and a list of any lines (left as bytes) it has read in. It detects the encoding from the presence of a utf-8 bom or an encoding cookie as specified in pep-0263. If both a bom and a cookie are present, but disagree, a SyntaxError will be raised. If the encoding cookie is an invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, 'utf-8-sig' is returned. If no encoding is specified, then the default of 'utf-8' will be returned. NFrcszWStyYdSw)N) StopIterationr)readlinerr read_or_stops  z%detect_encoding..read_or_stopcsz|d}Wntyd}durd|}t|wt|}|s(dSt|d}zt|}WntyQdurGd|}t|d|}t|wrp|j dkrldurcd}t|d}t||d 7}|S) Nrz'invalid or missing encoding declarationz {} for {!r}rzunknown encoding: zunknown encoding for {!r}: {}zencoding problem: utf-8z encoding problem for {!r}: utf-8z-sig) rUnicodeDecodeErrorformat SyntaxError cookie_refindallrr LookupErrorr)line line_stringmsgmatchesencodingcodec) bom_foundrrr find_cookies@        z$detect_encoding..find_cookieTrz utf-8-sig)__self__rAttributeErrorr7r)rrdefaultrrfirstsecondr)rrrrrs6   &      r)r9)r)unescape)ChainMap)MutableMapping)recursive_repr...csfdd}|S)zm Decorator to make a repr function return fillvalue for a recursive call csLtfdd}td|_td|_td|_tdi|_|S)Nc sJt|tf}|vr S|z |}W||S|wr\)id get_identrdiscard)r`rVresult) fillvalue repr_running user_functionrrwrappers    z=_recursive_repr..decorating_function..wrapperr.rcr-__annotations__)rgetattrr.rcr-r)rrr)rrrdecorating_functions  z,_recursive_repr..decorating_functionr)rrrrr_recursive_reprs rc@seZdZdZddZddZddZd'd d Zd d Zd dZ ddZ ddZ e ddZ eddZddZeZddZeddZddZdd Zd!d"Zd#d$Zd%d&ZdS)(ra A ChainMap groups multiple dicts (or other mappings) together to create a single, updateable view. The underlying mappings are stored in a list. That list is public and can accessed or updated using the *maps* attribute. There is no other state. Lookups search the underlying mappings successively until a key is found. In contrast, writes, updates, and deletions only operate on the first mapping. cGst|pig|_dS)zInitialize a ChainMap by setting *maps* to the given mappings. If no mappings are provided, a single empty dictionary is used. N)listmaps)r`rrrrrbszChainMap.__init__cCst|r\)KeyErrorr`rVrrr __missing__szChainMap.__missing__c Cs6|jD]}z||WStyYqw||Sr\)rrr)r`rVmappingrrr __getitem__s   zChainMap.__getitem__NcCs||vr||S|Sr\rr`rVrrrrrP'sz ChainMap.getcCttj|jSr\)rQrunionrrrrr__len__*rzChainMap.__len__cCrr\)iterrrrrrrr__iter__-rzChainMap.__iter__cstfdd|jDS)Nc3s|]}|vVqdSr\r)rsmrVrrrw1sz(ChainMap.__contains__..rrrrrr __contains__0szChainMap.__contains__cCs t|jSr\rrrrr__bool__3rzChainMap.__bool__cCsd|dtt|jS)Nz{0.__class__.__name__}({1})rN)rr<rRr4rrrrr__repr__6szChainMap.__repr__cGs|tj|g|RS)z?Create a ChainMap with a single dict created from the iterable.)dictfromkeys)clsiterablerrrrr;szChainMap.fromkeyscCs&|j|jdg|jddRS)zHNew ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]rrN) __class__rcopyrrrrr @s&z ChainMap.copycCs|jig|jRS)z;New ChainMap with a new dict followed by all previous maps.r rrrrr new_childFszChainMap.new_childcCs|j|jddS)zNew ChainMap from maps[1:].rNr rrrrparentsJszChainMap.parentscCs||jd|<dS)Nr)r)r`rVrWrrr __setitem__OrzChainMap.__setitem__cCs0z |jd|=WdStytd|w)Nr(Key not found in the first mapping: {!r})rrrrrrr __delitem__Rs  zChainMap.__delitem__cCs(z|jdWStytdw)zPRemove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.rz#No keys found in the first mapping.)rpopitemrrrrrrXs  zChainMap.popitemcGs8z |jdj|g|RWStytd|w)zWRemove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].rr)rpoprr)r`rVrrrrr_s  z ChainMap.popcCs|jddS)z'Clear maps[0], leaving maps[1:] intact.rN)rclearrrrrrfzChainMap.clearr\)r-r.r/rcrbrrrPrrrrrr classmethodrr __copy__r propertyr rrrrrrrrrrs0      r)cache_from_sourcecCs6|dsJ|dur d}|rd}||Sd}||S)Nz.pyTco)rq)rfdebug_overridesuffixrrrrpsr) OrderedDict)r)KeysView ValuesView ItemsViewc@seZdZdZddZejfddZejfddZdd Zd d Z d d Z d6ddZ ddZ ddZ ddZddZddZddZddZeZeZefdd Zd7d"d#Zd7d$d%Zd&d'Zd(d)Zed7d*d+Zd,d-Zd.d/Zd0d1Zd2d3Z d4d5Z!d!S)8rz)Dictionary that remembers insertion ordercOspt|dkrtdt|z|jWnty-g|_}||dg|dd<i|_Ynw|j|i|dS)zInitialize an ordered dictionary. Signature is the same as for regular dictionaries, but keyword arguments are not recommended because their insertion order is arbitrary. rz$expected at most 1 arguments, got %dN)rQr_OrderedDict__rootr_OrderedDict__map_OrderedDict__update)r`rkwdsrootrrrrbs     zOrderedDict.__init__cCsF||vr|j}|d}|||g|d<|d<|j|<||||dS)z!od.__setitem__(i, y) <==> od[i]=yrrN)r!r")r`rVrWZ dict_setitemr%lastrrrrs  zOrderedDict.__setitem__cCs0||||j|\}}}||d<||d<dS)z od.__delitem__(y) <==> del od[y]rrN)r"r)r`rVZ dict_delitem link_prev link_nextrrrrs  zOrderedDict.__delitem__cc:|j}|d}||ur|dV|d}||us dSdS)zod.__iter__() <==> iter(od)rrNr!r`r%currrrrr zOrderedDict.__iter__ccr))z#od.__reversed__() <==> reversed(od)rrNr*r+rrr __reversed__r-zOrderedDict.__reversed__cCsbz |jD]}|dd=q|j}||dg|dd<|jWn ty)Ynwt|dS)z.od.clear() -> None. Remove all items from od.N)r" itervaluesr!rrr)r`noder%rrrrs  zOrderedDict.clearTcCs||std|j}|r|d}|d}||d<||d<n|d}|d}||d<||d<|d}|j|=t||}||fS)zod.popitem() -> (k, v), return and remove a (key, value) pair. Pairs are returned in LIFO order if last is true or FIFO order if false. zdictionary is emptyrrr)rr!r"rr)r`r&r%linkr'r(rVrWrrrrs   zOrderedDict.popitemcCt|S)zod.keys() -> list of keys in od)rrrrrkeyszOrderedDict.keyscfddDS)z#od.values() -> list of values in odcsg|]}|qSrrrsrVrrrrxryz&OrderedDict.values..rrrrrvaluesrzOrderedDict.valuescr5)z.od.items() -> list of (key, value) pairs in odcsg|]}||fqSrrr6rrrrxz%OrderedDict.items..rrrrritemsrzOrderedDict.itemscCr2)z0od.iterkeys() -> an iterator over the keys in od)rrrrriterkeysr4zOrderedDict.iterkeysccs|D]}||VqdS)z2od.itervalues -> an iterator over the values in odNrr`krrrr/s zOrderedDict.itervaluesccs|D] }|||fVqdS)z=od.iteritems -> an iterator over the (key, value) items in odNrr;rrr iteritemsszOrderedDict.iteritemscOst|dkrtdt|f|std|d}d}t|dkr%|d}t|tr6|D]}||||<q,nt|drI|D]}||||<q?n |D]\}}|||<qK|D]\}}|||<qXdS) aod.update(E, **F) -> None. Update od from dict/iterable E and F. If E is a dict instance, does: for k in E: od[k] = E[k] If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] Or if E is an iterable of items, does: for k, v in E: od[k] = v In either case, this is followed by: for k, v in F.items(): od[k] = v rz8update() takes at most 2 positional arguments (%d given)z,update() takes at least 1 argument (0 given)rrrr3N)rQrrrhasattrr3r9)rr$r`otherrVrWrrrr_ s.        zOrderedDict.updatecCs0||vr ||}||=|S||jurt||S)zod.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised. )_OrderedDict__markerr)r`rVrrrrrr,s zOrderedDict.popNcCs||vr||S|||<|S)zDod.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in odrrrrr setdefault9szOrderedDict.setdefaultcCsj|si}t|tf}||vrdSd||<z|s#d|jjfW||=Sd|jj|fW||=S||=w)zod.__repr__() <==> repr(od)rrz%s()z%s(%r))r _get_identr r-r9)r` _repr_runningZcall_keyrrrr@szOrderedDict.__repr__csXfddD}t}ttD]}||dq|r&j|f|fSj|ffS)z%Return state information for picklingcsg|]}||gqSrrrsr<rrrrxPr8z*OrderedDict.__reduce__..N)varsr rrr )r`r9 inst_dictr<rrr __reduce__Ns  zOrderedDict.__reduce__cCs ||S)z!od.copy() -> a shallow copy of od)r rrrrr X zOrderedDict.copycCs|}|D]}|||<q|S)zOD.fromkeys(S[, v]) -> New ordered dictionary with keys from S and values equal to v (which defaults to None). r)rrrWdrVrrrr\s zOrderedDict.fromkeyscCs6t|trt|t|ko||kSt||S)zod.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive while comparison to a regular mapping is order-insensitive. )rrrQr9r__eq__r`r?rrrrJgs   zOrderedDict.__eq__cCs ||k Sr\rrKrrr__ne__przOrderedDict.__ne__cCr2)z@od.viewkeys() -> a set-like object providing a view on od's keys)rrrrrviewkeysur4zOrderedDict.viewkeyscCr2)z an object providing a view on od's values)rrrrr viewvaluesyr4zOrderedDict.viewvaluescCr2)zBod.viewitems() -> a set-like object providing a view on od's items)r rrrr viewitems}r4zOrderedDict.viewitems)Tr\)"r-r.r/rcrbrrrrr.rrr3r7r9r:r/r=r_r#objectr@rrArrGr rrrJrLrMrNrOrrrrrs<           r)BaseConfigurator valid_identz^[a-z_][a-z0-9_]*$cCst|}|s td|dS)Nz!Not a valid Python identifier: %rT) IDENTIFIERr>rO)rrrrrrRs  rRc@s"eZdZdZddZdddZdS)ConvertingDictz A converting dictionary wrapper.cCJt||}|j|}||ur#|||<t|tttfvr#||_||_ |Sr\) rr configuratorconvertrrTConvertingListConvertingTupleparentrVr`rVrWrrrrr   zConvertingDict.__getitem__NcCsLt|||}|j|}||ur$|||<t|tttfvr$||_||_ |Sr\) rrPrVrWrrTrXrYrZrVr`rVrrWrrrrrPs  zConvertingDict.getr\)r-r.r/rcrrPrrrrrTs rTcCsDt|||}|j|}||ur t|tttfvr ||_||_ |Sr\) rrrVrWrrTrXrYrZrVr]rrrrs  rc@s"eZdZdZddZdddZdS) rXzA converting list wrapper.cCrUr\) rrrVrWrrTrXrYrZrVr[rrrrr\zConvertingList.__getitem__cCs<t||}|j|}||urt|tttfvr||_|Sr\) rrrVrWrrTrXrYrZ)r`idxrWrrrrrs   zConvertingList.popN)r^)r-r.r/rcrrrrrrrXs rXc@rZ)rYzA converting tuple wrapper.cCsBt||}|j|}||urt|tttfvr||_||_ |Sr\) tuplerrVrWrrTrXrYrZrVr[rrrrs   zConvertingTuple.__getitem__N)r-r.r/rcrrrrrrYs rYc@seZdZdZedZedZedZedZ edZ ddd Z e e Zd d Zd d ZddZddZddZddZddZdS)rQzQ The configurator base class which defines some useful defaults. z%^(?P[a-z]+)://(?P.*)$z ^\s*(\w+)\s*z^\.\s*(\w+)\s*z^\[\s*(\w+)\s*\]\s*z^\d+$ ext_convert cfg_convert)rtcfgcCst||_||j_dSr\)rTconfigrV)r`rdrrrrbs  zBaseConfigurator.__init__c Cs|d}|d}z-||}|D]"}|d|7}zt||}Wqty4||t||}Yqw|WStyYtdd\}}td||f}|||_ |_ |w)zl Resolve strings to objects using standard import and attribute syntax. r0rrNzCannot resolve %r: %s) r2rimporterrr ImportErrorr~rrO __cause__ __traceback__) r`rrusedfoundrGetbvrrrresolves&       zBaseConfigurator.resolvecCs ||S)z*Default converter for the ext:// protocol.)rnr`rWrrrrarHzBaseConfigurator.ext_convertcCs|}|j|}|durtd|||d}|j|d}|r||j|}|r6||d}n1|j|}|rg|d}|j|sO||}nz t |}||}Wn t yf||}Ynw|rr||d}ntd||f|s%|S)z*Default converter for the cfg:// protocol.NzUnable to convert %rrzUnable to convert %r at %r) WORD_PATTERNr>rOendrdgroups DOT_PATTERN INDEX_PATTERN DIGIT_PATTERNintr)r`rWrestrrIr_nrrrrbs8          zBaseConfigurator.cfg_convertcCst|tst|trt|}||_|St|ts&t|tr&t|}||_|St|ts9t|tr9t|}||_|St|trd|j |}|rd| }|d}|j |d}|rd|d}t||}||}|S)z Convert values to an appropriate type. dicts, lists and tuples are replaced by their converting alternatives. Strings are checked to see if they have a conversion format and are converted if they do. prefixNr)rrTrrVrXrrYr` string_typesCONVERT_PATTERNr> groupdictvalue_convertersrPr)r`rWrrIry converterrrrrrW4s2   zBaseConfigurator.convertcsrd}t|s||}dd}tfddD}|di|}|r7|D] \}}t|||q,|S)z1Configure an object with a user-supplied factory.z()r0Ncs g|] }t|r||fqSr)rRrDrdrrrxWs z5BaseConfigurator.configure_custom..r)rrrnrr9setattr)r`rdrpropsrarrrWrrrconfigure_customPs   z!BaseConfigurator.configure_customcCst|tr t|}|S)z0Utility function which converts lists to tuples.)rrr`rorrras_tuple^s zBaseConfigurator.as_tupleN)r-r.r/rcr8r;r{rprsrtrur} staticmethod __import__rerbrnrarbrWrrrrrrrQs$     " rQ)r)rr\) __future__rrer8r~sslrf version_infor basestringrzrrtypesr file_type __builtin__builtins ConfigParser configparserZ _backportrrr r r r urllibr rrrrrrrurllib2rrrrr r!r"r#r$r%httplib xmlrpclibQueuequeuer&htmlentitydefs raw_input itertoolsr'filterr(r*iostrr) urllib.parseurllib.request urllib.error http.clientclientrequest xmlrpc.client html.parser html.entitiesentitiesinputr+r,rOrIrYr[rPrdF_OKX_OKzipfilerrr>rZBaseZipExtFilerrrr NameErrorcollections.abcrrrrgetfilesystemencodingrrtokenizercodecsrrr;rrhtmlr9cgir collectionsrrreprlibrrimportlib.utilrimprthreadrrB dummy_thread_abcollrrr rlogging.configrQrRIrSrTrrrXr`rYrrrrsT      $,     (0         2b  C             l      PKH]ggQpython3.10/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-310.pycnu[o aiŘ@sdZddlmZddlZddlmZddlZddlZddlZddl m Z m Z ddl m Z mZmZddlmZdd lmZmZdd lmZmZeeZGd d d e ZGd dde ZGddde ZGddde ZgdZdZ dZ!e"dZ#e"dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+e*dZ,d Z-e.Z/e/0e%e/0e&e/0e(e/0e*e/0e,e"d!Z1d"d#Z2d$d%Z3d&d'e/DZ4d(d'e45DZ6d)Z7d*Z8d+Z9d,Z:d-Z;d.ZZ?e"d0Z@d;d2d3ZAGd4d5d5e>ZBd6ZCd7ZDd8ZEGd9d:d:e>ZFdS)Attempt to read or write metadata fields that are conflictual.Nrrrrrr rrc@r) MetadataUnrecognizedVersionErrorz Unknown metadata version number.Nrrrrrr$rrc@r)MetadataInvalidErrorzA metadata value is invalidNrrrrrr(rr)MetadataPKG_INFO_ENCODINGPKG_INFO_PREFERRED_VERSIONutf-81.1z \| ) Metadata-VersionNameVersionPlatformSummary DescriptionKeywords Home-pageAuthor Author-emailLicense)r"r#r$r%Supported-Platformr&r'r(r)r*r+r, Classifier Download-URL ObsoletesProvidesRequires)r0r1r2r.r/)r"r#r$r%r-r&r'r(r)r*r+ MaintainerMaintainer-emailr,r.r/Obsoletes-Dist Project-URL Provides-Dist Requires-DistRequires-PythonRequires-External)r7r8r9r5r:r3r4r6)r"r#r$r%r-r&r'r(r)r*r+r3r4r,r.r/r5r6r7r8r9r:Private-Version Obsoleted-BySetup-Requires-Dist ExtensionProvides-Extra)r;r?r<r=r>)Description-Content-Typer2r1r0)r@z"extra\s*==\s*("([^"]+)"|'([^']+)')cCsV|dkrtS|dkr tS|dkrtS|dvr!ttddtDS|dkr'tSt|)N1.0r 1.2)1.32.1css|] }|tvr|VqdSN) _345_FIELDS).0frrr zsz%_version2fieldlist..2.0) _241_FIELDS _314_FIELDSrFtuple _566_FIELDS _426_FIELDSr)versionrrr_version2fieldlistqsrQc Csdd}g}|D]\}}|gddfvrq ||q gd}|D]x}|tvr7d|vr7|dtd||tvrJd|vrJ|dtd ||tvr]d |vr]|d td ||tvrpd |vrp|d td ||tvrd|vr|dkr|dtd||t vrd|vr|dtd|q"t |dkr|dSt |dkrtd|t dd|vo||t }d |vo||t }d|vo||t}d|vo||t} t|t|t|t| dkrt d|s|s|s| st|vrtS|rdS|rd S|r dSdS)z5Detect the best version depending on the fields used.cSs|D] }||vr dSqdS)NTFr)keysmarkersmarkerrrr _has_markers z"_best_version.._has_markerUNKNOWNN)rAr rBrCrJrDrAzRemoved 1.0 due to %sr zRemoved 1.1 due to %srBzRemoved 1.2 due to %srCzRemoved 1.3 due to %srDr'zRemoved 2.1 due to %srJzRemoved 2.0 due to %srrz)Out of options - unknown metadata set: %szUnknown metadata setz,You used incompatible 1.1/1.2/2.0/2.1 fields)itemsappendrKremoveloggerdebugrLrFrNrOlenr _314_MARKERS _345_MARKERS _566_MARKERS _426_MARKERSintr) fieldsrUrRkeyvalueZpossible_versionsZis_1_1Zis_1_2Zis_2_1Zis_2_0rrr _best_versionsb                $recCsi|] }|dd|qS)-_)lowerreplace)rGnamerrr srkcCsi|]\}}||qSrr)rGattrfieldrrrrk)r8r5r7)r9)r$)r%r.r0r2r1r5r7r8r:r6r-r=r?r>)r6)r()r*r3r&r'z[^A-Za-z0-9.]+FcCs0|rtd|}td|dd}d||fS)zhReturn the distribution name with version. If for_filename is true, return a filename-escaped form.rf .z%s-%s) _FILESAFEsubri)rjrPZ for_filenamerrr_get_name_and_versions  rsc@seZdZdZ  d?ddZddZdd Zd d Zd d ZddZ ddZ ddZ ddZ ddZ ddZd@ddZddZdd Zd!d"Zd#d$Zd@d%d&Zd@d'd(ZdAd)d*Zd+d,Zefd-d.Zd@d/d0Zd@d1d2Zd3d4Zd5d6Zd7d8Zd9d:Zd;d<Z d=d>Z!dS)BLegacyMetadataaoThe legacy metadata of a release. Supports versions 1.0, 1.1, 1.2, 2.0 and 1.3/2.1 (auto-detected). You can instantiate the class with one of these arguments (or none): - *path*, the path to a metadata file - *fileobj* give a file-like object with metadata as content - *mapping* is a dict-like object - *scheme* is a version scheme name NdefaultcCs|||gddkrtdi|_g|_d|_||_|dur%||dS|dur0||dS|dur?||| dSdS)N'path, fileobj and mapping are exclusive) count TypeError_fieldsZrequires_filesZ _dependenciesschemeread read_fileupdateset_metadata_version)selfpathfileobjmappingr{rrr__init__s  zLegacyMetadata.__init__cCst|j|jd<dSNr")rerzrrrrr sz#LegacyMetadata.set_metadata_versioncCs|d||fdS)Nz%s: %s )write)rrrjrdrrr _write_field zLegacyMetadata._write_fieldcCs ||SrE)getrrjrrr __getitem__s zLegacyMetadata.__getitem__cCs |||SrE)set)rrjrdrrr __setitem__s zLegacyMetadata.__setitem__cCs0||}z|j|=WdStyt|wrE) _convert_namerzKeyError)rrj field_namerrr __delitem__s  zLegacyMetadata.__delitem__cCs||jvp |||jvSrE)rzrrrrr __contains__s zLegacyMetadata.__contains__cCs(|tvr|S|dd}t||S)Nrfrg) _ALL_FIELDSrirh _ATTR2FIELDrrrrrr!s zLegacyMetadata._convert_namecCs|tvs|tvr gSdS)NrV) _LISTFIELDS_ELEMENTSFIELDrrrr_default_value'szLegacyMetadata._default_valuecCs"|jdvr td|Std|S)NrAr  )metadata_version_LINE_PREFIX_PRE_1_2rr_LINE_PREFIX_1_2rrdrrr_remove_line_prefix,s   z"LegacyMetadata._remove_line_prefixcCs|tvr||St|rE)rAttributeErrorrrrr __getattr__2szLegacyMetadata.__getattr__FcCst|d|d|S)zhReturn the distribution name with version. If filesafe is true, return a filename-escaped form.r#r$)rs)rZfilesaferrr get_fullname=szLegacyMetadata.get_fullnamecC||}|tvS)z+return True if name is a valid metadata key)rrrrrris_fieldCs zLegacyMetadata.is_fieldcCrrE)rrrrrris_multi_fieldHs zLegacyMetadata.is_multi_fieldcCs4tj|ddd}z ||W|dS|w)z*Read the metadata values from a file path.rrencodingN)codecsopenr}close)rfilepathfprrrr|Ls zLegacyMetadata.readcCst|}|d|jd<tD]8}||vrq |tvr3||}|tvr,|dur,dd|D}|||q ||}|durE|dkrE|||q |}|rN|n|d|d<dS)z,Read the metadata values from a file object.zmetadata-versionr"NcSsg|] }t|dqS,)rMsplitrGrdrrr asz,LegacyMetadata.read_file..rVr')rrzrrget_all_LISTTUPLEFIELDSr get_payload)rZfileobmsgrmvaluesrdbodyrrrr}Ts   zLegacyMetadata.read_filecCs6tj|ddd}z |||W|dS|w)z&Write the metadata fields to filepath.wrrN)rr write_filer)rr skip_unknownrrrrrpszLegacyMetadata.writecCs|t|dD]U}||}|r|dgdgfvrq |tvr+|||d|q |tvrH|dkrE|jdvr?|dd}n|dd}|g}|t vrSd d |D}|D] }||||qUq d S) z0Write the PKG-INFO format data to a file object.r"rVrr'rrr!z |cSg|]}d|qSrjoinrrrrrrnz-LegacyMetadata.write_file..N) rrQrrrrrrrir)r fileobjectrrmrrdrrrrxs(   zLegacyMetadata.write_filec szfdd}|s n t|dr|D] }||||qn |D] \}}|||q|r9|D] \}}|||q/dSdS)aSet metadata values from the given iterable `other` and kwargs. Behavior is like `dict.update`: If `other` has a ``keys`` method, they are looped over and ``self[key]`` is assigned ``other[key]``. Else, ``other`` is an iterable of ``(key, value)`` iterables. Keys that don't match a metadata field or that have an empty value are dropped. cs*|tvr|r||dSdSdSrE)rrr)rcrdrrr_sets z#LegacyMetadata.update.._setrRN)hasattrrRrW)rotherkwargsrkvrrrr~s      zLegacyMetadata.updatecCsV||}|tvs |dkr't|ttfs't|tr$dd|dD}ng}n|tvr=t|ttfs=t|tr;|g}ng}t t j r|d}t |j }|tvrl|durl|D]}||ddsjtd |||qVn+|tvr|dur||std |||n|tvr|dur||std ||||tvr|d kr||}||j|<dS) z"Control then set a metadata field.r%cSsg|]}|qSr)strip)rGrrrrrz&LegacyMetadata.set..rr#N;rz$'%s': '%s' is not valid (field '%s')z.'%s': '%s' is not a valid version (field '%s')r')rr isinstancelistrMrrrrZ isEnabledForloggingWARNINGr r{_PREDICATE_FIELDSis_valid_matcherwarning_VERSIONS_FIELDSis_valid_constraint_list_VERSION_FIELDSis_valid_version_UNICODEFIELDSrrz)rrjrd project_namer{rrrrrsP          zLegacyMetadata.setcCs||}||jvr|tur||}|S|tvr |j|}|S|tvrM|j|}|dur/gSg}|D]}|tvr?||q3||d|dfq3|S|tvr`|j|}t |t r`| dS|j|S)zGet a metadata field.Nrrr) rrz_MISSINGrrrrrXrrrr)rrjrurdresvalrrrrs.          zLegacyMetadata.getc s|gg}}dD] }||vr||q |r(|gkr(dd|}t|dD] }||vr5||q*|ddkr@||fSt|jfdd}t|ftjft j ffD] \}}|D]} | | d } | d urw|| sw|d | | fq^qX||fS) zkCheck if the metadata is compliant. If strict is True then raise if no Name or Version are provided)r#r$zmissing required metadata: %s, )r)r*r"rBcs(|D]}|ddsdSqdS)NrrFT)rr)rdrr{rrare_valid_constraintss z3LegacyMetadata.check..are_valid_constraintsNzWrong value for '%s': %s) rrXrrr r{rrrrrr) rstrictmissingwarningsrlrrrb controllerrmrdrrrchecks@         zLegacyMetadata.checkcCsh|t|d}i}|D]#}|r||jvr1t|}|dkr&||||<qdd||D||<q|S)aReturn fields as a dict. Field names will be converted to use the underscore-lowercase style instead of hyphen-mixed case (i.e. home_page instead of Home-page). This is as per https://www.python.org/dev/peps/pep-0566/#id17. r" project_urlcSrrr)rGurrrr5rnz)LegacyMetadata.todict..)rrQrz _FIELD2ATTR)rZ skip_missingrbdatarrcrrrtodict"s zLegacyMetadata.todictcCs8|ddkrdD] }||vr||=q|d|7<dS)Nr"r )r0r2r1r8r)r requirementsrmrrradd_requirements9s zLegacyMetadata.add_requirementscCstt|dSr)rrQrrrrrRDszLegacyMetadata.keysccs|D]}|VqdSrErR)rrcrrr__iter__Gs zLegacyMetadata.__iter__cfddDS)Ncsg|]}|qSrrrGrcrrrrLrz)LegacyMetadata.values..rrrrrrKrzLegacyMetadata.valuescr)Ncsg|]}||fqSrrrrrrrOsz(LegacyMetadata.items..rrrrrrWNrzLegacyMetadata.itemscCsd|jj|j|jfS)Nz <%s %s %s>) __class__rrjrPrrrr__repr__Qs zLegacyMetadata.__repr__NNNruFrE)"rrrrrrrrrrrrrrrrrrr|r}rrr~rrrrrrrRrrrWrrrrrrtsB       ,  ,  rtz pydist.jsonz metadata.jsonMETADATAc@seZdZdZedZedejZe Z edZ dZ de Zdddd Zd Zd Zedfedfe dfe dfd Zd Z  dHddZedZdefZdefZdefdefeeedefeeeedefddd Z[[ddZdIddZddZed d!Z ed"d#Z!e!j"d$d#Z!dJd%d&Z#ed'd(Z$ed)d*Z%e%j"d+d*Z%d,d-Z&d.d/Z'd0d1Z(d2d3Z)d4d5d6d7d8d9d:d;dd?Z+dKdBdCZ,dDdEZ-dFdGZ.dS)Lrz The metadata of a release. This implementation uses 2.0 (JSON) metadata where possible. If not possible, it wraps a LegacyMetadata instance which handles the key-value metadata format. z ^\d+(\.\d+)*$z!^[0-9A-Z]([0-9A-Z_.-]*[0-9A-Z])?$z .{1,2047}rJz distlib (%s)r)legacy)rjrPsummaryzqname version license summary description author author_email keywords platform home_page classifiers download_urlzwextras run_requires test_requires build_requires dev_requires provides meta_requires obsoleted_by supports_environments)rrjrPr)_legacy_datar{NrucCsB|||gddkrtdd|_d|_||_|dur=z |||||_WdSty<t||d|_|YdSwd}|r[t |d }| }Wdn1sUwYn|ra| }|duro|j |j d|_dSt |tsy|d}zt||_||j|WdStytt||d|_|YdSw)Nrvrw)rr{rbr generatorr)rr{)rxryrrr{_validate_mappingrrtvalidaterr|METADATA_VERSION GENERATORrr decodejsonloads ValueErrorr)rrrrr{rrHrrrrsH         zMetadata.__init__)rjrPlicensekeywordsrr8r=r?r.)r/N)r"N) run_requiresbuild_requires dev_requiresZ test_requires meta_requiresextrasmodules namespacesexportscommands classifiers source_urlrc CsXt|d}t|d}||vr||\}}|jr0|dur(|dur#dn|}|S|j|}|S|dur6dn|}|dvrF|j||}|St}|}|jd} | r|dkr^| d|}n'|dkrp| d} | ro| ||}n| d } | s}|jd } | r| ||}||ur|}|S||vrt||}|S|jr|j|}|S|j|}|S) N common_keys mapped_keysr r rr r  extensionsr python.commandsr python.detailspython.exports)object__getattribute__rrr) rrccommonmappedlkmakerresultrdsentineldrrrrsR   "           zMetadata.__getattribute__cCsP||jvr"|j|\}}|p|j|vr$||}|s&td||fdSdSdS)Nz.'%s' is an invalid value for the '%s' property)SYNTAX_VALIDATORSr{matchr)rrcrdr{pattern exclusionsmrrr_validate_values  zMetadata._validate_valuecCs0|||t|d}t|d}||vrd||\}}|jr,|dur%t||j|<dS|dvr7||j|<dS|jdi}|dkrH||d<dS|dkrX|di}|||<dS|d i}|||<dS||vrqt|||dS|d krt|t r| }|r| }ng}|jr||j|<dS||j|<dS) Nrrrrr rr rrr) r#rrrNotImplementedErrorr setdefault __setattr__rrrr)rrcrdrrrrgrrrrr&s<           zMetadata.__setattr__cCst|j|jdSNT)rsrjrPrrrrname_and_version%szMetadata.name_and_versioncCsF|jr |jd}n|jdg}d|j|jf}||vr!|||S)Nr7providesz%s (%s))rrr%rjrPrX)rrsrrrr))s  zMetadata.providescCs"|jr ||jd<dS||jd<dS)Nr7r))rrrrrrr)4sc Cs|jr|}|Sg}t|p g|j}|D]2}d|vr d|vr d}nd|vr'd}n|d|v}|r<|d}|rr r(r))Z requires_distr)Zsetup_requires_distrr-r))rrrrrrr)) rrZlmdrnkkwrRokauthor maintainerrrrr7s2      zMetadata._from_legacyr#r$r,r&r'r)r*r+r/) rjrP)rrrrr=)rpython.projectZ project_urlsZHome)rrEcontactsrrj)rrErFremailr )rrr c Csdd}|jr |jr Jt}|j}|jD]7\}}t|ts+||vr*||||<q|}d}|D]}z||}Wq1ttfyGd}Ynw|rN|||<q||j |j } ||j |j } |j rit|j |d<t| |d<t| |d<|S)NcSst}|D]>}|d}|d}|d}|D]+}|s#|s#||qd}|r+d|}|r8|r6d||f}n|}|d||fqq|S)Nr+r,r-r?z extra == "%s"z (%s) and %sr)rraddr)entriesr4r6r+r1ZrlistrrTrrrprocess_entriess$    z,Metadata._to_legacy..process_entriesTFr?r8r=)rrrtLEGACY_MAPPINGrWrrMr IndexErrorrrrrrsorted) rrJrZnmdr@rBrfoundrZr1Zr2rrr _to_legacys8     zMetadata._to_legacyFTcCs||gddkr td||r2|jr|j}n|}|r)|j||ddS|j||ddS|jr:|}n|j}|rKt j ||dddddSt |dd}t j ||ddddWddS1shwYdS) Nrz)Exactly one of path and fileobj is needed)rTrv) ensure_asciiindent sort_keysrr) rxrrrrOrrr7rrdumprr)rrrrrZ legacy_mdrrHrrrrs,    "zMetadata.writecCs|jr |j|dS|jdg}d}|D]}d|vr$d|vr$|}nq|dur5d|i}|d|dSt|dt|B}t||d<dS)Nrr,r+r-r)rrrr%insertrrM)rrralwaysentryZrsetrrrr szMetadata.add_requirementscCs*|jpd}|jp d}d|jj|j||fS)Nz (no name)z no versionz<%s %s %s (%s)>)rjrPrrr)rrjrPrrrrs  zMetadata.__repr__rrE)NN)NNFT)/rrrrrecompileZMETADATA_VERSION_MATCHERIZ NAME_MATCHERrZVERSION_MATCHERZSUMMARY_MATCHERrrrr;r<r9r __slots__rrrrZ none_listdictZ none_dictrrr#r&propertyr(r)setterr3r8r:rrrr7rKrOrrrrrrrr[s   - + '    *     2 rr)Gr __future__rrrGrrrrWr?rrcompatrrr rSr utilr r rPr r getLoggerrrZrrrr__all__rrrXrrrKrLr]rFr^rOr`rNr_rrr~ZEXTRA_RErQrerrWrrrrrrrrrrrqrsrtZMETADATA_FILENAMEZWHEEL_METADATA_FILENAMEZLEGACY_METADATA_FILENAMErrrrrsz             I   jPKH]# tMpython3.10/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-310.pycnu[o ai@sddlZddlmZddlZddlZddlmZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZzddlZWn eyEdZYnwddlZddlZddlZddlZddlZzddlZWn eymddlZYnwddlZddlmZddlmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0e 1e2Z3e 4dZ5e 4dZ6e 4d Z7e 4d Z8e 4d Z9e 4d Z:e 4d Z;e 4dZddZ?ddZ@ddZAdddZBddZCddZDdd ZEejFd!d"ZGejFd#d$ZHejFdd&d'ZIGd(d)d)eJZKd*d+ZLGd,d-d-eJZMd.d/ZNGd0d1d1eJZOe 4d2e jPZQd3d4ZRdd5d6ZSd7d8ZTd9d:ZUd;d<ZVd=d>ZWd?d@ZXe 4dAe jYZZe 4dBZ[ddCdDZ\e 4dEZ]dFdGZ^dHdIZ_dJdKZ`dLZadMdNZbdOdPZcGdQdRdReJZdGdSdTdTeJZeGdUdVdVeJZfdWZgddYdZZhd[d\Zid]ZjGd^d_d_eJZke 4d`Zle 4daZme 4dbZndcddZdedfZoerddglmpZqmrZrmsZsGdhdidie$jtZtGdjdkdkeqZpGdldmdmepe'ZuejvddnZwewdokr Gdpdqdqe$jxZxer Gdrdsdse$jyZyGdtdudue%jzZzerGdvdwdwe%j{Z{Gdxdydye%j|Z|dzd{Z}Gd|d}d}eJZ~Gd~dde~ZGddde~ZGddde(ZGdddeJZddZGdddeJZddZddZddZddddZddZdS)N)deque)iglob)DistlibException) string_types text_typeshutil raw_inputStringIOcache_from_sourceurlopenurljoinhttplib xmlrpclib splittype HTTPHandlerBaseConfigurator valid_ident Container configparserURLErrorZipFilefsdecodeunquoteurlparsez^([\w\.-]+)\s*z^([\w\.*+-]+)\s*z^(<=?|>=?|={2,3}|[~!]=)\s*z*^((<=?)|(>=?)|={2,3}|[~!]=|in|not\s+in)\s*z^or\b\s*z ^and\b\s*z(\S+)\s*z(([\s\w\.{}()*+#:;,/?!~`@$%^&=|<>\[\]-]+)cs6ddfddfddfdd|S) ae Parse a marker string and return a dictionary containing a marker expression. The dictionary will contain keys "op", "lhs" and "rhs" for non-terminals in the expression grammar, or strings. A string contained in quotes is to be interpreted as a literal string, and a string not contained in quotes is a variable (such as os_name). cSs0t|}|r|d}||d}||fS|std|d}|dvr-td|d|d}|dd}|g}|rw|d|krEn=|d|krW|||dd}nt|}|sdtd|||d||d}|s>d|}td|||d|}|dd }||fS) Nrzunexpected end of inputz'"zinvalid expression: %srzerror in string literal: %szunterminated string: %s) IDENTIFIERmatchgroupsend SyntaxErrorreplaceappend STRING_CHUNKjoinlstrip) remainingmresultqoqpartssr-/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/util.py marker_varAs>              z parse_marker..marker_varcs|r,|ddkr,|dd\}}|ddkr td||dd}||fS|\}}|rXt|}|s.marker_exprc\|\}}|r*t|}|s ||fS||d}|\}}d||d}|s||fS)Nandr3)ANDrrr&r5r'r6)r9r-r. marker_andx    z parse_marker..marker_andcr:)Norr3)ORrrr=)r>r-r.r8r?zparse_marker..markerr-) marker_stringr-)r8r>r9r/r. parse_marker8s  $   rCcCs|}|r |dr dSt|}|std||d}||d}d}}}}|r|ddkr|dd}|dkrHtd||d|} ||dd}g}| rt| }|sitd | | |d| |d} | s}n| dd krtd | | dd} | s\|sd}|r@|dd kr|dd}t |}|std ||d}t |} | j r| j std|||d}njdd} |ddkr| |\}}nY|dd}|dkrtd||d|} ||dd}t| r| | \}} n,t| }|s"td| |d} | |d} | r;td| d| fg}|r^|ddkrPtd||dd}t|\}}|rn|ddkrntd||st|}nd|ddd|Df}t||||||dS)z Parse a requirement passed in as a string. Return a Container whose attributes contain the various parts of the requirement. #Nzname expected: %sr[]rzunterminated extra: %szmalformed extra: %s,zcomma expected in extras: %s@zinvalid URI: %szInvalid URL: %scSst|}d}|rbg} |d}||d}t|}|s'td||d}|||f||d}|rD|ddkrEn|dd}|sPnt|}|s]td|q |sbd}||fS)z| Return a list of operator, version tuples if any are specified, else None. NTrzinvalid version: %srGrinvalid constraint: %s) COMPARE_OPrrrVERSION_IDENTIFIERr r"r%) ver_remainingr'versionsr4vr-r-r. get_versionss2       z'parse_requirement..get_versionsr0r1r2rIz~=;zinvalid requirement: %szunexpected trailing data: %s%s %s, cSsg|]}d|qS)rQr-).0conr-r-r. z%parse_requirement..)nameextras constraintsr8url requirement)strip startswithrrr rrfindr%r" NON_SPACErschemenetlocrJrKrCr$r)reqr&r'distnamerX mark_exprrMuriir,trO_rNrsr-r-r.parse_requirements                              rjcCsdd}i}|D]I\}}}tj||}t|D]8}tj||} t| D]*} ||| } |dur7|| dq%||| } |tjjdd} | d| || <q%qq|S)z%Find destinations for resources filescSsD|tjjd}|tjjd}||sJ|t|ddSN/)r!ospathsepr]lenr%)rootrnr-r-r. get_rel_pathsz)get_resources_dests..get_rel_pathNrl)rmrnr$rpopr!rorstrip)resources_rootrulesrr destinationsbasesuffixdestprefixabs_baseabs_globabs_path resource_filerel_pathrel_destr-r-r.get_resources_destss      rcCs*ttdr d}|Stjttdtjk}|S)N real_prefixT base_prefix)hasattrsysr{getattrr(r-r-r.in_venv(s rcCstj}t|ts t|}|SN)r executable isinstancerrrr-r-r.get_executable2s rcCsP|} t|}|}|s|r|}|r'|d}||vr |S|r'd|||f}q)NTrz %c: %s %s)r lower)prompt allowed_chars error_promptdefaultpr,cr-r-r.proceedDs rcCs8t|tr |}i}|D] }||vr||||<q |Sr)rrsplit)dkeysr(keyr-r-r.extract_by_keyTs  rcCsntjddkrtd|}|}t|}z6t|}|ddd}|D]!\}}|D]\}}d||f}t |} | dusDJ| ||<q0q(|WSt y[| ddYnwdd } t } z| | |Wnt jy|t|}t|}| | |Ynwi}| D]&} i|| <}| | D]\} }d| |f}t |} | dusJ| || <qq|S) Nrutf-8 extensionszpython.exportsexportsz%s = %scSs&t|dr ||dS||dS)N read_file)rrreadfp)cpstreamr-r-r. read_streamqs z!read_exports..read_stream)r version_infocodecs getreaderreadr jsonloaditemsget_export_entry Exceptionseekr ConfigParserMissingSectionHeaderErrorclosetextwrapdedentsections)rdatajdatar(groupentrieskrNr,entryrrrrWvaluer-r-r. read_exports]sL           rcCstjddkrtd|}t}|D]6\}}|||D](}|j dur.|j }nd|j |j f}|j rCd|d |j f}| ||j|q#q||dS)Nrrrz%s:%sz%s [%s]rR)rrr getwriterrrr add_sectionvaluesryr{flagsr$setrWwrite)rrrrrNrr,r-r-r. write_exportss   rc cs.t}z |VWt|dSt|wr)tempfilemkdtemprrmtree)tdr-r-r.tempdirs rc c8t}zt|dVWt|dSt|wr)rmgetcwdchdir)rcwdr-r-r.r  rc crr)socketgetdefaulttimeoutsetdefaulttimeout)secondsctor-r-r.socket_timeoutrrc@seZdZddZdddZdS)cached_propertycCs ||_dSr)func)selfrr-r-r.__init__ zcached_property.__init__NcCs,|dur|S||}t||jj||Sr)robject __setattr____name__)robjclsrr-r-r.__get__s  zcached_property.__get__r)r __module__ __qualname__rrr-r-r-r.rsrcCstjdkr|S|s |S|ddkrtd||ddkr#td||d}tj|vr8|tjtj|vs-|s=tjStjj|S)aReturn 'pathname' as a name that will work on the native filesystem. The path is split on '/' and put back together again using the current directory separator. Needed because filenames in the setup script are always supplied in Unix style, and have to be converted to the local convention before we can actually use them in the filesystem. Raises ValueError on non-Unix-ish systems if 'pathname' either starts or ends with a slash. rlrzpath '%s' cannot be absolutezpath '%s' cannot end with '/')rmro ValueErrorrcurdirremovernr$)pathnamepathsr-r-r. convert_paths          rc@seZdZd$ddZddZddZdd Zd%d d Zd&ddZddZ ddZ ddZ ddZ ddZ d'ddZddZddZd d!Zd"d#Zd S)( FileOperatorFcCs||_t|_|dSr)dry_runrensured _init_record)rrr-r-r.r zFileOperator.__init__cCsd|_t|_t|_dSNF)recordr files_written dirs_createdrr-r-r.rrzFileOperator._init_recordcCs|jr |j|dSdSr)rradd)rrnr-r-r.record_as_writtenszFileOperator.record_as_writtencCsHtj|stdtj|tj|sdSt|jt|jkS)aTell if the target is newer than the source. Returns true if 'source' exists and is more recently modified than 'target', or if 'source' exists and 'target' doesn't. Returns false if both exist and 'target' is the same age or younger than 'source'. Raise PackagingFileError if 'source' does not exist. Note that this test is not very accurate: files created in the same second will have the same "age". zfile '%r' does not existT)rmrnexistsrabspathstatst_mtime)rsourcetargetr-r-r.newers   zFileOperator.newerTcCs|tj|td|||js@d}|r2tj|r"d|}ntj|r2tj |s2d|}|r:t |dt ||| |dS)z8Copy a file respecting dry-run and force flags. zCopying %s to %sNz%s is a symlinkz%s is a non-regular filez which would be overwritten) ensure_dirrmrndirnameloggerinforislinkrisfilerrcopyfiler)rinfileoutfilecheckmsgr-r-r. copy_files    zFileOperator.copy_fileNcCstj|rJ|tj|td|||js?|dur%t|d}nt j|d|d}z t ||W| n| w| |dS)NzCopying stream %s to %swbwencoding)rmrnisdirrrrrropenrr copyfileobjrr)rinstreamrr  outstreamr-r-r. copy_streams zFileOperator.copy_streamcCsp|tj||js1tj|rt|t|d }||Wdn1s,wY| |dS)Nr) rrmrnrrrrr rr)rrnrfr-r-r.write_binary_file's    zFileOperator.write_binary_filecCs||||dSr)rencode)rrnrr r-r-r.write_text_file0zFileOperator.write_text_filecCsvtjdkstjdkr5tjdkr7|D]'}|jrtd|qt|j|B|@}td||t||qdSdSdS)Nposixjavazchanging mode of %szchanging mode of %s to %o) rmrW_namerrrrst_modechmod)rbitsmaskfilesrmoder-r-r.set_mode3szFileOperator.set_modecCs|dd|S)Nimi)r)r,rr-r-r.?szFileOperator.cCstj|}||jvr>tj|s@|j|tj|\}}||t d||j s3t ||j rB|j |dSdSdSdS)Nz Creating %s)rmrnrrrrrrrrrmkdirrr)rrnrrr-r-r.rAs    zFileOperator.ensure_dirc Cst|| }td|||jsG|s|||r,|sd}n||s$J|t|d}i}|r;ttdr;tj j |d<tj |||dfi|| ||S)NzByte-compiling %s to %sPycInvalidationModeinvalidation_modeT) r rrrrr]rpr py_compiler" CHECKED_HASHcompiler) rrnoptimizeforcer{hashed_invalidationdpathdiagpathcompile_kwargsr-r-r. byte_compileMs   zFileOperator.byte_compilecCstj|r^tj|r4tj|s4td||js t ||j r0||j vr2|j |dSdSdStj|r=d}nd}td|||jsNt ||j r`||j vrb|j |dSdSdSdS)NzRemoving directory tree at %slinkfilezRemoving %s %s)rmrnrr rrdebugrrrrrrr)rrnr,r-r-r.ensure_removed^s,       zFileOperator.ensure_removedcCsNd}|s%tj|rt|tj} |Stj|}||kr! |S|}|r|Sr)rmrnraccessW_OKr)rrnr(parentr-r-r. is_writabless  zFileOperator.is_writablecCs"|jsJ|j|jf}||S)zV Commit recorded changes, turn off recording, return changes. )rrrr)rr(r-r-r.commits  zFileOperator.commitcCs|jsCt|jD] }tj|rt|qt|jdd}|D]#}t |}|r=|dgks/Jtj ||d}t |t |q| dS)NT)reverse __pycache__r) rlistrrmrnrrsortedrlistdirr$rmdirr)rrdirsrflistsdr-r-r.rollbacks      zFileOperator.rollbackFTr)FFNF)rrrrrrrrrrrrset_executable_moderr-r1r5r6r@r-r-r-r.rs"       rcCs`|tjvr tj|}nt|}|dur|}|S|d}t||d}|D]}t||}q&|S)N.r)rmodules __import__rrrs) module_name dotted_pathmodr(r+rr-r-r.resolves    rJc@s6eZdZddZeddZddZddZej Z d S) ExportEntrycCs||_||_||_||_dSrrWr{ryr)rrWr{ryrr-r-r.rs zExportEntry.__init__cCst|j|jSr)rJr{ryrr-r-r.rszExportEntry.valuecCsd|j|j|j|jfS)NzrLrr-r-r.__repr__s zExportEntry.__repr__cCsFt|ts d}|S|j|jko |j|jko |j|jko |j|jk}|Sr)rrKrWr{ryr)rotherr(r-r-r.__eq__s    zExportEntry.__eq__N) rrrrrrrMrOr__hash__r-r-r-r.rKs  rKz(?P(\w|[-.+])+) \s*=\s*(?P(\w+)([:\.]\w+)*) \s*(\[\s*(?P[\w-]+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])? c Cst|}|sd}d|vsd|vrtd||S|}|d}|d}|d}|dkr4|d}}n|dkr>td||d\}}|d } | dur^d|vsUd|vr[td|g} n d d | d D} t|||| }|S) NrErFzInvalid specification '%s'rWcallable:rrrcSsg|]}|qSr-r\)rSrr-r-r.rUrVz$get_export_entry..rG)ENTRY_REsearchr groupdictcountrrK) specificationr'r(rrWrncolonsr{ryrr-r-r.rs:   rcCs|durd}tjdkrdtjvrtjd}ntjd}tj|r3t|tj}|s2t d|nz t |d}Wnt yOt j d |dd d }Ynw|s\t }t d |tj||S) a Return the default base location for distlib caches. If the directory does not exist, it is created. Use the suffix provided for the base directory, and default to '.distlib' if it isn't provided. On Windows, if LOCALAPPDATA is defined in the environment, then it is assumed to be a directory, and will be the parent directory of the result. On POSIX, and on Windows if LOCALAPPDATA is not defined, the user's home directory - using os.expanduser('~') - will be the parent directory of the result. The result is just the directory '.distlib' in the parent directory as determined above, or with the name specified with ``suffix``. Nz.distlibnt LOCALAPPDATAz $localappdata~z(Directory exists but is not writable: %sTzUnable to create %s)exc_infoFz#Default location unusable, using %s)rmrWenvironrn expandvars expanduserr r2r3rwarningmakedirsOSErrorrrr$)ryr(usabler-r-r.get_cache_bases*      recCsBtjtj|\}}|r|dd}|tjd}||dS)a Convert an absolute path to a directory name for use in a cache. The algorithm used is: #. On Windows, any ``':'`` in the drive is replaced with ``'---'``. #. Any occurrence of ``os.sep`` is replaced with ``'--'``. #. ``'.cache'`` is appended. rRz---z--z.cache)rmrn splitdriverr!ro)rnrrr-r-r.path_to_cache_dirs    rgcCs|ds |dS|Srk)endswith)r,r-r-r. ensure_slash$s ricCs`d}}d|vr|dd\}}d|vr|}n|dd\}}|r%t|}|r+t|}|||fS)NrHrrR)rsplitrr)rausernamepasswordr{r-r-r.parse_credentials*s rmcCstd}t||S)N)rmumaskrr-r-r.get_process_umask9s  rpcCs<d}d}t|D] \}}t|tsd}nq|dusJ|S)NTF) enumeraterr)seqr(rfr,r-r-r.is_string_sequence>s  rsz3([a-z0-9_]+([.-][a-z_][a-z0-9_]*)*)-([a-z0-9_.+-]+)z -py(\d\.?\d?)cCsd}d}t|dd}t|}|r |d}|d|}|rLt|t|dkrLtt |d|}|rL| }|d|||dd|f}|durbt |}|rb|d|d|f}|S)zw Extract name, version, python version from a filename (no extension) Return name, version, pyver or None N -rz\br) rr!PYTHON_VERSIONrUrstartrprerescaperPROJECT_NAME_AND_VERSION)filename project_namer(pyverr'nr-r-r.split_filenameMs"   rz-(?P[\w .-]+)\s*\(\s*(?P[^\s)]+)\)$cCs:t|}|s td||}|d|dfS)z A utility method used to get name and version from a string. From e.g. a Provides-Dist value. :param p: A value in a form 'foo (1.0)' :return: The name and version as a tuple. z$Ill-formed name/version string: '%s'rWver)NAME_VERSION_RErrrVr\r)rr'rr-r-r.parse_name_and_versionis  rcCst}t|pg}t|p g}d|vr|d||O}|D]<}|dkr*||q|drJ|dd}||vr@td|||vrI||q||vrUtd|||q|S)N*rurzundeclared extra: %s)rrrr]rra) requested availabler(runwantedr-r-r. get_extrasxs(        rc Csi}z*t|}|}|d}|dstd|W|Std|}t |}W|St yF}zt d||WYd}~|Sd}~ww)Nz Content-Typezapplication/jsonz(Unexpected response for JSON request: %srz&Failed to get external data for %s: %s) r rgetr]rr0rrrrr exception)rZr(respheadersctreaderer-r-r._get_external_datas    rz'https://www.red-dove.com/pypi/projects/cCs*d|d|f}tt|}t|}|S)Nz%s/%s/project.jsonrupperr _external_data_base_urlr)rWrZr(r-r-r.get_project_datas rcCs(d|d||f}tt|}t|S)Nz%s/%s/package-%s.jsonrr)rWversionrZr-r-r.get_package_datas rc@s(eZdZdZddZddZddZdS) Cachez A class implementing a cache for resources that need to live in the file system e.g. shared libraries. This class was moved from resources to here because it could be used by other modules, e.g. the wheel module. cCsPtj|s t|t|jd@dkrtd|tjtj ||_ dS)zu Initialise an instance. :param base: The base directory where the cache should be located. ?rzDirectory '%s' is not privateN) rmrnr rbrrrrarnormpathrx)rrxr-r-r.rs   zCache.__init__cCst|S)zN Converts a resource prefix to a directory name in the cache. )rg)rr{r-r-r. prefix_to_dirszCache.prefix_to_dirc Csg}t|jD]7}tj|j|}ztj|stj|r%t|n tj|r0t |Wqt y?| |Yqw|S)z" Clear the cache. ) rmr;rxrnr$rrrr rrrr")r not_removedfnr-r-r.clears    z Cache.clearN)rrr__doc__rrrr-r-r-r.rs  rc@s:eZdZdZddZdddZddZd d Zd d Zd S) EventMixinz1 A very simple publish/subscribe system. cCs i|_dSr) _subscribersrr-r-r.rrzEventMixin.__init__TcCsH|j}||vrt|g||<dS||}|r||dS||dS)a` Add a subscriber for an event. :param event: The name of an event. :param subscriber: The subscriber to be added (and called when the event is published). :param append: Whether to append or prepend the subscriber to an existing subscriber list for the event. N)rrr" appendleft)revent subscriberr"subssqr-r-r.rs zEventMixin.addcCs,|j}||vr td||||dS)z Remove a subscriber for an event. :param event: The name of an event. :param subscriber: The subscriber to be removed. zNo subscribers: %rN)rrr)rrrrr-r-r.rs zEventMixin.removecCst|j|dS)z Return an iterator for the subscribers for an event. :param event: The event to return subscribers for. r-)iterrr)rrr-r-r.get_subscribersszEventMixin.get_subscribersc Ospg}||D]%}z ||g|Ri|}Wnty&tdd}Ynw||qtd|||||S)a^ Publish a event and return a list of values returned by its subscribers. :param event: The event to publish. :param args: The positional arguments to pass to the event's subscribers. :param kwargs: The keyword arguments to pass to the event's subscribers. z"Exception during event publicationNz/publish %s: args = %s, kwargs = %s, result = %s)rrrrr"r0)rrargskwargsr(rrr-r-r.publish s    zEventMixin.publishNrB) rrrrrrrrrr-r-r-r.rs  rc@s^eZdZddZddZdddZdd Zd d Zd d ZddZ e ddZ e ddZ dS) SequencercCsi|_i|_t|_dSr)_preds_succsr_nodesrr-r-r.r(s zSequencer.__init__cCs|j|dSr)rrrnoder-r-r.add_node-szSequencer.add_nodeFcCs||jvr |j||rUt|j|dD]}|||qt|j|dD]}|||q(t|jD] \}}|sB|j|=q8t|jD] \}}|sT|j|=qJdSdS)Nr-)rrrrrrr9r)rredgesrr,rrNr-r-r. remove_node0s"   zSequencer.remove_nodecCs<||ksJ|j|t||j|t|dSr)r setdefaultrrr)rpredsuccr-r-r.r@s z Sequencer.addcCsz||ksJz |j|}|j|}Wn tytd|wz ||||WdSty<td||fw)Nz%r not a successor of anythingz%r not a successor of %r)rrKeyErrorrr)rrrpredssuccsr-r-r.rEs      zSequencer.removecCs||jvp||jvp||jvSr)rrr)rstepr-r-r.is_stepRszSequencer.is_stepcCs||s td|g}g}t}|||rI|d}||vr1||kr0||||n|||||j|d}| ||st |S)Nz Unknown: %rrr-) rrrr"rsrrrrextendreversed)rfinalr(todoseenrrr-r-r. get_stepsVs&         zSequencer.get_stepscsRdggiig|jfddD] }|vr&|qS)Nrcsd|<d|<dd7<|z|}Wn ty*g}Ynw|D]%}|vrC|t|||<q-|vrRt|||<q-||krxg} }||||krlnq^t|}|dSdS)Nrr)r"rminrstuple)r successors successorconnected_component componentgraphindex index_counterlowlinksr(stack strongconnectr-r.rzs4       z3Sequencer.strong_connections..strongconnect)rrr-rr.strong_connectionsos"zSequencer.strong_connectionscCsfdg}|jD]}|j|}|D] }|d||fqq|jD] }|d|q|dd|S)Nz digraph G {z %s -> %s;z %s;} )rr"rr$)rr(rrrrr-r-r.dots     z Sequencer.dotNrA) rrrrrrrrrrpropertyrrr-r-r-r.r's   2r).tar.gz.tar.bz2.tar.zip.tgz.tbz.whlTc sRfdd}tjtd}|durC|drd}n$|dr)d}d}n|dr3d }d }n|d r=d }d }ntd|z]|dkr]t|d }|r\|}|D]}||qUnt ||}|rr| }|D]}||qk|dkrt j ddkr| D]} t| jts| jd| _q|W|r|dSdS|r|ww)NcsRt|ts |d}tjtj|}|r!|tjkr't d|dS)Nrzpath outside destination: %r) rrdecodermrnrr$r]ror)rnrdest_dirplenr-r. check_paths   zunarchive..check_path)rrzip)rrtgzzr:gz)rrtbzzr:bz2rtarrzUnknown format for %rrrr)rmrnrrprhrrnamelisttarfiler getnamesrr getmembersrrWrr extractallr) archive_filenamerformatrrarchivernamesrWtarinfor-rr. unarchivesR               rc Cst}t|}t|d3}t|D]$\}}}|D]}tj||}||d} tj| |} ||| qqWd|S1sCwY|S)z*zip a directory tree into a BytesIO objectrN) ioBytesIOrprrmwalkrnr$r) directoryr(dlenzfrqr=rrWfullrelrzr-r-r.zip_dirs   r)rKMGTPc@sreZdZdZdddZddZdd Zd d Zd d Ze ddZ e ddZ ddZ e ddZ e ddZdS)ProgressUNKNOWNrdcCs<|dus ||ks J||_|_||_d|_d|_d|_dS)NrF)rcurmaxstartedelapseddone)rminvalmaxvalr-r-r.rs   zProgress.__init__cCsX|j|ksJ|jdus||jksJ||_t}|jdur$||_dS||j|_dSr)rrrtimerr)rcurvalnowr-r-r.update s  zProgress.updatecCs |dksJ||j|dSNr)r r)rincrr-r-r. increments zProgress.incrementcCs||j|Sr)r rrr-r-r.rws zProgress.startcCs |jdur ||jd|_dSNT)rr rrr-r-r.stops   z Progress.stopcCs|jdur|jS|jSr)runknownrr-r-r.maximum!szProgress.maximumcCsH|jrd}|S|jdurd}|Sd|j|j|j|j}d|}|S)Nz100 %z ?? %gY@z%3d %%)rrrr)rr(rNr-r-r. percentage%s zProgress.percentagecCs<|dkr |jdus|j|jkrd}|Stdt|}|S)Nrz??:??:??z%H:%M:%S)rrrrstrftimegmtime)rdurationr(r-r-r.format_duration0s zProgress.format_durationcCs|jr d}|j}n/d}|jdurd}n%|jdks|j|jkr!d}nt|j|j}||j|j}|d|j}d|||fS)NDonezETA rrrz%s: %s)rrrrrfloatr)rr{rgr-r-r.ETA9s z Progress.ETAcCsL|jdkrd}n |j|j|j}tD] }|dkrn|d}qd||fS)Nrgig@@z%d %sB/s)rrrUNITS)rr(unitr-r-r.speedLs   zProgress.speedN)rr)rrrrrr r rwrrrrrrrr-r-r-r.rs       rz \{([^}]*)\}z[^/\\,{]\*\*|\*\*[^/\\,}]z^[^{]*\}|\{[^}]*$cCs<t|r d}t||t|rd}t||t|S)zAExtended globbing function that supports ** and {opt1,opt2,opt3}.z7invalid glob %r: recursive glob "**" must be used alonez2invalid glob %r: mismatching set marker '{' or '}')_CHECK_RECURSIVE_GLOBrUr_CHECK_MISMATCH_SET_iglob) path_globrr-r-r.ras    rc cst|d}t|dkr6t|dksJ||\}}}|dD]}td|||fD]}|Vq-q!dSd|vrFt|D]}|Vq>dS|dd\}}|dkrTd}|dkr[d}n |d}|d }t|D]\}}} tj |}ttj ||D]} | Vq~qjdS) NrrrGrz**rDrrl\) RICH_GLOBrrprr$ std_iglobr%rmrrnr) r rich_path_globr{rryitemrnradicaldirrrr-r-r.rls6       r) HTTPSHandlermatch_hostnameCertificateErrorc@seZdZdZdZddZdS)HTTPSConnectionNTcCsZt|j|jf|j}t|ddr||_|tt ds8|j r$t j }nt j }t j ||j|j|t j|j d|_nCt t j}tt drK|jt jO_|jrV||j|ji}|j rqt j |_|j|j dtt ddrq|j|d<|j |fi||_|j r|jrzt|j|jtd |jWdSty|jtj|jwdSdS) N _tunnel_hostF SSLContext) cert_reqs ssl_versionca_certs OP_NO_SSLv2)cafileHAS_SNIserver_hostnamezHost verified: %s) rcreate_connectionhostporttimeoutrsock_tunnelrsslr0 CERT_REQUIRED CERT_NONE wrap_socketkey_file cert_filePROTOCOL_SSLv23r-optionsr1load_cert_chain verify_modeload_verify_locations check_domainr) getpeercertrr0r*shutdown SHUT_RDWRr)rr9r.contextrr-r-r.connectsF         zHTTPSConnection.connect)rrrr0rFrKr-r-r-r.r+s r+c@s&eZdZd ddZddZddZdS) r(TcCst|||_||_dSr)BaseHTTPSHandlerrr0rF)rr0rFr-r-r.rs  zHTTPSHandler.__init__cOs(t|i|}|jr|j|_|j|_|S)a This is called to create a connection instance. Normally you'd pass a connection class to do_open, but it doesn't actually check for a class, and just expects a callable. As long as we behave just as a constructor would have, we should be OK. If it ever changes so that we *must* pass a class, we'll create an UnsafeHTTPSConnection class which just sets check_domain to False in the class definition, and choose which one to pass to do_open. )r+r0rF)rrrr(r-r-r. _conn_makers  zHTTPSHandler._conn_makerc CsHz||j|WSty#}zdt|jvrtd|jd}~ww)Nzcertificate verify failedz*Unable to verify server certificate for %s)do_openrMrstrreasonr*r6)rrbrr-r-r. https_openszHTTPSHandler.https_openNrB)rrrrrMrQr-r-r-r.r(s  r(c@eZdZddZdS)HTTPSOnlyHandlercCs td|)NzAUnexpected HTTP request on what should be a secure connection: %s)r)rrbr-r-r. http_openszHTTPSOnlyHandler.http_openN)rrrrTr-r-r-r.rS rSrVc@eZdZdddZdS)HTTPrNcK*|dkrd}||j||fi|dSr _setupZ_connection_classrr6r7rr-r-r.rz HTTP.__init__rNrrrrr-r-r-r.rZrZc@rY)HTTPSrNcKr[r r\r^r-r-r.rr_zHTTPS.__init__r`rar-r-r-r.rcrbrcc@eZdZdddZddZdS) TransportrcC||_tj||dSr)r8rrerrr8 use_datetimer-r-r.rzTransport.__init__cCsb||\}}}tdkrt||jd}|S|jr||jdkr*||_|t|f|_|jd}|S)NrW)r8rr) get_host_info _ver_inforZr8 _connection_extra_headersrHTTPConnection)rr6hehx509r(r-r-r.make_connections zTransport.make_connectionNrrrrrrrr-r-r-r.re  rec@rd) SafeTransportrcCrfr)r8rrvrrgr-r-r.rrizSafeTransport.__init__cCs||\}}}|s i}|j|d<tdkr t|dfi|}|S|jr*||jdkr:||_|tj|dfi|f|_|jd}|S)Nr8rWrr)rjr8rkrcrlrmrr+)rr6rorprr(r-r-r.rrs  zSafeTransport.make_connectionNrsrtr-r-r-r.rvrurvc@rR) ServerProxycKsx|dd|_}|dur/t|d}|dd}|dkr t}nt}|||d|d<}||_tjj ||fi|dS)Nr8rrhhttps)rh transport) rsr8rrrvreryrrwr)rrerr8r`rhtclsrgr-r-r.r&s  zServerProxy.__init__Nrar-r-r-r.rw%rUrwcKs:tjddkr |d7}nd|d<d|d<t||fi|S)Nrrbrnewlinerr )rrr )rrrr-r-r. _csv_open;s  r}c@s4eZdZedededdZddZddZd S) CSVBaserG"r) delimiter quotecharlineterminatorcC|Srr-rr-r-r. __enter__MzCSVBase.__enter__cGs|jdSr)rr)rr]r-r-r.__exit__PszCSVBase.__exit__N)rrrrOdefaultsrrr-r-r-r.r~Fs r~c@s(eZdZddZddZddZeZdS) CSVReadercKs`d|vr|d}tjddkrtd|}||_nt|dd|_tj|jfi|j|_dS)Nrrrrrnr) rrrrrr}csvrr)rrrr-r-r.rUszCSVReader.__init__cCrrr-rr-r-r.__iter__`rzCSVReader.__iter__cCsFt|j}tjddkr!t|D]\}}t|ts |d||<q|SNrrr)nextrrrrqrrr)rr(rfr%r-r-r.rcs  zCSVReader.nextN)rrrrrr__next__r-r-r-r.rTs  rc@seZdZddZddZdS) CSVWritercKs(t|d|_tj|jfi|j|_dS)Nr)r}rrwriterr)rrrr-r-r.rns zCSVWriter.__init__cCsNtjddkrg}|D]}t|tr|d}||q |}|j|dSr)rrrrrr"rwriterow)rrowrr%r-r-r.rrs   zCSVWriter.writerowN)rrrrrr-r-r-r.rms rcsHeZdZeejZded<d fdd ZddZdd Zd d Z Z S) Configurator inc_convertincNcs"tt|||p t|_dSr)superrrrmrrx)rconfigrx __class__r-r.rszConfigurator.__init__c sfddd}t|s|}dd}dd}|r.tfdd|D}fd dD}t|}||i|}|rV|D] \}} t||| qI|S) Ncs|t|ttfrt|fdd|D}|St|tr7d|vr&|}|Si}|D] }||||<q*|S|}|S)Ncg|]}|qSr-r-)rSrfconvertr-r.rUrVzBConfigurator.configure_custom..convert..())rr9rtypedictconfigure_customr)or(r)rrr-r.rs   z.Configurator.configure_custom..convertrrDz[]r-crr-r-)rSrrr-r.rUrVz1Configurator.configure_custom..cs$g|]}t|r||fqSr-)r)rSr)rrr-r.rUs$)rsrQrJrrrsetattr) rrrpropsrrrr(r~rNr-)rrrr.rs    zConfigurator.configure_customcCs4|j|}t|trd|vr|||j|<}|S)Nr)rrrr)rrr(r-r-r. __getitem__s zConfigurator.__getitem__cCs\tj|stj|j|}tj|ddd}t|}Wd|S1s'wY|S)z*Default converter for the inc:// protocol.rrr N) rmrnisabsr$rxrr rr)rrrr(r-r-r.rs   zConfigurator.inc_convertr) rrrrrvalue_convertersrrrr __classcell__r-r-rr.rs rc@s*eZdZdZd ddZddZdd ZdS) SubprocessMixinzC Mixin for running subprocesses and capturing their output FNcCs||_||_dSr)verboseprogress)rrrr-r-r.rs zSubprocessMixin.__init__cCsl|j}|j} |}|sn"|dur|||n|s!tjdn tj|dtjq|dS)z Read lines from a subprocess' output stream and either pass to a progress callable (if specified) or write progress information to sys.stderr. TNrDr) rrreadlinerstderrrrflushr)rrrJrrr,r-r-r.rs   zSubprocessMixin.readercKstj|ftjtjd|}tj|j|jdfd}|tj|j|jdfd}|| | | |j durE| dd|S|j rNt jd|S)N)stdoutrr)rrrzdone.mainzdone. ) subprocessPopenPIPE threadingThreadrrrwrwaitr$rrrr)rcmdrrt1t2r-r-r. run_commands$    zSubprocessMixin.run_command)FN)rrrrrrrr-r-r-r.rs   rcCstdd|S)z,Normalize a python package name a la PEP 503z[-_.]+ru)rxsubr)rWr-r-r.normalize_namesrc@s.eZdZdZdZd ddZddZdd ZdS) PyPIRCFilezhttps://upload.pypi.org/legacy/pypiNcCs.|durtjtjdd}||_||_dS)Nr\z.pypirc)rmrnr$r`r{rZ)rrrZr-r-r.rs zPyPIRCFile.__init__c Csxi}tj|jr|jp|j}t}||j| }d|vr| dd}dd| dD}|gkr>d|vr.rrrrk repositoryrealm)rlNz server-loginrl)rkrlrrr)rmrnrr{rZDEFAULT_REPOSITORYrRawConfigParserrrrr DEFAULT_REALM has_option) rr(rrr index_servers_serversrrrr-r-r.rsZ   &        zPyPIRCFile.readcCst}|j}|||ds|d|dd||dd|t|d}||WddS1s:wYdS)Nrrkrlr) rrr{r has_sectionrrr r)rrkrlrrrr-r-r.r 9s     "zPyPIRCFile.updateNN)rrrrrrrr r-r-r-r.rs   :rcCst|jdS)zG Read the PyPI access configuration as supported by distutils. )rZ)rrZrrr-r-r. _load_pypircEsrcCst|j|jdSr)rr rkrlrr-r-r. _store_pypircKrrc Cstjdkr#dtjvrdSdtjvrdSdtjvr dStjSdtjvr-tjdStjd ks7ttd s:tjSt\}}}}}| d d }| d d d d}|dddkrcd||fS|dddkr|ddkrd}dt |dd|ddf}ddd}|d|tj 7}nL|dddkrdd l m }|S|dd!d"krd"}td#tj}||}|r|}n|dd!d$krddl} ddl} | | j|||\}}}d%|||fS)&aReturn a string that identifies the current platform. This is used mainly to distinguish platform-specific build directories and platform-specific built distributions. Typically includes the OS name and version and the architecture (as supplied by 'os.uname()'), although the exact information included depends on the OS; eg. on Linux, the kernel version isn't particularly important. Examples of returned values: linux-i586 linux-alpha (?) solaris-2.6-sun4u Windows will return one of: win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) win32 (all others - specifically, sys.platform is returned) For other non-POSIX platforms, currently just returns 'sys.platform'. rZamd64 win-amd64z(arm) win-arm32z(arm64)z win-arm64_PYTHON_HOST_PLATFORMrunamerlrrtrhruNlinuxz%s-%ssunosr5solarisz%d.%srrV32bit64bit)ilz.%saix) aix_platformrXcygwinz[\d.]+darwinz%s-%s-%s)rmrWrrrplatformr^rrr!intmaxsize _aix_supportrrxr&ASCIIrr _osx_supportdistutils.sysconfigget_platform_osx sysconfigget_config_vars) osnamer6releasermachinebitnessrrel_rer'rrr-r-r.get_host_platformSsR          rwin32rr)x86x64armcCs2tjdkrtStjd}|tvrtSt|S)NrZVSCMD_ARG_TGT_ARCH)rmrWrr^r_TARGET_TO_PLAT)cross_compilation_targetr-r-r. get_platforms  rr)rrr)r collectionsr contextlibrglobrr#rrloggingrmr$rxrr; ImportErrorrrrrrrZdummy_threadingrrrcompatrrrr r r r r rrrrrrrrrrrrr getLoggerrrr&rrKrJr7rAr<r_r#rCrjrrrrrrrcontextmanagerrrrrrrrrJrKVERBOSErTrrergrirmrprsIrzrvrrrrrrrrrrrARCHIVE_EXTENSIONSrrrrr"rrrr(rLr)r*r+rSrrkrZrcrervrwr}r~rrrrrrrrrrrr-r-r-r.s        \         Y}  /    8 )    ,H 6 ]   +)  7.QR PKH]yhhCpython3.10/site-packages/pip/_vendor/distlib/_backport/sysconfig.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2012 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # """Access to Python's configuration information.""" import codecs import os import re import sys from os.path import pardir, realpath try: import configparser except ImportError: import ConfigParser as configparser __all__ = [ 'get_config_h_filename', 'get_config_var', 'get_config_vars', 'get_makefile_filename', 'get_path', 'get_path_names', 'get_paths', 'get_platform', 'get_python_version', 'get_scheme_names', 'parse_config_h', ] def _safe_realpath(path): try: return realpath(path) except OSError: return path if sys.executable: _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) else: # sys.executable can be empty if argv[0] has been changed and Python is # unable to retrieve the real program name _PROJECT_BASE = _safe_realpath(os.getcwd()) if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) # PC/VS7.1 if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) # PC/AMD64 if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) def is_python_build(): for fn in ("Setup.dist", "Setup.local"): if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): return True return False _PYTHON_BUILD = is_python_build() _cfg_read = False def _ensure_cfg_read(): global _cfg_read if not _cfg_read: from ..resources import finder backport_package = __name__.rsplit('.', 1)[0] _finder = finder(backport_package) _cfgfile = _finder.find('sysconfig.cfg') assert _cfgfile, 'sysconfig.cfg exists' with _cfgfile.as_stream() as s: _SCHEMES.readfp(s) if _PYTHON_BUILD: for scheme in ('posix_prefix', 'posix_home'): _SCHEMES.set(scheme, 'include', '{srcdir}/Include') _SCHEMES.set(scheme, 'platinclude', '{projectbase}/.') _cfg_read = True _SCHEMES = configparser.RawConfigParser() _VAR_REPL = re.compile(r'\{([^{]*?)\}') def _expand_globals(config): _ensure_cfg_read() if config.has_section('globals'): globals = config.items('globals') else: globals = tuple() sections = config.sections() for section in sections: if section == 'globals': continue for option, value in globals: if config.has_option(section, option): continue config.set(section, option, value) config.remove_section('globals') # now expanding local variables defined in the cfg file # for section in config.sections(): variables = dict(config.items(section)) def _replacer(matchobj): name = matchobj.group(1) if name in variables: return variables[name] return matchobj.group(0) for option, value in config.items(section): config.set(section, option, _VAR_REPL.sub(_replacer, value)) #_expand_globals(_SCHEMES) _PY_VERSION = '%s.%s.%s' % sys.version_info[:3] _PY_VERSION_SHORT = '%s.%s' % sys.version_info[:2] _PY_VERSION_SHORT_NO_DOT = '%s%s' % sys.version_info[:2] _PREFIX = os.path.normpath(sys.prefix) _EXEC_PREFIX = os.path.normpath(sys.exec_prefix) _CONFIG_VARS = None _USER_BASE = None def _subst_vars(path, local_vars): """In the string `path`, replace tokens like {some.thing} with the corresponding value from the map `local_vars`. If there is no corresponding value, leave the token unchanged. """ def _replacer(matchobj): name = matchobj.group(1) if name in local_vars: return local_vars[name] elif name in os.environ: return os.environ[name] return matchobj.group(0) return _VAR_REPL.sub(_replacer, path) def _extend_dict(target_dict, other_dict): target_keys = target_dict.keys() for key, value in other_dict.items(): if key in target_keys: continue target_dict[key] = value def _expand_vars(scheme, vars): res = {} if vars is None: vars = {} _extend_dict(vars, get_config_vars()) for key, value in _SCHEMES.items(scheme): if os.name in ('posix', 'nt'): value = os.path.expanduser(value) res[key] = os.path.normpath(_subst_vars(value, vars)) return res def format_value(value, vars): def _replacer(matchobj): name = matchobj.group(1) if name in vars: return vars[name] return matchobj.group(0) return _VAR_REPL.sub(_replacer, value) def _get_default_scheme(): if os.name == 'posix': # the default scheme for posix is posix_prefix return 'posix_prefix' return os.name def _getuserbase(): env_base = os.environ.get("PYTHONUSERBASE", None) def joinuser(*args): return os.path.expanduser(os.path.join(*args)) # what about 'os2emx', 'riscos' ? if os.name == "nt": base = os.environ.get("APPDATA") or "~" if env_base: return env_base else: return joinuser(base, "Python") if sys.platform == "darwin": framework = get_config_var("PYTHONFRAMEWORK") if framework: if env_base: return env_base else: return joinuser("~", "Library", framework, "%d.%d" % sys.version_info[:2]) if env_base: return env_base else: return joinuser("~", ".local") def _parse_makefile(filename, vars=None): """Parse a Makefile-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. """ # Regexes needed for parsing Makefile (and similar syntaxes, # like old-style Setup files). _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") if vars is None: vars = {} done = {} notdone = {} with codecs.open(filename, encoding='utf-8', errors="surrogateescape") as f: lines = f.readlines() for line in lines: if line.startswith('#') or line.strip() == '': continue m = _variable_rx.match(line) if m: n, v = m.group(1, 2) v = v.strip() # `$$' is a literal `$' in make tmpv = v.replace('$$', '') if "$" in tmpv: notdone[n] = v else: try: v = int(v) except ValueError: # insert literal `$' done[n] = v.replace('$$', '$') else: done[n] = v # do variable interpolation here variables = list(notdone.keys()) # Variables with a 'PY_' prefix in the makefile. These need to # be made available without that prefix through sysconfig. # Special care is needed to ensure that variable expansion works, even # if the expansion uses the name without a prefix. renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') while len(variables) > 0: for name in tuple(variables): value = notdone[name] m = _findvar1_rx.search(value) or _findvar2_rx.search(value) if m is not None: n = m.group(1) found = True if n in done: item = str(done[n]) elif n in notdone: # get it on a subsequent round found = False elif n in os.environ: # do it like make: fall back to environment item = os.environ[n] elif n in renamed_variables: if (name.startswith('PY_') and name[3:] in renamed_variables): item = "" elif 'PY_' + n in notdone: found = False else: item = str(done['PY_' + n]) else: done[n] = item = "" if found: after = value[m.end():] value = value[:m.start()] + item + after if "$" in after: notdone[name] = value else: try: value = int(value) except ValueError: done[name] = value.strip() else: done[name] = value variables.remove(name) if (name.startswith('PY_') and name[3:] in renamed_variables): name = name[3:] if name not in done: done[name] = value else: # bogus variable reference (e.g. "prefix=$/opt/python"); # just drop it since we can't deal done[name] = value variables.remove(name) # strip spurious spaces for k, v in done.items(): if isinstance(v, str): done[k] = v.strip() # save the results in the global dictionary vars.update(done) return vars def get_makefile_filename(): """Return the path of the Makefile.""" if _PYTHON_BUILD: return os.path.join(_PROJECT_BASE, "Makefile") if hasattr(sys, 'abiflags'): config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags) else: config_dir_name = 'config' return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') def _init_posix(vars): """Initialize the module as appropriate for POSIX systems.""" # load the installed Makefile: makefile = get_makefile_filename() try: _parse_makefile(makefile, vars) except IOError as e: msg = "invalid Python installation: unable to open %s" % makefile if hasattr(e, "strerror"): msg = msg + " (%s)" % e.strerror raise IOError(msg) # load the installed pyconfig.h: config_h = get_config_h_filename() try: with open(config_h) as f: parse_config_h(f, vars) except IOError as e: msg = "invalid Python installation: unable to open %s" % config_h if hasattr(e, "strerror"): msg = msg + " (%s)" % e.strerror raise IOError(msg) # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. if _PYTHON_BUILD: vars['LDSHARED'] = vars['BLDSHARED'] def _init_non_posix(vars): """Initialize the module as appropriate for NT""" # set basic install directories vars['LIBDEST'] = get_path('stdlib') vars['BINLIBDEST'] = get_path('platstdlib') vars['INCLUDEPY'] = get_path('include') vars['SO'] = '.pyd' vars['EXE'] = '.exe' vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) # # public APIs # def parse_config_h(fp, vars=None): """Parse a config.h-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. """ if vars is None: vars = {} define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") while True: line = fp.readline() if not line: break m = define_rx.match(line) if m: n, v = m.group(1, 2) try: v = int(v) except ValueError: pass vars[n] = v else: m = undef_rx.match(line) if m: vars[m.group(1)] = 0 return vars def get_config_h_filename(): """Return the path of pyconfig.h.""" if _PYTHON_BUILD: if os.name == "nt": inc_dir = os.path.join(_PROJECT_BASE, "PC") else: inc_dir = _PROJECT_BASE else: inc_dir = get_path('platinclude') return os.path.join(inc_dir, 'pyconfig.h') def get_scheme_names(): """Return a tuple containing the schemes names.""" return tuple(sorted(_SCHEMES.sections())) def get_path_names(): """Return a tuple containing the paths names.""" # xxx see if we want a static list return _SCHEMES.options('posix_prefix') def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): """Return a mapping containing an install scheme. ``scheme`` is the install scheme name. If not provided, it will return the default scheme for the current platform. """ _ensure_cfg_read() if expand: return _expand_vars(scheme, vars) else: return dict(_SCHEMES.items(scheme)) def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): """Return a path corresponding to the scheme. ``scheme`` is the install scheme name. """ return get_paths(scheme, vars, expand)[name] def get_config_vars(*args): """With no arguments, return a dictionary of all configuration variables relevant for the current platform. On Unix, this means every variable defined in Python's installed Makefile; On Windows and Mac OS it's a much smaller set. With arguments, return a list of values that result from looking up each argument in the configuration variable dictionary. """ global _CONFIG_VARS if _CONFIG_VARS is None: _CONFIG_VARS = {} # Normalized versions of prefix and exec_prefix are handy to have; # in fact, these are the standard versions used most places in the # distutils2 module. _CONFIG_VARS['prefix'] = _PREFIX _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX _CONFIG_VARS['py_version'] = _PY_VERSION _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] _CONFIG_VARS['base'] = _PREFIX _CONFIG_VARS['platbase'] = _EXEC_PREFIX _CONFIG_VARS['projectbase'] = _PROJECT_BASE try: _CONFIG_VARS['abiflags'] = sys.abiflags except AttributeError: # sys.abiflags may not be defined on all platforms. _CONFIG_VARS['abiflags'] = '' if os.name in ('nt', 'os2'): _init_non_posix(_CONFIG_VARS) if os.name == 'posix': _init_posix(_CONFIG_VARS) # Setting 'userbase' is done below the call to the # init function to enable using 'get_config_var' in # the init-function. if sys.version >= '2.6': _CONFIG_VARS['userbase'] = _getuserbase() if 'srcdir' not in _CONFIG_VARS: _CONFIG_VARS['srcdir'] = _PROJECT_BASE else: _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['srcdir']) # Convert srcdir into an absolute path if it appears necessary. # Normally it is relative to the build directory. However, during # testing, for example, we might be running a non-installed python # from a different directory. if _PYTHON_BUILD and os.name == "posix": base = _PROJECT_BASE try: cwd = os.getcwd() except OSError: cwd = None if (not os.path.isabs(_CONFIG_VARS['srcdir']) and base != cwd): # srcdir is relative and we are not in the same directory # as the executable. Assume executable is in the build # directory and make srcdir absolute. srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) if sys.platform == 'darwin': kernel_version = os.uname()[2] # Kernel version (8.4.3) major_version = int(kernel_version.split('.')[0]) if major_version < 8: # On Mac OS X before 10.4, check if -arch and -isysroot # are in CFLAGS or LDFLAGS and remove them if they are. # This is needed when building extensions on a 10.3 system # using a universal build of python. for key in ('LDFLAGS', 'BASECFLAGS', # a number of derived variables. These need to be # patched up as well. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): flags = _CONFIG_VARS[key] flags = re.sub(r'-arch\s+\w+\s', ' ', flags) flags = re.sub('-isysroot [^ \t]*', ' ', flags) _CONFIG_VARS[key] = flags else: # Allow the user to override the architecture flags using # an environment variable. # NOTE: This name was introduced by Apple in OSX 10.5 and # is used by several scripting languages distributed with # that OS release. if 'ARCHFLAGS' in os.environ: arch = os.environ['ARCHFLAGS'] for key in ('LDFLAGS', 'BASECFLAGS', # a number of derived variables. These need to be # patched up as well. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): flags = _CONFIG_VARS[key] flags = re.sub(r'-arch\s+\w+\s', ' ', flags) flags = flags + ' ' + arch _CONFIG_VARS[key] = flags # If we're on OSX 10.5 or later and the user tries to # compiles an extension using an SDK that is not present # on the current machine it is better to not use an SDK # than to fail. # # The major usecase for this is users using a Python.org # binary installer on OSX 10.6: that installer uses # the 10.4u SDK, but that SDK is not installed by default # when you install Xcode. # CFLAGS = _CONFIG_VARS.get('CFLAGS', '') m = re.search(r'-isysroot\s+(\S+)', CFLAGS) if m is not None: sdk = m.group(1) if not os.path.exists(sdk): for key in ('LDFLAGS', 'BASECFLAGS', # a number of derived variables. These need to be # patched up as well. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): flags = _CONFIG_VARS[key] flags = re.sub(r'-isysroot\s+\S+(\s|$)', ' ', flags) _CONFIG_VARS[key] = flags if args: vals = [] for name in args: vals.append(_CONFIG_VARS.get(name)) return vals else: return _CONFIG_VARS def get_config_var(name): """Return the value of a single variable using the dictionary returned by 'get_config_vars()'. Equivalent to get_config_vars().get(name) """ return get_config_vars().get(name) def get_platform(): """Return a string that identifies the current platform. This is used mainly to distinguish platform-specific build directories and platform-specific built distributions. Typically includes the OS name and version and the architecture (as supplied by 'os.uname()'), although the exact information included depends on the OS; eg. for IRIX the architecture isn't particularly important (IRIX only runs on SGI hardware), but for Linux the kernel version isn't particularly important. Examples of returned values: linux-i586 linux-alpha (?) solaris-2.6-sun4u irix-5.3 irix64-6.2 Windows will return one of: win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) win-ia64 (64bit Windows on Itanium) win32 (all others - specifically, sys.platform is returned) For other non-POSIX platforms, currently just returns 'sys.platform'. """ if os.name == 'nt': # sniff sys.version for architecture. prefix = " bit (" i = sys.version.find(prefix) if i == -1: return sys.platform j = sys.version.find(")", i) look = sys.version[i+len(prefix):j].lower() if look == 'amd64': return 'win-amd64' if look == 'itanium': return 'win-ia64' return sys.platform if os.name != "posix" or not hasattr(os, 'uname'): # XXX what about the architecture? NT is Intel or Alpha, # Mac OS is M68k or PPC, etc. return sys.platform # Try to distinguish various flavours of Unix osname, host, release, version, machine = os.uname() # Convert the OS name to lowercase, remove '/' characters # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") osname = osname.lower().replace('/', '') machine = machine.replace(' ', '_') machine = machine.replace('/', '-') if osname[:5] == "linux": # At least on Linux/Intel, 'machine' is the processor -- # i386, etc. # XXX what about Alpha, SPARC, etc? return "%s-%s" % (osname, machine) elif osname[:5] == "sunos": if release[0] >= "5": # SunOS 5 == Solaris 2 osname = "solaris" release = "%d.%s" % (int(release[0]) - 3, release[2:]) # fall through to standard osname-release-machine representation elif osname[:4] == "irix": # could be "irix64"! return "%s-%s" % (osname, release) elif osname[:3] == "aix": return "%s-%s.%s" % (osname, version, release) elif osname[:6] == "cygwin": osname = "cygwin" rel_re = re.compile(r'[\d.]+') m = rel_re.match(release) if m: release = m.group() elif osname[:6] == "darwin": # # For our purposes, we'll assume that the system version from # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set # to. This makes the compatibility story a bit more sane because the # machine is going to compile and link as if it were # MACOSX_DEPLOYMENT_TARGET. cfgvars = get_config_vars() macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') if True: # Always calculate the release of the running machine, # needed to determine if we can build fat binaries or not. macrelease = macver # Get the system version. Reading this plist is a documented # way to get the system version (see the documentation for # the Gestalt Manager) try: f = open('/System/Library/CoreServices/SystemVersion.plist') except IOError: # We're on a plain darwin box, fall back to the default # behaviour. pass else: try: m = re.search(r'ProductUserVisibleVersion\s*' r'(.*?)', f.read()) finally: f.close() if m is not None: macrelease = '.'.join(m.group(1).split('.')[:2]) # else: fall back to the default behaviour if not macver: macver = macrelease if macver: release = macver osname = "macosx" if ((macrelease + '.') >= '10.4.' and '-arch' in get_config_vars().get('CFLAGS', '').strip()): # The universal build will build fat binaries, but not on # systems before 10.4 # # Try to detect 4-way universal builds, those have machine-type # 'universal' instead of 'fat'. machine = 'fat' cflags = get_config_vars().get('CFLAGS') archs = re.findall(r'-arch\s+(\S+)', cflags) archs = tuple(sorted(set(archs))) if len(archs) == 1: machine = archs[0] elif archs == ('i386', 'ppc'): machine = 'fat' elif archs == ('i386', 'x86_64'): machine = 'intel' elif archs == ('i386', 'ppc', 'x86_64'): machine = 'fat3' elif archs == ('ppc64', 'x86_64'): machine = 'fat64' elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): machine = 'universal' else: raise ValueError( "Don't know machine value for archs=%r" % (archs,)) elif machine == 'i386': # On OSX the machine type returned by uname is always the # 32-bit variant, even if the executable architecture is # the 64-bit variant if sys.maxsize >= 2**32: machine = 'x86_64' elif machine in ('PowerPC', 'Power_Macintosh'): # Pick a sane name for the PPC architecture. # See 'i386' case if sys.maxsize >= 2**32: machine = 'ppc64' else: machine = 'ppc' return "%s-%s-%s" % (osname, release, machine) def get_python_version(): return _PY_VERSION_SHORT def _print_dict(title, data): for index, (key, value) in enumerate(sorted(data.items())): if index == 0: print('%s: ' % (title)) print('\t%s = "%s"' % (key, value)) def _main(): """Display all information sysconfig detains.""" print('Platform: "%s"' % get_platform()) print('Python version: "%s"' % get_python_version()) print('Current installation scheme: "%s"' % _get_default_scheme()) print() _print_dict('Paths', get_paths()) print() _print_dict('Variables', get_config_vars()) if __name__ == '__main__': _main() PKH]7L]PTPTYpython3.10/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-310.pycnu[o aikd@sdZddlZddlZddlZddlmZddlZzddlmZWne y/ddl mZYnwddl Z ddl m Z zddlZdZWn e yMdZYnwzdd lmZWn e yadZYnwzdd lmZWn e yudZYnwgd ZGd d d eZGdddeZGdddeZGdddeZGdddeZzeWn eydZYnwdfddZddZddZ ddZ!dd Z"d!d"Z#d#d$Z$d%d&Z%dde$dfd'd(Z&dgd)d*Z'd+d,Z(d-d.Z)d/d0Z*d1d2Z+d3d4Z,  dhd6d7Z-did8d9Z.djd:d;Z/e-dgd?fe-d@gdAfe/gdBfdCZ0er'e-d>gd?fe0dD<dEdFZ1dkdHdIZ2dJdKZ3  dldLdMZ4dNdOZ5dPdQZ6  GdkdRdSZ7dTdUZ8dVdWZ9dXdYZ:dZd[Z;d\d]ge;gd=fd^ge;gdAfd_ge:gdBfd`ZdS)nzUtility functions for copying and archiving files and directory trees. XXX The functions here don't copy the resource fork or other metadata on Mac. N)abspath)Callable)tarfileTF)getpwnam)getgrnam) copyfileobjcopyfilecopymodecopystatcopycopy2copytreemovermtreeErrorSpecialFileError ExecError make_archiveget_archive_formatsregister_archive_formatunregister_archive_formatget_unpack_formatsregister_unpack_formatunregister_unpack_formatunpack_archiveignore_patternsc@s eZdZdS)rN)__name__ __module__ __qualname__r r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/_backport/shutil.pyr/src@eZdZdZdS)rz|Raised when trying to do a kind of operation (e.g. copying) which is not supported on a special file (e.g. a named pipe)Nrrr__doc__r r r r!r2rc@r")rz+Raised when a command could not be executedNr#r r r r!r6r%rc@r") ReadErrorz%Raised when an archive cannot be readNr#r r r r!r&9r%r&c@r") RegistryErrorzVRaised when a registry operation with the archiving and unpacking registries failsNr#r r r r!r'<r%r'@cCs ||}|s dS||q)z=copy data from file-like object fsrc to file-like object fdstrN)readwrite)fsrcfdstlengthbufr r r!rFs   rcCsZttjdrztj||WStyYdSwtjtj|tjtj|kS)NsamefileF)hasattrospathr/OSErrornormcasersrcdstr r r! _samefileNs  r8c Cst||r td||f||fD]}zt|}Wn ty#Yqwt|jr0td|qt|d+}t|d }t ||Wdn1sLwYWddSWddS1sdwYdS)zCopy data from src to dstz`%s` and `%s` are the same filez`%s` is a named piperbwbN) r8rr1statr3S_ISFIFOst_moderopenr)r6r7fnstr+r,r r r!r Zs$        "r cCs4ttdrt|}t|j}t||dSdS)zCopy mode bits from src to dstchmodN)r0r1r;S_IMODEr=rA)r6r7r@moder r r!r ns   r c Cst|}t|j}ttdrt||j|jfttdr%t||ttdrYt|dr[z t ||j WdSt yX}ztt drL|j t j krMWYd}~dSd}~wwdSdS)zCCopy all stat info (mode bits, atime, mtime, flags) from src to dstutimerAchflagsst_flags EOPNOTSUPPN)r1r;rBr=r0rDst_atimest_mtimerArErFr3errnorG)r6r7r@rCwhyr r r!r us"       r cC:tj|rtj|tj|}t||t||dS)zVCopy data and mode bits ("cp src dst"). The destination may be a directory. N)r1r2isdirjoinbasenamer r r5r r r!r   r cCrL)z]Copy data and all stat info ("cp -p src dst"). The destination may be a directory. N)r1r2rMrNrOr r r5r r r!r rPr csfdd}|S)zFunction that can be used as copytree() ignore parameter. Patterns is a sequence of glob-style patterns that are used to exclude filescs(g}D] }|t||qt|SN)extendfnmatchfilterset)r2names ignored_namespatternpatternsr r!_ignore_patternssz)ignore_patterns.._ignore_patternsr )rZr[r rYr!rs rc Cst|}|dur|||}nt}t|g}|D]} | |vr"qtj|| } tj|| } z:tj| rUt| } |rEt| | n$tj | sO|rOWq|| | ntj | rdt | | |||n|| | Wqt y} z| | jdWYd} ~ qd} ~ wty}z|| | t|fWYd}~qd}~wwzt||Wn&ty}ztdurt|trn | ||t|fWYd}~nd}~ww|rt |dS)aRecursively copy a directory tree. The destination directory must not already exist. If exception(s) occur, an Error is raised with a list of reasons. If the optional symlinks flag is true, symbolic links in the source tree result in symbolic links in the destination tree; if it is false, the contents of the files pointed to by symbolic links are copied. If the file pointed by the symlink doesn't exist, an exception will be added in the list of errors raised in an Error exception at the end of the copy process. You can set the optional ignore_dangling_symlinks flag to true if you want to silence this exception. Notice that this has no effect on platforms that don't support os.symlink. The optional ignore argument is a callable. If given, it is called with the `src` parameter, which is the directory being visited by copytree(), and `names` which is the list of `src` contents, as returned by os.listdir(): callable(src, names) -> ignored_names Since copytree() is called recursively, the callable will be called once for each directory that is copied. It returns a list of names relative to the `src` directory that should not be copied. The optional copy_function argument is a callable that will be used to copy each file. It will be called with the source path and the destination path as arguments. By default, copy2() is used, but any function that supports the same signature (like copy()) can be used. Nr)r1listdirrUmakedirsr2rNislinkreadlinksymlinkexistsrMrrrRargsEnvironmentErrorappendstrr r3 WindowsError isinstance)r6r7symlinksignore copy_functionignore_dangling_symlinksrVrWerrorsnamesrcnamedstnamelinktoerrrKr r r!rsR $        rc Csb|rdd}n|durdd}z tj|rtdWnty/|tjj|tYdSwg}zt|}WntjyL|tj|tYnw|D]D}tj||}zt |j }Wn tjyld}Ynwt |ryt |||qOzt|WqOtjy|tj|tYqOwzt|WdStjy|tj|tYdSw)aRecursively delete a directory tree. If ignore_errors is set, errors are ignored; otherwise, if onerror is set, it is called to handle the error with arguments (func, path, exc_info) where func is os.listdir, os.remove, or os.rmdir; path is the argument to that function that caused it to fail; and exc_info is a tuple returned by sys.exc_info(). If ignore_errors is false and onerror is None, an exception is raised. cWsdSrQr rbr r r!onerrorszrmtree..onerrorNcWsrQr rrr r r!rssz%Cannot call rmtree on a symbolic linkr)r1r2r^r3sysexc_infor\errorrNlstatr=r;S_ISDIRrremovermdir)r2 ignore_errorsrsrVrmfullnamerCr r r!rsJ    rcCstj|tjjSrQ)r1r2rOrstripsep)r2r r r! _basename*srcCs|}tj|r*t||rt||dStj|t|}tj|r*td|z t||WdSt yhtj|r[t ||rMtd||ft ||ddt |YdSt ||t|YdSw)aRecursively move a file or directory to another location. This is similar to the Unix "mv" command. If the destination is a directory or a symlink to a directory, the source is moved inside the directory. The destination path must not already exist. If the destination already exists but is not a directory, it may be overwritten depending on os.rename() semantics. If the destination is on our current filesystem, then rename() is used. Otherwise, src is copied to the destination and then removed. A lot more could be done here... A look at a mv.c shows a lot of the issues this implementation glosses over. Nz$Destination path '%s' already existsz.Cannot move a directory '%s' into itself '%s'.T)rh)r1r2rMr8renamerNrrarr3 _destinsrcrrr unlink)r6r7real_dstr r r!r/s&         rcCsNt|}t|}|tjjs|tjj7}|tjjs"|tjj7}||SrQ)rendswithr1r2r~ startswithr5r r r!rWs   rcCLtdus|dur dSzt|}Wn tyd}Ynw|dur$|dSdS)z"Returns a gid, given a group name.N)rKeyErrorrmresultr r r!_get_gid`  rcCr)z"Returns an uid, given a user name.Nr)rrrr r r!_get_uidlrrgzipcs ddd}ddi} trd|d<d| d<|d ur"|| vr"td ||d | |d} tj| } tj| sI|d urB|d | |sIt | |d urR|d t t fdd} |st | d||} z| j|| dW| | S| w| S)aCreate a (possibly compressed) tar file from all the files under 'base_dir'. 'compress' must be "gzip" (the default), "bzip2", or None. 'owner' and 'group' can be used to define an owner and a group for the archive that is being built. If not provided, the current owner and group will be used. The output tar file will be named 'base_name' + ".tar", possibly plus the appropriate compression extension (".gz", or ".bz2"). Returns the output filename. gz)rNrz.gzbz2bzip2.bz2NzCbad value for 'compress', or compression format not supported : {0}.tar creating %szCreating tar archivecs,dur |_|_dur|_|_|SrQ)gidgnameuiduname)tarinforgroupownerrr r! _set_uid_gidsz#_make_tarball.._set_uid_gidzw|%s)rT)_BZ2_SUPPORTED ValueErrorformatgetr1r2dirnamerainfor]rrrr>addclose) base_namebase_dircompressverbosedry_runrrloggertar_compression compress_ext archive_name archive_dirrtarr rr! _make_tarballxs:        rcCs\|rd}nd}ddlm}ddlm}z |d|||g|dWdS|y-td|w) Nz-rz-rqr)DistutilsExecError)spawnzip)rzkunable to create zip file '%s': could neither import the 'zipfile' module nor find a standalone zip utility)distutils.errorsrdistutils.spawnrr)r zip_filenamerr zipoptionsrrr r r!_call_external_zips   rcCs|d}tj|}tj|s!|dur|d||s!t|zddl}Wn ty2d}Ynw|dur@t|||||S|durK|d|||s|j |d|j d}t |D]+\} } } | D]#} tj tj | | } tj| r|| | |dur|d| qbq[||S) amCreate a zip file from all the files under 'base_dir'. The output zip file will be named 'base_name' + ".zip". Uses either the "zipfile" Python module (if available) or the InfoZIP "zip" utility (if installed and found on the default search path). If neither tool is available, raises ExecError. Returns the name of the output zip file. .zipNrrz#creating '%s' and adding '%s' to itw) compressionz adding '%s')r1r2rrarr]zipfile ImportErrorrZipFile ZIP_DEFLATEDwalknormpathrNisfiler*r)rrrrrrrrrdirpathdirnames filenamesrmr2r r r! _make_zipfilesD         r)rrzgzip'ed tar-file)rrzbzip2'ed tar-file)rNzuncompressed tar filezZIP file)gztarbztarrrrcCddtD}||S)zReturns a list of supported formats for archiving and unarchiving. Each element of the returned sequence is a tuple (name, description) cSsg|] \}}||dfqS)rr ).0rmregistryr r r! sz'get_archive_formats..)_ARCHIVE_FORMATSitemssortformatsr r r!rs rrcCsv|durg}t|tstd|t|ttfstd|D]}t|ttfr-t|dkr1tdq|||ft|<dS)auRegisters an archive format. name is the name of the format. function is the callable that will be used to create archives. If provided, extra_args is a sequence of (name, value) tuples that will be passed as arguments to the callable. description can be provided to describe the format, and will be returned by the get_archive_formats() function. NzThe %s object is not callablez!extra_args needs to be a sequencerz+extra_args elements are : (arg_name, value))rgr TypeErrortuplelistlenr)rmfunction extra_args descriptionelementr r r!r s   rcCs t|=dSrQ)rrmr r r!r s rc  Cs"t} |dur|dur|d|tj|}|st||dur&tj}||d} zt|} Wn ty>t d|w| d} | dD]\} }|| | <qG|dkr\|| d<|| d <z| ||fi| }W|durz|duru|d | t| |S|dur|dur|d | t| ww) aCreate an archive file (eg. zip or tar). 'base_name' is the name of the file to create, minus any format-specific extension; 'format' is the archive format: one of "zip", "tar", "bztar" or "gztar". 'root_dir' is a directory that will be the root directory of the archive; ie. we typically chdir into 'root_dir' before creating the archive. 'base_dir' is the directory where we start archiving from; ie. 'base_dir' will be the common prefix of all files and directories in the archive. 'root_dir' and 'base_dir' both default to the current directory. Returns the name of the archive file. 'owner' and 'group' are used when creating a tar archive. By default, uses the current owner and group. Nzchanging into '%s')rrzunknown archive format '%s'rrrrrzchanging back to '%s') r1getcwddebugr2rchdircurdirrrr)rrroot_dirrrrrrrsave_cwdkwargs format_infofuncargvalfilenamer r r!r#sB            rcCr)zReturns a list of supported formats for unpacking. Each element of the returned sequence is a tuple (name, extensions, description) cSs"g|] \}}||d|dfqS)rr )rrmrr r r!r`s"z&get_unpack_formats..)_UNPACK_FORMATSrrrr r r!rZs rc Csli}tD]\}}|dD]}|||<qq|D]}||vr*d}t||||fqt|ts4tddS)z+Checks what gets registered as an unpacker.rz!%s is already registered for "%s"z*The registered function must be a callableN)rrr'rgrr) extensionsrrexisting_extensionsrmrext extensionmsgr r r!_check_unpack_optionses   rcCs,|durg}t|||||||ft|<dS)aMRegisters an unpack format. `name` is the name of the format. `extensions` is a list of extensions corresponding to the format. `function` is the callable that will be used to unpack archives. The callable will receive archives to unpack. If it's unable to handle an archive, it needs to raise a ReadError exception. If provided, `extra_args` is a sequence of (name, value) tuples that will be passed as arguments to the callable. description can be provided to describe the format, and will be returned by the get_unpack_formats() function. N)rr)rmrrrrr r r!rws rcCs t|=dS)z*Removes the pack format from the registry.N)rrr r r!rs rcCs*tj|}tj|st|dSdS)z1Ensure that the parent directory of `path` existsN)r1r2rrMr])r2rr r r!_ensure_directorys  rc Cszddl}Wn tytdw||std|||}zR|D]F}|j}|ds5d|vr6q'tj j |g| dR}|sFq't || dsm||j}t|d}z ||W|~q'|~wq'W|dS|w)z+Unpack zip `filename` to `extract_dir` rNz/zlib not supported, cannot unpack this archive.z%s is not a zip file/z..r:)rrr& is_zipfilerinfolistrrr1r2rNsplitrrr)r>r*r) r extract_dirrrrrmtargetdatafr r r!_unpack_zipfiles:          rcCsPzt|}Wntjytd|wz ||W|dS|w)z:Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` z/%s is not a compressed or uncompressed tar fileN)rr>TarErrorr& extractallr)rrtarobjr r r!_unpack_tarfiles rz.tar.gzz.tgzrr)rrrrcCs:tD]\}}|dD] }||r|Sq qdS)Nr)rrr)rrmrrr r r!_find_unpack_formats   rcCs|durt}|dur4zt|}Wnty td|w|d}|||fit|ddSt|}|durCtd|t|d}tt|d}|||fi|dS)aUnpack an archive. `filename` is the name of the archive. `extract_dir` is the name of the target directory, where the archive is unpacked. If not provided, the current working directory is used. `format` is the archive format: one of "zip", "tar", or "gztar". Or any other registered format. If not provided, unpack_archive will use the filename extension and see if an unpacker was registered for that extension. In case none is found, a ValueError is raised. NzUnknown unpack format '{0}'rrzUnknown archive format '{0}') r1rrrrrdictrr&)rrrrrrr r r!rs    r)r()FN)rrrNNN)FF)rrN)Nr)NNrrNNN)NN)?r$r1rtr;os.pathrrScollections.abcrr collectionsrJrrrrpwdrgrpr__all__rcrrrr& Exceptionr'rf NameErrorrr8r r r r r rrrrrrrrrrrrrrrrrrrrrrrrrrr r r r!s             R1(    >  0    7  %  PKH]e [python3.10/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-310.pycnu[o ai@sdZdS)a Modules copied from Python 3 standard libraries, for internal use only. Individual classes and functions are found in d2._backport.misc. Intended usage is to always import things missing from 3.1 from that module: the built-in/stdlib objects will be used if found. N)__doc__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/_backport/__init__.pysPKH]Wu;66Zpython3.10/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-310.pycnu[o aii @sHddlmZ dZdZdZdZdZdZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZz ddlZddlZWn eyJdZZYnweefZzeef7ZWn ey_Ynwgd Zejdd krpddlZnddlZejZd Zd Zed Z dZ!dZ"dZ#dZ$dZ%dZ&d Z'dZ(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5d Z6d!Z7e6Z8e&e'e(e)e,e-e.e*e+e/e0e1f Z9e&e'e.e1fZ:e/e0e1fZ;d"Ze?e?e?e@e@e@d$ZAd%ZBd&ZCd'ZDd(ZEd)ZFd*ZGd+ZHd,ZId ZJd-ZKd.ZLd/ZMd0ZNd1ZOd2ZPd3ZQd!ZRd ZSe jTd4vrd5ZUneVZUd6d7ZWd8d9ZXd:d;ZYd2e8fdd?Z[d{d@dAZ\eBdBfeCdCfeDdDfeEdEfeFdFfeGdGffeKdHffeLdIffeMeHBdJfeHdKfeMdLffeNdHffeOdIffePeIBdJfeIdKfePdLffeQdHffeRdIffeSeJBdMfeJdNfeSdLfff Z]dOdPZ^GdQdRdRe_Z`GdSdTdTe`ZaGdUdVdVe`ZbGdWdXdXe`ZcGdYdZdZe`ZdGd[d\d\e`ZeGd]d^d^eeZfGd_d`d`eeZgGdadbdbeeZhGdcddddeeZiGdedfdfeeZjGdgdhdhekZlGdidjdjekZmGdkdldlekZnGdmdndnekZoGdodpdpekZpGdqdrdrekZqGdsdtdtekZrGdudvdvekZsGdwdxdxekZtdydzZueZvesjZdS)|)print_functionz $Revision$z0.9.0u"Lars Gustäbel (lars@gustaebel.de)z5$Date: 2011-02-25 17:42:01 +0200 (Fri, 25 Feb 2011) $z?$Id: tarfile.py 88586 2011-02-25 15:42:01Z marc-andre.lemburg $u4Gustavo Niemeyer, Niels Gustäbel, Richard Townsend.N)TarFileTarInfo is_tarfileTarErrorsustar sustar00d01234567LKSxgX)pathlinkpathsizemtimeuidgidunamegname)rrr#r$)atimectimer r!r"riii`@i ii@ )ntZcezutf-8cCs(|||}|d||t|tS)z8Convert a string to a null-terminated bytes object. N)encodelenNUL)slengthencodingerrorsr8/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/_backport/tarfile.pystns r:cCs*|d}|dkr|d|}|||S)z8Convert a null-terminated bytes object to a string. rN)finddecode)r4r6r7pr8r8r9ntss   r?cCs~|dtdkr"ztt|ddpdd}W|Sty!tdwd}tt|dD]}|dK}|t||d7}q,|S) z/Convert a number field to a python number. rr*asciistrict0r.zinvalid headerr)chrintr? ValueErrorInvalidHeaderErrorranger2ord)r4nir8r8r9ntis rKcCsd|krd|dkrnnd|d|fdt}|S|tks+|d|dkr/td|dkr?tdtd |d}t}t|dD]}| d|d @|dL}qH| dd |S) z/Convert a python number to a number field. rr.rz%0*or@r)zoverflow in number fieldLlr*) r1r3 GNU_FORMATrEstructunpackpack bytearrayrGinsert)rIdigitsformatr4rJr8r8r9itns   rWc Cshdttd|ddtd|dd}dttd|ddtd |dd}||fS) aCalculate the checksum for a member's header by summing up all characters except for the chksum field which is treated as if it was filled with spaces. According to the GNU tar sources, some tars (Sun and NeXT) calculate chksum with signed char, which will be different if there are chars in the buffer with the high bit set. So we calculate two checksums, unsigned and signed. r)Z148BNZ356Br Z148bZ356b)sumrPrQ)bufunsigned_chksum signed_chksumr8r8r9 calc_chksumss0 0r^cCs|dkrdS|dur |d}|s dS||q d}t||\}}t|D]}||}t||kr9td||q(|dkrW||}t||krRtd||dS)zjCopy length bytes from fileobj src to fileobj dst. If length is None, copy the entire content. rNTr'zend of file reached)readwritedivmodrGr2IOError)srcdstr5r[BUFSIZEblocks remainderbr8r8r9 copyfileobjs.         rirM-rhdcr>rwr4SxtTcCsJg}tD]}|D]\}}||@|kr||nq|dqd|S)zcConvert a file's mode to a string of the form -rwxrwxrwx. Used by TarFile.list() rj)filemode_tableappendjoin)modepermtablebitcharr8r8r9filemode8s     r|c@eZdZdZdS)rzBase exception.N__name__ __module__ __qualname____doc__r8r8r8r9rGrc@r}) ExtractErrorz%General exception for extract errors.Nr~r8r8r8r9rJrrc@r}) ReadErrorz&Exception for unreadable tar archives.Nr~r8r8r8r9rMrrc@r})CompressionErrorz.Exception for unavailable compression methods.Nr~r8r8r8r9rPrrc@r}) StreamErrorz=Exception for unsupported operations on stream-like TarFiles.Nr~r8r8r8r9rSrrc@r}) HeaderErrorz!Base exception for header errors.Nr~r8r8r8r9rVrrc@r})EmptyHeaderErrorzException for empty headers.Nr~r8r8r8r9rYrrc@r})TruncatedHeaderErrorz Exception for truncated headers.Nr~r8r8r8r9r\rrc@r})EOFHeaderErrorz"Exception for end of file headers.Nr~r8r8r8r9r_rrc@r})rFzException for invalid headers.Nr~r8r8r8r9rFbrrFc@r})SubsequentHeaderErrorz3Exception for missing and invalid extended headers.Nr~r8r8r8r9rerrc@0eZdZdZddZddZddZdd Zd S) _LowLevelFilezLow-level file object. Supports reading and writing. It is used instead of a regular file object for streaming access. cCsFtjtjtjBtjBd|}ttdr|tjO}t||d|_dS)N)rmrnO_BINARYi) osO_RDONLYO_WRONLYO_CREATO_TRUNChasattrropenfd)selfnamerwr8r8r9__init__rs  z_LowLevelFile.__init__cCst|jdSN)rcloserrr8r8r9r{z_LowLevelFile.closecCst|j|Sr)rr_rrrr8r8r9r_~z_LowLevelFile.readcCst|j|dSr)rr`rrr4r8r8r9r`sz_LowLevelFile.writeN)rrrrrrr_r`r8r8r8r9rls   rc@steZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ dddZ dddZ ddZddZdS)_StreamaClass that serves as an adapter between TarFile and a stream-like object. The stream-like object only needs to have a read() or write() method and is accessed blockwise. Use of gzip or bzip2 compression is possible. A stream-like object could be for example: sys.stdin, sys.stdout, a socket, a tape device etc. _Stream is intended to be used only internally. cCsBd|_|durt||}d|_|dkrt|}|}|pd|_||_||_||_||_d|_ d|_ d|_ z\|dkrbzddl }Wn t yKtd w||_ |d|_|d kr^|n||d krzddl}Wn t ywtd w|d krd|_||_WdS||_WdSWdS|js|jd|_ ) z$Construct a _Stream object. TNF*rsrgzzzlib module is not availablermbz2bz2 module is not available) _extfileobjr _StreamProxy getcomptyperrwcomptypefileobjbufsizer[posclosedzlib ImportErrorrcrc32crc _init_read_gz_init_write_gzrdbufBZ2Decompressorcmp BZ2Compressorr)rrrwrrrrrr8r8r9rsV          z_Stream.__init__cCs$t|dr|js|dSdSdS)Nr)rrrrr8r8r9__del__s z_Stream.__del__cCs|jd|jj|jj |jjd|_tdtt }| d|d|j dr3|j dd|_ | |j d d tdS) z6Initialize for writing with gzip compression. rZ(d?d@Z)dAdBZ*dCdDZ+dEdFZ,dGdHZ-dIdJZ.dKdLZ/dMdNZ0dOdPZ1dQdRZ2dSdTZ3dUS)WraInformational class which holds the details about an archive member given by a tar header block. TarInfo objects are returned by TarFile.getmember(), TarFile.getmembers() and TarFile.gettarinfo() and are usually created internally. )rrwr!r"rr chksumtypelinknamer#r$devmajordevminorrr pax_headersrr_sparse_structs _link_targetrscCsj||_d|_d|_d|_d|_d|_d|_t|_d|_ d|_ d|_ d|_ d|_ d|_d|_d|_i|_dS)zXConstruct a TarInfo object. name is the optional name of the member. irrsN)rrwr!r"rr rREGTYPErrr#r$rrrrrrrrr8r8r9rs" zTarInfo.__init__cCrrrrr8r8r9_getpathrzTarInfo._getpathcC ||_dSrrrr8r8r9_setpathrzTarInfo._setpathcCrrrrr8r8r9 _getlinkpathrzTarInfo._getlinkpathcCrrr)rrr8r8r9 _setlinkpathrzTarInfo._setlinkpathcCsd|jj|jt|fS)Nz<%s %r at %#x>) __class__rridrr8r8r9__repr__szTarInfo.__repr__cCsl|j|jd@|j|j|j|j|j|j|j|j |j |j |j d }|dt kr4|dds4|dd7<|S)z9Return the TarInfo's attributes as a dictionary. ) rrwr!r"rr rrrr#r$rrrr/)rrwr!r"rr rrrr#r$rrDIRTYPEr)rinfor8r8r9get_infos"zTarInfo.get_infosurrogateescapecCsP|}|tkr||||S|tkr||||S|tkr$|||Std)zr&r8r8r9r@sB   ( z"TarInfo._create_pax_generic_headerc Csft|dkr tdt|tkrtd|ttkrtdt|dd}|t|vr1t d|}t |dd|||_ t|dd |_ t|d d |_ t|d d |_t|d d |_t|d d|_||_|dd |_t |d d|||_t |dd|||_t |dd|||_t|dd|_t|dd|_t |dd||}|jtkr|j drt|_|jtkrd}g}tdD]0} zt|||d} t||d|d} Wn tyYn w|| | f|d7}qt|d} t|dd} || | f|_ |!r |j "d|_ |r1|jt#vr1|d|j |_ |S)zAConstruct a TarInfo object from a 512 byte bytes object. rz empty headerztruncated headerzend of file headerrXrYz bad checksumr lt|ii i)iIiQiYir$ir/r:iii)$r2rrrcountr3rrKr^rFr?rrwr!r"rr rrrr#r$rrAREGTYPErr%GNUTYPE_SPARSErGrEruboolrisdirrstrip GNU_TYPES)rFr[r6r7robjr0rstructsrJrnumbytes isextendedorigsizer8r8r9frombufs\          zTarInfo.frombufcCs8|jt}|||j|j}|jt|_||S)zOReturn the next TarInfo object from TarFile object tarfile. ) rr_rrgr6r7rr _proc_member)rFrr[rbr8r8r9 fromtarfiles  zTarInfo.fromtarfilecCsP|jttfvr ||S|jtkr||S|jtttfvr#| |S| |S)zYChoose the right processing method depending on the type and call it. ) rr9r8 _proc_gnulongr] _proc_sparserArESOLARIS_XHDTYPE _proc_pax _proc_builtinrrr8r8r9rhs     zTarInfo._proc_membercCsR|j|_|j}|s|jtvr|||j7}||_| |j |j |j |S)zfProcess a builtin type or an unknown type which will be treated as a regular file. ) rrrisregrSUPPORTED_TYPES_blockrr_apply_pax_inforr6r7)rrrr8r8r9rn$s zTarInfo._proc_builtincCs|j||j}z||}Wn tytdw|j|_|jt kr1t ||j |j |_ |S|jtkr?t ||j |j |_|S)zSProcess the blocks that hold a GNU longname or longlink member. missing or bad subsequent header)rr_rrrrirrrrr9r?r6r7rr8r)rrr[nextr8r8r9rj5s   zTarInfo._proc_gnulongc Cs|j\}}}|`|rS|jt}d}tdD]4}zt|||d}t||d|d} Wn ty:Ynw|rF| rF||| f|d7}qt|d}|s ||_ |j |_ |j | |j |_||_ |S)z8Process a GNU sparse header plus extra headers. rr:rZi)rrr_rrGrKrErur^rrrrrrr) rrrcrerfr[rrJrrdr8r8r9rkKs,       zTarInfo._proc_sparsecCs|j||j}|jtkr|j}n|j}t d|}|dur,| d d|d<| d}|dkr9|j }nd}td}d} |||}|sLnF|\} } t| } ||d d|d| d} || dd|j} | tvr|| ||j |j} n || dd|j} | || <|| 7}qCz||} Wn tytd wd |vr|| |n!d |vr|| ||n| ddkr| ddkr|| |||jttfvr| ||j |j|j | _ d|vr| j!} | "s| jt#vr| | | j7} | |_ | S)zVProcess an extended or global header as described in POSIX.1-2008. s\d+ hdrcharset=([^\n]+)\nNrrD hdrcharsetZBINARYs(\d+) ([^=]+)=rTrrtGNU.sparse.mapGNU.sparse.sizezGNU.sparse.major1zGNU.sparse.minorrBr)$rr_rrrrrErr;researchgroupr=rIr6compilematchgroupsrDendr_decode_pax_fieldr7PAX_NAME_FIELDSrirr_proc_gnusparse_01_proc_gnusparse_00_proc_gnusparse_10rArlrsrrrprq)rrr[rrrwr6regexrr5rRrSrurr8r8r9rmgsj       $     zTarInfo._proc_paxcCshg}td|D] }|t|dqg}td|D] }|t|dqtt|||_dS)z?Process a GNU tar extended sparse header, version 0.0. s\d+ GNU.sparse.offset=(\d+)\nrs\d+ GNU.sparse.numbytes=(\d+)\nN)r{finditerrurDr}listzipr)rrurr[offsetsrrdr8r8r9rszTarInfo._proc_gnusparse_00cCs@dd|ddD}tt|ddd|ddd|_dS)z?Process a GNU tar extended sparse header, version 0.1. cSsg|]}t|qSr8)rD).0rpr8r8r9 sz.TarInfo._proc_gnusparse_01..rx,Nrr)splitrrr)rrurrr8r8r9rs(zTarInfo._proc_gnusparse_01cCsd}g}|jt}|dd\}}t|}t||dkrAd|vr*||jt7}|dd\}}|t|t||dks|j|_t t |ddd|ddd|_ dS)z?Process a GNU tar extended sparse header, version 1.0. Nrrr) rr_rrrDr2rurrrrr)rrurrfieldsrr[numberr8r8r9rs  (zTarInfo._proc_gnusparse_10c Cs|D]T\}}|dkrt|d|q|dkr t|dt|q|dkr-t|dt|q|tvrX|tvrIzt||}Wn tyHd}Ynw|dkrR|d}t|||q||_dS) zoReplace fields with supplemental information from a previous pax extended or global header. zGNU.sparse.namerryrzGNU.sparse.realsizerr$N) rOsetattrrD PAX_FIELDSPAX_NUMBER_FIELDSrEr`r;r)rrr6r7rRrSr8r8r9rss&   zTarInfo._apply_pax_infocCs.z||dWSty|||YSw)z1Decode a single field from a pax record. rA)r=UnicodeDecodeError)rrSr6fallback_encodingfallback_errorsr8r8r9rs  zTarInfo._decode_pax_fieldcCs"t|t\}}|r |d7}|tS)z_Round up a byte count by BLOCKSIZE and return it, e.g. _block(834) => 1024. r)rar)rr[rfrgr8r8r9rr szTarInfo._blockcCs |jtvSr)r REGULAR_TYPESrr8r8r9rprz TarInfo.isregcCs|Sr)rprr8r8r9isfileszTarInfo.isfilecC |jtkSr)rr%rr8r8r9r_rz TarInfo.isdircCrr)rSYMTYPErr8r8r9issymrz TarInfo.issymcCrr)rLNKTYPErr8r8r9islnkrz TarInfo.islnkcCrr)rCHRTYPErr8r8r9ischr rz TarInfo.ischrcCrr)rBLKTYPErr8r8r9isblk"rz TarInfo.isblkcCrr)rFIFOTYPErr8r8r9isfifo$rzTarInfo.isfifocCs |jduSr)rrr8r8r9issparse&rzTarInfo.issparsecCs|jtttfvSr)rrrrrr8r8r9isdev(rz TarInfo.isdevN)rs)4rrrr __slots__rrrpropertyrrrrr"r'DEFAULT_FORMATENCODINGr.r*r+r- classmethodrGr4 staticmethodr5rLr7r@rgrirhrnrjrkrmrrrrsrrrrprr_rrrrrrrr8r8r8r9rsh    1     2 >  f   rc@seZdZdZdZdZdZdZeZ e Z dZ e ZeZ   dVdd Zedddefd d ZedWd d ZedXddZedXddZddddZddZddZddZddZdYdd ZdZd"d#Zd[d$d%Zd\d&d'Z d]d)d*Z!d^d,d-Z"d.d/Z#dZd0d1Z$d2d3Z%d4d5Z&d6d7Z'd8d9Z(d:d;Z)dd?Z+d@dAZ,dBdCZ-dDdEZ.d_dFdGZ/dHdIZ0d\dJdKZ1dLdMZ2dNdOZ3dPdQZ4dRdSZ5dTdUZ6dS)`rz=The TarFile Class provides an interface to tar archives. rFrNrmr(c  Cszt|dks |dvrtd||_dddd||_|s7|jdkr-tj|s-d |_d|_t||j}d |_n|d urCt |d rC|j }t |d rL|j|_d|_|rWtj |nd |_ ||_ |d urd||_ |d urk||_|d urr||_|d ury||_|d ur||_| |_| d ur|j tkr| |_ni|_| d ur| |_| d ur| |_d |_g|_d |_|j |_i|_zy|jdkrd |_||_|jdkr |j |jz|j |}|j!|Wn!t"y|j |jYnt#y} zt$t%| d } ~ wwq|jdvr'd|_|jr*|j&|j'}|j (||jt|7_Wd SWd SWd S|js9|j )d|_)aOpen an (uncompressed) tar archive `name'. `mode' is either 'r' to read from an existing archive, 'a' to append data to an existing file or 'w' to create a new file overwriting an existing one. `mode' defaults to 'r'. If `fileobj' is given, it is used for reading or writing data. If it can be determined, `mode' is overridden by `fileobj's mode. `fileobj' is not closed, when TarFile is closed. rrmode must be 'r', 'a' or 'w'rbzr+bwb)rmarnrrnFNrrwTrmaw)*r2rErw_moderrexists bltn_openrrrabspathrrVr dereference ignore_zerosr6r7r,rdebug errorlevelrmembers_loadedrrinodes firstmemberrurrirurrrr?rGr;r`r)rrrwrrVrrrr6r7rrrer[r8r8r9rFs             zTarFile.__init__c Ks|s|std|dvrP|jD]<}t||j|}|dur!|}z ||d|fi|WSttfyK} z|durA||WYd} ~ qd} ~ wwtdd|vr|dd\} }| p_d} |pcd}||jvrrt||j|}ntd |||| |fi|Sd |vr|d d\} }| pd} |pd}| d vrtd t|| |||} z ||| | fi|} Wn| d | _ | S|dvr|j |||fi|Std)a|Open a tar archive for reading, writing or appending. Return an appropriate TarFile class. mode: 'r' or 'r:*' open for reading with transparent compression 'r:' open for reading exclusively uncompressed 'r:gz' open for reading with gzip compression 'r:bz2' open for reading with bzip2 compression 'a' or 'a:' open for appending, creating the file if necessary 'w' or 'w:' open for writing without compression 'w:gz' open for writing with gzip compression 'w:bz2' open for writing with bzip2 compression 'r|*' open a stream of tar blocks with transparent compression 'r|' open an uncompressed stream of tar blocks for reading 'r|gz' open a gzip compressed stream of tar blocks 'r|bz2' open a bzip2 compressed stream of tar blocks 'w|' open an uncompressed stream for writing 'w|gz' open a gzip compressed stream for writing 'w|bz2' open a bzip2 compressed stream for writing znothing to open)rmzr:*Nrmz%file could not be opened successfully:rrzunknown compression type %r|rwmode must be 'r' or 'w'Frzundiscernible mode) rE OPEN_METHrrrrrrrrrtaropen) rFrrwrrkwargsrfunc saved_posrr|streamrqr8r8r9rsR     z TarFile.opencKs0t|dks |dvrtd||||fi|S)zCOpen uncompressed tar archive name for reading or writing. rrr)r2rE)rFrrwrrr8r8r9rszTarFile.taropenrc Kst|dks |dvrtdz ddl}|jWn ttfy$tdw|du}z|||d||}|j|||fi|}Wn'tyZ|sQ|durQ| |durVt d|sg|durg| ||_ |S) zkOpen gzip compressed tar archive name for reading or writing. Appending is not allowed. rrrrNzgzip module is not availablerhr) r2rEgzipGzipFilerAttributeErrorrrrbrrr) rFrrwr compresslevelrrZ extfileobjrqr8r8r9gzopens0    zTarFile.gzopenc Kst|dks |dvrtdzddl}Wn tytdw|dur*t||}n|j|||d}z |j|||fi|}Wntt fyP| t dwd |_ |S) zlOpen bzip2 compressed tar archive name for reading or writing. Appending is not allowed. rrzmode must be 'r' or 'w'.rNr)rznot a bzip2 fileF) r2rErrrrBZ2FilerrbEOFErrorrrr)rFrrwrrrrrqr8r8r9bz2open$s$   zTarFile.bz2openrrr)rrrcCs|jrdS|jdvr3|jttd|jtd7_t|jt\}}|dkr3|jtt||j s;|j d|_dS)zlClose the TarFile. In write-mode, two finishing zero blocks are appended to the archive. NrrrT) rrwrr`r3rrra RECORDSIZErr)rrfrgr8r8r9rHs   z TarFile.closecCs"||}|durtd||S)aReturn a TarInfo object for member `name'. If `name' can not be found in the archive, KeyError is raised. If a member occurs more than once in the archive, its last occurrence is assumed to be the most up-to-date version. Nzfilename %r not found) _getmemberKeyError)rrrr8r8r9 getmember\s  zTarFile.getmembercCs||js ||jS)zReturn the members of the archive as a list of TarInfo objects. The list has the same order as the members in the archive. )_checkr_loadrrr8r8r9 getmembersgszTarFile.getmemberscCsdd|DS)zReturn the members of the archive as a list of their names. It has the same order as the list returned by getmembers(). cSsg|]}|jqSr8r)rrr8r8r9rusz$TarFile.getnames..)rrr8r8r9getnamesqszTarFile.getnamesc CsT|d|dur |j}|dur|}tj|\}}|tjd}|d}|}||_ |durEt tdr?|j s?t |}n t |}nt|}d}|j}t |r|j|jf} |j sx|jdkrx| |jvrx||j| krxt} |j| }n;t} | dr||j| <n/t |rt} n't |rt} nt |rt} t|}nt |rt } n t !|rt"} ndS||_||_#|j$|_%|j&|_'| tkr|j(|_)nd|_)|j*|_+| |_,||_-t.rz t./|j%d|_0Wn t1yYnwt2rz t23|j'd|_4Wn t1yYnw| t t"fvr(t tdr(t td r(t5|j6|_7t8|j6|_9|S) aOCreate a TarInfo object for either the file `name' or the file object `fileobj' (using os.fstat on its file descriptor). You can modify some of the TarInfo's attributes before you add it using addfile(). If given, `arcname' specifies an alternative name for the file in the archive. rNr$lstatrsrrmajorminor):rrrr splitdriverseplstriprrrrrstatfstatfilenost_modeS_ISREGst_inost_devst_nlinkrrrS_ISDIRr%S_ISFIFOrS_ISLNKrreadlinkS_ISCHRrS_ISBLKrrwst_uidr!st_gidr"st_sizerst_mtimer rrpwdgetpwuidr#rgrpgetgrgidr$rst_rdevrrr) rrarcnamerdrvrstatresrstmdinoderr8r8r9 gettarinfows                zTarFile.gettarinfoTcCs||D]{}|rUtt|jddtd|jp|j|jp|jfdd|s-| rzlink to)rprintr|rwr#r!r$r"rrrrrr localtimer rr_rrr)rverboserr8r8r9rs:  z TarFile.listc Csn|d|dur |}|dur(ddl}|dtd||r(|dd|dS|jdur@tj||jkr@|dd|dS|d|| ||}|durZ|dd |dS|durp||}|durp|dd|dS| rt |d }| ||| dS|r| ||rt|D]}|jtj||tj|||||d qdSdS| |dS) a~Add the file `name' to the archive. `name' may be any type of file (directory, fifo, symbolic link, etc.). If given, `arcname' specifies an alternative name for the file in the archive. Directories are added recursively by default. This can be avoided by setting `recursive' to False. `exclude' is a function that should return True for each filename to be excluded. `filter' is a function that expects a TarInfo object argument and returns the changed TarInfo object, if it returns None the TarInfo object will be excluded from the archive. rNrzuse the filter argument insteadrztarfile: Excluded %rztarfile: Skipped %rrztarfile: Unsupported type %rr)filter)rwarningswarnDeprecationWarning_dbgrrrrrrpraddfilerr_listdiraddrv) rrr recursiveexcluderrrfr8r8r9rsL       z TarFile.addcCs|dt|}||j|j|j}|j||jt |7_|durRt ||j|j t |j t \}}|dkrI|jtt ||d7}|j|t 7_|j|dS)a]Add the TarInfo object `tarinfo' to the archive. If `fileobj' is given, tarinfo.size bytes are read from it and added to the archive. You can create TarInfo objects using gettarinfo(). On Windows platforms, `fileobj' should always be opened with mode 'rb' to avoid irritation about the file size. rNrr)rr;r.rVr6r7rr`rr2rirrarr3rru)rrrr[rfrgr8r8r9r4s   zTarFile.addfile.c Csg}|dur|}|D]}|r||t|}d|_|j||| dq |jddd||D]>}tj ||j }z| ||| ||| ||Wq7tyu}z|jdkrc|dd|WYd}~q7d}~wwdS) aMExtract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. `path' specifies a different directory to extract to. `members' is optional and must be a subset of the list returned by getmembers(). N set_attrscSrrr)rr8r8r9dsz$TarFile.extractall..)keyr tarfile: %s)r_rur;rwextractsortreverserrrvrchownutimechmodrrr)rrr directoriesrdirpathrr8r8r9 extractallNs0     zTarFile.extractallrsc Cs|dt|tr||}n|}|rtj||j|_ z|j |tj||j |dWdSt yk}z/|j dkr>|jdurM|dd|jn|dd|j|jfWYd}~dSWYd}~dSd}~wty}z|j dkrx|dd|WYd}~dSd}~ww)axExtract a member from the archive to the current working directory, using its full name. Its file information is extracted as accurately as possible. `member' may be a filename or a TarInfo object. You can specify a different directory using `path'. File attributes (owner, mtime, mode) are set unless `set_attrs' is False. rmr rNrrztarfile: %s %r)rr=r?rrrrrvrr_extract_memberrEnvironmentErrorrfilenamerstrerrorr)rmemberrrrrr8r8r9rts0      & zTarFile.extractcCs|dt|tr||}n|}|r|||S|jtvr'|||S|s/| rAt|j t r9t d| ||SdS)aExtract a member from the archive as a file object. `member' may be a filename or a TarInfo object. If `member' is a regular file, a file-like object is returned. If `member' is a link, a file-like object is constructed from the link's target. If `member' is none of the above, None is returned. The file-like object is read-only and provides the following methods: read(), readline(), readlines(), seek() and tell() rmz'cannot extract (sym)link as file objectN)rr=r?rrp fileobjectrrqrrrrr extractfile_find_link_target)rrrr8r8r9r!s      zTarFile.extractfilecCsT|d}|dtj}tj|}|rtj|st||s'| r4| dd|j |j fn| d|j | rF|||nF|rQ|||n;|r\|||n0|sd|rk|||n!|ss| rz|||n|jtvr|||n||||r|||| s||||||dSdSdS)z\Extract the TarInfo object tarinfo to a physical file called targetpath. r$rz%s -> %sN)r`rrrrdirnamermakedirsrrrrrrpmakefiler_makedirrmakefiforrmakedevmakelinkrrq makeunknownrrr)rr targetpathr upperdirsr8r8r9rs8       zTarFile._extract_memberc CsHz t|dWdSty#}z|jtjkrWYd}~dSd}~ww)z,Make a directory called targetpath. r N)rmkdirrerrnoEEXISTrrr+rr8r8r9r&s zTarFile.makedircCs||j}||jt|d}|jdur'|jD]\}}||t|||qnt|||j||j||dS)z'Make a file called targetpath. rN) rrrrrrirtruncater)rrr+sourcetargetrrr8r8r9r%s      zTarFile.makefilecCs"||||dd|jdS)zYMake a file from a TarInfo object with an unknown type at targetpath. rz9tarfile: Unknown file type %r, extracted as regular file.N)r%rrrrr+r8r8r9r* s  zTarFile.makeunknowncCs ttdr t|dStd)z'Make a fifo called targetpath. mkfifozfifo not supported by systemN)rrr5rr4r8r8r9r' s zTarFile.makefifocCs^ttdr ttdstd|j}|r|tjO}n|tjO}t||t |j |j dS)z|jr td|jj|dur|j|vrtd|jdSdS)znCheck if TarFile is still open, and if the operation's mode corresponds to TarFile's mode. z %s is closedNzbad operation for mode %r)rrbr rrw)rrwr8r8r9r s zTarFile._checkcCsX|rtj|jd|j}d}n|j}|}|j||dd}|dur*td||S)zZFind the target member of a symlink or hardlink member in the archive. r$NT)rrIzlinkname %r not found)rrrr#rrrr)rrrlimitrr8r8r9r" s zTarFile._find_link_targetcCs|jrt|jSt|S)z$Provide an iterator object. )riterrTarIterrr8r8r9r  s zTarFile.__iter__cCs ||jkrt|tjddSdS)z.Write debugging output to sys.stderr. )fileN)rrr@stderr)rlevelmsgr8r8r9r s z TarFile._dbgcCs ||Sr)rrr8r8r9 __enter__ szTarFile.__enter__cCs.|dur |dS|js|jd|_dSr)rrrr)rrrS tracebackr8r8r9__exit__ s    zTarFile.__exit__) NrmNNNNNNr(NNN)rmN)rmNr)NNN)T)NTNNr)r N)rsTr)7rrrrrrrrrrVrr6r7rrrr rrrrrrrrrrrrrrrrrrr!rr&r%r*r'r(r)rrrrurrrr"r rrSrUr8r8r8r9r,sr kK       b  >  &# &0   1   rc@s,eZdZdZddZddZddZeZdS) rNzMIterator Class. for tarinfo in TarFile(...): suite... cCs||_d|_dS)z$Construct a TarIter object. rN)rrFror8r8r9r s zTarIter.__init__cCs|S)z Return iterator object. r8rr8r8r9r  szTarIter.__iter__cCs\|jjs|j}|sd|j_tnz |jj|j}Wn ty$tw|jd7_|S)zReturn the next item using TarFile's next() method. When all members have been read, set TarFile as _loaded. Tr)rrru StopIterationrrF IndexErrorrKr8r8r9__next__ s  zTarIter.__next__N)rrrrrr rXrur8r8r8r9rN s rNcCs,z t|}|WdStyYdSw)zfReturn True if name points to a tar archive that we are able to handle, else return False. TF)rrr)rrqr8r8r9r# s rr)w __future__r __version__version __author____date__Z __cvsid__ __credits__r@rrr.rrPr;r{rrrrNotImplementedErrorr;Z WindowsError NameError__all__ version_info __builtin__builtinsr_openr3rrr6r1r3r2rHrr\rrrrr%rCONTTYPEr9r8r]rArErlr)rOr,rrqrrarsetrr>rDrS_IFLNKS_IFREGr7S_IFDIRr8S_IFIFOZTSUIDZTSGIDZTSVTXZTUREADZTUWRITEZTUEXECZTGREADZTGWRITEZTGEXECZTOREADZTOWRITEZTOEXECrrgetfilesystemencodingr:r?rKrWr^rirtr| ExceptionrrrrrrrrrrFrobjectrrrrrrrrrNrrr8r8r8r9sV           i?KT* PKH]eJ1}}Wpython3.10/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-310.pycnu[o ai@sdZddlZddlZgdZzddlmZWney$d ddZYnwzeZWney<ddl m Z d d ZYnwzej Z WdSe yQd d Z YdSw)z/Backports for individual classes and functions.N)cache_from_sourcecallablefsencode)rTcCs|rdpd}||S)Nco)Zpy_filedebugextrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/_backport/misc.pyrs r)CallablecCs t|tS)N) isinstancer )objrrr rs rcCs8t|tr|St|tr|tStdt|j)Nzexpect bytes or str, not %s) r bytesstrencodesysgetfilesystemencoding TypeErrortype__name__)filenamerrr r"s  r)T) __doc__osr__all__impr ImportErrorr NameError collectionsr rAttributeErrorrrrr s(      PKH]}=>=>\python3.10/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-310.pycnu[o aih@sdZddlZddlZddlZddlZddlmZmZzddlZWn e y-ddl ZYnwgdZ ddZ ej rCeje ej Zne eZejdkraded dvrae ejeeZejdkrzd ed dvrze ejeeeZejdkrd ed dvre ejeeeZddZeZdaddZeZedZddZdejddZdejddZ dejddZ!ej"ej#Z$ej"ej%Z&da'dZ(ddZ)ddZ*dd Z+d!d"Z,d#d$Z-d%d&Z.dId'd(Z/d)d*Z0d+d,Z1d-d.Z2dId/d0Z3d1d2Z4d3d4Z5d5d6Z6e-dd7fd8d9Z7e-dd7fd:d;Z8dd?Z:d@dAZ;dBdCZe?dHkrHe>dSdS)Jz-Access to Python's configuration information.N)pardirrealpath) get_config_h_filenameget_config_varget_config_varsget_makefile_filenameget_pathget_path_names get_paths get_platformget_python_versionget_scheme_namesparse_config_hcCs"zt|WSty|YSwN)rOSError)pathr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/distlib/_backport/sysconfig.py_safe_realpath"s   rntZpcbuildiz\pc\viz\pcbuild\amd64icCs,dD]}tjtjtd|rdSqdS)N)z Setup.distz Setup.localModulesTF)osrisfilejoin _PROJECT_BASE)fnrrris_python_build:s rFcCstsQddlm}tddd}||}|d}|sJd| }t|Wdn1s3wYt rMdD]}t |d d t |d d q._replacer) r2 has_sectionitemstuplesections has_optionr.remove_sectiondict _VAR_REPLsub)configr3rAsectionoptionvaluer<rr:r_expand_globalsYs*       rKz%s.%s.%sz%s.%srz%s%scfdd}t||S)zIn the string `path`, replace tokens like {some.thing} with the corresponding value from the map `local_vars`. If there is no corresponding value, leave the token unchanged. cs8|d}|vr |S|tjvrtj|S|dSr5)r7renvironr8 local_varsrrr<s    z_subst_vars.._replacerrErF)rrPr<rrOr _subst_varss  rRcCs0|}|D] \}}||vrq|||<qdSr)keysr?) target_dict other_dict target_keyskeyrJrrr _extend_dicts  rXcCs`i}|duri}t|tt|D]\}}tjdvr"tj|}tjt ||||<q|S)N)posixr) rXrr+r?rr9r expandusernormpathrR)r1varsresrWrJrrr _expand_varss   r^crM)Ncr4r5r6r8r\rrr<r=zformat_value.._replacerrQ)rJr\r<rr_r format_values  r`cCstjdkrdStjS)NrYr!)rr9rrrr_get_default_schemes racCstjdd}dd}tjdkr!tjdpd}|r|S||dStjdkr>td }|r>|r0|S|dd |d tjdd S|rB|S|dd S)NPYTHONUSERBASEcWstjtjj|Sr)rrrZr)argsrrrjoinusersz_getuserbase..joinuserrAPPDATA~PythondarwinPYTHONFRAMEWORKLibraryz%d.%drz.local)rrNgetr9sysplatformr version_info)env_baserdbaseZ frameworkrrr _getuserbases$      rqc Cstd}td}td}|duri}i}i}tj|ddd }|}Wdn1s0wY|D]L} | dsD| d krEq7|| } | r| d d \} } | } | d d } d | vrg| || <q7zt | } Wnt y~| d d || <Yq7w| || <q7t | }d}t|dkrlt|D]}||}||p||} | dur\| d } d}| |vrt|| }n>| |vrd}n7| tjvrtj| }n,| |vr|dr|dd|vrd }nd| |vrd}nt|d| }nd || <}|r[|| d}|d| ||}d |vr|||<qzt |}Wnt y3|||<Ynw|||<|||dr[|dd|vr[|dd}||vr[|||<q|||<||qt|dks|D]\}} t| tr| ||<qp|||S)zParse a Makefile-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. z"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)z\$\(([A-Za-z][A-Za-z0-9_]*)\)z\${([A-Za-z][A-Za-z0-9_]*)}Nzutf-8surrogateescape)encodingerrors#r rz$$$)CFLAGSLDFLAGSCPPFLAGSrTFPY_rL)recompilecodecsopen readlines startswithstripmatchr7replaceint ValueErrorlistrSlenr@searchstrrrNendstartremover? isinstanceupdate)filenamer\ _variable_rx _findvar1_rx _findvar2_rxdonenotdoneflineslinemnvtmpvr;renamed_variablesr9rJfounditemafterkrrr_parse_makefiles                          :   rcCsDtr tjtdSttdrdttjf}nd}tjt d|dS)z Return the path of the Makefile.Makefileabiflagsz config-%s%srGstdlib) r-rrrrhasattrrl_PY_VERSION_SHORTrr)config_dir_namerrrrKs  rc Cst}zt||Wn ty*}zd|}t|dr"|d|j}t|d}~wwt}zt| }t||Wdn1sCwYWn tyi}zd|}t|dra|d|j}t|d}~wwtrt|d|d<dSdS)z7Initialize the module as appropriate for POSIX systems.z.invalid Python installation: unable to open %sstrerrorz (%s)N BLDSHAREDLDSHARED) rrIOErrorrrrrrr-)r\makefileemsgconfig_hrrrr _init_posixVs4    rcCsVtd|d<td|d<td|d<d|d<d |d <t|d <tjttj|d <d S)z+Initialize the module as appropriate for NTrLIBDEST platstdlib BINLIBDESTr# INCLUDEPYz.pydSOz.exeEXEVERSIONBINDIRN)r_PY_VERSION_SHORT_NO_DOTrrdirnamerrl executabler_rrr_init_non_posixrs   rcCs|duri}td}td} |}|s |S||}|r>|dd\}}zt|}Wn ty8Ynw|||<n||}|rLd||d<q)zParse a config.h-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. Nz"#define ([A-Z][A-Za-z0-9_]+) (.*) z&/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/ Tr rr)r|r}readlinerr7rr)fpr\ define_rxundef_rxrrrrrrrrs,       rcCs:trtjdkrtjtd}nt}ntd}tj|dS)zReturn the path of pyconfig.h.rPCr$z pyconfig.h)r-rr9rrrr)inc_dirrrrrs  rcCstttS)z,Return a tuple containing the schemes names.)r@sortedr+rArrrrr sr cCs tdS)z*Return a tuple containing the paths names.r!)r+optionsrrrrr s r TcCs"t|r t||Stt|S)zReturn a mapping containing an install scheme. ``scheme`` is the install scheme name. If not provided, it will return the default scheme for the current platform. )r2r^rDr+r?)r1r\expandrrrr s r cCst||||S)z[Return a path corresponding to the scheme. ``scheme`` is the install scheme name. )r )r9r1r\rrrrrsrcGstdur3iattd<ttd<ttd<ttd<tdtdtd<ttd <ttd <ttd <ztjtd <Wn tyAd td <Ynwt j dvrKt tt j dkrTt ttj dkr^ttd<dtvrgttd<nttdtd<trt j dkrt}zt }Wn tyd}Ynwt jtds||krt j|td}t j|td<tjdkr3t d}t|dd}|dkrdD]}t|}tdd|}tdd|}|t|<qnWdt jvrt jd}dD]}t|}tdd|}|d|}|t|<qtdd } td| } | dur3| d} t j!| s3dD]}t|}tdd|}|t|<q |rHg} |D] } | "t| q:| StS)ayWith no arguments, return a dictionary of all configuration variables relevant for the current platform. On Unix, this means every variable defined in Python's installed Makefile; On Windows and Mac OS it's a much smaller set. With arguments, return a list of values that result from looking up each argument in the configuration variable dictionary. Nprefix exec_prefix py_versionpy_version_shortrrpy_version_nodotrpplatbase projectbaserrv)rZos2rYz2.6userbasesrcdirrhr)ry BASECFLAGSrx PY_CFLAGSrz -arch\s+\w+\s z-isysroot [^ ]*Z ARCHFLAGSrxz-isysroot\s+(\S+)r z-isysroot\s+\S+(\s|$))# _CONFIG_VARS_PREFIX _EXEC_PREFIX _PY_VERSIONrrrlrAttributeErrorrr9rrversionrqrr-getcwdrrisabsrr[rmunamersplitr|rFrNrkrr7existsappend)rcrpcwdrZkernel_version major_versionrWflagsarchrxrZsdkvalsr9rrrrs                     rcCs t|S)zReturn the value of a single variable using the dictionary returned by 'get_config_vars()'. Equivalent to get_config_vars().get(name) )rrk)r9rrrrPs rcCsTtjdkr7d}tj|}|dkrtjStjd|}tj|t||}|dkr.dS|dkr4dStjStjd ksAttd sDtjSt \}}}}}| d d }| d d}| d d}|dddkrod||fS|dddkr|ddkrd}dt |dd|ddf}n|dddkrd||fS|dddkrd|||fS|ddd krd }t d!} | |} | r| }n|ddd"krt} | d#} | } ztd%}Wn tyYn)wzt d&|} W|n|w| durd'| d(d'dd} | s| } | r| }d)}| d'd*krd+td,d vrd-}td,}t d.|}ttt|}t|d(krV|d}nM|d/kr^d-}nE|d0krfd1}n=|d2krnd3}n5|d4krvd5}n-|d6kr~d7}n%td8|f|d9krtjd:krd;}n|d}d?|||fS)@aReturn a string that identifies the current platform. This is used mainly to distinguish platform-specific build directories and platform-specific built distributions. Typically includes the OS name and version and the architecture (as supplied by 'os.uname()'), although the exact information included depends on the OS; eg. for IRIX the architecture isn't particularly important (IRIX only runs on SGI hardware), but for Linux the kernel version isn't particularly important. Examples of returned values: linux-i586 linux-alpha (?) solaris-2.6-sun4u irix-5.3 irix64-6.2 Windows will return one of: win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) win-ia64 (64bit Windows on Itanium) win32 (all others - specifically, sys.platform is returned) For other non-POSIX platforms, currently just returns 'sys.platform'. rz bit ()amd64z win-amd64Zitaniumzwin-ia64rYr/rvr_-Nlinuxz%s-%ssunosr5solarisz%d.%srLrZirixaixz%s-%s.%scygwinz[\d.]+rhMACOSX_DEPLOYMENT_TARGETTz0/System/Library/CoreServices/SystemVersion.plistz=ProductUserVisibleVersion\s*(.*?)rr macosxz10.4.z-archrxfatz -arch\s+(\S+))i386ppc)rx86_64intel)rrrZfat3)ppc64rfat64)rrrr universalz%Don't know machine value for archs=%rrlr)PowerPCPower_Macintoshrrz%s-%s-%s) rr9rlrr)rmrlowerrrrrr|r}rr7rrkrrrreadcloserrrfindallr@rr.rmaxsize)rijZlookosnamehostreleasermachinerel_rerZcfgvarsZmacverZ macreleasercflagsZarchsrrrr Ys                          r cCstSr)rrrrrr sr cCsFtt|D]\}\}}|dkrtd|td||fqdS)Nrz%s: z %s = "%s") enumeraterr?print)titledataindexrWrJrrr _print_dicts  rcCsRtdttdttdtttdtttdtdS)z*Display all information sysconfig detains.zPlatform: "%s"zPython version: "%s"z!Current installation scheme: "%s"Paths VariablesN)rr r rarr rrrrr_mains r__main__r)@__doc__r~rr|rlos.pathrr configparser ImportError ConfigParser__all__rrrrrrr9rrrr-r%r2RawConfigParserr+r}rErKrnrrrr[rrrrr _USER_BASErRrXr^r`rarqrrrrrrr r r rrrr r rrr'rrrrs~     !   v     # PKH]/e>python3.10/site-packages/pip/_vendor/distlib/_backport/misc.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2012 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # """Backports for individual classes and functions.""" import os import sys __all__ = ['cache_from_source', 'callable', 'fsencode'] try: from imp import cache_from_source except ImportError: def cache_from_source(py_file, debug=__debug__): ext = debug and 'c' or 'o' return py_file + ext try: callable = callable except NameError: from collections import Callable def callable(obj): return isinstance(obj, Callable) try: fsencode = os.fsencode except AttributeError: def fsencode(filename): if isinstance(filename, bytes): return filename elif isinstance(filename, str): return filename.encode(sys.getfilesystemencoding()) else: raise TypeError("expect bytes or str, not %s" % type(filename).__name__) PKH]9kdkd@python3.10/site-packages/pip/_vendor/distlib/_backport/shutil.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2012 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # """Utility functions for copying and archiving files and directory trees. XXX The functions here don't copy the resource fork or other metadata on Mac. """ import os import sys import stat from os.path import abspath import fnmatch try: from collections.abc import Callable except ImportError: from collections import Callable import errno from . import tarfile try: import bz2 _BZ2_SUPPORTED = True except ImportError: _BZ2_SUPPORTED = False try: from pwd import getpwnam except ImportError: getpwnam = None try: from grp import getgrnam except ImportError: getgrnam = None __all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", "copytree", "move", "rmtree", "Error", "SpecialFileError", "ExecError", "make_archive", "get_archive_formats", "register_archive_format", "unregister_archive_format", "get_unpack_formats", "register_unpack_format", "unregister_unpack_format", "unpack_archive", "ignore_patterns"] class Error(EnvironmentError): pass class SpecialFileError(EnvironmentError): """Raised when trying to do a kind of operation (e.g. copying) which is not supported on a special file (e.g. a named pipe)""" class ExecError(EnvironmentError): """Raised when a command could not be executed""" class ReadError(EnvironmentError): """Raised when an archive cannot be read""" class RegistryError(Exception): """Raised when a registry operation with the archiving and unpacking registries fails""" try: WindowsError except NameError: WindowsError = None def copyfileobj(fsrc, fdst, length=16*1024): """copy data from file-like object fsrc to file-like object fdst""" while 1: buf = fsrc.read(length) if not buf: break fdst.write(buf) def _samefile(src, dst): # Macintosh, Unix. if hasattr(os.path, 'samefile'): try: return os.path.samefile(src, dst) except OSError: return False # All other platforms: check for same pathname. return (os.path.normcase(os.path.abspath(src)) == os.path.normcase(os.path.abspath(dst))) def copyfile(src, dst): """Copy data from src to dst""" if _samefile(src, dst): raise Error("`%s` and `%s` are the same file" % (src, dst)) for fn in [src, dst]: try: st = os.stat(fn) except OSError: # File most likely does not exist pass else: # XXX What about other special files? (sockets, devices...) if stat.S_ISFIFO(st.st_mode): raise SpecialFileError("`%s` is a named pipe" % fn) with open(src, 'rb') as fsrc: with open(dst, 'wb') as fdst: copyfileobj(fsrc, fdst) def copymode(src, dst): """Copy mode bits from src to dst""" if hasattr(os, 'chmod'): st = os.stat(src) mode = stat.S_IMODE(st.st_mode) os.chmod(dst, mode) def copystat(src, dst): """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" st = os.stat(src) mode = stat.S_IMODE(st.st_mode) if hasattr(os, 'utime'): os.utime(dst, (st.st_atime, st.st_mtime)) if hasattr(os, 'chmod'): os.chmod(dst, mode) if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): try: os.chflags(dst, st.st_flags) except OSError as why: if (not hasattr(errno, 'EOPNOTSUPP') or why.errno != errno.EOPNOTSUPP): raise def copy(src, dst): """Copy data and mode bits ("cp src dst"). The destination may be a directory. """ if os.path.isdir(dst): dst = os.path.join(dst, os.path.basename(src)) copyfile(src, dst) copymode(src, dst) def copy2(src, dst): """Copy data and all stat info ("cp -p src dst"). The destination may be a directory. """ if os.path.isdir(dst): dst = os.path.join(dst, os.path.basename(src)) copyfile(src, dst) copystat(src, dst) def ignore_patterns(*patterns): """Function that can be used as copytree() ignore parameter. Patterns is a sequence of glob-style patterns that are used to exclude files""" def _ignore_patterns(path, names): ignored_names = [] for pattern in patterns: ignored_names.extend(fnmatch.filter(names, pattern)) return set(ignored_names) return _ignore_patterns def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False): """Recursively copy a directory tree. The destination directory must not already exist. If exception(s) occur, an Error is raised with a list of reasons. If the optional symlinks flag is true, symbolic links in the source tree result in symbolic links in the destination tree; if it is false, the contents of the files pointed to by symbolic links are copied. If the file pointed by the symlink doesn't exist, an exception will be added in the list of errors raised in an Error exception at the end of the copy process. You can set the optional ignore_dangling_symlinks flag to true if you want to silence this exception. Notice that this has no effect on platforms that don't support os.symlink. The optional ignore argument is a callable. If given, it is called with the `src` parameter, which is the directory being visited by copytree(), and `names` which is the list of `src` contents, as returned by os.listdir(): callable(src, names) -> ignored_names Since copytree() is called recursively, the callable will be called once for each directory that is copied. It returns a list of names relative to the `src` directory that should not be copied. The optional copy_function argument is a callable that will be used to copy each file. It will be called with the source path and the destination path as arguments. By default, copy2() is used, but any function that supports the same signature (like copy()) can be used. """ names = os.listdir(src) if ignore is not None: ignored_names = ignore(src, names) else: ignored_names = set() os.makedirs(dst) errors = [] for name in names: if name in ignored_names: continue srcname = os.path.join(src, name) dstname = os.path.join(dst, name) try: if os.path.islink(srcname): linkto = os.readlink(srcname) if symlinks: os.symlink(linkto, dstname) else: # ignore dangling symlink if the flag is on if not os.path.exists(linkto) and ignore_dangling_symlinks: continue # otherwise let the copy occurs. copy2 will raise an error copy_function(srcname, dstname) elif os.path.isdir(srcname): copytree(srcname, dstname, symlinks, ignore, copy_function) else: # Will raise a SpecialFileError for unsupported file types copy_function(srcname, dstname) # catch the Error from the recursive copytree so that we can # continue with other files except Error as err: errors.extend(err.args[0]) except EnvironmentError as why: errors.append((srcname, dstname, str(why))) try: copystat(src, dst) except OSError as why: if WindowsError is not None and isinstance(why, WindowsError): # Copying file access times may fail on Windows pass else: errors.extend((src, dst, str(why))) if errors: raise Error(errors) def rmtree(path, ignore_errors=False, onerror=None): """Recursively delete a directory tree. If ignore_errors is set, errors are ignored; otherwise, if onerror is set, it is called to handle the error with arguments (func, path, exc_info) where func is os.listdir, os.remove, or os.rmdir; path is the argument to that function that caused it to fail; and exc_info is a tuple returned by sys.exc_info(). If ignore_errors is false and onerror is None, an exception is raised. """ if ignore_errors: def onerror(*args): pass elif onerror is None: def onerror(*args): raise try: if os.path.islink(path): # symlinks to directories are forbidden, see bug #1669 raise OSError("Cannot call rmtree on a symbolic link") except OSError: onerror(os.path.islink, path, sys.exc_info()) # can't continue even if onerror hook returns return names = [] try: names = os.listdir(path) except os.error: onerror(os.listdir, path, sys.exc_info()) for name in names: fullname = os.path.join(path, name) try: mode = os.lstat(fullname).st_mode except os.error: mode = 0 if stat.S_ISDIR(mode): rmtree(fullname, ignore_errors, onerror) else: try: os.remove(fullname) except os.error: onerror(os.remove, fullname, sys.exc_info()) try: os.rmdir(path) except os.error: onerror(os.rmdir, path, sys.exc_info()) def _basename(path): # A basename() variant which first strips the trailing slash, if present. # Thus we always get the last component of the path, even for directories. return os.path.basename(path.rstrip(os.path.sep)) def move(src, dst): """Recursively move a file or directory to another location. This is similar to the Unix "mv" command. If the destination is a directory or a symlink to a directory, the source is moved inside the directory. The destination path must not already exist. If the destination already exists but is not a directory, it may be overwritten depending on os.rename() semantics. If the destination is on our current filesystem, then rename() is used. Otherwise, src is copied to the destination and then removed. A lot more could be done here... A look at a mv.c shows a lot of the issues this implementation glosses over. """ real_dst = dst if os.path.isdir(dst): if _samefile(src, dst): # We might be on a case insensitive filesystem, # perform the rename anyway. os.rename(src, dst) return real_dst = os.path.join(dst, _basename(src)) if os.path.exists(real_dst): raise Error("Destination path '%s' already exists" % real_dst) try: os.rename(src, real_dst) except OSError: if os.path.isdir(src): if _destinsrc(src, dst): raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) copytree(src, real_dst, symlinks=True) rmtree(src) else: copy2(src, real_dst) os.unlink(src) def _destinsrc(src, dst): src = abspath(src) dst = abspath(dst) if not src.endswith(os.path.sep): src += os.path.sep if not dst.endswith(os.path.sep): dst += os.path.sep return dst.startswith(src) def _get_gid(name): """Returns a gid, given a group name.""" if getgrnam is None or name is None: return None try: result = getgrnam(name) except KeyError: result = None if result is not None: return result[2] return None def _get_uid(name): """Returns an uid, given a user name.""" if getpwnam is None or name is None: return None try: result = getpwnam(name) except KeyError: result = None if result is not None: return result[2] return None def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, owner=None, group=None, logger=None): """Create a (possibly compressed) tar file from all the files under 'base_dir'. 'compress' must be "gzip" (the default), "bzip2", or None. 'owner' and 'group' can be used to define an owner and a group for the archive that is being built. If not provided, the current owner and group will be used. The output tar file will be named 'base_name' + ".tar", possibly plus the appropriate compression extension (".gz", or ".bz2"). Returns the output filename. """ tar_compression = {'gzip': 'gz', None: ''} compress_ext = {'gzip': '.gz'} if _BZ2_SUPPORTED: tar_compression['bzip2'] = 'bz2' compress_ext['bzip2'] = '.bz2' # flags for compression program, each element of list will be an argument if compress is not None and compress not in compress_ext: raise ValueError("bad value for 'compress', or compression format not " "supported : {0}".format(compress)) archive_name = base_name + '.tar' + compress_ext.get(compress, '') archive_dir = os.path.dirname(archive_name) if not os.path.exists(archive_dir): if logger is not None: logger.info("creating %s", archive_dir) if not dry_run: os.makedirs(archive_dir) # creating the tarball if logger is not None: logger.info('Creating tar archive') uid = _get_uid(owner) gid = _get_gid(group) def _set_uid_gid(tarinfo): if gid is not None: tarinfo.gid = gid tarinfo.gname = group if uid is not None: tarinfo.uid = uid tarinfo.uname = owner return tarinfo if not dry_run: tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) try: tar.add(base_dir, filter=_set_uid_gid) finally: tar.close() return archive_name def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): # XXX see if we want to keep an external call here if verbose: zipoptions = "-r" else: zipoptions = "-rq" from distutils.errors import DistutilsExecError from distutils.spawn import spawn try: spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) except DistutilsExecError: # XXX really should distinguish between "couldn't find # external 'zip' command" and "zip failed". raise ExecError("unable to create zip file '%s': " "could neither import the 'zipfile' module nor " "find a standalone zip utility") % zip_filename def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): """Create a zip file from all the files under 'base_dir'. The output zip file will be named 'base_name' + ".zip". Uses either the "zipfile" Python module (if available) or the InfoZIP "zip" utility (if installed and found on the default search path). If neither tool is available, raises ExecError. Returns the name of the output zip file. """ zip_filename = base_name + ".zip" archive_dir = os.path.dirname(base_name) if not os.path.exists(archive_dir): if logger is not None: logger.info("creating %s", archive_dir) if not dry_run: os.makedirs(archive_dir) # If zipfile module is not available, try spawning an external 'zip' # command. try: import zipfile except ImportError: zipfile = None if zipfile is None: _call_external_zip(base_dir, zip_filename, verbose, dry_run) else: if logger is not None: logger.info("creating '%s' and adding '%s' to it", zip_filename, base_dir) if not dry_run: zip = zipfile.ZipFile(zip_filename, "w", compression=zipfile.ZIP_DEFLATED) for dirpath, dirnames, filenames in os.walk(base_dir): for name in filenames: path = os.path.normpath(os.path.join(dirpath, name)) if os.path.isfile(path): zip.write(path, path) if logger is not None: logger.info("adding '%s'", path) zip.close() return zip_filename _ARCHIVE_FORMATS = { 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), 'bztar': (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), 'zip': (_make_zipfile, [], "ZIP file"), } if _BZ2_SUPPORTED: _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file") def get_archive_formats(): """Returns a list of supported formats for archiving and unarchiving. Each element of the returned sequence is a tuple (name, description) """ formats = [(name, registry[2]) for name, registry in _ARCHIVE_FORMATS.items()] formats.sort() return formats def register_archive_format(name, function, extra_args=None, description=''): """Registers an archive format. name is the name of the format. function is the callable that will be used to create archives. If provided, extra_args is a sequence of (name, value) tuples that will be passed as arguments to the callable. description can be provided to describe the format, and will be returned by the get_archive_formats() function. """ if extra_args is None: extra_args = [] if not isinstance(function, Callable): raise TypeError('The %s object is not callable' % function) if not isinstance(extra_args, (tuple, list)): raise TypeError('extra_args needs to be a sequence') for element in extra_args: if not isinstance(element, (tuple, list)) or len(element) !=2: raise TypeError('extra_args elements are : (arg_name, value)') _ARCHIVE_FORMATS[name] = (function, extra_args, description) def unregister_archive_format(name): del _ARCHIVE_FORMATS[name] def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, dry_run=0, owner=None, group=None, logger=None): """Create an archive file (eg. zip or tar). 'base_name' is the name of the file to create, minus any format-specific extension; 'format' is the archive format: one of "zip", "tar", "bztar" or "gztar". 'root_dir' is a directory that will be the root directory of the archive; ie. we typically chdir into 'root_dir' before creating the archive. 'base_dir' is the directory where we start archiving from; ie. 'base_dir' will be the common prefix of all files and directories in the archive. 'root_dir' and 'base_dir' both default to the current directory. Returns the name of the archive file. 'owner' and 'group' are used when creating a tar archive. By default, uses the current owner and group. """ save_cwd = os.getcwd() if root_dir is not None: if logger is not None: logger.debug("changing into '%s'", root_dir) base_name = os.path.abspath(base_name) if not dry_run: os.chdir(root_dir) if base_dir is None: base_dir = os.curdir kwargs = {'dry_run': dry_run, 'logger': logger} try: format_info = _ARCHIVE_FORMATS[format] except KeyError: raise ValueError("unknown archive format '%s'" % format) func = format_info[0] for arg, val in format_info[1]: kwargs[arg] = val if format != 'zip': kwargs['owner'] = owner kwargs['group'] = group try: filename = func(base_name, base_dir, **kwargs) finally: if root_dir is not None: if logger is not None: logger.debug("changing back to '%s'", save_cwd) os.chdir(save_cwd) return filename def get_unpack_formats(): """Returns a list of supported formats for unpacking. Each element of the returned sequence is a tuple (name, extensions, description) """ formats = [(name, info[0], info[3]) for name, info in _UNPACK_FORMATS.items()] formats.sort() return formats def _check_unpack_options(extensions, function, extra_args): """Checks what gets registered as an unpacker.""" # first make sure no other unpacker is registered for this extension existing_extensions = {} for name, info in _UNPACK_FORMATS.items(): for ext in info[0]: existing_extensions[ext] = name for extension in extensions: if extension in existing_extensions: msg = '%s is already registered for "%s"' raise RegistryError(msg % (extension, existing_extensions[extension])) if not isinstance(function, Callable): raise TypeError('The registered function must be a callable') def register_unpack_format(name, extensions, function, extra_args=None, description=''): """Registers an unpack format. `name` is the name of the format. `extensions` is a list of extensions corresponding to the format. `function` is the callable that will be used to unpack archives. The callable will receive archives to unpack. If it's unable to handle an archive, it needs to raise a ReadError exception. If provided, `extra_args` is a sequence of (name, value) tuples that will be passed as arguments to the callable. description can be provided to describe the format, and will be returned by the get_unpack_formats() function. """ if extra_args is None: extra_args = [] _check_unpack_options(extensions, function, extra_args) _UNPACK_FORMATS[name] = extensions, function, extra_args, description def unregister_unpack_format(name): """Removes the pack format from the registry.""" del _UNPACK_FORMATS[name] def _ensure_directory(path): """Ensure that the parent directory of `path` exists""" dirname = os.path.dirname(path) if not os.path.isdir(dirname): os.makedirs(dirname) def _unpack_zipfile(filename, extract_dir): """Unpack zip `filename` to `extract_dir` """ try: import zipfile except ImportError: raise ReadError('zlib not supported, cannot unpack this archive.') if not zipfile.is_zipfile(filename): raise ReadError("%s is not a zip file" % filename) zip = zipfile.ZipFile(filename) try: for info in zip.infolist(): name = info.filename # don't extract absolute paths or ones with .. in them if name.startswith('/') or '..' in name: continue target = os.path.join(extract_dir, *name.split('/')) if not target: continue _ensure_directory(target) if not name.endswith('/'): # file data = zip.read(info.filename) f = open(target, 'wb') try: f.write(data) finally: f.close() del data finally: zip.close() def _unpack_tarfile(filename, extract_dir): """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` """ try: tarobj = tarfile.open(filename) except tarfile.TarError: raise ReadError( "%s is not a compressed or uncompressed tar file" % filename) try: tarobj.extractall(extract_dir) finally: tarobj.close() _UNPACK_FORMATS = { 'gztar': (['.tar.gz', '.tgz'], _unpack_tarfile, [], "gzip'ed tar-file"), 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file") } if _BZ2_SUPPORTED: _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], "bzip2'ed tar-file") def _find_unpack_format(filename): for name, info in _UNPACK_FORMATS.items(): for extension in info[0]: if filename.endswith(extension): return name return None def unpack_archive(filename, extract_dir=None, format=None): """Unpack an archive. `filename` is the name of the archive. `extract_dir` is the name of the target directory, where the archive is unpacked. If not provided, the current working directory is used. `format` is the archive format: one of "zip", "tar", or "gztar". Or any other registered format. If not provided, unpack_archive will use the filename extension and see if an unpacker was registered for that extension. In case none is found, a ValueError is raised. """ if extract_dir is None: extract_dir = os.getcwd() if format is not None: try: format_info = _UNPACK_FORMATS[format] except KeyError: raise ValueError("Unknown unpack format '{0}'".format(format)) func = format_info[1] func(filename, extract_dir, **dict(format_info[2])) else: # we need to look at the registered unpackers supported extensions format = _find_unpack_format(filename) if format is None: raise ReadError("Unknown archive format '{0}'".format(filename)) func = _UNPACK_FORMATS[format][1] kwargs = dict(_UNPACK_FORMATS[format][2]) func(filename, extract_dir, **kwargs) PKH]o9 9 Dpython3.10/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfgnu[[posix_prefix] # Configuration directories. Some of these come straight out of the # configure script. They are for implementing the other variables, not to # be used directly in [resource_locations]. confdir = /etc datadir = /usr/share libdir = /usr/lib statedir = /var # User resource directory local = ~/.local/{distribution.name} stdlib = {base}/lib/python{py_version_short} platstdlib = {platbase}/lib/python{py_version_short} purelib = {base}/lib/python{py_version_short}/site-packages platlib = {platbase}/lib/python{py_version_short}/site-packages include = {base}/include/python{py_version_short}{abiflags} platinclude = {platbase}/include/python{py_version_short}{abiflags} data = {base} [posix_home] stdlib = {base}/lib/python platstdlib = {base}/lib/python purelib = {base}/lib/python platlib = {base}/lib/python include = {base}/include/python platinclude = {base}/include/python scripts = {base}/bin data = {base} [nt] stdlib = {base}/Lib platstdlib = {base}/Lib purelib = {base}/Lib/site-packages platlib = {base}/Lib/site-packages include = {base}/Include platinclude = {base}/Include scripts = {base}/Scripts data = {base} [os2] stdlib = {base}/Lib platstdlib = {base}/Lib purelib = {base}/Lib/site-packages platlib = {base}/Lib/site-packages include = {base}/Include platinclude = {base}/Include scripts = {base}/Scripts data = {base} [os2_home] stdlib = {userbase}/lib/python{py_version_short} platstdlib = {userbase}/lib/python{py_version_short} purelib = {userbase}/lib/python{py_version_short}/site-packages platlib = {userbase}/lib/python{py_version_short}/site-packages include = {userbase}/include/python{py_version_short} scripts = {userbase}/bin data = {userbase} [nt_user] stdlib = {userbase}/Python{py_version_nodot} platstdlib = {userbase}/Python{py_version_nodot} purelib = {userbase}/Python{py_version_nodot}/site-packages platlib = {userbase}/Python{py_version_nodot}/site-packages include = {userbase}/Python{py_version_nodot}/Include scripts = {userbase}/Scripts data = {userbase} [posix_user] stdlib = {userbase}/lib/python{py_version_short} platstdlib = {userbase}/lib/python{py_version_short} purelib = {userbase}/lib/python{py_version_short}/site-packages platlib = {userbase}/lib/python{py_version_short}/site-packages include = {userbase}/include/python{py_version_short} scripts = {userbase}/bin data = {userbase} [osx_framework_user] stdlib = {userbase}/lib/python platstdlib = {userbase}/lib/python purelib = {userbase}/lib/python/site-packages platlib = {userbase}/lib/python/site-packages include = {userbase}/include scripts = {userbase}/bin data = {userbase} PKH]DBCiiApython3.10/site-packages/pip/_vendor/distlib/_backport/tarfile.pynu[#------------------------------------------------------------------- # tarfile.py #------------------------------------------------------------------- # Copyright (C) 2002 Lars Gustaebel # All rights reserved. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # from __future__ import print_function """Read from and write to tar format archives. """ __version__ = "$Revision$" version = "0.9.0" __author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)" __date__ = "$Date: 2011-02-25 17:42:01 +0200 (Fri, 25 Feb 2011) $" __cvsid__ = "$Id: tarfile.py 88586 2011-02-25 15:42:01Z marc-andre.lemburg $" __credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend." #--------- # Imports #--------- import sys import os import stat import errno import time import struct import copy import re try: import grp, pwd except ImportError: grp = pwd = None # os.symlink on Windows prior to 6.0 raises NotImplementedError symlink_exception = (AttributeError, NotImplementedError) try: # WindowsError (1314) will be raised if the caller does not hold the # SeCreateSymbolicLinkPrivilege privilege symlink_exception += (WindowsError,) except NameError: pass # from tarfile import * __all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"] if sys.version_info[0] < 3: import __builtin__ as builtins else: import builtins _open = builtins.open # Since 'open' is TarFile.open #--------------------------------------------------------- # tar constants #--------------------------------------------------------- NUL = b"\0" # the null character BLOCKSIZE = 512 # length of processing blocks RECORDSIZE = BLOCKSIZE * 20 # length of records GNU_MAGIC = b"ustar \0" # magic gnu tar string POSIX_MAGIC = b"ustar\x0000" # magic posix tar string LENGTH_NAME = 100 # maximum length of a filename LENGTH_LINK = 100 # maximum length of a linkname LENGTH_PREFIX = 155 # maximum length of the prefix field REGTYPE = b"0" # regular file AREGTYPE = b"\0" # regular file LNKTYPE = b"1" # link (inside tarfile) SYMTYPE = b"2" # symbolic link CHRTYPE = b"3" # character special device BLKTYPE = b"4" # block special device DIRTYPE = b"5" # directory FIFOTYPE = b"6" # fifo special device CONTTYPE = b"7" # contiguous file GNUTYPE_LONGNAME = b"L" # GNU tar longname GNUTYPE_LONGLINK = b"K" # GNU tar longlink GNUTYPE_SPARSE = b"S" # GNU tar sparse file XHDTYPE = b"x" # POSIX.1-2001 extended header XGLTYPE = b"g" # POSIX.1-2001 global header SOLARIS_XHDTYPE = b"X" # Solaris extended header USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format GNU_FORMAT = 1 # GNU tar format PAX_FORMAT = 2 # POSIX.1-2001 (pax) format DEFAULT_FORMAT = GNU_FORMAT #--------------------------------------------------------- # tarfile constants #--------------------------------------------------------- # File types that tarfile supports: SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, CONTTYPE, CHRTYPE, BLKTYPE, GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, GNUTYPE_SPARSE) # File types that will be treated as a regular file. REGULAR_TYPES = (REGTYPE, AREGTYPE, CONTTYPE, GNUTYPE_SPARSE) # File types that are part of the GNU tar format. GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, GNUTYPE_SPARSE) # Fields from a pax header that override a TarInfo attribute. PAX_FIELDS = ("path", "linkpath", "size", "mtime", "uid", "gid", "uname", "gname") # Fields from a pax header that are affected by hdrcharset. PAX_NAME_FIELDS = set(("path", "linkpath", "uname", "gname")) # Fields in a pax header that are numbers, all other fields # are treated as strings. PAX_NUMBER_FIELDS = { "atime": float, "ctime": float, "mtime": float, "uid": int, "gid": int, "size": int } #--------------------------------------------------------- # Bits used in the mode field, values in octal. #--------------------------------------------------------- S_IFLNK = 0o120000 # symbolic link S_IFREG = 0o100000 # regular file S_IFBLK = 0o060000 # block device S_IFDIR = 0o040000 # directory S_IFCHR = 0o020000 # character device S_IFIFO = 0o010000 # fifo TSUID = 0o4000 # set UID on execution TSGID = 0o2000 # set GID on execution TSVTX = 0o1000 # reserved TUREAD = 0o400 # read by owner TUWRITE = 0o200 # write by owner TUEXEC = 0o100 # execute/search by owner TGREAD = 0o040 # read by group TGWRITE = 0o020 # write by group TGEXEC = 0o010 # execute/search by group TOREAD = 0o004 # read by other TOWRITE = 0o002 # write by other TOEXEC = 0o001 # execute/search by other #--------------------------------------------------------- # initialization #--------------------------------------------------------- if os.name in ("nt", "ce"): ENCODING = "utf-8" else: ENCODING = sys.getfilesystemencoding() #--------------------------------------------------------- # Some useful functions #--------------------------------------------------------- def stn(s, length, encoding, errors): """Convert a string to a null-terminated bytes object. """ s = s.encode(encoding, errors) return s[:length] + (length - len(s)) * NUL def nts(s, encoding, errors): """Convert a null-terminated bytes object to a string. """ p = s.find(b"\0") if p != -1: s = s[:p] return s.decode(encoding, errors) def nti(s): """Convert a number field to a python number. """ # There are two possible encodings for a number field, see # itn() below. if s[0] != chr(0o200): try: n = int(nts(s, "ascii", "strict") or "0", 8) except ValueError: raise InvalidHeaderError("invalid header") else: n = 0 for i in range(len(s) - 1): n <<= 8 n += ord(s[i + 1]) return n def itn(n, digits=8, format=DEFAULT_FORMAT): """Convert a python number to a number field. """ # POSIX 1003.1-1988 requires numbers to be encoded as a string of # octal digits followed by a null-byte, this allows values up to # (8**(digits-1))-1. GNU tar allows storing numbers greater than # that if necessary. A leading 0o200 byte indicates this particular # encoding, the following digits-1 bytes are a big-endian # representation. This allows values up to (256**(digits-1))-1. if 0 <= n < 8 ** (digits - 1): s = ("%0*o" % (digits - 1, n)).encode("ascii") + NUL else: if format != GNU_FORMAT or n >= 256 ** (digits - 1): raise ValueError("overflow in number field") if n < 0: # XXX We mimic GNU tar's behaviour with negative numbers, # this could raise OverflowError. n = struct.unpack("L", struct.pack("l", n))[0] s = bytearray() for i in range(digits - 1): s.insert(0, n & 0o377) n >>= 8 s.insert(0, 0o200) return s def calc_chksums(buf): """Calculate the checksum for a member's header by summing up all characters except for the chksum field which is treated as if it was filled with spaces. According to the GNU tar sources, some tars (Sun and NeXT) calculate chksum with signed char, which will be different if there are chars in the buffer with the high bit set. So we calculate two checksums, unsigned and signed. """ unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512])) signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512])) return unsigned_chksum, signed_chksum def copyfileobj(src, dst, length=None): """Copy length bytes from fileobj src to fileobj dst. If length is None, copy the entire content. """ if length == 0: return if length is None: while True: buf = src.read(16*1024) if not buf: break dst.write(buf) return BUFSIZE = 16 * 1024 blocks, remainder = divmod(length, BUFSIZE) for b in range(blocks): buf = src.read(BUFSIZE) if len(buf) < BUFSIZE: raise IOError("end of file reached") dst.write(buf) if remainder != 0: buf = src.read(remainder) if len(buf) < remainder: raise IOError("end of file reached") dst.write(buf) return filemode_table = ( ((S_IFLNK, "l"), (S_IFREG, "-"), (S_IFBLK, "b"), (S_IFDIR, "d"), (S_IFCHR, "c"), (S_IFIFO, "p")), ((TUREAD, "r"),), ((TUWRITE, "w"),), ((TUEXEC|TSUID, "s"), (TSUID, "S"), (TUEXEC, "x")), ((TGREAD, "r"),), ((TGWRITE, "w"),), ((TGEXEC|TSGID, "s"), (TSGID, "S"), (TGEXEC, "x")), ((TOREAD, "r"),), ((TOWRITE, "w"),), ((TOEXEC|TSVTX, "t"), (TSVTX, "T"), (TOEXEC, "x")) ) def filemode(mode): """Convert a file's mode to a string of the form -rwxrwxrwx. Used by TarFile.list() """ perm = [] for table in filemode_table: for bit, char in table: if mode & bit == bit: perm.append(char) break else: perm.append("-") return "".join(perm) class TarError(Exception): """Base exception.""" pass class ExtractError(TarError): """General exception for extract errors.""" pass class ReadError(TarError): """Exception for unreadable tar archives.""" pass class CompressionError(TarError): """Exception for unavailable compression methods.""" pass class StreamError(TarError): """Exception for unsupported operations on stream-like TarFiles.""" pass class HeaderError(TarError): """Base exception for header errors.""" pass class EmptyHeaderError(HeaderError): """Exception for empty headers.""" pass class TruncatedHeaderError(HeaderError): """Exception for truncated headers.""" pass class EOFHeaderError(HeaderError): """Exception for end of file headers.""" pass class InvalidHeaderError(HeaderError): """Exception for invalid headers.""" pass class SubsequentHeaderError(HeaderError): """Exception for missing and invalid extended headers.""" pass #--------------------------- # internal stream interface #--------------------------- class _LowLevelFile(object): """Low-level file object. Supports reading and writing. It is used instead of a regular file object for streaming access. """ def __init__(self, name, mode): mode = { "r": os.O_RDONLY, "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC, }[mode] if hasattr(os, "O_BINARY"): mode |= os.O_BINARY self.fd = os.open(name, mode, 0o666) def close(self): os.close(self.fd) def read(self, size): return os.read(self.fd, size) def write(self, s): os.write(self.fd, s) class _Stream(object): """Class that serves as an adapter between TarFile and a stream-like object. The stream-like object only needs to have a read() or write() method and is accessed blockwise. Use of gzip or bzip2 compression is possible. A stream-like object could be for example: sys.stdin, sys.stdout, a socket, a tape device etc. _Stream is intended to be used only internally. """ def __init__(self, name, mode, comptype, fileobj, bufsize): """Construct a _Stream object. """ self._extfileobj = True if fileobj is None: fileobj = _LowLevelFile(name, mode) self._extfileobj = False if comptype == '*': # Enable transparent compression detection for the # stream interface fileobj = _StreamProxy(fileobj) comptype = fileobj.getcomptype() self.name = name or "" self.mode = mode self.comptype = comptype self.fileobj = fileobj self.bufsize = bufsize self.buf = b"" self.pos = 0 self.closed = False try: if comptype == "gz": try: import zlib except ImportError: raise CompressionError("zlib module is not available") self.zlib = zlib self.crc = zlib.crc32(b"") if mode == "r": self._init_read_gz() else: self._init_write_gz() if comptype == "bz2": try: import bz2 except ImportError: raise CompressionError("bz2 module is not available") if mode == "r": self.dbuf = b"" self.cmp = bz2.BZ2Decompressor() else: self.cmp = bz2.BZ2Compressor() except: if not self._extfileobj: self.fileobj.close() self.closed = True raise def __del__(self): if hasattr(self, "closed") and not self.closed: self.close() def _init_write_gz(self): """Initialize for writing with gzip compression. """ self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, -self.zlib.MAX_WBITS, self.zlib.DEF_MEM_LEVEL, 0) timestamp = struct.pack(" self.bufsize: self.fileobj.write(self.buf[:self.bufsize]) self.buf = self.buf[self.bufsize:] def close(self): """Close the _Stream object. No operation should be done on it afterwards. """ if self.closed: return if self.mode == "w" and self.comptype != "tar": self.buf += self.cmp.flush() if self.mode == "w" and self.buf: self.fileobj.write(self.buf) self.buf = b"" if self.comptype == "gz": # The native zlib crc is an unsigned 32-bit integer, but # the Python wrapper implicitly casts that to a signed C # long. So, on a 32-bit box self.crc may "look negative", # while the same crc on a 64-bit box may "look positive". # To avoid irksome warnings from the `struct` module, force # it to look positive on all boxes. self.fileobj.write(struct.pack("= 0: blocks, remainder = divmod(pos - self.pos, self.bufsize) for i in range(blocks): self.read(self.bufsize) self.read(remainder) else: raise StreamError("seeking backwards is not allowed") return self.pos def read(self, size=None): """Return the next size number of bytes from the stream. If size is not defined, return all bytes of the stream up to EOF. """ if size is None: t = [] while True: buf = self._read(self.bufsize) if not buf: break t.append(buf) buf = "".join(t) else: buf = self._read(size) self.pos += len(buf) return buf def _read(self, size): """Return size bytes from the stream. """ if self.comptype == "tar": return self.__read(size) c = len(self.dbuf) while c < size: buf = self.__read(self.bufsize) if not buf: break try: buf = self.cmp.decompress(buf) except IOError: raise ReadError("invalid compressed data") self.dbuf += buf c += len(buf) buf = self.dbuf[:size] self.dbuf = self.dbuf[size:] return buf def __read(self, size): """Return size bytes from stream. If internal buffer is empty, read another block from the stream. """ c = len(self.buf) while c < size: buf = self.fileobj.read(self.bufsize) if not buf: break self.buf += buf c += len(buf) buf = self.buf[:size] self.buf = self.buf[size:] return buf # class _Stream class _StreamProxy(object): """Small proxy class that enables transparent compression detection for the Stream interface (mode 'r|*'). """ def __init__(self, fileobj): self.fileobj = fileobj self.buf = self.fileobj.read(BLOCKSIZE) def read(self, size): self.read = self.fileobj.read return self.buf def getcomptype(self): if self.buf.startswith(b"\037\213\010"): return "gz" if self.buf.startswith(b"BZh91"): return "bz2" return "tar" def close(self): self.fileobj.close() # class StreamProxy class _BZ2Proxy(object): """Small proxy class that enables external file object support for "r:bz2" and "w:bz2" modes. This is actually a workaround for a limitation in bz2 module's BZ2File class which (unlike gzip.GzipFile) has no support for a file object argument. """ blocksize = 16 * 1024 def __init__(self, fileobj, mode): self.fileobj = fileobj self.mode = mode self.name = getattr(self.fileobj, "name", None) self.init() def init(self): import bz2 self.pos = 0 if self.mode == "r": self.bz2obj = bz2.BZ2Decompressor() self.fileobj.seek(0) self.buf = b"" else: self.bz2obj = bz2.BZ2Compressor() def read(self, size): x = len(self.buf) while x < size: raw = self.fileobj.read(self.blocksize) if not raw: break data = self.bz2obj.decompress(raw) self.buf += data x += len(data) buf = self.buf[:size] self.buf = self.buf[size:] self.pos += len(buf) return buf def seek(self, pos): if pos < self.pos: self.init() self.read(pos - self.pos) def tell(self): return self.pos def write(self, data): self.pos += len(data) raw = self.bz2obj.compress(data) self.fileobj.write(raw) def close(self): if self.mode == "w": raw = self.bz2obj.flush() self.fileobj.write(raw) # class _BZ2Proxy #------------------------ # Extraction file object #------------------------ class _FileInFile(object): """A thin wrapper around an existing file object that provides a part of its data as an individual file object. """ def __init__(self, fileobj, offset, size, blockinfo=None): self.fileobj = fileobj self.offset = offset self.size = size self.position = 0 if blockinfo is None: blockinfo = [(0, size)] # Construct a map with data and zero blocks. self.map_index = 0 self.map = [] lastpos = 0 realpos = self.offset for offset, size in blockinfo: if offset > lastpos: self.map.append((False, lastpos, offset, None)) self.map.append((True, offset, offset + size, realpos)) realpos += size lastpos = offset + size if lastpos < self.size: self.map.append((False, lastpos, self.size, None)) def seekable(self): if not hasattr(self.fileobj, "seekable"): # XXX gzip.GzipFile and bz2.BZ2File return True return self.fileobj.seekable() def tell(self): """Return the current file position. """ return self.position def seek(self, position): """Seek to a position in the file. """ self.position = position def read(self, size=None): """Read data from the file. """ if size is None: size = self.size - self.position else: size = min(size, self.size - self.position) buf = b"" while size > 0: while True: data, start, stop, offset = self.map[self.map_index] if start <= self.position < stop: break else: self.map_index += 1 if self.map_index == len(self.map): self.map_index = 0 length = min(size, stop - self.position) if data: self.fileobj.seek(offset + (self.position - start)) buf += self.fileobj.read(length) else: buf += NUL * length size -= length self.position += length return buf #class _FileInFile class ExFileObject(object): """File-like object for reading an archive member. Is returned by TarFile.extractfile(). """ blocksize = 1024 def __init__(self, tarfile, tarinfo): self.fileobj = _FileInFile(tarfile.fileobj, tarinfo.offset_data, tarinfo.size, tarinfo.sparse) self.name = tarinfo.name self.mode = "r" self.closed = False self.size = tarinfo.size self.position = 0 self.buffer = b"" def readable(self): return True def writable(self): return False def seekable(self): return self.fileobj.seekable() def read(self, size=None): """Read at most size bytes from the file. If size is not present or None, read all data until EOF is reached. """ if self.closed: raise ValueError("I/O operation on closed file") buf = b"" if self.buffer: if size is None: buf = self.buffer self.buffer = b"" else: buf = self.buffer[:size] self.buffer = self.buffer[size:] if size is None: buf += self.fileobj.read() else: buf += self.fileobj.read(size - len(buf)) self.position += len(buf) return buf # XXX TextIOWrapper uses the read1() method. read1 = read def readline(self, size=-1): """Read one entire line from the file. If size is present and non-negative, return a string with at most that size, which may be an incomplete line. """ if self.closed: raise ValueError("I/O operation on closed file") pos = self.buffer.find(b"\n") + 1 if pos == 0: # no newline found. while True: buf = self.fileobj.read(self.blocksize) self.buffer += buf if not buf or b"\n" in buf: pos = self.buffer.find(b"\n") + 1 if pos == 0: # no newline found. pos = len(self.buffer) break if size != -1: pos = min(size, pos) buf = self.buffer[:pos] self.buffer = self.buffer[pos:] self.position += len(buf) return buf def readlines(self): """Return a list with all remaining lines. """ result = [] while True: line = self.readline() if not line: break result.append(line) return result def tell(self): """Return the current file position. """ if self.closed: raise ValueError("I/O operation on closed file") return self.position def seek(self, pos, whence=os.SEEK_SET): """Seek to a position in the file. """ if self.closed: raise ValueError("I/O operation on closed file") if whence == os.SEEK_SET: self.position = min(max(pos, 0), self.size) elif whence == os.SEEK_CUR: if pos < 0: self.position = max(self.position + pos, 0) else: self.position = min(self.position + pos, self.size) elif whence == os.SEEK_END: self.position = max(min(self.size + pos, self.size), 0) else: raise ValueError("Invalid argument") self.buffer = b"" self.fileobj.seek(self.position) def close(self): """Close the file object. """ self.closed = True def __iter__(self): """Get an iterator over the file's lines. """ while True: line = self.readline() if not line: break yield line #class ExFileObject #------------------ # Exported Classes #------------------ class TarInfo(object): """Informational class which holds the details about an archive member given by a tar header block. TarInfo objects are returned by TarFile.getmember(), TarFile.getmembers() and TarFile.gettarinfo() and are usually created internally. """ __slots__ = ("name", "mode", "uid", "gid", "size", "mtime", "chksum", "type", "linkname", "uname", "gname", "devmajor", "devminor", "offset", "offset_data", "pax_headers", "sparse", "tarfile", "_sparse_structs", "_link_target") def __init__(self, name=""): """Construct a TarInfo object. name is the optional name of the member. """ self.name = name # member name self.mode = 0o644 # file permissions self.uid = 0 # user id self.gid = 0 # group id self.size = 0 # file size self.mtime = 0 # modification time self.chksum = 0 # header checksum self.type = REGTYPE # member type self.linkname = "" # link name self.uname = "" # user name self.gname = "" # group name self.devmajor = 0 # device major number self.devminor = 0 # device minor number self.offset = 0 # the tar header starts here self.offset_data = 0 # the file's data starts here self.sparse = None # sparse member information self.pax_headers = {} # pax header information # In pax headers the "name" and "linkname" field are called # "path" and "linkpath". def _getpath(self): return self.name def _setpath(self, name): self.name = name path = property(_getpath, _setpath) def _getlinkpath(self): return self.linkname def _setlinkpath(self, linkname): self.linkname = linkname linkpath = property(_getlinkpath, _setlinkpath) def __repr__(self): return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) def get_info(self): """Return the TarInfo's attributes as a dictionary. """ info = { "name": self.name, "mode": self.mode & 0o7777, "uid": self.uid, "gid": self.gid, "size": self.size, "mtime": self.mtime, "chksum": self.chksum, "type": self.type, "linkname": self.linkname, "uname": self.uname, "gname": self.gname, "devmajor": self.devmajor, "devminor": self.devminor } if info["type"] == DIRTYPE and not info["name"].endswith("/"): info["name"] += "/" return info def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="surrogateescape"): """Return a tar header as a string of 512 byte blocks. """ info = self.get_info() if format == USTAR_FORMAT: return self.create_ustar_header(info, encoding, errors) elif format == GNU_FORMAT: return self.create_gnu_header(info, encoding, errors) elif format == PAX_FORMAT: return self.create_pax_header(info, encoding) else: raise ValueError("invalid format") def create_ustar_header(self, info, encoding, errors): """Return the object as a ustar header block. """ info["magic"] = POSIX_MAGIC if len(info["linkname"]) > LENGTH_LINK: raise ValueError("linkname is too long") if len(info["name"]) > LENGTH_NAME: info["prefix"], info["name"] = self._posix_split_name(info["name"]) return self._create_header(info, USTAR_FORMAT, encoding, errors) def create_gnu_header(self, info, encoding, errors): """Return the object as a GNU header block sequence. """ info["magic"] = GNU_MAGIC buf = b"" if len(info["linkname"]) > LENGTH_LINK: buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors) if len(info["name"]) > LENGTH_NAME: buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME, encoding, errors) return buf + self._create_header(info, GNU_FORMAT, encoding, errors) def create_pax_header(self, info, encoding): """Return the object as a ustar header block. If it cannot be represented this way, prepend a pax extended header sequence with supplement information. """ info["magic"] = POSIX_MAGIC pax_headers = self.pax_headers.copy() # Test string fields for values that exceed the field length or cannot # be represented in ASCII encoding. for name, hname, length in ( ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK), ("uname", "uname", 32), ("gname", "gname", 32)): if hname in pax_headers: # The pax header has priority. continue # Try to encode the string as ASCII. try: info[name].encode("ascii", "strict") except UnicodeEncodeError: pax_headers[hname] = info[name] continue if len(info[name]) > length: pax_headers[hname] = info[name] # Test number fields for values that exceed the field limit or values # that like to be stored as float. for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)): if name in pax_headers: # The pax header has priority. Avoid overflow. info[name] = 0 continue val = info[name] if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float): pax_headers[name] = str(val) info[name] = 0 # Create a pax extended header if necessary. if pax_headers: buf = self._create_pax_generic_header(pax_headers, XHDTYPE, encoding) else: buf = b"" return buf + self._create_header(info, USTAR_FORMAT, "ascii", "replace") @classmethod def create_pax_global_header(cls, pax_headers): """Return the object as a pax global header block sequence. """ return cls._create_pax_generic_header(pax_headers, XGLTYPE, "utf8") def _posix_split_name(self, name): """Split a name longer than 100 chars into a prefix and a name part. """ prefix = name[:LENGTH_PREFIX + 1] while prefix and prefix[-1] != "/": prefix = prefix[:-1] name = name[len(prefix):] prefix = prefix[:-1] if not prefix or len(name) > LENGTH_NAME: raise ValueError("name is too long") return prefix, name @staticmethod def _create_header(info, format, encoding, errors): """Return a header block. info is a dictionary with file information, format must be one of the *_FORMAT constants. """ parts = [ stn(info.get("name", ""), 100, encoding, errors), itn(info.get("mode", 0) & 0o7777, 8, format), itn(info.get("uid", 0), 8, format), itn(info.get("gid", 0), 8, format), itn(info.get("size", 0), 12, format), itn(info.get("mtime", 0), 12, format), b" ", # checksum field info.get("type", REGTYPE), stn(info.get("linkname", ""), 100, encoding, errors), info.get("magic", POSIX_MAGIC), stn(info.get("uname", ""), 32, encoding, errors), stn(info.get("gname", ""), 32, encoding, errors), itn(info.get("devmajor", 0), 8, format), itn(info.get("devminor", 0), 8, format), stn(info.get("prefix", ""), 155, encoding, errors) ] buf = struct.pack("%ds" % BLOCKSIZE, b"".join(parts)) chksum = calc_chksums(buf[-BLOCKSIZE:])[0] buf = buf[:-364] + ("%06o\0" % chksum).encode("ascii") + buf[-357:] return buf @staticmethod def _create_payload(payload): """Return the string payload filled with zero bytes up to the next 512 byte border. """ blocks, remainder = divmod(len(payload), BLOCKSIZE) if remainder > 0: payload += (BLOCKSIZE - remainder) * NUL return payload @classmethod def _create_gnu_long_header(cls, name, type, encoding, errors): """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence for name. """ name = name.encode(encoding, errors) + NUL info = {} info["name"] = "././@LongLink" info["type"] = type info["size"] = len(name) info["magic"] = GNU_MAGIC # create extended header + name blocks. return cls._create_header(info, USTAR_FORMAT, encoding, errors) + \ cls._create_payload(name) @classmethod def _create_pax_generic_header(cls, pax_headers, type, encoding): """Return a POSIX.1-2008 extended or global header sequence that contains a list of keyword, value pairs. The values must be strings. """ # Check if one of the fields contains surrogate characters and thereby # forces hdrcharset=BINARY, see _proc_pax() for more information. binary = False for keyword, value in pax_headers.items(): try: value.encode("utf8", "strict") except UnicodeEncodeError: binary = True break records = b"" if binary: # Put the hdrcharset field at the beginning of the header. records += b"21 hdrcharset=BINARY\n" for keyword, value in pax_headers.items(): keyword = keyword.encode("utf8") if binary: # Try to restore the original byte representation of `value'. # Needless to say, that the encoding must match the string. value = value.encode(encoding, "surrogateescape") else: value = value.encode("utf8") l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n' n = p = 0 while True: n = l + len(str(p)) if n == p: break p = n records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n" # We use a hardcoded "././@PaxHeader" name like star does # instead of the one that POSIX recommends. info = {} info["name"] = "././@PaxHeader" info["type"] = type info["size"] = len(records) info["magic"] = POSIX_MAGIC # Create pax header + record blocks. return cls._create_header(info, USTAR_FORMAT, "ascii", "replace") + \ cls._create_payload(records) @classmethod def frombuf(cls, buf, encoding, errors): """Construct a TarInfo object from a 512 byte bytes object. """ if len(buf) == 0: raise EmptyHeaderError("empty header") if len(buf) != BLOCKSIZE: raise TruncatedHeaderError("truncated header") if buf.count(NUL) == BLOCKSIZE: raise EOFHeaderError("end of file header") chksum = nti(buf[148:156]) if chksum not in calc_chksums(buf): raise InvalidHeaderError("bad checksum") obj = cls() obj.name = nts(buf[0:100], encoding, errors) obj.mode = nti(buf[100:108]) obj.uid = nti(buf[108:116]) obj.gid = nti(buf[116:124]) obj.size = nti(buf[124:136]) obj.mtime = nti(buf[136:148]) obj.chksum = chksum obj.type = buf[156:157] obj.linkname = nts(buf[157:257], encoding, errors) obj.uname = nts(buf[265:297], encoding, errors) obj.gname = nts(buf[297:329], encoding, errors) obj.devmajor = nti(buf[329:337]) obj.devminor = nti(buf[337:345]) prefix = nts(buf[345:500], encoding, errors) # Old V7 tar format represents a directory as a regular # file with a trailing slash. if obj.type == AREGTYPE and obj.name.endswith("/"): obj.type = DIRTYPE # The old GNU sparse format occupies some of the unused # space in the buffer for up to 4 sparse structures. # Save the them for later processing in _proc_sparse(). if obj.type == GNUTYPE_SPARSE: pos = 386 structs = [] for i in range(4): try: offset = nti(buf[pos:pos + 12]) numbytes = nti(buf[pos + 12:pos + 24]) except ValueError: break structs.append((offset, numbytes)) pos += 24 isextended = bool(buf[482]) origsize = nti(buf[483:495]) obj._sparse_structs = (structs, isextended, origsize) # Remove redundant slashes from directories. if obj.isdir(): obj.name = obj.name.rstrip("/") # Reconstruct a ustar longname. if prefix and obj.type not in GNU_TYPES: obj.name = prefix + "/" + obj.name return obj @classmethod def fromtarfile(cls, tarfile): """Return the next TarInfo object from TarFile object tarfile. """ buf = tarfile.fileobj.read(BLOCKSIZE) obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) obj.offset = tarfile.fileobj.tell() - BLOCKSIZE return obj._proc_member(tarfile) #-------------------------------------------------------------------------- # The following are methods that are called depending on the type of a # member. The entry point is _proc_member() which can be overridden in a # subclass to add custom _proc_*() methods. A _proc_*() method MUST # implement the following # operations: # 1. Set self.offset_data to the position where the data blocks begin, # if there is data that follows. # 2. Set tarfile.offset to the position where the next member's header will # begin. # 3. Return self or another valid TarInfo object. def _proc_member(self, tarfile): """Choose the right processing method depending on the type and call it. """ if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK): return self._proc_gnulong(tarfile) elif self.type == GNUTYPE_SPARSE: return self._proc_sparse(tarfile) elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE): return self._proc_pax(tarfile) else: return self._proc_builtin(tarfile) def _proc_builtin(self, tarfile): """Process a builtin type or an unknown type which will be treated as a regular file. """ self.offset_data = tarfile.fileobj.tell() offset = self.offset_data if self.isreg() or self.type not in SUPPORTED_TYPES: # Skip the following data blocks. offset += self._block(self.size) tarfile.offset = offset # Patch the TarInfo object with saved global # header information. self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors) return self def _proc_gnulong(self, tarfile): """Process the blocks that hold a GNU longname or longlink member. """ buf = tarfile.fileobj.read(self._block(self.size)) # Fetch the next header and process it. try: next = self.fromtarfile(tarfile) except HeaderError: raise SubsequentHeaderError("missing or bad subsequent header") # Patch the TarInfo object from the next header with # the longname information. next.offset = self.offset if self.type == GNUTYPE_LONGNAME: next.name = nts(buf, tarfile.encoding, tarfile.errors) elif self.type == GNUTYPE_LONGLINK: next.linkname = nts(buf, tarfile.encoding, tarfile.errors) return next def _proc_sparse(self, tarfile): """Process a GNU sparse header plus extra headers. """ # We already collected some sparse structures in frombuf(). structs, isextended, origsize = self._sparse_structs del self._sparse_structs # Collect sparse structures from extended header blocks. while isextended: buf = tarfile.fileobj.read(BLOCKSIZE) pos = 0 for i in range(21): try: offset = nti(buf[pos:pos + 12]) numbytes = nti(buf[pos + 12:pos + 24]) except ValueError: break if offset and numbytes: structs.append((offset, numbytes)) pos += 24 isextended = bool(buf[504]) self.sparse = structs self.offset_data = tarfile.fileobj.tell() tarfile.offset = self.offset_data + self._block(self.size) self.size = origsize return self def _proc_pax(self, tarfile): """Process an extended or global header as described in POSIX.1-2008. """ # Read the header information. buf = tarfile.fileobj.read(self._block(self.size)) # A pax header stores supplemental information for either # the following file (extended) or all following files # (global). if self.type == XGLTYPE: pax_headers = tarfile.pax_headers else: pax_headers = tarfile.pax_headers.copy() # Check if the pax header contains a hdrcharset field. This tells us # the encoding of the path, linkpath, uname and gname fields. Normally, # these fields are UTF-8 encoded but since POSIX.1-2008 tar # implementations are allowed to store them as raw binary strings if # the translation to UTF-8 fails. match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf) if match is not None: pax_headers["hdrcharset"] = match.group(1).decode("utf8") # For the time being, we don't care about anything other than "BINARY". # The only other value that is currently allowed by the standard is # "ISO-IR 10646 2000 UTF-8" in other words UTF-8. hdrcharset = pax_headers.get("hdrcharset") if hdrcharset == "BINARY": encoding = tarfile.encoding else: encoding = "utf8" # Parse pax header information. A record looks like that: # "%d %s=%s\n" % (length, keyword, value). length is the size # of the complete record including the length field itself and # the newline. keyword and value are both UTF-8 encoded strings. regex = re.compile(br"(\d+) ([^=]+)=") pos = 0 while True: match = regex.match(buf, pos) if not match: break length, keyword = match.groups() length = int(length) value = buf[match.end(2) + 1:match.start(1) + length - 1] # Normally, we could just use "utf8" as the encoding and "strict" # as the error handler, but we better not take the risk. For # example, GNU tar <= 1.23 is known to store filenames it cannot # translate to UTF-8 as raw strings (unfortunately without a # hdrcharset=BINARY header). # We first try the strict standard encoding, and if that fails we # fall back on the user's encoding and error handler. keyword = self._decode_pax_field(keyword, "utf8", "utf8", tarfile.errors) if keyword in PAX_NAME_FIELDS: value = self._decode_pax_field(value, encoding, tarfile.encoding, tarfile.errors) else: value = self._decode_pax_field(value, "utf8", "utf8", tarfile.errors) pax_headers[keyword] = value pos += length # Fetch the next header. try: next = self.fromtarfile(tarfile) except HeaderError: raise SubsequentHeaderError("missing or bad subsequent header") # Process GNU sparse information. if "GNU.sparse.map" in pax_headers: # GNU extended sparse format version 0.1. self._proc_gnusparse_01(next, pax_headers) elif "GNU.sparse.size" in pax_headers: # GNU extended sparse format version 0.0. self._proc_gnusparse_00(next, pax_headers, buf) elif pax_headers.get("GNU.sparse.major") == "1" and pax_headers.get("GNU.sparse.minor") == "0": # GNU extended sparse format version 1.0. self._proc_gnusparse_10(next, pax_headers, tarfile) if self.type in (XHDTYPE, SOLARIS_XHDTYPE): # Patch the TarInfo object with the extended header info. next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) next.offset = self.offset if "size" in pax_headers: # If the extended header replaces the size field, # we need to recalculate the offset where the next # header starts. offset = next.offset_data if next.isreg() or next.type not in SUPPORTED_TYPES: offset += next._block(next.size) tarfile.offset = offset return next def _proc_gnusparse_00(self, next, pax_headers, buf): """Process a GNU tar extended sparse header, version 0.0. """ offsets = [] for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf): offsets.append(int(match.group(1))) numbytes = [] for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf): numbytes.append(int(match.group(1))) next.sparse = list(zip(offsets, numbytes)) def _proc_gnusparse_01(self, next, pax_headers): """Process a GNU tar extended sparse header, version 0.1. """ sparse = [int(x) for x in pax_headers["GNU.sparse.map"].split(",")] next.sparse = list(zip(sparse[::2], sparse[1::2])) def _proc_gnusparse_10(self, next, pax_headers, tarfile): """Process a GNU tar extended sparse header, version 1.0. """ fields = None sparse = [] buf = tarfile.fileobj.read(BLOCKSIZE) fields, buf = buf.split(b"\n", 1) fields = int(fields) while len(sparse) < fields * 2: if b"\n" not in buf: buf += tarfile.fileobj.read(BLOCKSIZE) number, buf = buf.split(b"\n", 1) sparse.append(int(number)) next.offset_data = tarfile.fileobj.tell() next.sparse = list(zip(sparse[::2], sparse[1::2])) def _apply_pax_info(self, pax_headers, encoding, errors): """Replace fields with supplemental information from a previous pax extended or global header. """ for keyword, value in pax_headers.items(): if keyword == "GNU.sparse.name": setattr(self, "path", value) elif keyword == "GNU.sparse.size": setattr(self, "size", int(value)) elif keyword == "GNU.sparse.realsize": setattr(self, "size", int(value)) elif keyword in PAX_FIELDS: if keyword in PAX_NUMBER_FIELDS: try: value = PAX_NUMBER_FIELDS[keyword](value) except ValueError: value = 0 if keyword == "path": value = value.rstrip("/") setattr(self, keyword, value) self.pax_headers = pax_headers.copy() def _decode_pax_field(self, value, encoding, fallback_encoding, fallback_errors): """Decode a single field from a pax record. """ try: return value.decode(encoding, "strict") except UnicodeDecodeError: return value.decode(fallback_encoding, fallback_errors) def _block(self, count): """Round up a byte count by BLOCKSIZE and return it, e.g. _block(834) => 1024. """ blocks, remainder = divmod(count, BLOCKSIZE) if remainder: blocks += 1 return blocks * BLOCKSIZE def isreg(self): return self.type in REGULAR_TYPES def isfile(self): return self.isreg() def isdir(self): return self.type == DIRTYPE def issym(self): return self.type == SYMTYPE def islnk(self): return self.type == LNKTYPE def ischr(self): return self.type == CHRTYPE def isblk(self): return self.type == BLKTYPE def isfifo(self): return self.type == FIFOTYPE def issparse(self): return self.sparse is not None def isdev(self): return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE) # class TarInfo class TarFile(object): """The TarFile Class provides an interface to tar archives. """ debug = 0 # May be set from 0 (no msgs) to 3 (all msgs) dereference = False # If true, add content of linked file to the # tar file, else the link. ignore_zeros = False # If true, skips empty or invalid blocks and # continues processing. errorlevel = 1 # If 0, fatal errors only appear in debug # messages (if debug >= 0). If > 0, errors # are passed to the caller as exceptions. format = DEFAULT_FORMAT # The format to use when creating an archive. encoding = ENCODING # Encoding for 8-bit character strings. errors = None # Error handler for unicode conversion. tarinfo = TarInfo # The default TarInfo class to use. fileobject = ExFileObject # The default ExFileObject class to use. def __init__(self, name=None, mode="r", fileobj=None, format=None, tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, errors="surrogateescape", pax_headers=None, debug=None, errorlevel=None): """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to read from an existing archive, 'a' to append data to an existing file or 'w' to create a new file overwriting an existing one. `mode' defaults to 'r'. If `fileobj' is given, it is used for reading or writing data. If it can be determined, `mode' is overridden by `fileobj's mode. `fileobj' is not closed, when TarFile is closed. """ if len(mode) > 1 or mode not in "raw": raise ValueError("mode must be 'r', 'a' or 'w'") self.mode = mode self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] if not fileobj: if self.mode == "a" and not os.path.exists(name): # Create nonexistent files in append mode. self.mode = "w" self._mode = "wb" fileobj = bltn_open(name, self._mode) self._extfileobj = False else: if name is None and hasattr(fileobj, "name"): name = fileobj.name if hasattr(fileobj, "mode"): self._mode = fileobj.mode self._extfileobj = True self.name = os.path.abspath(name) if name else None self.fileobj = fileobj # Init attributes. if format is not None: self.format = format if tarinfo is not None: self.tarinfo = tarinfo if dereference is not None: self.dereference = dereference if ignore_zeros is not None: self.ignore_zeros = ignore_zeros if encoding is not None: self.encoding = encoding self.errors = errors if pax_headers is not None and self.format == PAX_FORMAT: self.pax_headers = pax_headers else: self.pax_headers = {} if debug is not None: self.debug = debug if errorlevel is not None: self.errorlevel = errorlevel # Init datastructures. self.closed = False self.members = [] # list of members as TarInfo objects self._loaded = False # flag if all members have been read self.offset = self.fileobj.tell() # current position in the archive file self.inodes = {} # dictionary caching the inodes of # archive members already added try: if self.mode == "r": self.firstmember = None self.firstmember = self.next() if self.mode == "a": # Move to the end of the archive, # before the first empty block. while True: self.fileobj.seek(self.offset) try: tarinfo = self.tarinfo.fromtarfile(self) self.members.append(tarinfo) except EOFHeaderError: self.fileobj.seek(self.offset) break except HeaderError as e: raise ReadError(str(e)) if self.mode in "aw": self._loaded = True if self.pax_headers: buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) self.fileobj.write(buf) self.offset += len(buf) except: if not self._extfileobj: self.fileobj.close() self.closed = True raise #-------------------------------------------------------------------------- # Below are the classmethods which act as alternate constructors to the # TarFile class. The open() method is the only one that is needed for # public use; it is the "super"-constructor and is able to select an # adequate "sub"-constructor for a particular compression using the mapping # from OPEN_METH. # # This concept allows one to subclass TarFile without losing the comfort of # the super-constructor. A sub-constructor is registered and made available # by adding it to the mapping in OPEN_METH. @classmethod def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): """Open a tar archive for reading, writing or appending. Return an appropriate TarFile class. mode: 'r' or 'r:*' open for reading with transparent compression 'r:' open for reading exclusively uncompressed 'r:gz' open for reading with gzip compression 'r:bz2' open for reading with bzip2 compression 'a' or 'a:' open for appending, creating the file if necessary 'w' or 'w:' open for writing without compression 'w:gz' open for writing with gzip compression 'w:bz2' open for writing with bzip2 compression 'r|*' open a stream of tar blocks with transparent compression 'r|' open an uncompressed stream of tar blocks for reading 'r|gz' open a gzip compressed stream of tar blocks 'r|bz2' open a bzip2 compressed stream of tar blocks 'w|' open an uncompressed stream for writing 'w|gz' open a gzip compressed stream for writing 'w|bz2' open a bzip2 compressed stream for writing """ if not name and not fileobj: raise ValueError("nothing to open") if mode in ("r", "r:*"): # Find out which *open() is appropriate for opening the file. for comptype in cls.OPEN_METH: func = getattr(cls, cls.OPEN_METH[comptype]) if fileobj is not None: saved_pos = fileobj.tell() try: return func(name, "r", fileobj, **kwargs) except (ReadError, CompressionError) as e: if fileobj is not None: fileobj.seek(saved_pos) continue raise ReadError("file could not be opened successfully") elif ":" in mode: filemode, comptype = mode.split(":", 1) filemode = filemode or "r" comptype = comptype or "tar" # Select the *open() function according to # given compression. if comptype in cls.OPEN_METH: func = getattr(cls, cls.OPEN_METH[comptype]) else: raise CompressionError("unknown compression type %r" % comptype) return func(name, filemode, fileobj, **kwargs) elif "|" in mode: filemode, comptype = mode.split("|", 1) filemode = filemode or "r" comptype = comptype or "tar" if filemode not in "rw": raise ValueError("mode must be 'r' or 'w'") stream = _Stream(name, filemode, comptype, fileobj, bufsize) try: t = cls(name, filemode, stream, **kwargs) except: stream.close() raise t._extfileobj = False return t elif mode in "aw": return cls.taropen(name, mode, fileobj, **kwargs) raise ValueError("undiscernible mode") @classmethod def taropen(cls, name, mode="r", fileobj=None, **kwargs): """Open uncompressed tar archive name for reading or writing. """ if len(mode) > 1 or mode not in "raw": raise ValueError("mode must be 'r', 'a' or 'w'") return cls(name, mode, fileobj, **kwargs) @classmethod def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): """Open gzip compressed tar archive name for reading or writing. Appending is not allowed. """ if len(mode) > 1 or mode not in "rw": raise ValueError("mode must be 'r' or 'w'") try: import gzip gzip.GzipFile except (ImportError, AttributeError): raise CompressionError("gzip module is not available") extfileobj = fileobj is not None try: fileobj = gzip.GzipFile(name, mode + "b", compresslevel, fileobj) t = cls.taropen(name, mode, fileobj, **kwargs) except IOError: if not extfileobj and fileobj is not None: fileobj.close() if fileobj is None: raise raise ReadError("not a gzip file") except: if not extfileobj and fileobj is not None: fileobj.close() raise t._extfileobj = extfileobj return t @classmethod def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): """Open bzip2 compressed tar archive name for reading or writing. Appending is not allowed. """ if len(mode) > 1 or mode not in "rw": raise ValueError("mode must be 'r' or 'w'.") try: import bz2 except ImportError: raise CompressionError("bz2 module is not available") if fileobj is not None: fileobj = _BZ2Proxy(fileobj, mode) else: fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel) try: t = cls.taropen(name, mode, fileobj, **kwargs) except (IOError, EOFError): fileobj.close() raise ReadError("not a bzip2 file") t._extfileobj = False return t # All *open() methods are registered here. OPEN_METH = { "tar": "taropen", # uncompressed tar "gz": "gzopen", # gzip compressed tar "bz2": "bz2open" # bzip2 compressed tar } #-------------------------------------------------------------------------- # The public methods which TarFile provides: def close(self): """Close the TarFile. In write-mode, two finishing zero blocks are appended to the archive. """ if self.closed: return if self.mode in "aw": self.fileobj.write(NUL * (BLOCKSIZE * 2)) self.offset += (BLOCKSIZE * 2) # fill up the end with zero-blocks # (like option -b20 for tar does) blocks, remainder = divmod(self.offset, RECORDSIZE) if remainder > 0: self.fileobj.write(NUL * (RECORDSIZE - remainder)) if not self._extfileobj: self.fileobj.close() self.closed = True def getmember(self, name): """Return a TarInfo object for member `name'. If `name' can not be found in the archive, KeyError is raised. If a member occurs more than once in the archive, its last occurrence is assumed to be the most up-to-date version. """ tarinfo = self._getmember(name) if tarinfo is None: raise KeyError("filename %r not found" % name) return tarinfo def getmembers(self): """Return the members of the archive as a list of TarInfo objects. The list has the same order as the members in the archive. """ self._check() if not self._loaded: # if we want to obtain a list of self._load() # all members, we first have to # scan the whole archive. return self.members def getnames(self): """Return the members of the archive as a list of their names. It has the same order as the list returned by getmembers(). """ return [tarinfo.name for tarinfo in self.getmembers()] def gettarinfo(self, name=None, arcname=None, fileobj=None): """Create a TarInfo object for either the file `name' or the file object `fileobj' (using os.fstat on its file descriptor). You can modify some of the TarInfo's attributes before you add it using addfile(). If given, `arcname' specifies an alternative name for the file in the archive. """ self._check("aw") # When fileobj is given, replace name by # fileobj's real name. if fileobj is not None: name = fileobj.name # Building the name of the member in the archive. # Backward slashes are converted to forward slashes, # Absolute paths are turned to relative paths. if arcname is None: arcname = name drv, arcname = os.path.splitdrive(arcname) arcname = arcname.replace(os.sep, "/") arcname = arcname.lstrip("/") # Now, fill the TarInfo object with # information specific for the file. tarinfo = self.tarinfo() tarinfo.tarfile = self # Use os.stat or os.lstat, depending on platform # and if symlinks shall be resolved. if fileobj is None: if hasattr(os, "lstat") and not self.dereference: statres = os.lstat(name) else: statres = os.stat(name) else: statres = os.fstat(fileobj.fileno()) linkname = "" stmd = statres.st_mode if stat.S_ISREG(stmd): inode = (statres.st_ino, statres.st_dev) if not self.dereference and statres.st_nlink > 1 and \ inode in self.inodes and arcname != self.inodes[inode]: # Is it a hardlink to an already # archived file? type = LNKTYPE linkname = self.inodes[inode] else: # The inode is added only if its valid. # For win32 it is always 0. type = REGTYPE if inode[0]: self.inodes[inode] = arcname elif stat.S_ISDIR(stmd): type = DIRTYPE elif stat.S_ISFIFO(stmd): type = FIFOTYPE elif stat.S_ISLNK(stmd): type = SYMTYPE linkname = os.readlink(name) elif stat.S_ISCHR(stmd): type = CHRTYPE elif stat.S_ISBLK(stmd): type = BLKTYPE else: return None # Fill the TarInfo object with all # information we can get. tarinfo.name = arcname tarinfo.mode = stmd tarinfo.uid = statres.st_uid tarinfo.gid = statres.st_gid if type == REGTYPE: tarinfo.size = statres.st_size else: tarinfo.size = 0 tarinfo.mtime = statres.st_mtime tarinfo.type = type tarinfo.linkname = linkname if pwd: try: tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0] except KeyError: pass if grp: try: tarinfo.gname = grp.getgrgid(tarinfo.gid)[0] except KeyError: pass if type in (CHRTYPE, BLKTYPE): if hasattr(os, "major") and hasattr(os, "minor"): tarinfo.devmajor = os.major(statres.st_rdev) tarinfo.devminor = os.minor(statres.st_rdev) return tarinfo def list(self, verbose=True): """Print a table of contents to sys.stdout. If `verbose' is False, only the names of the members are printed. If it is True, an `ls -l'-like output is produced. """ self._check() for tarinfo in self: if verbose: print(filemode(tarinfo.mode), end=' ') print("%s/%s" % (tarinfo.uname or tarinfo.uid, tarinfo.gname or tarinfo.gid), end=' ') if tarinfo.ischr() or tarinfo.isblk(): print("%10s" % ("%d,%d" \ % (tarinfo.devmajor, tarinfo.devminor)), end=' ') else: print("%10d" % tarinfo.size, end=' ') print("%d-%02d-%02d %02d:%02d:%02d" \ % time.localtime(tarinfo.mtime)[:6], end=' ') print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ') if verbose: if tarinfo.issym(): print("->", tarinfo.linkname, end=' ') if tarinfo.islnk(): print("link to", tarinfo.linkname, end=' ') print() def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): """Add the file `name' to the archive. `name' may be any type of file (directory, fifo, symbolic link, etc.). If given, `arcname' specifies an alternative name for the file in the archive. Directories are added recursively by default. This can be avoided by setting `recursive' to False. `exclude' is a function that should return True for each filename to be excluded. `filter' is a function that expects a TarInfo object argument and returns the changed TarInfo object, if it returns None the TarInfo object will be excluded from the archive. """ self._check("aw") if arcname is None: arcname = name # Exclude pathnames. if exclude is not None: import warnings warnings.warn("use the filter argument instead", DeprecationWarning, 2) if exclude(name): self._dbg(2, "tarfile: Excluded %r" % name) return # Skip if somebody tries to archive the archive... if self.name is not None and os.path.abspath(name) == self.name: self._dbg(2, "tarfile: Skipped %r" % name) return self._dbg(1, name) # Create a TarInfo object from the file. tarinfo = self.gettarinfo(name, arcname) if tarinfo is None: self._dbg(1, "tarfile: Unsupported type %r" % name) return # Change or exclude the TarInfo object. if filter is not None: tarinfo = filter(tarinfo) if tarinfo is None: self._dbg(2, "tarfile: Excluded %r" % name) return # Append the tar header and data to the archive. if tarinfo.isreg(): f = bltn_open(name, "rb") self.addfile(tarinfo, f) f.close() elif tarinfo.isdir(): self.addfile(tarinfo) if recursive: for f in os.listdir(name): self.add(os.path.join(name, f), os.path.join(arcname, f), recursive, exclude, filter=filter) else: self.addfile(tarinfo) def addfile(self, tarinfo, fileobj=None): """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is given, tarinfo.size bytes are read from it and added to the archive. You can create TarInfo objects using gettarinfo(). On Windows platforms, `fileobj' should always be opened with mode 'rb' to avoid irritation about the file size. """ self._check("aw") tarinfo = copy.copy(tarinfo) buf = tarinfo.tobuf(self.format, self.encoding, self.errors) self.fileobj.write(buf) self.offset += len(buf) # If there's data to follow, append it. if fileobj is not None: copyfileobj(fileobj, self.fileobj, tarinfo.size) blocks, remainder = divmod(tarinfo.size, BLOCKSIZE) if remainder > 0: self.fileobj.write(NUL * (BLOCKSIZE - remainder)) blocks += 1 self.offset += blocks * BLOCKSIZE self.members.append(tarinfo) def extractall(self, path=".", members=None): """Extract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. `path' specifies a different directory to extract to. `members' is optional and must be a subset of the list returned by getmembers(). """ directories = [] if members is None: members = self for tarinfo in members: if tarinfo.isdir(): # Extract directories with a safe mode. directories.append(tarinfo) tarinfo = copy.copy(tarinfo) tarinfo.mode = 0o700 # Do not set_attrs directories, as we will do that further down self.extract(tarinfo, path, set_attrs=not tarinfo.isdir()) # Reverse sort directories. directories.sort(key=lambda a: a.name) directories.reverse() # Set correct owner, mtime and filemode on directories. for tarinfo in directories: dirpath = os.path.join(path, tarinfo.name) try: self.chown(tarinfo, dirpath) self.utime(tarinfo, dirpath) self.chmod(tarinfo, dirpath) except ExtractError as e: if self.errorlevel > 1: raise else: self._dbg(1, "tarfile: %s" % e) def extract(self, member, path="", set_attrs=True): """Extract a member from the archive to the current working directory, using its full name. Its file information is extracted as accurately as possible. `member' may be a filename or a TarInfo object. You can specify a different directory using `path'. File attributes (owner, mtime, mode) are set unless `set_attrs' is False. """ self._check("r") if isinstance(member, str): tarinfo = self.getmember(member) else: tarinfo = member # Prepare the link target for makelink(). if tarinfo.islnk(): tarinfo._link_target = os.path.join(path, tarinfo.linkname) try: self._extract_member(tarinfo, os.path.join(path, tarinfo.name), set_attrs=set_attrs) except EnvironmentError as e: if self.errorlevel > 0: raise else: if e.filename is None: self._dbg(1, "tarfile: %s" % e.strerror) else: self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) except ExtractError as e: if self.errorlevel > 1: raise else: self._dbg(1, "tarfile: %s" % e) def extractfile(self, member): """Extract a member from the archive as a file object. `member' may be a filename or a TarInfo object. If `member' is a regular file, a file-like object is returned. If `member' is a link, a file-like object is constructed from the link's target. If `member' is none of the above, None is returned. The file-like object is read-only and provides the following methods: read(), readline(), readlines(), seek() and tell() """ self._check("r") if isinstance(member, str): tarinfo = self.getmember(member) else: tarinfo = member if tarinfo.isreg(): return self.fileobject(self, tarinfo) elif tarinfo.type not in SUPPORTED_TYPES: # If a member's type is unknown, it is treated as a # regular file. return self.fileobject(self, tarinfo) elif tarinfo.islnk() or tarinfo.issym(): if isinstance(self.fileobj, _Stream): # A small but ugly workaround for the case that someone tries # to extract a (sym)link as a file-object from a non-seekable # stream of tar blocks. raise StreamError("cannot extract (sym)link as file object") else: # A (sym)link's file object is its target's file object. return self.extractfile(self._find_link_target(tarinfo)) else: # If there's no data associated with the member (directory, chrdev, # blkdev, etc.), return None instead of a file object. return None def _extract_member(self, tarinfo, targetpath, set_attrs=True): """Extract the TarInfo object tarinfo to a physical file called targetpath. """ # Fetch the TarInfo object for the given name # and build the destination pathname, replacing # forward slashes to platform specific separators. targetpath = targetpath.rstrip("/") targetpath = targetpath.replace("/", os.sep) # Create all upper directories. upperdirs = os.path.dirname(targetpath) if upperdirs and not os.path.exists(upperdirs): # Create directories that are not part of the archive with # default permissions. os.makedirs(upperdirs) if tarinfo.islnk() or tarinfo.issym(): self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) else: self._dbg(1, tarinfo.name) if tarinfo.isreg(): self.makefile(tarinfo, targetpath) elif tarinfo.isdir(): self.makedir(tarinfo, targetpath) elif tarinfo.isfifo(): self.makefifo(tarinfo, targetpath) elif tarinfo.ischr() or tarinfo.isblk(): self.makedev(tarinfo, targetpath) elif tarinfo.islnk() or tarinfo.issym(): self.makelink(tarinfo, targetpath) elif tarinfo.type not in SUPPORTED_TYPES: self.makeunknown(tarinfo, targetpath) else: self.makefile(tarinfo, targetpath) if set_attrs: self.chown(tarinfo, targetpath) if not tarinfo.issym(): self.chmod(tarinfo, targetpath) self.utime(tarinfo, targetpath) #-------------------------------------------------------------------------- # Below are the different file methods. They are called via # _extract_member() when extract() is called. They can be replaced in a # subclass to implement other functionality. def makedir(self, tarinfo, targetpath): """Make a directory called targetpath. """ try: # Use a safe mode for the directory, the real mode is set # later in _extract_member(). os.mkdir(targetpath, 0o700) except EnvironmentError as e: if e.errno != errno.EEXIST: raise def makefile(self, tarinfo, targetpath): """Make a file called targetpath. """ source = self.fileobj source.seek(tarinfo.offset_data) target = bltn_open(targetpath, "wb") if tarinfo.sparse is not None: for offset, size in tarinfo.sparse: target.seek(offset) copyfileobj(source, target, size) else: copyfileobj(source, target, tarinfo.size) target.seek(tarinfo.size) target.truncate() target.close() def makeunknown(self, tarinfo, targetpath): """Make a file from a TarInfo object with an unknown type at targetpath. """ self.makefile(tarinfo, targetpath) self._dbg(1, "tarfile: Unknown file type %r, " \ "extracted as regular file." % tarinfo.type) def makefifo(self, tarinfo, targetpath): """Make a fifo called targetpath. """ if hasattr(os, "mkfifo"): os.mkfifo(targetpath) else: raise ExtractError("fifo not supported by system") def makedev(self, tarinfo, targetpath): """Make a character or block device called targetpath. """ if not hasattr(os, "mknod") or not hasattr(os, "makedev"): raise ExtractError("special devices not supported by system") mode = tarinfo.mode if tarinfo.isblk(): mode |= stat.S_IFBLK else: mode |= stat.S_IFCHR os.mknod(targetpath, mode, os.makedev(tarinfo.devmajor, tarinfo.devminor)) def makelink(self, tarinfo, targetpath): """Make a (symbolic) link called targetpath. If it cannot be created (platform limitation), we try to make a copy of the referenced file instead of a link. """ try: # For systems that support symbolic and hard links. if tarinfo.issym(): os.symlink(tarinfo.linkname, targetpath) else: # See extract(). if os.path.exists(tarinfo._link_target): os.link(tarinfo._link_target, targetpath) else: self._extract_member(self._find_link_target(tarinfo), targetpath) except symlink_exception: if tarinfo.issym(): linkpath = os.path.join(os.path.dirname(tarinfo.name), tarinfo.linkname) else: linkpath = tarinfo.linkname else: try: self._extract_member(self._find_link_target(tarinfo), targetpath) except KeyError: raise ExtractError("unable to resolve link inside archive") def chown(self, tarinfo, targetpath): """Set owner of targetpath according to tarinfo. """ if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: # We have to be root to do so. try: g = grp.getgrnam(tarinfo.gname)[2] except KeyError: g = tarinfo.gid try: u = pwd.getpwnam(tarinfo.uname)[2] except KeyError: u = tarinfo.uid try: if tarinfo.issym() and hasattr(os, "lchown"): os.lchown(targetpath, u, g) else: if sys.platform != "os2emx": os.chown(targetpath, u, g) except EnvironmentError as e: raise ExtractError("could not change owner") def chmod(self, tarinfo, targetpath): """Set file permissions of targetpath according to tarinfo. """ if hasattr(os, 'chmod'): try: os.chmod(targetpath, tarinfo.mode) except EnvironmentError as e: raise ExtractError("could not change mode") def utime(self, tarinfo, targetpath): """Set modification time of targetpath according to tarinfo. """ if not hasattr(os, 'utime'): return try: os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) except EnvironmentError as e: raise ExtractError("could not change modification time") #-------------------------------------------------------------------------- def next(self): """Return the next member of the archive as a TarInfo object, when TarFile is opened for reading. Return None if there is no more available. """ self._check("ra") if self.firstmember is not None: m = self.firstmember self.firstmember = None return m # Read the next block. self.fileobj.seek(self.offset) tarinfo = None while True: try: tarinfo = self.tarinfo.fromtarfile(self) except EOFHeaderError as e: if self.ignore_zeros: self._dbg(2, "0x%X: %s" % (self.offset, e)) self.offset += BLOCKSIZE continue except InvalidHeaderError as e: if self.ignore_zeros: self._dbg(2, "0x%X: %s" % (self.offset, e)) self.offset += BLOCKSIZE continue elif self.offset == 0: raise ReadError(str(e)) except EmptyHeaderError: if self.offset == 0: raise ReadError("empty file") except TruncatedHeaderError as e: if self.offset == 0: raise ReadError(str(e)) except SubsequentHeaderError as e: raise ReadError(str(e)) break if tarinfo is not None: self.members.append(tarinfo) else: self._loaded = True return tarinfo #-------------------------------------------------------------------------- # Little helper methods: def _getmember(self, name, tarinfo=None, normalize=False): """Find an archive member by name from bottom to top. If tarinfo is given, it is used as the starting point. """ # Ensure that all members have been loaded. members = self.getmembers() # Limit the member search list up to tarinfo. if tarinfo is not None: members = members[:members.index(tarinfo)] if normalize: name = os.path.normpath(name) for member in reversed(members): if normalize: member_name = os.path.normpath(member.name) else: member_name = member.name if name == member_name: return member def _load(self): """Read through the entire archive file and look for readable members. """ while True: tarinfo = self.next() if tarinfo is None: break self._loaded = True def _check(self, mode=None): """Check if TarFile is still open, and if the operation's mode corresponds to TarFile's mode. """ if self.closed: raise IOError("%s is closed" % self.__class__.__name__) if mode is not None and self.mode not in mode: raise IOError("bad operation for mode %r" % self.mode) def _find_link_target(self, tarinfo): """Find the target member of a symlink or hardlink member in the archive. """ if tarinfo.issym(): # Always search the entire archive. linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname limit = None else: # Search the archive before the link, because a hard link is # just a reference to an already archived file. linkname = tarinfo.linkname limit = tarinfo member = self._getmember(linkname, tarinfo=limit, normalize=True) if member is None: raise KeyError("linkname %r not found" % linkname) return member def __iter__(self): """Provide an iterator object. """ if self._loaded: return iter(self.members) else: return TarIter(self) def _dbg(self, level, msg): """Write debugging output to sys.stderr. """ if level <= self.debug: print(msg, file=sys.stderr) def __enter__(self): self._check() return self def __exit__(self, type, value, traceback): if type is None: self.close() else: # An exception occurred. We must not call close() because # it would try to write end-of-archive blocks and padding. if not self._extfileobj: self.fileobj.close() self.closed = True # class TarFile class TarIter(object): """Iterator Class. for tarinfo in TarFile(...): suite... """ def __init__(self, tarfile): """Construct a TarIter object. """ self.tarfile = tarfile self.index = 0 def __iter__(self): """Return iterator object. """ return self def __next__(self): """Return the next item using TarFile's next() method. When all members have been read, set TarFile as _loaded. """ # Fix for SF #1100429: Under rare circumstances it can # happen that getmembers() is called during iteration, # which will cause TarIter to stop prematurely. if not self.tarfile._loaded: tarinfo = self.tarfile.next() if not tarinfo: self.tarfile._loaded = True raise StopIteration else: try: tarinfo = self.tarfile.members[self.index] except IndexError: raise StopIteration self.index += 1 return tarinfo next = __next__ # for Python 2.x #-------------------- # exported functions #-------------------- def is_tarfile(name): """Return True if name points to a tar archive that we are able to handle, else return False. """ try: t = open(name) t.close() return True except TarError: return False bltn_open = open open = TarFile.open PKH]#gBpython3.10/site-packages/pip/_vendor/distlib/_backport/__init__.pynu["""Modules copied from Python 3 standard libraries, for internal use only. Individual classes and functions are found in d2._backport.misc. Intended usage is to always import things missing from 3.1 from that module: the built-in/stdlib objects will be used if found. """ PKH]m4python3.10/site-packages/pip/_vendor/distlib/util.pynu[# # Copyright (C) 2012-2021 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # import codecs from collections import deque import contextlib import csv from glob import iglob as std_iglob import io import json import logging import os import py_compile import re import socket try: import ssl except ImportError: # pragma: no cover ssl = None import subprocess import sys import tarfile import tempfile import textwrap try: import threading except ImportError: # pragma: no cover import dummy_threading as threading import time from . import DistlibException from .compat import (string_types, text_type, shutil, raw_input, StringIO, cache_from_source, urlopen, urljoin, httplib, xmlrpclib, splittype, HTTPHandler, BaseConfigurator, valid_ident, Container, configparser, URLError, ZipFile, fsdecode, unquote, urlparse) logger = logging.getLogger(__name__) # # Requirement parsing code as per PEP 508 # IDENTIFIER = re.compile(r'^([\w\.-]+)\s*') VERSION_IDENTIFIER = re.compile(r'^([\w\.*+-]+)\s*') COMPARE_OP = re.compile(r'^(<=?|>=?|={2,3}|[~!]=)\s*') MARKER_OP = re.compile(r'^((<=?)|(>=?)|={2,3}|[~!]=|in|not\s+in)\s*') OR = re.compile(r'^or\b\s*') AND = re.compile(r'^and\b\s*') NON_SPACE = re.compile(r'(\S+)\s*') STRING_CHUNK = re.compile(r'([\s\w\.{}()*+#:;,/?!~`@$%^&=|<>\[\]-]+)') def parse_marker(marker_string): """ Parse a marker string and return a dictionary containing a marker expression. The dictionary will contain keys "op", "lhs" and "rhs" for non-terminals in the expression grammar, or strings. A string contained in quotes is to be interpreted as a literal string, and a string not contained in quotes is a variable (such as os_name). """ def marker_var(remaining): # either identifier, or literal string m = IDENTIFIER.match(remaining) if m: result = m.groups()[0] remaining = remaining[m.end():] elif not remaining: raise SyntaxError('unexpected end of input') else: q = remaining[0] if q not in '\'"': raise SyntaxError('invalid expression: %s' % remaining) oq = '\'"'.replace(q, '') remaining = remaining[1:] parts = [q] while remaining: # either a string chunk, or oq, or q to terminate if remaining[0] == q: break elif remaining[0] == oq: parts.append(oq) remaining = remaining[1:] else: m = STRING_CHUNK.match(remaining) if not m: raise SyntaxError('error in string literal: %s' % remaining) parts.append(m.groups()[0]) remaining = remaining[m.end():] else: s = ''.join(parts) raise SyntaxError('unterminated string: %s' % s) parts.append(q) result = ''.join(parts) remaining = remaining[1:].lstrip() # skip past closing quote return result, remaining def marker_expr(remaining): if remaining and remaining[0] == '(': result, remaining = marker(remaining[1:].lstrip()) if remaining[0] != ')': raise SyntaxError('unterminated parenthesis: %s' % remaining) remaining = remaining[1:].lstrip() else: lhs, remaining = marker_var(remaining) while remaining: m = MARKER_OP.match(remaining) if not m: break op = m.groups()[0] remaining = remaining[m.end():] rhs, remaining = marker_var(remaining) lhs = {'op': op, 'lhs': lhs, 'rhs': rhs} result = lhs return result, remaining def marker_and(remaining): lhs, remaining = marker_expr(remaining) while remaining: m = AND.match(remaining) if not m: break remaining = remaining[m.end():] rhs, remaining = marker_expr(remaining) lhs = {'op': 'and', 'lhs': lhs, 'rhs': rhs} return lhs, remaining def marker(remaining): lhs, remaining = marker_and(remaining) while remaining: m = OR.match(remaining) if not m: break remaining = remaining[m.end():] rhs, remaining = marker_and(remaining) lhs = {'op': 'or', 'lhs': lhs, 'rhs': rhs} return lhs, remaining return marker(marker_string) def parse_requirement(req): """ Parse a requirement passed in as a string. Return a Container whose attributes contain the various parts of the requirement. """ remaining = req.strip() if not remaining or remaining.startswith('#'): return None m = IDENTIFIER.match(remaining) if not m: raise SyntaxError('name expected: %s' % remaining) distname = m.groups()[0] remaining = remaining[m.end():] extras = mark_expr = versions = uri = None if remaining and remaining[0] == '[': i = remaining.find(']', 1) if i < 0: raise SyntaxError('unterminated extra: %s' % remaining) s = remaining[1:i] remaining = remaining[i + 1:].lstrip() extras = [] while s: m = IDENTIFIER.match(s) if not m: raise SyntaxError('malformed extra: %s' % s) extras.append(m.groups()[0]) s = s[m.end():] if not s: break if s[0] != ',': raise SyntaxError('comma expected in extras: %s' % s) s = s[1:].lstrip() if not extras: extras = None if remaining: if remaining[0] == '@': # it's a URI remaining = remaining[1:].lstrip() m = NON_SPACE.match(remaining) if not m: raise SyntaxError('invalid URI: %s' % remaining) uri = m.groups()[0] t = urlparse(uri) # there are issues with Python and URL parsing, so this test # is a bit crude. See bpo-20271, bpo-23505. Python doesn't # always parse invalid URLs correctly - it should raise # exceptions for malformed URLs if not (t.scheme and t.netloc): raise SyntaxError('Invalid URL: %s' % uri) remaining = remaining[m.end():].lstrip() else: def get_versions(ver_remaining): """ Return a list of operator, version tuples if any are specified, else None. """ m = COMPARE_OP.match(ver_remaining) versions = None if m: versions = [] while True: op = m.groups()[0] ver_remaining = ver_remaining[m.end():] m = VERSION_IDENTIFIER.match(ver_remaining) if not m: raise SyntaxError('invalid version: %s' % ver_remaining) v = m.groups()[0] versions.append((op, v)) ver_remaining = ver_remaining[m.end():] if not ver_remaining or ver_remaining[0] != ',': break ver_remaining = ver_remaining[1:].lstrip() # Some packages have a trailing comma which would break things # See issue #148 if not ver_remaining: break m = COMPARE_OP.match(ver_remaining) if not m: raise SyntaxError('invalid constraint: %s' % ver_remaining) if not versions: versions = None return versions, ver_remaining if remaining[0] != '(': versions, remaining = get_versions(remaining) else: i = remaining.find(')', 1) if i < 0: raise SyntaxError('unterminated parenthesis: %s' % remaining) s = remaining[1:i] remaining = remaining[i + 1:].lstrip() # As a special diversion from PEP 508, allow a version number # a.b.c in parentheses as a synonym for ~= a.b.c (because this # is allowed in earlier PEPs) if COMPARE_OP.match(s): versions, _ = get_versions(s) else: m = VERSION_IDENTIFIER.match(s) if not m: raise SyntaxError('invalid constraint: %s' % s) v = m.groups()[0] s = s[m.end():].lstrip() if s: raise SyntaxError('invalid constraint: %s' % s) versions = [('~=', v)] if remaining: if remaining[0] != ';': raise SyntaxError('invalid requirement: %s' % remaining) remaining = remaining[1:].lstrip() mark_expr, remaining = parse_marker(remaining) if remaining and remaining[0] != '#': raise SyntaxError('unexpected trailing data: %s' % remaining) if not versions: rs = distname else: rs = '%s %s' % (distname, ', '.join(['%s %s' % con for con in versions])) return Container(name=distname, extras=extras, constraints=versions, marker=mark_expr, url=uri, requirement=rs) def get_resources_dests(resources_root, rules): """Find destinations for resources files""" def get_rel_path(root, path): # normalizes and returns a lstripped-/-separated path root = root.replace(os.path.sep, '/') path = path.replace(os.path.sep, '/') assert path.startswith(root) return path[len(root):].lstrip('/') destinations = {} for base, suffix, dest in rules: prefix = os.path.join(resources_root, base) for abs_base in iglob(prefix): abs_glob = os.path.join(abs_base, suffix) for abs_path in iglob(abs_glob): resource_file = get_rel_path(resources_root, abs_path) if dest is None: # remove the entry if it was here destinations.pop(resource_file, None) else: rel_path = get_rel_path(abs_base, abs_path) rel_dest = dest.replace(os.path.sep, '/').rstrip('/') destinations[resource_file] = rel_dest + '/' + rel_path return destinations def in_venv(): if hasattr(sys, 'real_prefix'): # virtualenv venvs result = True else: # PEP 405 venvs result = sys.prefix != getattr(sys, 'base_prefix', sys.prefix) return result def get_executable(): # The __PYVENV_LAUNCHER__ dance is apparently no longer needed, as # changes to the stub launcher mean that sys.executable always points # to the stub on OS X # if sys.platform == 'darwin' and ('__PYVENV_LAUNCHER__' # in os.environ): # result = os.environ['__PYVENV_LAUNCHER__'] # else: # result = sys.executable # return result # Avoid normcasing: see issue #143 # result = os.path.normcase(sys.executable) result = sys.executable if not isinstance(result, text_type): result = fsdecode(result) return result def proceed(prompt, allowed_chars, error_prompt=None, default=None): p = prompt while True: s = raw_input(p) p = prompt if not s and default: s = default if s: c = s[0].lower() if c in allowed_chars: break if error_prompt: p = '%c: %s\n%s' % (c, error_prompt, prompt) return c def extract_by_key(d, keys): if isinstance(keys, string_types): keys = keys.split() result = {} for key in keys: if key in d: result[key] = d[key] return result def read_exports(stream): if sys.version_info[0] >= 3: # needs to be a text stream stream = codecs.getreader('utf-8')(stream) # Try to load as JSON, falling back on legacy format data = stream.read() stream = StringIO(data) try: jdata = json.load(stream) result = jdata['extensions']['python.exports']['exports'] for group, entries in result.items(): for k, v in entries.items(): s = '%s = %s' % (k, v) entry = get_export_entry(s) assert entry is not None entries[k] = entry return result except Exception: stream.seek(0, 0) def read_stream(cp, stream): if hasattr(cp, 'read_file'): cp.read_file(stream) else: cp.readfp(stream) cp = configparser.ConfigParser() try: read_stream(cp, stream) except configparser.MissingSectionHeaderError: stream.close() data = textwrap.dedent(data) stream = StringIO(data) read_stream(cp, stream) result = {} for key in cp.sections(): result[key] = entries = {} for name, value in cp.items(key): s = '%s = %s' % (name, value) entry = get_export_entry(s) assert entry is not None #entry.dist = self entries[name] = entry return result def write_exports(exports, stream): if sys.version_info[0] >= 3: # needs to be a text stream stream = codecs.getwriter('utf-8')(stream) cp = configparser.ConfigParser() for k, v in exports.items(): # TODO check k, v for valid values cp.add_section(k) for entry in v.values(): if entry.suffix is None: s = entry.prefix else: s = '%s:%s' % (entry.prefix, entry.suffix) if entry.flags: s = '%s [%s]' % (s, ', '.join(entry.flags)) cp.set(k, entry.name, s) cp.write(stream) @contextlib.contextmanager def tempdir(): td = tempfile.mkdtemp() try: yield td finally: shutil.rmtree(td) @contextlib.contextmanager def chdir(d): cwd = os.getcwd() try: os.chdir(d) yield finally: os.chdir(cwd) @contextlib.contextmanager def socket_timeout(seconds=15): cto = socket.getdefaulttimeout() try: socket.setdefaulttimeout(seconds) yield finally: socket.setdefaulttimeout(cto) class cached_property(object): def __init__(self, func): self.func = func #for attr in ('__name__', '__module__', '__doc__'): # setattr(self, attr, getattr(func, attr, None)) def __get__(self, obj, cls=None): if obj is None: return self value = self.func(obj) object.__setattr__(obj, self.func.__name__, value) #obj.__dict__[self.func.__name__] = value = self.func(obj) return value def convert_path(pathname): """Return 'pathname' as a name that will work on the native filesystem. The path is split on '/' and put back together again using the current directory separator. Needed because filenames in the setup script are always supplied in Unix style, and have to be converted to the local convention before we can actually use them in the filesystem. Raises ValueError on non-Unix-ish systems if 'pathname' either starts or ends with a slash. """ if os.sep == '/': return pathname if not pathname: return pathname if pathname[0] == '/': raise ValueError("path '%s' cannot be absolute" % pathname) if pathname[-1] == '/': raise ValueError("path '%s' cannot end with '/'" % pathname) paths = pathname.split('/') while os.curdir in paths: paths.remove(os.curdir) if not paths: return os.curdir return os.path.join(*paths) class FileOperator(object): def __init__(self, dry_run=False): self.dry_run = dry_run self.ensured = set() self._init_record() def _init_record(self): self.record = False self.files_written = set() self.dirs_created = set() def record_as_written(self, path): if self.record: self.files_written.add(path) def newer(self, source, target): """Tell if the target is newer than the source. Returns true if 'source' exists and is more recently modified than 'target', or if 'source' exists and 'target' doesn't. Returns false if both exist and 'target' is the same age or younger than 'source'. Raise PackagingFileError if 'source' does not exist. Note that this test is not very accurate: files created in the same second will have the same "age". """ if not os.path.exists(source): raise DistlibException("file '%r' does not exist" % os.path.abspath(source)) if not os.path.exists(target): return True return os.stat(source).st_mtime > os.stat(target).st_mtime def copy_file(self, infile, outfile, check=True): """Copy a file respecting dry-run and force flags. """ self.ensure_dir(os.path.dirname(outfile)) logger.info('Copying %s to %s', infile, outfile) if not self.dry_run: msg = None if check: if os.path.islink(outfile): msg = '%s is a symlink' % outfile elif os.path.exists(outfile) and not os.path.isfile(outfile): msg = '%s is a non-regular file' % outfile if msg: raise ValueError(msg + ' which would be overwritten') shutil.copyfile(infile, outfile) self.record_as_written(outfile) def copy_stream(self, instream, outfile, encoding=None): assert not os.path.isdir(outfile) self.ensure_dir(os.path.dirname(outfile)) logger.info('Copying stream %s to %s', instream, outfile) if not self.dry_run: if encoding is None: outstream = open(outfile, 'wb') else: outstream = codecs.open(outfile, 'w', encoding=encoding) try: shutil.copyfileobj(instream, outstream) finally: outstream.close() self.record_as_written(outfile) def write_binary_file(self, path, data): self.ensure_dir(os.path.dirname(path)) if not self.dry_run: if os.path.exists(path): os.remove(path) with open(path, 'wb') as f: f.write(data) self.record_as_written(path) def write_text_file(self, path, data, encoding): self.write_binary_file(path, data.encode(encoding)) def set_mode(self, bits, mask, files): if os.name == 'posix' or (os.name == 'java' and os._name == 'posix'): # Set the executable bits (owner, group, and world) on # all the files specified. for f in files: if self.dry_run: logger.info("changing mode of %s", f) else: mode = (os.stat(f).st_mode | bits) & mask logger.info("changing mode of %s to %o", f, mode) os.chmod(f, mode) set_executable_mode = lambda s, f: s.set_mode(0o555, 0o7777, f) def ensure_dir(self, path): path = os.path.abspath(path) if path not in self.ensured and not os.path.exists(path): self.ensured.add(path) d, f = os.path.split(path) self.ensure_dir(d) logger.info('Creating %s' % path) if not self.dry_run: os.mkdir(path) if self.record: self.dirs_created.add(path) def byte_compile(self, path, optimize=False, force=False, prefix=None, hashed_invalidation=False): dpath = cache_from_source(path, not optimize) logger.info('Byte-compiling %s to %s', path, dpath) if not self.dry_run: if force or self.newer(path, dpath): if not prefix: diagpath = None else: assert path.startswith(prefix) diagpath = path[len(prefix):] compile_kwargs = {} if hashed_invalidation and hasattr(py_compile, 'PycInvalidationMode'): compile_kwargs['invalidation_mode'] = py_compile.PycInvalidationMode.CHECKED_HASH py_compile.compile(path, dpath, diagpath, True, **compile_kwargs) # raise error self.record_as_written(dpath) return dpath def ensure_removed(self, path): if os.path.exists(path): if os.path.isdir(path) and not os.path.islink(path): logger.debug('Removing directory tree at %s', path) if not self.dry_run: shutil.rmtree(path) if self.record: if path in self.dirs_created: self.dirs_created.remove(path) else: if os.path.islink(path): s = 'link' else: s = 'file' logger.debug('Removing %s %s', s, path) if not self.dry_run: os.remove(path) if self.record: if path in self.files_written: self.files_written.remove(path) def is_writable(self, path): result = False while not result: if os.path.exists(path): result = os.access(path, os.W_OK) break parent = os.path.dirname(path) if parent == path: break path = parent return result def commit(self): """ Commit recorded changes, turn off recording, return changes. """ assert self.record result = self.files_written, self.dirs_created self._init_record() return result def rollback(self): if not self.dry_run: for f in list(self.files_written): if os.path.exists(f): os.remove(f) # dirs should all be empty now, except perhaps for # __pycache__ subdirs # reverse so that subdirs appear before their parents dirs = sorted(self.dirs_created, reverse=True) for d in dirs: flist = os.listdir(d) if flist: assert flist == ['__pycache__'] sd = os.path.join(d, flist[0]) os.rmdir(sd) os.rmdir(d) # should fail if non-empty self._init_record() def resolve(module_name, dotted_path): if module_name in sys.modules: mod = sys.modules[module_name] else: mod = __import__(module_name) if dotted_path is None: result = mod else: parts = dotted_path.split('.') result = getattr(mod, parts.pop(0)) for p in parts: result = getattr(result, p) return result class ExportEntry(object): def __init__(self, name, prefix, suffix, flags): self.name = name self.prefix = prefix self.suffix = suffix self.flags = flags @cached_property def value(self): return resolve(self.prefix, self.suffix) def __repr__(self): # pragma: no cover return '' % (self.name, self.prefix, self.suffix, self.flags) def __eq__(self, other): if not isinstance(other, ExportEntry): result = False else: result = (self.name == other.name and self.prefix == other.prefix and self.suffix == other.suffix and self.flags == other.flags) return result __hash__ = object.__hash__ ENTRY_RE = re.compile(r'''(?P(\w|[-.+])+) \s*=\s*(?P(\w+)([:\.]\w+)*) \s*(\[\s*(?P[\w-]+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])? ''', re.VERBOSE) def get_export_entry(specification): m = ENTRY_RE.search(specification) if not m: result = None if '[' in specification or ']' in specification: raise DistlibException("Invalid specification " "'%s'" % specification) else: d = m.groupdict() name = d['name'] path = d['callable'] colons = path.count(':') if colons == 0: prefix, suffix = path, None else: if colons != 1: raise DistlibException("Invalid specification " "'%s'" % specification) prefix, suffix = path.split(':') flags = d['flags'] if flags is None: if '[' in specification or ']' in specification: raise DistlibException("Invalid specification " "'%s'" % specification) flags = [] else: flags = [f.strip() for f in flags.split(',')] result = ExportEntry(name, prefix, suffix, flags) return result def get_cache_base(suffix=None): """ Return the default base location for distlib caches. If the directory does not exist, it is created. Use the suffix provided for the base directory, and default to '.distlib' if it isn't provided. On Windows, if LOCALAPPDATA is defined in the environment, then it is assumed to be a directory, and will be the parent directory of the result. On POSIX, and on Windows if LOCALAPPDATA is not defined, the user's home directory - using os.expanduser('~') - will be the parent directory of the result. The result is just the directory '.distlib' in the parent directory as determined above, or with the name specified with ``suffix``. """ if suffix is None: suffix = '.distlib' if os.name == 'nt' and 'LOCALAPPDATA' in os.environ: result = os.path.expandvars('$localappdata') else: # Assume posix, or old Windows result = os.path.expanduser('~') # we use 'isdir' instead of 'exists', because we want to # fail if there's a file with that name if os.path.isdir(result): usable = os.access(result, os.W_OK) if not usable: logger.warning('Directory exists but is not writable: %s', result) else: try: os.makedirs(result) usable = True except OSError: logger.warning('Unable to create %s', result, exc_info=True) usable = False if not usable: result = tempfile.mkdtemp() logger.warning('Default location unusable, using %s', result) return os.path.join(result, suffix) def path_to_cache_dir(path): """ Convert an absolute path to a directory name for use in a cache. The algorithm used is: #. On Windows, any ``':'`` in the drive is replaced with ``'---'``. #. Any occurrence of ``os.sep`` is replaced with ``'--'``. #. ``'.cache'`` is appended. """ d, p = os.path.splitdrive(os.path.abspath(path)) if d: d = d.replace(':', '---') p = p.replace(os.sep, '--') return d + p + '.cache' def ensure_slash(s): if not s.endswith('/'): return s + '/' return s def parse_credentials(netloc): username = password = None if '@' in netloc: prefix, netloc = netloc.rsplit('@', 1) if ':' not in prefix: username = prefix else: username, password = prefix.split(':', 1) if username: username = unquote(username) if password: password = unquote(password) return username, password, netloc def get_process_umask(): result = os.umask(0o22) os.umask(result) return result def is_string_sequence(seq): result = True i = None for i, s in enumerate(seq): if not isinstance(s, string_types): result = False break assert i is not None return result PROJECT_NAME_AND_VERSION = re.compile('([a-z0-9_]+([.-][a-z_][a-z0-9_]*)*)-' '([a-z0-9_.+-]+)', re.I) PYTHON_VERSION = re.compile(r'-py(\d\.?\d?)') def split_filename(filename, project_name=None): """ Extract name, version, python version from a filename (no extension) Return name, version, pyver or None """ result = None pyver = None filename = unquote(filename).replace(' ', '-') m = PYTHON_VERSION.search(filename) if m: pyver = m.group(1) filename = filename[:m.start()] if project_name and len(filename) > len(project_name) + 1: m = re.match(re.escape(project_name) + r'\b', filename) if m: n = m.end() result = filename[:n], filename[n + 1:], pyver if result is None: m = PROJECT_NAME_AND_VERSION.match(filename) if m: result = m.group(1), m.group(3), pyver return result # Allow spaces in name because of legacy dists like "Twisted Core" NAME_VERSION_RE = re.compile(r'(?P[\w .-]+)\s*' r'\(\s*(?P[^\s)]+)\)$') def parse_name_and_version(p): """ A utility method used to get name and version from a string. From e.g. a Provides-Dist value. :param p: A value in a form 'foo (1.0)' :return: The name and version as a tuple. """ m = NAME_VERSION_RE.match(p) if not m: raise DistlibException('Ill-formed name/version string: \'%s\'' % p) d = m.groupdict() return d['name'].strip().lower(), d['ver'] def get_extras(requested, available): result = set() requested = set(requested or []) available = set(available or []) if '*' in requested: requested.remove('*') result |= available for r in requested: if r == '-': result.add(r) elif r.startswith('-'): unwanted = r[1:] if unwanted not in available: logger.warning('undeclared extra: %s' % unwanted) if unwanted in result: result.remove(unwanted) else: if r not in available: logger.warning('undeclared extra: %s' % r) result.add(r) return result # # Extended metadata functionality # def _get_external_data(url): result = {} try: # urlopen might fail if it runs into redirections, # because of Python issue #13696. Fixed in locators # using a custom redirect handler. resp = urlopen(url) headers = resp.info() ct = headers.get('Content-Type') if not ct.startswith('application/json'): logger.debug('Unexpected response for JSON request: %s', ct) else: reader = codecs.getreader('utf-8')(resp) #data = reader.read().decode('utf-8') #result = json.loads(data) result = json.load(reader) except Exception as e: logger.exception('Failed to get external data for %s: %s', url, e) return result _external_data_base_url = 'https://www.red-dove.com/pypi/projects/' def get_project_data(name): url = '%s/%s/project.json' % (name[0].upper(), name) url = urljoin(_external_data_base_url, url) result = _get_external_data(url) return result def get_package_data(name, version): url = '%s/%s/package-%s.json' % (name[0].upper(), name, version) url = urljoin(_external_data_base_url, url) return _get_external_data(url) class Cache(object): """ A class implementing a cache for resources that need to live in the file system e.g. shared libraries. This class was moved from resources to here because it could be used by other modules, e.g. the wheel module. """ def __init__(self, base): """ Initialise an instance. :param base: The base directory where the cache should be located. """ # we use 'isdir' instead of 'exists', because we want to # fail if there's a file with that name if not os.path.isdir(base): # pragma: no cover os.makedirs(base) if (os.stat(base).st_mode & 0o77) != 0: logger.warning('Directory \'%s\' is not private', base) self.base = os.path.abspath(os.path.normpath(base)) def prefix_to_dir(self, prefix): """ Converts a resource prefix to a directory name in the cache. """ return path_to_cache_dir(prefix) def clear(self): """ Clear the cache. """ not_removed = [] for fn in os.listdir(self.base): fn = os.path.join(self.base, fn) try: if os.path.islink(fn) or os.path.isfile(fn): os.remove(fn) elif os.path.isdir(fn): shutil.rmtree(fn) except Exception: not_removed.append(fn) return not_removed class EventMixin(object): """ A very simple publish/subscribe system. """ def __init__(self): self._subscribers = {} def add(self, event, subscriber, append=True): """ Add a subscriber for an event. :param event: The name of an event. :param subscriber: The subscriber to be added (and called when the event is published). :param append: Whether to append or prepend the subscriber to an existing subscriber list for the event. """ subs = self._subscribers if event not in subs: subs[event] = deque([subscriber]) else: sq = subs[event] if append: sq.append(subscriber) else: sq.appendleft(subscriber) def remove(self, event, subscriber): """ Remove a subscriber for an event. :param event: The name of an event. :param subscriber: The subscriber to be removed. """ subs = self._subscribers if event not in subs: raise ValueError('No subscribers: %r' % event) subs[event].remove(subscriber) def get_subscribers(self, event): """ Return an iterator for the subscribers for an event. :param event: The event to return subscribers for. """ return iter(self._subscribers.get(event, ())) def publish(self, event, *args, **kwargs): """ Publish a event and return a list of values returned by its subscribers. :param event: The event to publish. :param args: The positional arguments to pass to the event's subscribers. :param kwargs: The keyword arguments to pass to the event's subscribers. """ result = [] for subscriber in self.get_subscribers(event): try: value = subscriber(event, *args, **kwargs) except Exception: logger.exception('Exception during event publication') value = None result.append(value) logger.debug('publish %s: args = %s, kwargs = %s, result = %s', event, args, kwargs, result) return result # # Simple sequencing # class Sequencer(object): def __init__(self): self._preds = {} self._succs = {} self._nodes = set() # nodes with no preds/succs def add_node(self, node): self._nodes.add(node) def remove_node(self, node, edges=False): if node in self._nodes: self._nodes.remove(node) if edges: for p in set(self._preds.get(node, ())): self.remove(p, node) for s in set(self._succs.get(node, ())): self.remove(node, s) # Remove empties for k, v in list(self._preds.items()): if not v: del self._preds[k] for k, v in list(self._succs.items()): if not v: del self._succs[k] def add(self, pred, succ): assert pred != succ self._preds.setdefault(succ, set()).add(pred) self._succs.setdefault(pred, set()).add(succ) def remove(self, pred, succ): assert pred != succ try: preds = self._preds[succ] succs = self._succs[pred] except KeyError: # pragma: no cover raise ValueError('%r not a successor of anything' % succ) try: preds.remove(pred) succs.remove(succ) except KeyError: # pragma: no cover raise ValueError('%r not a successor of %r' % (succ, pred)) def is_step(self, step): return (step in self._preds or step in self._succs or step in self._nodes) def get_steps(self, final): if not self.is_step(final): raise ValueError('Unknown: %r' % final) result = [] todo = [] seen = set() todo.append(final) while todo: step = todo.pop(0) if step in seen: # if a step was already seen, # move it to the end (so it will appear earlier # when reversed on return) ... but not for the # final step, as that would be confusing for # users if step != final: result.remove(step) result.append(step) else: seen.add(step) result.append(step) preds = self._preds.get(step, ()) todo.extend(preds) return reversed(result) @property def strong_connections(self): #http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm index_counter = [0] stack = [] lowlinks = {} index = {} result = [] graph = self._succs def strongconnect(node): # set the depth index for this node to the smallest unused index index[node] = index_counter[0] lowlinks[node] = index_counter[0] index_counter[0] += 1 stack.append(node) # Consider successors try: successors = graph[node] except Exception: successors = [] for successor in successors: if successor not in lowlinks: # Successor has not yet been visited strongconnect(successor) lowlinks[node] = min(lowlinks[node],lowlinks[successor]) elif successor in stack: # the successor is in the stack and hence in the current # strongly connected component (SCC) lowlinks[node] = min(lowlinks[node],index[successor]) # If `node` is a root node, pop the stack and generate an SCC if lowlinks[node] == index[node]: connected_component = [] while True: successor = stack.pop() connected_component.append(successor) if successor == node: break component = tuple(connected_component) # storing the result result.append(component) for node in graph: if node not in lowlinks: strongconnect(node) return result @property def dot(self): result = ['digraph G {'] for succ in self._preds: preds = self._preds[succ] for pred in preds: result.append(' %s -> %s;' % (pred, succ)) for node in self._nodes: result.append(' %s;' % node) result.append('}') return '\n'.join(result) # # Unarchiving functionality for zip, tar, tgz, tbz, whl # ARCHIVE_EXTENSIONS = ('.tar.gz', '.tar.bz2', '.tar', '.zip', '.tgz', '.tbz', '.whl') def unarchive(archive_filename, dest_dir, format=None, check=True): def check_path(path): if not isinstance(path, text_type): path = path.decode('utf-8') p = os.path.abspath(os.path.join(dest_dir, path)) if not p.startswith(dest_dir) or p[plen] != os.sep: raise ValueError('path outside destination: %r' % p) dest_dir = os.path.abspath(dest_dir) plen = len(dest_dir) archive = None if format is None: if archive_filename.endswith(('.zip', '.whl')): format = 'zip' elif archive_filename.endswith(('.tar.gz', '.tgz')): format = 'tgz' mode = 'r:gz' elif archive_filename.endswith(('.tar.bz2', '.tbz')): format = 'tbz' mode = 'r:bz2' elif archive_filename.endswith('.tar'): format = 'tar' mode = 'r' else: # pragma: no cover raise ValueError('Unknown format for %r' % archive_filename) try: if format == 'zip': archive = ZipFile(archive_filename, 'r') if check: names = archive.namelist() for name in names: check_path(name) else: archive = tarfile.open(archive_filename, mode) if check: names = archive.getnames() for name in names: check_path(name) if format != 'zip' and sys.version_info[0] < 3: # See Python issue 17153. If the dest path contains Unicode, # tarfile extraction fails on Python 2.x if a member path name # contains non-ASCII characters - it leads to an implicit # bytes -> unicode conversion using ASCII to decode. for tarinfo in archive.getmembers(): if not isinstance(tarinfo.name, text_type): tarinfo.name = tarinfo.name.decode('utf-8') archive.extractall(dest_dir) finally: if archive: archive.close() def zip_dir(directory): """zip a directory tree into a BytesIO object""" result = io.BytesIO() dlen = len(directory) with ZipFile(result, "w") as zf: for root, dirs, files in os.walk(directory): for name in files: full = os.path.join(root, name) rel = root[dlen:] dest = os.path.join(rel, name) zf.write(full, dest) return result # # Simple progress bar # UNITS = ('', 'K', 'M', 'G','T','P') class Progress(object): unknown = 'UNKNOWN' def __init__(self, minval=0, maxval=100): assert maxval is None or maxval >= minval self.min = self.cur = minval self.max = maxval self.started = None self.elapsed = 0 self.done = False def update(self, curval): assert self.min <= curval assert self.max is None or curval <= self.max self.cur = curval now = time.time() if self.started is None: self.started = now else: self.elapsed = now - self.started def increment(self, incr): assert incr >= 0 self.update(self.cur + incr) def start(self): self.update(self.min) return self def stop(self): if self.max is not None: self.update(self.max) self.done = True @property def maximum(self): return self.unknown if self.max is None else self.max @property def percentage(self): if self.done: result = '100 %' elif self.max is None: result = ' ?? %' else: v = 100.0 * (self.cur - self.min) / (self.max - self.min) result = '%3d %%' % v return result def format_duration(self, duration): if (duration <= 0) and self.max is None or self.cur == self.min: result = '??:??:??' #elif duration < 1: # result = '--:--:--' else: result = time.strftime('%H:%M:%S', time.gmtime(duration)) return result @property def ETA(self): if self.done: prefix = 'Done' t = self.elapsed #import pdb; pdb.set_trace() else: prefix = 'ETA ' if self.max is None: t = -1 elif self.elapsed == 0 or (self.cur == self.min): t = 0 else: #import pdb; pdb.set_trace() t = float(self.max - self.min) t /= self.cur - self.min t = (t - 1) * self.elapsed return '%s: %s' % (prefix, self.format_duration(t)) @property def speed(self): if self.elapsed == 0: result = 0.0 else: result = (self.cur - self.min) / self.elapsed for unit in UNITS: if result < 1000: break result /= 1000.0 return '%d %sB/s' % (result, unit) # # Glob functionality # RICH_GLOB = re.compile(r'\{([^}]*)\}') _CHECK_RECURSIVE_GLOB = re.compile(r'[^/\\,{]\*\*|\*\*[^/\\,}]') _CHECK_MISMATCH_SET = re.compile(r'^[^{]*\}|\{[^}]*$') def iglob(path_glob): """Extended globbing function that supports ** and {opt1,opt2,opt3}.""" if _CHECK_RECURSIVE_GLOB.search(path_glob): msg = """invalid glob %r: recursive glob "**" must be used alone""" raise ValueError(msg % path_glob) if _CHECK_MISMATCH_SET.search(path_glob): msg = """invalid glob %r: mismatching set marker '{' or '}'""" raise ValueError(msg % path_glob) return _iglob(path_glob) def _iglob(path_glob): rich_path_glob = RICH_GLOB.split(path_glob, 1) if len(rich_path_glob) > 1: assert len(rich_path_glob) == 3, rich_path_glob prefix, set, suffix = rich_path_glob for item in set.split(','): for path in _iglob(''.join((prefix, item, suffix))): yield path else: if '**' not in path_glob: for item in std_iglob(path_glob): yield item else: prefix, radical = path_glob.split('**', 1) if prefix == '': prefix = '.' if radical == '': radical = '*' else: # we support both radical = radical.lstrip('/') radical = radical.lstrip('\\') for path, dir, files in os.walk(prefix): path = os.path.normpath(path) for fn in _iglob(os.path.join(path, radical)): yield fn if ssl: from .compat import (HTTPSHandler as BaseHTTPSHandler, match_hostname, CertificateError) # # HTTPSConnection which verifies certificates/matches domains # class HTTPSConnection(httplib.HTTPSConnection): ca_certs = None # set this to the path to the certs file (.pem) check_domain = True # only used if ca_certs is not None # noinspection PyPropertyAccess def connect(self): sock = socket.create_connection((self.host, self.port), self.timeout) if getattr(self, '_tunnel_host', False): self.sock = sock self._tunnel() if not hasattr(ssl, 'SSLContext'): # For 2.x if self.ca_certs: cert_reqs = ssl.CERT_REQUIRED else: cert_reqs = ssl.CERT_NONE self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, cert_reqs=cert_reqs, ssl_version=ssl.PROTOCOL_SSLv23, ca_certs=self.ca_certs) else: # pragma: no cover context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) if hasattr(ssl, 'OP_NO_SSLv2'): context.options |= ssl.OP_NO_SSLv2 if self.cert_file: context.load_cert_chain(self.cert_file, self.key_file) kwargs = {} if self.ca_certs: context.verify_mode = ssl.CERT_REQUIRED context.load_verify_locations(cafile=self.ca_certs) if getattr(ssl, 'HAS_SNI', False): kwargs['server_hostname'] = self.host self.sock = context.wrap_socket(sock, **kwargs) if self.ca_certs and self.check_domain: try: match_hostname(self.sock.getpeercert(), self.host) logger.debug('Host verified: %s', self.host) except CertificateError: # pragma: no cover self.sock.shutdown(socket.SHUT_RDWR) self.sock.close() raise class HTTPSHandler(BaseHTTPSHandler): def __init__(self, ca_certs, check_domain=True): BaseHTTPSHandler.__init__(self) self.ca_certs = ca_certs self.check_domain = check_domain def _conn_maker(self, *args, **kwargs): """ This is called to create a connection instance. Normally you'd pass a connection class to do_open, but it doesn't actually check for a class, and just expects a callable. As long as we behave just as a constructor would have, we should be OK. If it ever changes so that we *must* pass a class, we'll create an UnsafeHTTPSConnection class which just sets check_domain to False in the class definition, and choose which one to pass to do_open. """ result = HTTPSConnection(*args, **kwargs) if self.ca_certs: result.ca_certs = self.ca_certs result.check_domain = self.check_domain return result def https_open(self, req): try: return self.do_open(self._conn_maker, req) except URLError as e: if 'certificate verify failed' in str(e.reason): raise CertificateError('Unable to verify server certificate ' 'for %s' % req.host) else: raise # # To prevent against mixing HTTP traffic with HTTPS (examples: A Man-In-The- # Middle proxy using HTTP listens on port 443, or an index mistakenly serves # HTML containing a http://xyz link when it should be https://xyz), # you can use the following handler class, which does not allow HTTP traffic. # # It works by inheriting from HTTPHandler - so build_opener won't add a # handler for HTTP itself. # class HTTPSOnlyHandler(HTTPSHandler, HTTPHandler): def http_open(self, req): raise URLError('Unexpected HTTP request on what should be a secure ' 'connection: %s' % req) # # XML-RPC with timeouts # _ver_info = sys.version_info[:2] if _ver_info == (2, 6): class HTTP(httplib.HTTP): def __init__(self, host='', port=None, **kwargs): if port == 0: # 0 means use port 0, not the default port port = None self._setup(self._connection_class(host, port, **kwargs)) if ssl: class HTTPS(httplib.HTTPS): def __init__(self, host='', port=None, **kwargs): if port == 0: # 0 means use port 0, not the default port port = None self._setup(self._connection_class(host, port, **kwargs)) class Transport(xmlrpclib.Transport): def __init__(self, timeout, use_datetime=0): self.timeout = timeout xmlrpclib.Transport.__init__(self, use_datetime) def make_connection(self, host): h, eh, x509 = self.get_host_info(host) if _ver_info == (2, 6): result = HTTP(h, timeout=self.timeout) else: if not self._connection or host != self._connection[0]: self._extra_headers = eh self._connection = host, httplib.HTTPConnection(h) result = self._connection[1] return result if ssl: class SafeTransport(xmlrpclib.SafeTransport): def __init__(self, timeout, use_datetime=0): self.timeout = timeout xmlrpclib.SafeTransport.__init__(self, use_datetime) def make_connection(self, host): h, eh, kwargs = self.get_host_info(host) if not kwargs: kwargs = {} kwargs['timeout'] = self.timeout if _ver_info == (2, 6): result = HTTPS(host, None, **kwargs) else: if not self._connection or host != self._connection[0]: self._extra_headers = eh self._connection = host, httplib.HTTPSConnection(h, None, **kwargs) result = self._connection[1] return result class ServerProxy(xmlrpclib.ServerProxy): def __init__(self, uri, **kwargs): self.timeout = timeout = kwargs.pop('timeout', None) # The above classes only come into play if a timeout # is specified if timeout is not None: # scheme = splittype(uri) # deprecated as of Python 3.8 scheme = urlparse(uri)[0] use_datetime = kwargs.get('use_datetime', 0) if scheme == 'https': tcls = SafeTransport else: tcls = Transport kwargs['transport'] = t = tcls(timeout, use_datetime=use_datetime) self.transport = t xmlrpclib.ServerProxy.__init__(self, uri, **kwargs) # # CSV functionality. This is provided because on 2.x, the csv module can't # handle Unicode. However, we need to deal with Unicode in e.g. RECORD files. # def _csv_open(fn, mode, **kwargs): if sys.version_info[0] < 3: mode += 'b' else: kwargs['newline'] = '' # Python 3 determines encoding from locale. Force 'utf-8' # file encoding to match other forced utf-8 encoding kwargs['encoding'] = 'utf-8' return open(fn, mode, **kwargs) class CSVBase(object): defaults = { 'delimiter': str(','), # The strs are used because we need native 'quotechar': str('"'), # str in the csv API (2.x won't take 'lineterminator': str('\n') # Unicode) } def __enter__(self): return self def __exit__(self, *exc_info): self.stream.close() class CSVReader(CSVBase): def __init__(self, **kwargs): if 'stream' in kwargs: stream = kwargs['stream'] if sys.version_info[0] >= 3: # needs to be a text stream stream = codecs.getreader('utf-8')(stream) self.stream = stream else: self.stream = _csv_open(kwargs['path'], 'r') self.reader = csv.reader(self.stream, **self.defaults) def __iter__(self): return self def next(self): result = next(self.reader) if sys.version_info[0] < 3: for i, item in enumerate(result): if not isinstance(item, text_type): result[i] = item.decode('utf-8') return result __next__ = next class CSVWriter(CSVBase): def __init__(self, fn, **kwargs): self.stream = _csv_open(fn, 'w') self.writer = csv.writer(self.stream, **self.defaults) def writerow(self, row): if sys.version_info[0] < 3: r = [] for item in row: if isinstance(item, text_type): item = item.encode('utf-8') r.append(item) row = r self.writer.writerow(row) # # Configurator functionality # class Configurator(BaseConfigurator): value_converters = dict(BaseConfigurator.value_converters) value_converters['inc'] = 'inc_convert' def __init__(self, config, base=None): super(Configurator, self).__init__(config) self.base = base or os.getcwd() def configure_custom(self, config): def convert(o): if isinstance(o, (list, tuple)): result = type(o)([convert(i) for i in o]) elif isinstance(o, dict): if '()' in o: result = self.configure_custom(o) else: result = {} for k in o: result[k] = convert(o[k]) else: result = self.convert(o) return result c = config.pop('()') if not callable(c): c = self.resolve(c) props = config.pop('.', None) # Check for valid identifiers args = config.pop('[]', ()) if args: args = tuple([convert(o) for o in args]) items = [(k, convert(config[k])) for k in config if valid_ident(k)] kwargs = dict(items) result = c(*args, **kwargs) if props: for n, v in props.items(): setattr(result, n, convert(v)) return result def __getitem__(self, key): result = self.config[key] if isinstance(result, dict) and '()' in result: self.config[key] = result = self.configure_custom(result) return result def inc_convert(self, value): """Default converter for the inc:// protocol.""" if not os.path.isabs(value): value = os.path.join(self.base, value) with codecs.open(value, 'r', encoding='utf-8') as f: result = json.load(f) return result class SubprocessMixin(object): """ Mixin for running subprocesses and capturing their output """ def __init__(self, verbose=False, progress=None): self.verbose = verbose self.progress = progress def reader(self, stream, context): """ Read lines from a subprocess' output stream and either pass to a progress callable (if specified) or write progress information to sys.stderr. """ progress = self.progress verbose = self.verbose while True: s = stream.readline() if not s: break if progress is not None: progress(s, context) else: if not verbose: sys.stderr.write('.') else: sys.stderr.write(s.decode('utf-8')) sys.stderr.flush() stream.close() def run_command(self, cmd, **kwargs): p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) t1 = threading.Thread(target=self.reader, args=(p.stdout, 'stdout')) t1.start() t2 = threading.Thread(target=self.reader, args=(p.stderr, 'stderr')) t2.start() p.wait() t1.join() t2.join() if self.progress is not None: self.progress('done.', 'main') elif self.verbose: sys.stderr.write('done.\n') return p def normalize_name(name): """Normalize a python package name a la PEP 503""" # https://www.python.org/dev/peps/pep-0503/#normalized-names return re.sub('[-_.]+', '-', name).lower() # def _get_pypirc_command(): # """ # Get the distutils command for interacting with PyPI configurations. # :return: the command. # """ # from distutils.core import Distribution # from distutils.config import PyPIRCCommand # d = Distribution() # return PyPIRCCommand(d) class PyPIRCFile(object): DEFAULT_REPOSITORY = 'https://upload.pypi.org/legacy/' DEFAULT_REALM = 'pypi' def __init__(self, fn=None, url=None): if fn is None: fn = os.path.join(os.path.expanduser('~'), '.pypirc') self.filename = fn self.url = url def read(self): result = {} if os.path.exists(self.filename): repository = self.url or self.DEFAULT_REPOSITORY config = configparser.RawConfigParser() config.read(self.filename) sections = config.sections() if 'distutils' in sections: # let's get the list of servers index_servers = config.get('distutils', 'index-servers') _servers = [server.strip() for server in index_servers.split('\n') if server.strip() != ''] if _servers == []: # nothing set, let's try to get the default pypi if 'pypi' in sections: _servers = ['pypi'] else: for server in _servers: result = {'server': server} result['username'] = config.get(server, 'username') # optional params for key, default in (('repository', self.DEFAULT_REPOSITORY), ('realm', self.DEFAULT_REALM), ('password', None)): if config.has_option(server, key): result[key] = config.get(server, key) else: result[key] = default # work around people having "repository" for the "pypi" # section of their config set to the HTTP (rather than # HTTPS) URL if (server == 'pypi' and repository in (self.DEFAULT_REPOSITORY, 'pypi')): result['repository'] = self.DEFAULT_REPOSITORY elif (result['server'] != repository and result['repository'] != repository): result = {} elif 'server-login' in sections: # old format server = 'server-login' if config.has_option(server, 'repository'): repository = config.get(server, 'repository') else: repository = self.DEFAULT_REPOSITORY result = { 'username': config.get(server, 'username'), 'password': config.get(server, 'password'), 'repository': repository, 'server': server, 'realm': self.DEFAULT_REALM } return result def update(self, username, password): # import pdb; pdb.set_trace() config = configparser.RawConfigParser() fn = self.filename config.read(fn) if not config.has_section('pypi'): config.add_section('pypi') config.set('pypi', 'username', username) config.set('pypi', 'password', password) with open(fn, 'w') as f: config.write(f) def _load_pypirc(index): """ Read the PyPI access configuration as supported by distutils. """ return PyPIRCFile(url=index.url).read() def _store_pypirc(index): PyPIRCFile().update(index.username, index.password) # # get_platform()/get_host_platform() copied from Python 3.10.a0 source, with some minor # tweaks # def get_host_platform(): """Return a string that identifies the current platform. This is used mainly to distinguish platform-specific build directories and platform-specific built distributions. Typically includes the OS name and version and the architecture (as supplied by 'os.uname()'), although the exact information included depends on the OS; eg. on Linux, the kernel version isn't particularly important. Examples of returned values: linux-i586 linux-alpha (?) solaris-2.6-sun4u Windows will return one of: win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) win32 (all others - specifically, sys.platform is returned) For other non-POSIX platforms, currently just returns 'sys.platform'. """ if os.name == 'nt': if 'amd64' in sys.version.lower(): return 'win-amd64' if '(arm)' in sys.version.lower(): return 'win-arm32' if '(arm64)' in sys.version.lower(): return 'win-arm64' return sys.platform # Set for cross builds explicitly if "_PYTHON_HOST_PLATFORM" in os.environ: return os.environ["_PYTHON_HOST_PLATFORM"] if os.name != 'posix' or not hasattr(os, 'uname'): # XXX what about the architecture? NT is Intel or Alpha, # Mac OS is M68k or PPC, etc. return sys.platform # Try to distinguish various flavours of Unix (osname, host, release, version, machine) = os.uname() # Convert the OS name to lowercase, remove '/' characters, and translate # spaces (for "Power Macintosh") osname = osname.lower().replace('/', '') machine = machine.replace(' ', '_').replace('/', '-') if osname[:5] == 'linux': # At least on Linux/Intel, 'machine' is the processor -- # i386, etc. # XXX what about Alpha, SPARC, etc? return "%s-%s" % (osname, machine) elif osname[:5] == 'sunos': if release[0] >= '5': # SunOS 5 == Solaris 2 osname = 'solaris' release = '%d.%s' % (int(release[0]) - 3, release[2:]) # We can't use 'platform.architecture()[0]' because a # bootstrap problem. We use a dict to get an error # if some suspicious happens. bitness = {2147483647:'32bit', 9223372036854775807:'64bit'} machine += '.%s' % bitness[sys.maxsize] # fall through to standard osname-release-machine representation elif osname[:3] == 'aix': from _aix_support import aix_platform return aix_platform() elif osname[:6] == 'cygwin': osname = 'cygwin' rel_re = re.compile (r'[\d.]+', re.ASCII) m = rel_re.match(release) if m: release = m.group() elif osname[:6] == 'darwin': import _osx_support, distutils.sysconfig osname, release, machine = _osx_support.get_platform_osx( distutils.sysconfig.get_config_vars(), osname, release, machine) return '%s-%s-%s' % (osname, release, machine) _TARGET_TO_PLAT = { 'x86' : 'win32', 'x64' : 'win-amd64', 'arm' : 'win-arm32', } def get_platform(): if os.name != 'nt': return get_host_platform() cross_compilation_target = os.environ.get('VSCMD_ARG_TGT_ARCH') if cross_compilation_target not in _TARGET_TO_PLAT: return get_host_platform() return _TARGET_TO_PLAT[cross_compilation_target] PKH]E8E8E7python3.10/site-packages/pip/_vendor/distlib/scripts.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2013-2015 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # from io import BytesIO import logging import os import re import struct import sys from .compat import sysconfig, detect_encoding, ZipFile from .resources import finder from .util import (FileOperator, get_export_entry, convert_path, get_executable, get_platform, in_venv) logger = logging.getLogger(__name__) _DEFAULT_MANIFEST = ''' '''.strip() # check if Python is called on the first line with this expression FIRST_LINE_RE = re.compile(b'^#!.*pythonw?[0-9.]*([ \t].*)?$') SCRIPT_TEMPLATE = r'''# -*- coding: utf-8 -*- import re import sys from %(module)s import %(import_name)s if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(%(func)s()) ''' def enquote_executable(executable): if ' ' in executable: # make sure we quote only the executable in case of env # for example /usr/bin/env "/dir with spaces/bin/jython" # instead of "/usr/bin/env /dir with spaces/bin/jython" # otherwise whole if executable.startswith('/usr/bin/env '): env, _executable = executable.split(' ', 1) if ' ' in _executable and not _executable.startswith('"'): executable = '%s "%s"' % (env, _executable) else: if not executable.startswith('"'): executable = '"%s"' % executable return executable # Keep the old name around (for now), as there is at least one project using it! _enquote_executable = enquote_executable class ScriptMaker(object): """ A class to copy or create scripts from source scripts or callable specifications. """ script_template = SCRIPT_TEMPLATE executable = None # for shebangs def __init__(self, source_dir, target_dir, add_launchers=True, dry_run=False, fileop=None): self.source_dir = source_dir self.target_dir = target_dir self.add_launchers = add_launchers self.force = False self.clobber = False # It only makes sense to set mode bits on POSIX. self.set_mode = (os.name == 'posix') or (os.name == 'java' and os._name == 'posix') self.variants = set(('', 'X.Y')) self._fileop = fileop or FileOperator(dry_run) self._is_nt = os.name == 'nt' or ( os.name == 'java' and os._name == 'nt') self.version_info = sys.version_info def _get_alternate_executable(self, executable, options): if options.get('gui', False) and self._is_nt: # pragma: no cover dn, fn = os.path.split(executable) fn = fn.replace('python', 'pythonw') executable = os.path.join(dn, fn) return executable if sys.platform.startswith('java'): # pragma: no cover def _is_shell(self, executable): """ Determine if the specified executable is a script (contains a #! line) """ try: with open(executable) as fp: return fp.read(2) == '#!' except (OSError, IOError): logger.warning('Failed to open %s', executable) return False def _fix_jython_executable(self, executable): if self._is_shell(executable): # Workaround for Jython is not needed on Linux systems. import java if java.lang.System.getProperty('os.name') == 'Linux': return executable elif executable.lower().endswith('jython.exe'): # Use wrapper exe for Jython on Windows return executable return '/usr/bin/env %s' % executable def _build_shebang(self, executable, post_interp): """ Build a shebang line. In the simple case (on Windows, or a shebang line which is not too long or contains spaces) use a simple formulation for the shebang. Otherwise, use /bin/sh as the executable, with a contrived shebang which allows the script to run either under Python or sh, using suitable quoting. Thanks to Harald Nordgren for his input. See also: http://www.in-ulm.de/~mascheck/various/shebang/#length https://hg.mozilla.org/mozilla-central/file/tip/mach """ if os.name != 'posix': simple_shebang = True else: # Add 3 for '#!' prefix and newline suffix. shebang_length = len(executable) + len(post_interp) + 3 if sys.platform == 'darwin': max_shebang_length = 512 else: max_shebang_length = 127 simple_shebang = ((b' ' not in executable) and (shebang_length <= max_shebang_length)) if simple_shebang: result = b'#!' + executable + post_interp + b'\n' else: result = b'#!/bin/sh\n' result += b"'''exec' " + executable + post_interp + b' "$0" "$@"\n' result += b"' '''" return result def _get_shebang(self, encoding, post_interp=b'', options=None): enquote = True if self.executable: executable = self.executable enquote = False # assume this will be taken care of elif not sysconfig.is_python_build(): executable = get_executable() elif in_venv(): # pragma: no cover executable = os.path.join(sysconfig.get_path('scripts'), 'python%s' % sysconfig.get_config_var('EXE')) else: # pragma: no cover executable = os.path.join( sysconfig.get_config_var('BINDIR'), 'python%s%s' % (sysconfig.get_config_var('VERSION'), sysconfig.get_config_var('EXE'))) if not os.path.isfile(executable): # for Python builds from source on Windows, no Python executables with # a version suffix are created, so we use python.exe executable = os.path.join(sysconfig.get_config_var('BINDIR'), 'python%s' % (sysconfig.get_config_var('EXE'))) if options: executable = self._get_alternate_executable(executable, options) if sys.platform.startswith('java'): # pragma: no cover executable = self._fix_jython_executable(executable) # Normalise case for Windows - COMMENTED OUT # executable = os.path.normcase(executable) # N.B. The normalising operation above has been commented out: See # issue #124. Although paths in Windows are generally case-insensitive, # they aren't always. For example, a path containing a ẞ (which is a # LATIN CAPITAL LETTER SHARP S - U+1E9E) is normcased to ß (which is a # LATIN SMALL LETTER SHARP S' - U+00DF). The two are not considered by # Windows as equivalent in path names. # If the user didn't specify an executable, it may be necessary to # cater for executable paths with spaces (not uncommon on Windows) if enquote: executable = enquote_executable(executable) # Issue #51: don't use fsencode, since we later try to # check that the shebang is decodable using utf-8. executable = executable.encode('utf-8') # in case of IronPython, play safe and enable frames support if (sys.platform == 'cli' and '-X:Frames' not in post_interp and '-X:FullFrames' not in post_interp): # pragma: no cover post_interp += b' -X:Frames' shebang = self._build_shebang(executable, post_interp) # Python parser starts to read a script using UTF-8 until # it gets a #coding:xxx cookie. The shebang has to be the # first line of a file, the #coding:xxx cookie cannot be # written before. So the shebang has to be decodable from # UTF-8. try: shebang.decode('utf-8') except UnicodeDecodeError: # pragma: no cover raise ValueError( 'The shebang (%r) is not decodable from utf-8' % shebang) # If the script is encoded to a custom encoding (use a # #coding:xxx cookie), the shebang has to be decodable from # the script encoding too. if encoding != 'utf-8': try: shebang.decode(encoding) except UnicodeDecodeError: # pragma: no cover raise ValueError( 'The shebang (%r) is not decodable ' 'from the script encoding (%r)' % (shebang, encoding)) return shebang def _get_script_text(self, entry): return self.script_template % dict(module=entry.prefix, import_name=entry.suffix.split('.')[0], func=entry.suffix) manifest = _DEFAULT_MANIFEST def get_manifest(self, exename): base = os.path.basename(exename) return self.manifest % base def _write_script(self, names, shebang, script_bytes, filenames, ext): use_launcher = self.add_launchers and self._is_nt linesep = os.linesep.encode('utf-8') if not shebang.endswith(linesep): shebang += linesep if not use_launcher: script_bytes = shebang + script_bytes else: # pragma: no cover if ext == 'py': launcher = self._get_launcher('t') else: launcher = self._get_launcher('w') stream = BytesIO() with ZipFile(stream, 'w') as zf: zf.writestr('__main__.py', script_bytes) zip_data = stream.getvalue() script_bytes = launcher + shebang + zip_data for name in names: outname = os.path.join(self.target_dir, name) if use_launcher: # pragma: no cover n, e = os.path.splitext(outname) if e.startswith('.py'): outname = n outname = '%s.exe' % outname try: self._fileop.write_binary_file(outname, script_bytes) except Exception: # Failed writing an executable - it might be in use. logger.warning('Failed to write executable - trying to ' 'use .deleteme logic') dfname = '%s.deleteme' % outname if os.path.exists(dfname): os.remove(dfname) # Not allowed to fail here os.rename(outname, dfname) # nor here self._fileop.write_binary_file(outname, script_bytes) logger.debug('Able to replace executable using ' '.deleteme logic') try: os.remove(dfname) except Exception: pass # still in use - ignore error else: if self._is_nt and not outname.endswith('.' + ext): # pragma: no cover outname = '%s.%s' % (outname, ext) if os.path.exists(outname) and not self.clobber: logger.warning('Skipping existing file %s', outname) continue self._fileop.write_binary_file(outname, script_bytes) if self.set_mode: self._fileop.set_executable_mode([outname]) filenames.append(outname) variant_separator = '-' def get_script_filenames(self, name): result = set() if '' in self.variants: result.add(name) if 'X' in self.variants: result.add('%s%s' % (name, self.version_info[0])) if 'X.Y' in self.variants: result.add('%s%s%s.%s' % (name, self.variant_separator, self.version_info[0], self.version_info[1])) return result def _make_script(self, entry, filenames, options=None): post_interp = b'' if options: args = options.get('interpreter_args', []) if args: args = ' %s' % ' '.join(args) post_interp = args.encode('utf-8') shebang = self._get_shebang('utf-8', post_interp, options=options) script = self._get_script_text(entry).encode('utf-8') scriptnames = self.get_script_filenames(entry.name) if options and options.get('gui', False): ext = 'pyw' else: ext = 'py' self._write_script(scriptnames, shebang, script, filenames, ext) def _copy_script(self, script, filenames): adjust = False script = os.path.join(self.source_dir, convert_path(script)) outname = os.path.join(self.target_dir, os.path.basename(script)) if not self.force and not self._fileop.newer(script, outname): logger.debug('not copying %s (up-to-date)', script) return # Always open the file, but ignore failures in dry-run mode -- # that way, we'll get accurate feedback if we can read the # script. try: f = open(script, 'rb') except IOError: # pragma: no cover if not self.dry_run: raise f = None else: first_line = f.readline() if not first_line: # pragma: no cover logger.warning('%s is an empty file (skipping)', script) return match = FIRST_LINE_RE.match(first_line.replace(b'\r\n', b'\n')) if match: adjust = True post_interp = match.group(1) or b'' if not adjust: if f: f.close() self._fileop.copy_file(script, outname) if self.set_mode: self._fileop.set_executable_mode([outname]) filenames.append(outname) else: logger.info('copying and adjusting %s -> %s', script, self.target_dir) if not self._fileop.dry_run: encoding, lines = detect_encoding(f.readline) f.seek(0) shebang = self._get_shebang(encoding, post_interp) if b'pythonw' in first_line: # pragma: no cover ext = 'pyw' else: ext = 'py' n = os.path.basename(outname) self._write_script([n], shebang, f.read(), filenames, ext) if f: f.close() @property def dry_run(self): return self._fileop.dry_run @dry_run.setter def dry_run(self, value): self._fileop.dry_run = value if os.name == 'nt' or (os.name == 'java' and os._name == 'nt'): # pragma: no cover # Executable launcher support. # Launchers are from https://bitbucket.org/vinay.sajip/simple_launcher/ def _get_launcher(self, kind): if struct.calcsize('P') == 8: # 64-bit bits = '64' else: bits = '32' platform_suffix = '-arm' if get_platform() == 'win-arm64' else '' name = '%s%s%s.exe' % (kind, bits, platform_suffix) # Issue 31: don't hardcode an absolute package name, but # determine it relative to the current package distlib_package = __name__.rsplit('.', 1)[0] resource = finder(distlib_package).find(name) if not resource: msg = ('Unable to find resource %s in package %s' % (name, distlib_package)) raise ValueError(msg) return resource.bytes # Public API follows def make(self, specification, options=None): """ Make a script. :param specification: The specification, which is either a valid export entry specification (to make a script from a callable) or a filename (to make a script by copying from a source location). :param options: A dictionary of options controlling script generation. :return: A list of all absolute pathnames written to. """ filenames = [] entry = get_export_entry(specification) if entry is None: self._copy_script(specification, filenames) else: self._make_script(entry, filenames, options=options) return filenames def make_multiple(self, specifications, options=None): """ Take a list of specifications and make scripts from them, :param specifications: A list of specifications. :return: A list of all absolute pathnames written to, """ filenames = [] for specification in specifications: filenames.extend(self.make(specification, options)) return filenames PKH]@css8python3.10/site-packages/pip/_vendor/distlib/database.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2012-2017 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # """PEP 376 implementation.""" from __future__ import unicode_literals import base64 import codecs import contextlib import hashlib import logging import os import posixpath import sys import zipimport from . import DistlibException, resources from .compat import StringIO from .version import get_scheme, UnsupportedVersionError from .metadata import (Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME, LEGACY_METADATA_FILENAME) from .util import (parse_requirement, cached_property, parse_name_and_version, read_exports, write_exports, CSVReader, CSVWriter) __all__ = ['Distribution', 'BaseInstalledDistribution', 'InstalledDistribution', 'EggInfoDistribution', 'DistributionPath'] logger = logging.getLogger(__name__) EXPORTS_FILENAME = 'pydist-exports.json' COMMANDS_FILENAME = 'pydist-commands.json' DIST_FILES = ('INSTALLER', METADATA_FILENAME, 'RECORD', 'REQUESTED', 'RESOURCES', EXPORTS_FILENAME, 'SHARED') DISTINFO_EXT = '.dist-info' class _Cache(object): """ A simple cache mapping names and .dist-info paths to distributions """ def __init__(self): """ Initialise an instance. There is normally one for each DistributionPath. """ self.name = {} self.path = {} self.generated = False def clear(self): """ Clear the cache, setting it to its initial state. """ self.name.clear() self.path.clear() self.generated = False def add(self, dist): """ Add a distribution to the cache. :param dist: The distribution to add. """ if dist.path not in self.path: self.path[dist.path] = dist self.name.setdefault(dist.key, []).append(dist) class DistributionPath(object): """ Represents a set of distributions installed on a path (typically sys.path). """ def __init__(self, path=None, include_egg=False): """ Create an instance from a path, optionally including legacy (distutils/ setuptools/distribute) distributions. :param path: The path to use, as a list of directories. If not specified, sys.path is used. :param include_egg: If True, this instance will look for and return legacy distributions as well as those based on PEP 376. """ if path is None: path = sys.path self.path = path self._include_dist = True self._include_egg = include_egg self._cache = _Cache() self._cache_egg = _Cache() self._cache_enabled = True self._scheme = get_scheme('default') def _get_cache_enabled(self): return self._cache_enabled def _set_cache_enabled(self, value): self._cache_enabled = value cache_enabled = property(_get_cache_enabled, _set_cache_enabled) def clear_cache(self): """ Clears the internal cache. """ self._cache.clear() self._cache_egg.clear() def _yield_distributions(self): """ Yield .dist-info and/or .egg(-info) distributions. """ # We need to check if we've seen some resources already, because on # some Linux systems (e.g. some Debian/Ubuntu variants) there are # symlinks which alias other files in the environment. seen = set() for path in self.path: finder = resources.finder_for_path(path) if finder is None: continue r = finder.find('') if not r or not r.is_container: continue rset = sorted(r.resources) for entry in rset: r = finder.find(entry) if not r or r.path in seen: continue if self._include_dist and entry.endswith(DISTINFO_EXT): possible_filenames = [METADATA_FILENAME, WHEEL_METADATA_FILENAME, LEGACY_METADATA_FILENAME] for metadata_filename in possible_filenames: metadata_path = posixpath.join(entry, metadata_filename) pydist = finder.find(metadata_path) if pydist: break else: continue with contextlib.closing(pydist.as_stream()) as stream: metadata = Metadata(fileobj=stream, scheme='legacy') logger.debug('Found %s', r.path) seen.add(r.path) yield new_dist_class(r.path, metadata=metadata, env=self) elif self._include_egg and entry.endswith(('.egg-info', '.egg')): logger.debug('Found %s', r.path) seen.add(r.path) yield old_dist_class(r.path, self) def _generate_cache(self): """ Scan the path for distributions and populate the cache with those that are found. """ gen_dist = not self._cache.generated gen_egg = self._include_egg and not self._cache_egg.generated if gen_dist or gen_egg: for dist in self._yield_distributions(): if isinstance(dist, InstalledDistribution): self._cache.add(dist) else: self._cache_egg.add(dist) if gen_dist: self._cache.generated = True if gen_egg: self._cache_egg.generated = True @classmethod def distinfo_dirname(cls, name, version): """ The *name* and *version* parameters are converted into their filename-escaped form, i.e. any ``'-'`` characters are replaced with ``'_'`` other than the one in ``'dist-info'`` and the one separating the name from the version number. :parameter name: is converted to a standard distribution name by replacing any runs of non- alphanumeric characters with a single ``'-'``. :type name: string :parameter version: is converted to a standard version string. Spaces become dots, and all other non-alphanumeric characters (except dots) become dashes, with runs of multiple dashes condensed to a single dash. :type version: string :returns: directory name :rtype: string""" name = name.replace('-', '_') return '-'.join([name, version]) + DISTINFO_EXT def get_distributions(self): """ Provides an iterator that looks for distributions and returns :class:`InstalledDistribution` or :class:`EggInfoDistribution` instances for each one of them. :rtype: iterator of :class:`InstalledDistribution` and :class:`EggInfoDistribution` instances """ if not self._cache_enabled: for dist in self._yield_distributions(): yield dist else: self._generate_cache() for dist in self._cache.path.values(): yield dist if self._include_egg: for dist in self._cache_egg.path.values(): yield dist def get_distribution(self, name): """ Looks for a named distribution on the path. This function only returns the first result found, as no more than one value is expected. If nothing is found, ``None`` is returned. :rtype: :class:`InstalledDistribution`, :class:`EggInfoDistribution` or ``None`` """ result = None name = name.lower() if not self._cache_enabled: for dist in self._yield_distributions(): if dist.key == name: result = dist break else: self._generate_cache() if name in self._cache.name: result = self._cache.name[name][0] elif self._include_egg and name in self._cache_egg.name: result = self._cache_egg.name[name][0] return result def provides_distribution(self, name, version=None): """ Iterates over all distributions to find which distributions provide *name*. If a *version* is provided, it will be used to filter the results. This function only returns the first result found, since no more than one values are expected. If the directory is not found, returns ``None``. :parameter version: a version specifier that indicates the version required, conforming to the format in ``PEP-345`` :type name: string :type version: string """ matcher = None if version is not None: try: matcher = self._scheme.matcher('%s (%s)' % (name, version)) except ValueError: raise DistlibException('invalid name or version: %r, %r' % (name, version)) for dist in self.get_distributions(): # We hit a problem on Travis where enum34 was installed and doesn't # have a provides attribute ... if not hasattr(dist, 'provides'): logger.debug('No "provides": %s', dist) else: provided = dist.provides for p in provided: p_name, p_ver = parse_name_and_version(p) if matcher is None: if p_name == name: yield dist break else: if p_name == name and matcher.match(p_ver): yield dist break def get_file_path(self, name, relative_path): """ Return the path to a resource file. """ dist = self.get_distribution(name) if dist is None: raise LookupError('no distribution named %r found' % name) return dist.get_resource_path(relative_path) def get_exported_entries(self, category, name=None): """ Return all of the exported entries in a particular category. :param category: The category to search for entries. :param name: If specified, only entries with that name are returned. """ for dist in self.get_distributions(): r = dist.exports if category in r: d = r[category] if name is not None: if name in d: yield d[name] else: for v in d.values(): yield v class Distribution(object): """ A base class for distributions, whether installed or from indexes. Either way, it must have some metadata, so that's all that's needed for construction. """ build_time_dependency = False """ Set to True if it's known to be only a build-time dependency (i.e. not needed after installation). """ requested = False """A boolean that indicates whether the ``REQUESTED`` metadata file is present (in other words, whether the package was installed by user request or it was installed as a dependency).""" def __init__(self, metadata): """ Initialise an instance. :param metadata: The instance of :class:`Metadata` describing this distribution. """ self.metadata = metadata self.name = metadata.name self.key = self.name.lower() # for case-insensitive comparisons self.version = metadata.version self.locator = None self.digest = None self.extras = None # additional features requested self.context = None # environment marker overrides self.download_urls = set() self.digests = {} @property def source_url(self): """ The source archive download URL for this distribution. """ return self.metadata.source_url download_url = source_url # Backward compatibility @property def name_and_version(self): """ A utility property which displays the name and version in parentheses. """ return '%s (%s)' % (self.name, self.version) @property def provides(self): """ A set of distribution names and versions provided by this distribution. :return: A set of "name (version)" strings. """ plist = self.metadata.provides s = '%s (%s)' % (self.name, self.version) if s not in plist: plist.append(s) return plist def _get_requirements(self, req_attr): md = self.metadata logger.debug('Getting requirements from metadata %r', md.todict()) reqts = getattr(md, req_attr) return set(md.get_requirements(reqts, extras=self.extras, env=self.context)) @property def run_requires(self): return self._get_requirements('run_requires') @property def meta_requires(self): return self._get_requirements('meta_requires') @property def build_requires(self): return self._get_requirements('build_requires') @property def test_requires(self): return self._get_requirements('test_requires') @property def dev_requires(self): return self._get_requirements('dev_requires') def matches_requirement(self, req): """ Say if this instance matches (fulfills) a requirement. :param req: The requirement to match. :rtype req: str :return: True if it matches, else False. """ # Requirement may contain extras - parse to lose those # from what's passed to the matcher r = parse_requirement(req) scheme = get_scheme(self.metadata.scheme) try: matcher = scheme.matcher(r.requirement) except UnsupportedVersionError: # XXX compat-mode if cannot read the version logger.warning('could not read version %r - using name only', req) name = req.split()[0] matcher = scheme.matcher(name) name = matcher.key # case-insensitive result = False for p in self.provides: p_name, p_ver = parse_name_and_version(p) if p_name != name: continue try: result = matcher.match(p_ver) break except UnsupportedVersionError: pass return result def __repr__(self): """ Return a textual representation of this instance, """ if self.source_url: suffix = ' [%s]' % self.source_url else: suffix = '' return '' % (self.name, self.version, suffix) def __eq__(self, other): """ See if this distribution is the same as another. :param other: The distribution to compare with. To be equal to one another. distributions must have the same type, name, version and source_url. :return: True if it is the same, else False. """ if type(other) is not type(self): result = False else: result = (self.name == other.name and self.version == other.version and self.source_url == other.source_url) return result def __hash__(self): """ Compute hash in a way which matches the equality test. """ return hash(self.name) + hash(self.version) + hash(self.source_url) class BaseInstalledDistribution(Distribution): """ This is the base class for installed distributions (whether PEP 376 or legacy). """ hasher = None def __init__(self, metadata, path, env=None): """ Initialise an instance. :param metadata: An instance of :class:`Metadata` which describes the distribution. This will normally have been initialised from a metadata file in the ``path``. :param path: The path of the ``.dist-info`` or ``.egg-info`` directory for the distribution. :param env: This is normally the :class:`DistributionPath` instance where this distribution was found. """ super(BaseInstalledDistribution, self).__init__(metadata) self.path = path self.dist_path = env def get_hash(self, data, hasher=None): """ Get the hash of some data, using a particular hash algorithm, if specified. :param data: The data to be hashed. :type data: bytes :param hasher: The name of a hash implementation, supported by hashlib, or ``None``. Examples of valid values are ``'sha1'``, ``'sha224'``, ``'sha384'``, '``sha256'``, ``'md5'`` and ``'sha512'``. If no hasher is specified, the ``hasher`` attribute of the :class:`InstalledDistribution` instance is used. If the hasher is determined to be ``None``, MD5 is used as the hashing algorithm. :returns: The hash of the data. If a hasher was explicitly specified, the returned hash will be prefixed with the specified hasher followed by '='. :rtype: str """ if hasher is None: hasher = self.hasher if hasher is None: hasher = hashlib.md5 prefix = '' else: hasher = getattr(hashlib, hasher) prefix = '%s=' % self.hasher digest = hasher(data).digest() digest = base64.urlsafe_b64encode(digest).rstrip(b'=').decode('ascii') return '%s%s' % (prefix, digest) class InstalledDistribution(BaseInstalledDistribution): """ Created with the *path* of the ``.dist-info`` directory provided to the constructor. It reads the metadata contained in ``pydist.json`` when it is instantiated., or uses a passed in Metadata instance (useful for when dry-run mode is being used). """ hasher = 'sha256' def __init__(self, path, metadata=None, env=None): self.modules = [] self.finder = finder = resources.finder_for_path(path) if finder is None: raise ValueError('finder unavailable for %s' % path) if env and env._cache_enabled and path in env._cache.path: metadata = env._cache.path[path].metadata elif metadata is None: r = finder.find(METADATA_FILENAME) # Temporary - for Wheel 0.23 support if r is None: r = finder.find(WHEEL_METADATA_FILENAME) # Temporary - for legacy support if r is None: r = finder.find(LEGACY_METADATA_FILENAME) if r is None: raise ValueError('no %s found in %s' % (METADATA_FILENAME, path)) with contextlib.closing(r.as_stream()) as stream: metadata = Metadata(fileobj=stream, scheme='legacy') super(InstalledDistribution, self).__init__(metadata, path, env) if env and env._cache_enabled: env._cache.add(self) r = finder.find('REQUESTED') self.requested = r is not None p = os.path.join(path, 'top_level.txt') if os.path.exists(p): with open(p, 'rb') as f: data = f.read().decode('utf-8') self.modules = data.splitlines() def __repr__(self): return '' % ( self.name, self.version, self.path) def __str__(self): return "%s %s" % (self.name, self.version) def _get_records(self): """ Get the list of installed files for the distribution :return: A list of tuples of path, hash and size. Note that hash and size might be ``None`` for some entries. The path is exactly as stored in the file (which is as in PEP 376). """ results = [] r = self.get_distinfo_resource('RECORD') with contextlib.closing(r.as_stream()) as stream: with CSVReader(stream=stream) as record_reader: # Base location is parent dir of .dist-info dir #base_location = os.path.dirname(self.path) #base_location = os.path.abspath(base_location) for row in record_reader: missing = [None for i in range(len(row), 3)] path, checksum, size = row + missing #if not os.path.isabs(path): # path = path.replace('/', os.sep) # path = os.path.join(base_location, path) results.append((path, checksum, size)) return results @cached_property def exports(self): """ Return the information exported by this distribution. :return: A dictionary of exports, mapping an export category to a dict of :class:`ExportEntry` instances describing the individual export entries, and keyed by name. """ result = {} r = self.get_distinfo_resource(EXPORTS_FILENAME) if r: result = self.read_exports() return result def read_exports(self): """ Read exports data from a file in .ini format. :return: A dictionary of exports, mapping an export category to a list of :class:`ExportEntry` instances describing the individual export entries. """ result = {} r = self.get_distinfo_resource(EXPORTS_FILENAME) if r: with contextlib.closing(r.as_stream()) as stream: result = read_exports(stream) return result def write_exports(self, exports): """ Write a dictionary of exports to a file in .ini format. :param exports: A dictionary of exports, mapping an export category to a list of :class:`ExportEntry` instances describing the individual export entries. """ rf = self.get_distinfo_file(EXPORTS_FILENAME) with open(rf, 'w') as f: write_exports(exports, f) def get_resource_path(self, relative_path): """ NOTE: This API may change in the future. Return the absolute path to a resource file with the given relative path. :param relative_path: The path, relative to .dist-info, of the resource of interest. :return: The absolute path where the resource is to be found. """ r = self.get_distinfo_resource('RESOURCES') with contextlib.closing(r.as_stream()) as stream: with CSVReader(stream=stream) as resources_reader: for relative, destination in resources_reader: if relative == relative_path: return destination raise KeyError('no resource file with relative path %r ' 'is installed' % relative_path) def list_installed_files(self): """ Iterates over the ``RECORD`` entries and returns a tuple ``(path, hash, size)`` for each line. :returns: iterator of (path, hash, size) """ for result in self._get_records(): yield result def write_installed_files(self, paths, prefix, dry_run=False): """ Writes the ``RECORD`` file, using the ``paths`` iterable passed in. Any existing ``RECORD`` file is silently overwritten. prefix is used to determine when to write absolute paths. """ prefix = os.path.join(prefix, '') base = os.path.dirname(self.path) base_under_prefix = base.startswith(prefix) base = os.path.join(base, '') record_path = self.get_distinfo_file('RECORD') logger.info('creating %s', record_path) if dry_run: return None with CSVWriter(record_path) as writer: for path in paths: if os.path.isdir(path) or path.endswith(('.pyc', '.pyo')): # do not put size and hash, as in PEP-376 hash_value = size = '' else: size = '%d' % os.path.getsize(path) with open(path, 'rb') as fp: hash_value = self.get_hash(fp.read()) if path.startswith(base) or (base_under_prefix and path.startswith(prefix)): path = os.path.relpath(path, base) writer.writerow((path, hash_value, size)) # add the RECORD file itself if record_path.startswith(base): record_path = os.path.relpath(record_path, base) writer.writerow((record_path, '', '')) return record_path def check_installed_files(self): """ Checks that the hashes and sizes of the files in ``RECORD`` are matched by the files themselves. Returns a (possibly empty) list of mismatches. Each entry in the mismatch list will be a tuple consisting of the path, 'exists', 'size' or 'hash' according to what didn't match (existence is checked first, then size, then hash), the expected value and the actual value. """ mismatches = [] base = os.path.dirname(self.path) record_path = self.get_distinfo_file('RECORD') for path, hash_value, size in self.list_installed_files(): if not os.path.isabs(path): path = os.path.join(base, path) if path == record_path: continue if not os.path.exists(path): mismatches.append((path, 'exists', True, False)) elif os.path.isfile(path): actual_size = str(os.path.getsize(path)) if size and actual_size != size: mismatches.append((path, 'size', size, actual_size)) elif hash_value: if '=' in hash_value: hasher = hash_value.split('=', 1)[0] else: hasher = None with open(path, 'rb') as f: actual_hash = self.get_hash(f.read(), hasher) if actual_hash != hash_value: mismatches.append((path, 'hash', hash_value, actual_hash)) return mismatches @cached_property def shared_locations(self): """ A dictionary of shared locations whose keys are in the set 'prefix', 'purelib', 'platlib', 'scripts', 'headers', 'data' and 'namespace'. The corresponding value is the absolute path of that category for this distribution, and takes into account any paths selected by the user at installation time (e.g. via command-line arguments). In the case of the 'namespace' key, this would be a list of absolute paths for the roots of namespace packages in this distribution. The first time this property is accessed, the relevant information is read from the SHARED file in the .dist-info directory. """ result = {} shared_path = os.path.join(self.path, 'SHARED') if os.path.isfile(shared_path): with codecs.open(shared_path, 'r', encoding='utf-8') as f: lines = f.read().splitlines() for line in lines: key, value = line.split('=', 1) if key == 'namespace': result.setdefault(key, []).append(value) else: result[key] = value return result def write_shared_locations(self, paths, dry_run=False): """ Write shared location information to the SHARED file in .dist-info. :param paths: A dictionary as described in the documentation for :meth:`shared_locations`. :param dry_run: If True, the action is logged but no file is actually written. :return: The path of the file written to. """ shared_path = os.path.join(self.path, 'SHARED') logger.info('creating %s', shared_path) if dry_run: return None lines = [] for key in ('prefix', 'lib', 'headers', 'scripts', 'data'): path = paths[key] if os.path.isdir(paths[key]): lines.append('%s=%s' % (key, path)) for ns in paths.get('namespace', ()): lines.append('namespace=%s' % ns) with codecs.open(shared_path, 'w', encoding='utf-8') as f: f.write('\n'.join(lines)) return shared_path def get_distinfo_resource(self, path): if path not in DIST_FILES: raise DistlibException('invalid path for a dist-info file: ' '%r at %r' % (path, self.path)) finder = resources.finder_for_path(self.path) if finder is None: raise DistlibException('Unable to get a finder for %s' % self.path) return finder.find(path) def get_distinfo_file(self, path): """ Returns a path located under the ``.dist-info`` directory. Returns a string representing the path. :parameter path: a ``'/'``-separated path relative to the ``.dist-info`` directory or an absolute path; If *path* is an absolute path and doesn't start with the ``.dist-info`` directory path, a :class:`DistlibException` is raised :type path: str :rtype: str """ # Check if it is an absolute path # XXX use relpath, add tests if path.find(os.sep) >= 0: # it's an absolute path? distinfo_dirname, path = path.split(os.sep)[-2:] if distinfo_dirname != self.path.split(os.sep)[-1]: raise DistlibException( 'dist-info file %r does not belong to the %r %s ' 'distribution' % (path, self.name, self.version)) # The file must be relative if path not in DIST_FILES: raise DistlibException('invalid path for a dist-info file: ' '%r at %r' % (path, self.path)) return os.path.join(self.path, path) def list_distinfo_files(self): """ Iterates over the ``RECORD`` entries and returns paths for each line if the path is pointing to a file located in the ``.dist-info`` directory or one of its subdirectories. :returns: iterator of paths """ base = os.path.dirname(self.path) for path, checksum, size in self._get_records(): # XXX add separator or use real relpath algo if not os.path.isabs(path): path = os.path.join(base, path) if path.startswith(self.path): yield path def __eq__(self, other): return (isinstance(other, InstalledDistribution) and self.path == other.path) # See http://docs.python.org/reference/datamodel#object.__hash__ __hash__ = object.__hash__ class EggInfoDistribution(BaseInstalledDistribution): """Created with the *path* of the ``.egg-info`` directory or file provided to the constructor. It reads the metadata contained in the file itself, or if the given path happens to be a directory, the metadata is read from the file ``PKG-INFO`` under that directory.""" requested = True # as we have no way of knowing, assume it was shared_locations = {} def __init__(self, path, env=None): def set_name_and_version(s, n, v): s.name = n s.key = n.lower() # for case-insensitive comparisons s.version = v self.path = path self.dist_path = env if env and env._cache_enabled and path in env._cache_egg.path: metadata = env._cache_egg.path[path].metadata set_name_and_version(self, metadata.name, metadata.version) else: metadata = self._get_metadata(path) # Need to be set before caching set_name_and_version(self, metadata.name, metadata.version) if env and env._cache_enabled: env._cache_egg.add(self) super(EggInfoDistribution, self).__init__(metadata, path, env) def _get_metadata(self, path): requires = None def parse_requires_data(data): """Create a list of dependencies from a requires.txt file. *data*: the contents of a setuptools-produced requires.txt file. """ reqs = [] lines = data.splitlines() for line in lines: line = line.strip() if line.startswith('['): logger.warning('Unexpected line: quitting requirement scan: %r', line) break r = parse_requirement(line) if not r: logger.warning('Not recognised as a requirement: %r', line) continue if r.extras: logger.warning('extra requirements in requires.txt are ' 'not supported') if not r.constraints: reqs.append(r.name) else: cons = ', '.join('%s%s' % c for c in r.constraints) reqs.append('%s (%s)' % (r.name, cons)) return reqs def parse_requires_path(req_path): """Create a list of dependencies from a requires.txt file. *req_path*: the path to a setuptools-produced requires.txt file. """ reqs = [] try: with codecs.open(req_path, 'r', 'utf-8') as fp: reqs = parse_requires_data(fp.read()) except IOError: pass return reqs tl_path = tl_data = None if path.endswith('.egg'): if os.path.isdir(path): p = os.path.join(path, 'EGG-INFO') meta_path = os.path.join(p, 'PKG-INFO') metadata = Metadata(path=meta_path, scheme='legacy') req_path = os.path.join(p, 'requires.txt') tl_path = os.path.join(p, 'top_level.txt') requires = parse_requires_path(req_path) else: # FIXME handle the case where zipfile is not available zipf = zipimport.zipimporter(path) fileobj = StringIO( zipf.get_data('EGG-INFO/PKG-INFO').decode('utf8')) metadata = Metadata(fileobj=fileobj, scheme='legacy') try: data = zipf.get_data('EGG-INFO/requires.txt') tl_data = zipf.get_data('EGG-INFO/top_level.txt').decode('utf-8') requires = parse_requires_data(data.decode('utf-8')) except IOError: requires = None elif path.endswith('.egg-info'): if os.path.isdir(path): req_path = os.path.join(path, 'requires.txt') requires = parse_requires_path(req_path) path = os.path.join(path, 'PKG-INFO') tl_path = os.path.join(path, 'top_level.txt') metadata = Metadata(path=path, scheme='legacy') else: raise DistlibException('path must end with .egg-info or .egg, ' 'got %r' % path) if requires: metadata.add_requirements(requires) # look for top-level modules in top_level.txt, if present if tl_data is None: if tl_path is not None and os.path.exists(tl_path): with open(tl_path, 'rb') as f: tl_data = f.read().decode('utf-8') if not tl_data: tl_data = [] else: tl_data = tl_data.splitlines() self.modules = tl_data return metadata def __repr__(self): return '' % ( self.name, self.version, self.path) def __str__(self): return "%s %s" % (self.name, self.version) def check_installed_files(self): """ Checks that the hashes and sizes of the files in ``RECORD`` are matched by the files themselves. Returns a (possibly empty) list of mismatches. Each entry in the mismatch list will be a tuple consisting of the path, 'exists', 'size' or 'hash' according to what didn't match (existence is checked first, then size, then hash), the expected value and the actual value. """ mismatches = [] record_path = os.path.join(self.path, 'installed-files.txt') if os.path.exists(record_path): for path, _, _ in self.list_installed_files(): if path == record_path: continue if not os.path.exists(path): mismatches.append((path, 'exists', True, False)) return mismatches def list_installed_files(self): """ Iterates over the ``installed-files.txt`` entries and returns a tuple ``(path, hash, size)`` for each line. :returns: a list of (path, hash, size) """ def _md5(path): f = open(path, 'rb') try: content = f.read() finally: f.close() return hashlib.md5(content).hexdigest() def _size(path): return os.stat(path).st_size record_path = os.path.join(self.path, 'installed-files.txt') result = [] if os.path.exists(record_path): with codecs.open(record_path, 'r', encoding='utf-8') as f: for line in f: line = line.strip() p = os.path.normpath(os.path.join(self.path, line)) # "./" is present as a marker between installed files # and installation metadata files if not os.path.exists(p): logger.warning('Non-existent file: %s', p) if p.endswith(('.pyc', '.pyo')): continue #otherwise fall through and fail if not os.path.isdir(p): result.append((p, _md5(p), _size(p))) result.append((record_path, None, None)) return result def list_distinfo_files(self, absolute=False): """ Iterates over the ``installed-files.txt`` entries and returns paths for each line if the path is pointing to a file located in the ``.egg-info`` directory or one of its subdirectories. :parameter absolute: If *absolute* is ``True``, each returned path is transformed into a local absolute path. Otherwise the raw value from ``installed-files.txt`` is returned. :type absolute: boolean :returns: iterator of paths """ record_path = os.path.join(self.path, 'installed-files.txt') if os.path.exists(record_path): skip = True with codecs.open(record_path, 'r', encoding='utf-8') as f: for line in f: line = line.strip() if line == './': skip = False continue if not skip: p = os.path.normpath(os.path.join(self.path, line)) if p.startswith(self.path): if absolute: yield p else: yield line def __eq__(self, other): return (isinstance(other, EggInfoDistribution) and self.path == other.path) # See http://docs.python.org/reference/datamodel#object.__hash__ __hash__ = object.__hash__ new_dist_class = InstalledDistribution old_dist_class = EggInfoDistribution class DependencyGraph(object): """ Represents a dependency graph between distributions. The dependency relationships are stored in an ``adjacency_list`` that maps distributions to a list of ``(other, label)`` tuples where ``other`` is a distribution and the edge is labeled with ``label`` (i.e. the version specifier, if such was provided). Also, for more efficient traversal, for every distribution ``x``, a list of predecessors is kept in ``reverse_list[x]``. An edge from distribution ``a`` to distribution ``b`` means that ``a`` depends on ``b``. If any missing dependencies are found, they are stored in ``missing``, which is a dictionary that maps distributions to a list of requirements that were not provided by any other distributions. """ def __init__(self): self.adjacency_list = {} self.reverse_list = {} self.missing = {} def add_distribution(self, distribution): """Add the *distribution* to the graph. :type distribution: :class:`distutils2.database.InstalledDistribution` or :class:`distutils2.database.EggInfoDistribution` """ self.adjacency_list[distribution] = [] self.reverse_list[distribution] = [] #self.missing[distribution] = [] def add_edge(self, x, y, label=None): """Add an edge from distribution *x* to distribution *y* with the given *label*. :type x: :class:`distutils2.database.InstalledDistribution` or :class:`distutils2.database.EggInfoDistribution` :type y: :class:`distutils2.database.InstalledDistribution` or :class:`distutils2.database.EggInfoDistribution` :type label: ``str`` or ``None`` """ self.adjacency_list[x].append((y, label)) # multiple edges are allowed, so be careful if x not in self.reverse_list[y]: self.reverse_list[y].append(x) def add_missing(self, distribution, requirement): """ Add a missing *requirement* for the given *distribution*. :type distribution: :class:`distutils2.database.InstalledDistribution` or :class:`distutils2.database.EggInfoDistribution` :type requirement: ``str`` """ logger.debug('%s missing %r', distribution, requirement) self.missing.setdefault(distribution, []).append(requirement) def _repr_dist(self, dist): return '%s %s' % (dist.name, dist.version) def repr_node(self, dist, level=1): """Prints only a subgraph""" output = [self._repr_dist(dist)] for other, label in self.adjacency_list[dist]: dist = self._repr_dist(other) if label is not None: dist = '%s [%s]' % (dist, label) output.append(' ' * level + str(dist)) suboutput = self.repr_node(other, level + 1) subs = suboutput.split('\n') output.extend(subs[1:]) return '\n'.join(output) def to_dot(self, f, skip_disconnected=True): """Writes a DOT output for the graph to the provided file *f*. If *skip_disconnected* is set to ``True``, then all distributions that are not dependent on any other distribution are skipped. :type f: has to support ``file``-like operations :type skip_disconnected: ``bool`` """ disconnected = [] f.write("digraph dependencies {\n") for dist, adjs in self.adjacency_list.items(): if len(adjs) == 0 and not skip_disconnected: disconnected.append(dist) for other, label in adjs: if not label is None: f.write('"%s" -> "%s" [label="%s"]\n' % (dist.name, other.name, label)) else: f.write('"%s" -> "%s"\n' % (dist.name, other.name)) if not skip_disconnected and len(disconnected) > 0: f.write('subgraph disconnected {\n') f.write('label = "Disconnected"\n') f.write('bgcolor = red\n') for dist in disconnected: f.write('"%s"' % dist.name) f.write('\n') f.write('}\n') f.write('}\n') def topological_sort(self): """ Perform a topological sort of the graph. :return: A tuple, the first element of which is a topologically sorted list of distributions, and the second element of which is a list of distributions that cannot be sorted because they have circular dependencies and so form a cycle. """ result = [] # Make a shallow copy of the adjacency list alist = {} for k, v in self.adjacency_list.items(): alist[k] = v[:] while True: # See what we can remove in this run to_remove = [] for k, v in list(alist.items())[:]: if not v: to_remove.append(k) del alist[k] if not to_remove: # What's left in alist (if anything) is a cycle. break # Remove from the adjacency list of others for k, v in alist.items(): alist[k] = [(d, r) for d, r in v if d not in to_remove] logger.debug('Moving to result: %s', ['%s (%s)' % (d.name, d.version) for d in to_remove]) result.extend(to_remove) return result, list(alist.keys()) def __repr__(self): """Representation of the graph""" output = [] for dist, adjs in self.adjacency_list.items(): output.append(self.repr_node(dist)) return '\n'.join(output) def make_graph(dists, scheme='default'): """Makes a dependency graph from the given distributions. :parameter dists: a list of distributions :type dists: list of :class:`distutils2.database.InstalledDistribution` and :class:`distutils2.database.EggInfoDistribution` instances :rtype: a :class:`DependencyGraph` instance """ scheme = get_scheme(scheme) graph = DependencyGraph() provided = {} # maps names to lists of (version, dist) tuples # first, build the graph and find out what's provided for dist in dists: graph.add_distribution(dist) for p in dist.provides: name, version = parse_name_and_version(p) logger.debug('Add to provided: %s, %s, %s', name, version, dist) provided.setdefault(name, []).append((version, dist)) # now make the edges for dist in dists: requires = (dist.run_requires | dist.meta_requires | dist.build_requires | dist.dev_requires) for req in requires: try: matcher = scheme.matcher(req) except UnsupportedVersionError: # XXX compat-mode if cannot read the version logger.warning('could not read version %r - using name only', req) name = req.split()[0] matcher = scheme.matcher(name) name = matcher.key # case-insensitive matched = False if name in provided: for version, provider in provided[name]: try: match = matcher.match(version) except UnsupportedVersionError: match = False if match: graph.add_edge(dist, provider, req) matched = True break if not matched: graph.add_missing(dist, req) return graph def get_dependent_dists(dists, dist): """Recursively generate a list of distributions from *dists* that are dependent on *dist*. :param dists: a list of distributions :param dist: a distribution, member of *dists* for which we are interested """ if dist not in dists: raise DistlibException('given distribution %r is not a member ' 'of the list' % dist.name) graph = make_graph(dists) dep = [dist] # dependent distributions todo = graph.reverse_list[dist] # list of nodes we should inspect while todo: d = todo.pop() dep.append(d) for succ in graph.reverse_list[d]: if succ not in dep: todo.append(succ) dep.pop(0) # remove dist from dep, was there to prevent infinite loops return dep def get_required_dists(dists, dist): """Recursively generate a list of distributions from *dists* that are required by *dist*. :param dists: a list of distributions :param dist: a distribution, member of *dists* for which we are interested """ if dist not in dists: raise DistlibException('given distribution %r is not a member ' 'of the list' % dist.name) graph = make_graph(dists) req = [] # required distributions todo = graph.adjacency_list[dist] # list of nodes we should inspect while todo: d = todo.pop()[0] req.append(d) for pred in graph.adjacency_list[d]: if pred not in req: todo.append(pred) return req def make_dist(name, version, **kwargs): """ A convenience method for making a dist given just a name and version. """ summary = kwargs.pop('summary', 'Placeholder for summary') md = Metadata(**kwargs) md.name = name md.version = version md.summary = summary or 'Placeholder for summary' return Distribution(md) PKH]5python3.10/site-packages/pip/_vendor/distlib/wheel.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2013-2020 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # from __future__ import unicode_literals import base64 import codecs import datetime from email import message_from_file import hashlib import imp import json import logging import os import posixpath import re import shutil import sys import tempfile import zipfile from . import __version__, DistlibException from .compat import sysconfig, ZipFile, fsdecode, text_type, filter from .database import InstalledDistribution from .metadata import (Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME, LEGACY_METADATA_FILENAME) from .util import (FileOperator, convert_path, CSVReader, CSVWriter, Cache, cached_property, get_cache_base, read_exports, tempdir, get_platform) from .version import NormalizedVersion, UnsupportedVersionError logger = logging.getLogger(__name__) cache = None # created when needed if hasattr(sys, 'pypy_version_info'): # pragma: no cover IMP_PREFIX = 'pp' elif sys.platform.startswith('java'): # pragma: no cover IMP_PREFIX = 'jy' elif sys.platform == 'cli': # pragma: no cover IMP_PREFIX = 'ip' else: IMP_PREFIX = 'cp' VER_SUFFIX = sysconfig.get_config_var('py_version_nodot') if not VER_SUFFIX: # pragma: no cover VER_SUFFIX = '%s%s' % sys.version_info[:2] PYVER = 'py' + VER_SUFFIX IMPVER = IMP_PREFIX + VER_SUFFIX ARCH = get_platform().replace('-', '_').replace('.', '_') ABI = sysconfig.get_config_var('SOABI') if ABI and ABI.startswith('cpython-'): ABI = ABI.replace('cpython-', 'cp').split('-')[0] else: def _derive_abi(): parts = ['cp', VER_SUFFIX] if sysconfig.get_config_var('Py_DEBUG'): parts.append('d') if sysconfig.get_config_var('WITH_PYMALLOC'): parts.append('m') if sysconfig.get_config_var('Py_UNICODE_SIZE') == 4: parts.append('u') return ''.join(parts) ABI = _derive_abi() del _derive_abi FILENAME_RE = re.compile(r''' (?P[^-]+) -(?P\d+[^-]*) (-(?P\d+[^-]*))? -(?P\w+\d+(\.\w+\d+)*) -(?P\w+) -(?P\w+(\.\w+)*) \.whl$ ''', re.IGNORECASE | re.VERBOSE) NAME_VERSION_RE = re.compile(r''' (?P[^-]+) -(?P\d+[^-]*) (-(?P\d+[^-]*))?$ ''', re.IGNORECASE | re.VERBOSE) SHEBANG_RE = re.compile(br'\s*#![^\r\n]*') SHEBANG_DETAIL_RE = re.compile(br'^(\s*#!("[^"]+"|\S+))\s+(.*)$') SHEBANG_PYTHON = b'#!python' SHEBANG_PYTHONW = b'#!pythonw' if os.sep == '/': to_posix = lambda o: o else: to_posix = lambda o: o.replace(os.sep, '/') class Mounter(object): def __init__(self): self.impure_wheels = {} self.libs = {} def add(self, pathname, extensions): self.impure_wheels[pathname] = extensions self.libs.update(extensions) def remove(self, pathname): extensions = self.impure_wheels.pop(pathname) for k, v in extensions: if k in self.libs: del self.libs[k] def find_module(self, fullname, path=None): if fullname in self.libs: result = self else: result = None return result def load_module(self, fullname): if fullname in sys.modules: result = sys.modules[fullname] else: if fullname not in self.libs: raise ImportError('unable to find extension for %s' % fullname) result = imp.load_dynamic(fullname, self.libs[fullname]) result.__loader__ = self parts = fullname.rsplit('.', 1) if len(parts) > 1: result.__package__ = parts[0] return result _hook = Mounter() class Wheel(object): """ Class to build and install from Wheel files (PEP 427). """ wheel_version = (1, 1) hash_kind = 'sha256' def __init__(self, filename=None, sign=False, verify=False): """ Initialise an instance using a (valid) filename. """ self.sign = sign self.should_verify = verify self.buildver = '' self.pyver = [PYVER] self.abi = ['none'] self.arch = ['any'] self.dirname = os.getcwd() if filename is None: self.name = 'dummy' self.version = '0.1' self._filename = self.filename else: m = NAME_VERSION_RE.match(filename) if m: info = m.groupdict('') self.name = info['nm'] # Reinstate the local version separator self.version = info['vn'].replace('_', '-') self.buildver = info['bn'] self._filename = self.filename else: dirname, filename = os.path.split(filename) m = FILENAME_RE.match(filename) if not m: raise DistlibException('Invalid name or ' 'filename: %r' % filename) if dirname: self.dirname = os.path.abspath(dirname) self._filename = filename info = m.groupdict('') self.name = info['nm'] self.version = info['vn'] self.buildver = info['bn'] self.pyver = info['py'].split('.') self.abi = info['bi'].split('.') self.arch = info['ar'].split('.') @property def filename(self): """ Build and return a filename from the various components. """ if self.buildver: buildver = '-' + self.buildver else: buildver = '' pyver = '.'.join(self.pyver) abi = '.'.join(self.abi) arch = '.'.join(self.arch) # replace - with _ as a local version separator version = self.version.replace('-', '_') return '%s-%s%s-%s-%s-%s.whl' % (self.name, version, buildver, pyver, abi, arch) @property def exists(self): path = os.path.join(self.dirname, self.filename) return os.path.isfile(path) @property def tags(self): for pyver in self.pyver: for abi in self.abi: for arch in self.arch: yield pyver, abi, arch @cached_property def metadata(self): pathname = os.path.join(self.dirname, self.filename) name_ver = '%s-%s' % (self.name, self.version) info_dir = '%s.dist-info' % name_ver wrapper = codecs.getreader('utf-8') with ZipFile(pathname, 'r') as zf: wheel_metadata = self.get_wheel_metadata(zf) wv = wheel_metadata['Wheel-Version'].split('.', 1) file_version = tuple([int(i) for i in wv]) # if file_version < (1, 1): # fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME, # LEGACY_METADATA_FILENAME] # else: # fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME] fns = [WHEEL_METADATA_FILENAME, LEGACY_METADATA_FILENAME] result = None for fn in fns: try: metadata_filename = posixpath.join(info_dir, fn) with zf.open(metadata_filename) as bf: wf = wrapper(bf) result = Metadata(fileobj=wf) if result: break except KeyError: pass if not result: raise ValueError('Invalid wheel, because metadata is ' 'missing: looked in %s' % ', '.join(fns)) return result def get_wheel_metadata(self, zf): name_ver = '%s-%s' % (self.name, self.version) info_dir = '%s.dist-info' % name_ver metadata_filename = posixpath.join(info_dir, 'WHEEL') with zf.open(metadata_filename) as bf: wf = codecs.getreader('utf-8')(bf) message = message_from_file(wf) return dict(message) @cached_property def info(self): pathname = os.path.join(self.dirname, self.filename) with ZipFile(pathname, 'r') as zf: result = self.get_wheel_metadata(zf) return result def process_shebang(self, data): m = SHEBANG_RE.match(data) if m: end = m.end() shebang, data_after_shebang = data[:end], data[end:] # Preserve any arguments after the interpreter if b'pythonw' in shebang.lower(): shebang_python = SHEBANG_PYTHONW else: shebang_python = SHEBANG_PYTHON m = SHEBANG_DETAIL_RE.match(shebang) if m: args = b' ' + m.groups()[-1] else: args = b'' shebang = shebang_python + args data = shebang + data_after_shebang else: cr = data.find(b'\r') lf = data.find(b'\n') if cr < 0 or cr > lf: term = b'\n' else: if data[cr:cr + 2] == b'\r\n': term = b'\r\n' else: term = b'\r' data = SHEBANG_PYTHON + term + data return data def get_hash(self, data, hash_kind=None): if hash_kind is None: hash_kind = self.hash_kind try: hasher = getattr(hashlib, hash_kind) except AttributeError: raise DistlibException('Unsupported hash algorithm: %r' % hash_kind) result = hasher(data).digest() result = base64.urlsafe_b64encode(result).rstrip(b'=').decode('ascii') return hash_kind, result def write_record(self, records, record_path, base): records = list(records) # make a copy, as mutated p = to_posix(os.path.relpath(record_path, base)) records.append((p, '', '')) with CSVWriter(record_path) as writer: for row in records: writer.writerow(row) def write_records(self, info, libdir, archive_paths): records = [] distinfo, info_dir = info hasher = getattr(hashlib, self.hash_kind) for ap, p in archive_paths: with open(p, 'rb') as f: data = f.read() digest = '%s=%s' % self.get_hash(data) size = os.path.getsize(p) records.append((ap, digest, size)) p = os.path.join(distinfo, 'RECORD') self.write_record(records, p, libdir) ap = to_posix(os.path.join(info_dir, 'RECORD')) archive_paths.append((ap, p)) def build_zip(self, pathname, archive_paths): with ZipFile(pathname, 'w', zipfile.ZIP_DEFLATED) as zf: for ap, p in archive_paths: logger.debug('Wrote %s to %s in wheel', p, ap) zf.write(p, ap) def build(self, paths, tags=None, wheel_version=None): """ Build a wheel from files in specified paths, and use any specified tags when determining the name of the wheel. """ if tags is None: tags = {} libkey = list(filter(lambda o: o in paths, ('purelib', 'platlib')))[0] if libkey == 'platlib': is_pure = 'false' default_pyver = [IMPVER] default_abi = [ABI] default_arch = [ARCH] else: is_pure = 'true' default_pyver = [PYVER] default_abi = ['none'] default_arch = ['any'] self.pyver = tags.get('pyver', default_pyver) self.abi = tags.get('abi', default_abi) self.arch = tags.get('arch', default_arch) libdir = paths[libkey] name_ver = '%s-%s' % (self.name, self.version) data_dir = '%s.data' % name_ver info_dir = '%s.dist-info' % name_ver archive_paths = [] # First, stuff which is not in site-packages for key in ('data', 'headers', 'scripts'): if key not in paths: continue path = paths[key] if os.path.isdir(path): for root, dirs, files in os.walk(path): for fn in files: p = fsdecode(os.path.join(root, fn)) rp = os.path.relpath(p, path) ap = to_posix(os.path.join(data_dir, key, rp)) archive_paths.append((ap, p)) if key == 'scripts' and not p.endswith('.exe'): with open(p, 'rb') as f: data = f.read() data = self.process_shebang(data) with open(p, 'wb') as f: f.write(data) # Now, stuff which is in site-packages, other than the # distinfo stuff. path = libdir distinfo = None for root, dirs, files in os.walk(path): if root == path: # At the top level only, save distinfo for later # and skip it for now for i, dn in enumerate(dirs): dn = fsdecode(dn) if dn.endswith('.dist-info'): distinfo = os.path.join(root, dn) del dirs[i] break assert distinfo, '.dist-info directory expected, not found' for fn in files: # comment out next suite to leave .pyc files in if fsdecode(fn).endswith(('.pyc', '.pyo')): continue p = os.path.join(root, fn) rp = to_posix(os.path.relpath(p, path)) archive_paths.append((rp, p)) # Now distinfo. Assumed to be flat, i.e. os.listdir is enough. files = os.listdir(distinfo) for fn in files: if fn not in ('RECORD', 'INSTALLER', 'SHARED', 'WHEEL'): p = fsdecode(os.path.join(distinfo, fn)) ap = to_posix(os.path.join(info_dir, fn)) archive_paths.append((ap, p)) wheel_metadata = [ 'Wheel-Version: %d.%d' % (wheel_version or self.wheel_version), 'Generator: distlib %s' % __version__, 'Root-Is-Purelib: %s' % is_pure, ] for pyver, abi, arch in self.tags: wheel_metadata.append('Tag: %s-%s-%s' % (pyver, abi, arch)) p = os.path.join(distinfo, 'WHEEL') with open(p, 'w') as f: f.write('\n'.join(wheel_metadata)) ap = to_posix(os.path.join(info_dir, 'WHEEL')) archive_paths.append((ap, p)) # sort the entries by archive path. Not needed by any spec, but it # keeps the archive listing and RECORD tidier than they would otherwise # be. Use the number of path segments to keep directory entries together, # and keep the dist-info stuff at the end. def sorter(t): ap = t[0] n = ap.count('/') if '.dist-info' in ap: n += 10000 return (n, ap) archive_paths = sorted(archive_paths, key=sorter) # Now, at last, RECORD. # Paths in here are archive paths - nothing else makes sense. self.write_records((distinfo, info_dir), libdir, archive_paths) # Now, ready to build the zip file pathname = os.path.join(self.dirname, self.filename) self.build_zip(pathname, archive_paths) return pathname def skip_entry(self, arcname): """ Determine whether an archive entry should be skipped when verifying or installing. """ # The signature file won't be in RECORD, # and we don't currently don't do anything with it # We also skip directories, as they won't be in RECORD # either. See: # # https://github.com/pypa/wheel/issues/294 # https://github.com/pypa/wheel/issues/287 # https://github.com/pypa/wheel/pull/289 # return arcname.endswith(('/', '/RECORD.jws')) def install(self, paths, maker, **kwargs): """ Install a wheel to the specified paths. If kwarg ``warner`` is specified, it should be a callable, which will be called with two tuples indicating the wheel version of this software and the wheel version in the file, if there is a discrepancy in the versions. This can be used to issue any warnings to raise any exceptions. If kwarg ``lib_only`` is True, only the purelib/platlib files are installed, and the headers, scripts, data and dist-info metadata are not written. If kwarg ``bytecode_hashed_invalidation`` is True, written bytecode will try to use file-hash based invalidation (PEP-552) on supported interpreter versions (CPython 2.7+). The return value is a :class:`InstalledDistribution` instance unless ``options.lib_only`` is True, in which case the return value is ``None``. """ dry_run = maker.dry_run warner = kwargs.get('warner') lib_only = kwargs.get('lib_only', False) bc_hashed_invalidation = kwargs.get('bytecode_hashed_invalidation', False) pathname = os.path.join(self.dirname, self.filename) name_ver = '%s-%s' % (self.name, self.version) data_dir = '%s.data' % name_ver info_dir = '%s.dist-info' % name_ver metadata_name = posixpath.join(info_dir, LEGACY_METADATA_FILENAME) wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') record_name = posixpath.join(info_dir, 'RECORD') wrapper = codecs.getreader('utf-8') with ZipFile(pathname, 'r') as zf: with zf.open(wheel_metadata_name) as bwf: wf = wrapper(bwf) message = message_from_file(wf) wv = message['Wheel-Version'].split('.', 1) file_version = tuple([int(i) for i in wv]) if (file_version != self.wheel_version) and warner: warner(self.wheel_version, file_version) if message['Root-Is-Purelib'] == 'true': libdir = paths['purelib'] else: libdir = paths['platlib'] records = {} with zf.open(record_name) as bf: with CSVReader(stream=bf) as reader: for row in reader: p = row[0] records[p] = row data_pfx = posixpath.join(data_dir, '') info_pfx = posixpath.join(info_dir, '') script_pfx = posixpath.join(data_dir, 'scripts', '') # make a new instance rather than a copy of maker's, # as we mutate it fileop = FileOperator(dry_run=dry_run) fileop.record = True # so we can rollback if needed bc = not sys.dont_write_bytecode # Double negatives. Lovely! outfiles = [] # for RECORD writing # for script copying/shebang processing workdir = tempfile.mkdtemp() # set target dir later # we default add_launchers to False, as the # Python Launcher should be used instead maker.source_dir = workdir maker.target_dir = None try: for zinfo in zf.infolist(): arcname = zinfo.filename if isinstance(arcname, text_type): u_arcname = arcname else: u_arcname = arcname.decode('utf-8') if self.skip_entry(u_arcname): continue row = records[u_arcname] if row[2] and str(zinfo.file_size) != row[2]: raise DistlibException('size mismatch for ' '%s' % u_arcname) if row[1]: kind, value = row[1].split('=', 1) with zf.open(arcname) as bf: data = bf.read() _, digest = self.get_hash(data, kind) if digest != value: raise DistlibException('digest mismatch for ' '%s' % arcname) if lib_only and u_arcname.startswith((info_pfx, data_pfx)): logger.debug('lib_only: skipping %s', u_arcname) continue is_script = (u_arcname.startswith(script_pfx) and not u_arcname.endswith('.exe')) if u_arcname.startswith(data_pfx): _, where, rp = u_arcname.split('/', 2) outfile = os.path.join(paths[where], convert_path(rp)) else: # meant for site-packages. if u_arcname in (wheel_metadata_name, record_name): continue outfile = os.path.join(libdir, convert_path(u_arcname)) if not is_script: with zf.open(arcname) as bf: fileop.copy_stream(bf, outfile) # Issue #147: permission bits aren't preserved. Using # zf.extract(zinfo, libdir) should have worked, but didn't, # see https://www.thetopsites.net/article/53834422.shtml # So ... manually preserve permission bits as given in zinfo if os.name == 'posix': # just set the normal permission bits os.chmod(outfile, (zinfo.external_attr >> 16) & 0x1FF) outfiles.append(outfile) # Double check the digest of the written file if not dry_run and row[1]: with open(outfile, 'rb') as bf: data = bf.read() _, newdigest = self.get_hash(data, kind) if newdigest != digest: raise DistlibException('digest mismatch ' 'on write for ' '%s' % outfile) if bc and outfile.endswith('.py'): try: pyc = fileop.byte_compile(outfile, hashed_invalidation=bc_hashed_invalidation) outfiles.append(pyc) except Exception: # Don't give up if byte-compilation fails, # but log it and perhaps warn the user logger.warning('Byte-compilation failed', exc_info=True) else: fn = os.path.basename(convert_path(arcname)) workname = os.path.join(workdir, fn) with zf.open(arcname) as bf: fileop.copy_stream(bf, workname) dn, fn = os.path.split(outfile) maker.target_dir = dn filenames = maker.make(fn) fileop.set_executable_mode(filenames) outfiles.extend(filenames) if lib_only: logger.debug('lib_only: returning None') dist = None else: # Generate scripts # Try to get pydist.json so we can see if there are # any commands to generate. If this fails (e.g. because # of a legacy wheel), log a warning but don't give up. commands = None file_version = self.info['Wheel-Version'] if file_version == '1.0': # Use legacy info ep = posixpath.join(info_dir, 'entry_points.txt') try: with zf.open(ep) as bwf: epdata = read_exports(bwf) commands = {} for key in ('console', 'gui'): k = '%s_scripts' % key if k in epdata: commands['wrap_%s' % key] = d = {} for v in epdata[k].values(): s = '%s:%s' % (v.prefix, v.suffix) if v.flags: s += ' [%s]' % ','.join(v.flags) d[v.name] = s except Exception: logger.warning('Unable to read legacy script ' 'metadata, so cannot generate ' 'scripts') else: try: with zf.open(metadata_name) as bwf: wf = wrapper(bwf) commands = json.load(wf).get('extensions') if commands: commands = commands.get('python.commands') except Exception: logger.warning('Unable to read JSON metadata, so ' 'cannot generate scripts') if commands: console_scripts = commands.get('wrap_console', {}) gui_scripts = commands.get('wrap_gui', {}) if console_scripts or gui_scripts: script_dir = paths.get('scripts', '') if not os.path.isdir(script_dir): raise ValueError('Valid script path not ' 'specified') maker.target_dir = script_dir for k, v in console_scripts.items(): script = '%s = %s' % (k, v) filenames = maker.make(script) fileop.set_executable_mode(filenames) if gui_scripts: options = {'gui': True } for k, v in gui_scripts.items(): script = '%s = %s' % (k, v) filenames = maker.make(script, options) fileop.set_executable_mode(filenames) p = os.path.join(libdir, info_dir) dist = InstalledDistribution(p) # Write SHARED paths = dict(paths) # don't change passed in dict del paths['purelib'] del paths['platlib'] paths['lib'] = libdir p = dist.write_shared_locations(paths, dry_run) if p: outfiles.append(p) # Write RECORD dist.write_installed_files(outfiles, paths['prefix'], dry_run) return dist except Exception: # pragma: no cover logger.exception('installation failed.') fileop.rollback() raise finally: shutil.rmtree(workdir) def _get_dylib_cache(self): global cache if cache is None: # Use native string to avoid issues on 2.x: see Python #20140. base = os.path.join(get_cache_base(), str('dylib-cache'), '%s.%s' % sys.version_info[:2]) cache = Cache(base) return cache def _get_extensions(self): pathname = os.path.join(self.dirname, self.filename) name_ver = '%s-%s' % (self.name, self.version) info_dir = '%s.dist-info' % name_ver arcname = posixpath.join(info_dir, 'EXTENSIONS') wrapper = codecs.getreader('utf-8') result = [] with ZipFile(pathname, 'r') as zf: try: with zf.open(arcname) as bf: wf = wrapper(bf) extensions = json.load(wf) cache = self._get_dylib_cache() prefix = cache.prefix_to_dir(pathname) cache_base = os.path.join(cache.base, prefix) if not os.path.isdir(cache_base): os.makedirs(cache_base) for name, relpath in extensions.items(): dest = os.path.join(cache_base, convert_path(relpath)) if not os.path.exists(dest): extract = True else: file_time = os.stat(dest).st_mtime file_time = datetime.datetime.fromtimestamp(file_time) info = zf.getinfo(relpath) wheel_time = datetime.datetime(*info.date_time) extract = wheel_time > file_time if extract: zf.extract(relpath, cache_base) result.append((name, dest)) except KeyError: pass return result def is_compatible(self): """ Determine if a wheel is compatible with the running system. """ return is_compatible(self) def is_mountable(self): """ Determine if a wheel is asserted as mountable by its metadata. """ return True # for now - metadata details TBD def mount(self, append=False): pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) if not self.is_compatible(): msg = 'Wheel %s not compatible with this Python.' % pathname raise DistlibException(msg) if not self.is_mountable(): msg = 'Wheel %s is marked as not mountable.' % pathname raise DistlibException(msg) if pathname in sys.path: logger.debug('%s already in path', pathname) else: if append: sys.path.append(pathname) else: sys.path.insert(0, pathname) extensions = self._get_extensions() if extensions: if _hook not in sys.meta_path: sys.meta_path.append(_hook) _hook.add(pathname, extensions) def unmount(self): pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) if pathname not in sys.path: logger.debug('%s not in path', pathname) else: sys.path.remove(pathname) if pathname in _hook.impure_wheels: _hook.remove(pathname) if not _hook.impure_wheels: if _hook in sys.meta_path: sys.meta_path.remove(_hook) def verify(self): pathname = os.path.join(self.dirname, self.filename) name_ver = '%s-%s' % (self.name, self.version) data_dir = '%s.data' % name_ver info_dir = '%s.dist-info' % name_ver metadata_name = posixpath.join(info_dir, LEGACY_METADATA_FILENAME) wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') record_name = posixpath.join(info_dir, 'RECORD') wrapper = codecs.getreader('utf-8') with ZipFile(pathname, 'r') as zf: with zf.open(wheel_metadata_name) as bwf: wf = wrapper(bwf) message = message_from_file(wf) wv = message['Wheel-Version'].split('.', 1) file_version = tuple([int(i) for i in wv]) # TODO version verification records = {} with zf.open(record_name) as bf: with CSVReader(stream=bf) as reader: for row in reader: p = row[0] records[p] = row for zinfo in zf.infolist(): arcname = zinfo.filename if isinstance(arcname, text_type): u_arcname = arcname else: u_arcname = arcname.decode('utf-8') # See issue #115: some wheels have .. in their entries, but # in the filename ... e.g. __main__..py ! So the check is # updated to look for .. in the directory portions p = u_arcname.split('/') if '..' in p: raise DistlibException('invalid entry in ' 'wheel: %r' % u_arcname) if self.skip_entry(u_arcname): continue row = records[u_arcname] if row[2] and str(zinfo.file_size) != row[2]: raise DistlibException('size mismatch for ' '%s' % u_arcname) if row[1]: kind, value = row[1].split('=', 1) with zf.open(arcname) as bf: data = bf.read() _, digest = self.get_hash(data, kind) if digest != value: raise DistlibException('digest mismatch for ' '%s' % arcname) def update(self, modifier, dest_dir=None, **kwargs): """ Update the contents of a wheel in a generic way. The modifier should be a callable which expects a dictionary argument: its keys are archive-entry paths, and its values are absolute filesystem paths where the contents the corresponding archive entries can be found. The modifier is free to change the contents of the files pointed to, add new entries and remove entries, before returning. This method will extract the entire contents of the wheel to a temporary location, call the modifier, and then use the passed (and possibly updated) dictionary to write a new wheel. If ``dest_dir`` is specified, the new wheel is written there -- otherwise, the original wheel is overwritten. The modifier should return True if it updated the wheel, else False. This method returns the same value the modifier returns. """ def get_version(path_map, info_dir): version = path = None key = '%s/%s' % (info_dir, LEGACY_METADATA_FILENAME) if key not in path_map: key = '%s/PKG-INFO' % info_dir if key in path_map: path = path_map[key] version = Metadata(path=path).version return version, path def update_version(version, path): updated = None try: v = NormalizedVersion(version) i = version.find('-') if i < 0: updated = '%s+1' % version else: parts = [int(s) for s in version[i + 1:].split('.')] parts[-1] += 1 updated = '%s+%s' % (version[:i], '.'.join(str(i) for i in parts)) except UnsupportedVersionError: logger.debug('Cannot update non-compliant (PEP-440) ' 'version %r', version) if updated: md = Metadata(path=path) md.version = updated legacy = path.endswith(LEGACY_METADATA_FILENAME) md.write(path=path, legacy=legacy) logger.debug('Version updated from %r to %r', version, updated) pathname = os.path.join(self.dirname, self.filename) name_ver = '%s-%s' % (self.name, self.version) info_dir = '%s.dist-info' % name_ver record_name = posixpath.join(info_dir, 'RECORD') with tempdir() as workdir: with ZipFile(pathname, 'r') as zf: path_map = {} for zinfo in zf.infolist(): arcname = zinfo.filename if isinstance(arcname, text_type): u_arcname = arcname else: u_arcname = arcname.decode('utf-8') if u_arcname == record_name: continue if '..' in u_arcname: raise DistlibException('invalid entry in ' 'wheel: %r' % u_arcname) zf.extract(zinfo, workdir) path = os.path.join(workdir, convert_path(u_arcname)) path_map[u_arcname] = path # Remember the version. original_version, _ = get_version(path_map, info_dir) # Files extracted. Call the modifier. modified = modifier(path_map, **kwargs) if modified: # Something changed - need to build a new wheel. current_version, path = get_version(path_map, info_dir) if current_version and (current_version == original_version): # Add or update local version to signify changes. update_version(current_version, path) # Decide where the new wheel goes. if dest_dir is None: fd, newpath = tempfile.mkstemp(suffix='.whl', prefix='wheel-update-', dir=workdir) os.close(fd) else: if not os.path.isdir(dest_dir): raise DistlibException('Not a directory: %r' % dest_dir) newpath = os.path.join(dest_dir, self.filename) archive_paths = list(path_map.items()) distinfo = os.path.join(workdir, info_dir) info = distinfo, info_dir self.write_records(info, workdir, archive_paths) self.build_zip(newpath, archive_paths) if dest_dir is None: shutil.copyfile(newpath, pathname) return modified def _get_glibc_version(): import platform ver = platform.libc_ver() result = [] if ver[0] == 'glibc': for s in ver[1].split('.'): result.append(int(s) if s.isdigit() else 0) result = tuple(result) return result def compatible_tags(): """ Return (pyver, abi, arch) tuples compatible with this Python. """ versions = [VER_SUFFIX] major = VER_SUFFIX[0] for minor in range(sys.version_info[1] - 1, - 1, -1): versions.append(''.join([major, str(minor)])) abis = [] for suffix, _, _ in imp.get_suffixes(): if suffix.startswith('.abi'): abis.append(suffix.split('.', 2)[1]) abis.sort() if ABI != 'none': abis.insert(0, ABI) abis.append('none') result = [] arches = [ARCH] if sys.platform == 'darwin': m = re.match(r'(\w+)_(\d+)_(\d+)_(\w+)$', ARCH) if m: name, major, minor, arch = m.groups() minor = int(minor) matches = [arch] if arch in ('i386', 'ppc'): matches.append('fat') if arch in ('i386', 'ppc', 'x86_64'): matches.append('fat3') if arch in ('ppc64', 'x86_64'): matches.append('fat64') if arch in ('i386', 'x86_64'): matches.append('intel') if arch in ('i386', 'x86_64', 'intel', 'ppc', 'ppc64'): matches.append('universal') while minor >= 0: for match in matches: s = '%s_%s_%s_%s' % (name, major, minor, match) if s != ARCH: # already there arches.append(s) minor -= 1 # Most specific - our Python version, ABI and arch for abi in abis: for arch in arches: result.append((''.join((IMP_PREFIX, versions[0])), abi, arch)) # manylinux if abi != 'none' and sys.platform.startswith('linux'): arch = arch.replace('linux_', '') parts = _get_glibc_version() if len(parts) == 2: if parts >= (2, 5): result.append((''.join((IMP_PREFIX, versions[0])), abi, 'manylinux1_%s' % arch)) if parts >= (2, 12): result.append((''.join((IMP_PREFIX, versions[0])), abi, 'manylinux2010_%s' % arch)) if parts >= (2, 17): result.append((''.join((IMP_PREFIX, versions[0])), abi, 'manylinux2014_%s' % arch)) result.append((''.join((IMP_PREFIX, versions[0])), abi, 'manylinux_%s_%s_%s' % (parts[0], parts[1], arch))) # where no ABI / arch dependency, but IMP_PREFIX dependency for i, version in enumerate(versions): result.append((''.join((IMP_PREFIX, version)), 'none', 'any')) if i == 0: result.append((''.join((IMP_PREFIX, version[0])), 'none', 'any')) # no IMP_PREFIX, ABI or arch dependency for i, version in enumerate(versions): result.append((''.join(('py', version)), 'none', 'any')) if i == 0: result.append((''.join(('py', version[0])), 'none', 'any')) return set(result) COMPATIBLE_TAGS = compatible_tags() del compatible_tags def is_compatible(wheel, tags=None): if not isinstance(wheel, Wheel): wheel = Wheel(wheel) # assume it's a filename result = False if tags is None: tags = COMPATIBLE_TAGS for ver, abi, arch in tags: if ver in wheel.pyver and abi in wheel.abi and arch in wheel.arch: result = True break return result PKH]Io 8python3.10/site-packages/pip/_vendor/distlib/locators.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2012-2015 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # import gzip from io import BytesIO import json import logging import os import posixpath import re try: import threading except ImportError: # pragma: no cover import dummy_threading as threading import zlib from . import DistlibException from .compat import (urljoin, urlparse, urlunparse, url2pathname, pathname2url, queue, quote, unescape, build_opener, HTTPRedirectHandler as BaseRedirectHandler, text_type, Request, HTTPError, URLError) from .database import Distribution, DistributionPath, make_dist from .metadata import Metadata, MetadataInvalidError from .util import (cached_property, ensure_slash, split_filename, get_project_data, parse_requirement, parse_name_and_version, ServerProxy, normalize_name) from .version import get_scheme, UnsupportedVersionError from .wheel import Wheel, is_compatible logger = logging.getLogger(__name__) HASHER_HASH = re.compile(r'^(\w+)=([a-f0-9]+)') CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') DEFAULT_INDEX = 'https://pypi.org/pypi' def get_all_distribution_names(url=None): """ Return all distribution names known by an index. :param url: The URL of the index. :return: A list of all known distribution names. """ if url is None: url = DEFAULT_INDEX client = ServerProxy(url, timeout=3.0) try: return client.list_packages() finally: client('close')() class RedirectHandler(BaseRedirectHandler): """ A class to work around a bug in some Python 3.2.x releases. """ # There's a bug in the base version for some 3.2.x # (e.g. 3.2.2 on Ubuntu Oneiric). If a Location header # returns e.g. /abc, it bails because it says the scheme '' # is bogus, when actually it should use the request's # URL for the scheme. See Python issue #13696. def http_error_302(self, req, fp, code, msg, headers): # Some servers (incorrectly) return multiple Location headers # (so probably same goes for URI). Use first header. newurl = None for key in ('location', 'uri'): if key in headers: newurl = headers[key] break if newurl is None: # pragma: no cover return urlparts = urlparse(newurl) if urlparts.scheme == '': newurl = urljoin(req.get_full_url(), newurl) if hasattr(headers, 'replace_header'): headers.replace_header(key, newurl) else: headers[key] = newurl return BaseRedirectHandler.http_error_302(self, req, fp, code, msg, headers) http_error_301 = http_error_303 = http_error_307 = http_error_302 class Locator(object): """ A base class for locators - things that locate distributions. """ source_extensions = ('.tar.gz', '.tar.bz2', '.tar', '.zip', '.tgz', '.tbz') binary_extensions = ('.egg', '.exe', '.whl') excluded_extensions = ('.pdf',) # A list of tags indicating which wheels you want to match. The default # value of None matches against the tags compatible with the running # Python. If you want to match other values, set wheel_tags on a locator # instance to a list of tuples (pyver, abi, arch) which you want to match. wheel_tags = None downloadable_extensions = source_extensions + ('.whl',) def __init__(self, scheme='default'): """ Initialise an instance. :param scheme: Because locators look for most recent versions, they need to know the version scheme to use. This specifies the current PEP-recommended scheme - use ``'legacy'`` if you need to support existing distributions on PyPI. """ self._cache = {} self.scheme = scheme # Because of bugs in some of the handlers on some of the platforms, # we use our own opener rather than just using urlopen. self.opener = build_opener(RedirectHandler()) # If get_project() is called from locate(), the matcher instance # is set from the requirement passed to locate(). See issue #18 for # why this can be useful to know. self.matcher = None self.errors = queue.Queue() def get_errors(self): """ Return any errors which have occurred. """ result = [] while not self.errors.empty(): # pragma: no cover try: e = self.errors.get(False) result.append(e) except self.errors.Empty: continue self.errors.task_done() return result def clear_errors(self): """ Clear any errors which may have been logged. """ # Just get the errors and throw them away self.get_errors() def clear_cache(self): self._cache.clear() def _get_scheme(self): return self._scheme def _set_scheme(self, value): self._scheme = value scheme = property(_get_scheme, _set_scheme) def _get_project(self, name): """ For a given project, get a dictionary mapping available versions to Distribution instances. This should be implemented in subclasses. If called from a locate() request, self.matcher will be set to a matcher for the requirement to satisfy, otherwise it will be None. """ raise NotImplementedError('Please implement in the subclass') def get_distribution_names(self): """ Return all the distribution names known to this locator. """ raise NotImplementedError('Please implement in the subclass') def get_project(self, name): """ For a given project, get a dictionary mapping available versions to Distribution instances. This calls _get_project to do all the work, and just implements a caching layer on top. """ if self._cache is None: # pragma: no cover result = self._get_project(name) elif name in self._cache: result = self._cache[name] else: self.clear_errors() result = self._get_project(name) self._cache[name] = result return result def score_url(self, url): """ Give an url a score which can be used to choose preferred URLs for a given project release. """ t = urlparse(url) basename = posixpath.basename(t.path) compatible = True is_wheel = basename.endswith('.whl') is_downloadable = basename.endswith(self.downloadable_extensions) if is_wheel: compatible = is_compatible(Wheel(basename), self.wheel_tags) return (t.scheme == 'https', 'pypi.org' in t.netloc, is_downloadable, is_wheel, compatible, basename) def prefer_url(self, url1, url2): """ Choose one of two URLs where both are candidates for distribution archives for the same version of a distribution (for example, .tar.gz vs. zip). The current implementation favours https:// URLs over http://, archives from PyPI over those from other locations, wheel compatibility (if a wheel) and then the archive name. """ result = url2 if url1: s1 = self.score_url(url1) s2 = self.score_url(url2) if s1 > s2: result = url1 if result != url2: logger.debug('Not replacing %r with %r', url1, url2) else: logger.debug('Replacing %r with %r', url1, url2) return result def split_filename(self, filename, project_name): """ Attempt to split a filename in project name, version and Python version. """ return split_filename(filename, project_name) def convert_url_to_download_info(self, url, project_name): """ See if a URL is a candidate for a download URL for a project (the URL has typically been scraped from an HTML page). If it is, a dictionary is returned with keys "name", "version", "filename" and "url"; otherwise, None is returned. """ def same_project(name1, name2): return normalize_name(name1) == normalize_name(name2) result = None scheme, netloc, path, params, query, frag = urlparse(url) if frag.lower().startswith('egg='): # pragma: no cover logger.debug('%s: version hint in fragment: %r', project_name, frag) m = HASHER_HASH.match(frag) if m: algo, digest = m.groups() else: algo, digest = None, None origpath = path if path and path[-1] == '/': # pragma: no cover path = path[:-1] if path.endswith('.whl'): try: wheel = Wheel(path) if not is_compatible(wheel, self.wheel_tags): logger.debug('Wheel not compatible: %s', path) else: if project_name is None: include = True else: include = same_project(wheel.name, project_name) if include: result = { 'name': wheel.name, 'version': wheel.version, 'filename': wheel.filename, 'url': urlunparse((scheme, netloc, origpath, params, query, '')), 'python-version': ', '.join( ['.'.join(list(v[2:])) for v in wheel.pyver]), } except Exception as e: # pragma: no cover logger.warning('invalid path for wheel: %s', path) elif not path.endswith(self.downloadable_extensions): # pragma: no cover logger.debug('Not downloadable: %s', path) else: # downloadable extension path = filename = posixpath.basename(path) for ext in self.downloadable_extensions: if path.endswith(ext): path = path[:-len(ext)] t = self.split_filename(path, project_name) if not t: # pragma: no cover logger.debug('No match for project/version: %s', path) else: name, version, pyver = t if not project_name or same_project(project_name, name): result = { 'name': name, 'version': version, 'filename': filename, 'url': urlunparse((scheme, netloc, origpath, params, query, '')), #'packagetype': 'sdist', } if pyver: # pragma: no cover result['python-version'] = pyver break if result and algo: result['%s_digest' % algo] = digest return result def _get_digest(self, info): """ Get a digest from a dictionary by looking at a "digests" dictionary or keys of the form 'algo_digest'. Returns a 2-tuple (algo, digest) if found, else None. Currently looks only for SHA256, then MD5. """ result = None if 'digests' in info: digests = info['digests'] for algo in ('sha256', 'md5'): if algo in digests: result = (algo, digests[algo]) break if not result: for algo in ('sha256', 'md5'): key = '%s_digest' % algo if key in info: result = (algo, info[key]) break return result def _update_version_data(self, result, info): """ Update a result dictionary (the final result from _get_project) with a dictionary for a specific version, which typically holds information gleaned from a filename or URL for an archive for the distribution. """ name = info.pop('name') version = info.pop('version') if version in result: dist = result[version] md = dist.metadata else: dist = make_dist(name, version, scheme=self.scheme) md = dist.metadata dist.digest = digest = self._get_digest(info) url = info['url'] result['digests'][url] = digest if md.source_url != info['url']: md.source_url = self.prefer_url(md.source_url, url) result['urls'].setdefault(version, set()).add(url) dist.locator = self result[version] = dist def locate(self, requirement, prereleases=False): """ Find the most recent distribution which matches the given requirement. :param requirement: A requirement of the form 'foo (1.0)' or perhaps 'foo (>= 1.0, < 2.0, != 1.3)' :param prereleases: If ``True``, allow pre-release versions to be located. Otherwise, pre-release versions are not returned. :return: A :class:`Distribution` instance, or ``None`` if no such distribution could be located. """ result = None r = parse_requirement(requirement) if r is None: # pragma: no cover raise DistlibException('Not a valid requirement: %r' % requirement) scheme = get_scheme(self.scheme) self.matcher = matcher = scheme.matcher(r.requirement) logger.debug('matcher: %s (%s)', matcher, type(matcher).__name__) versions = self.get_project(r.name) if len(versions) > 2: # urls and digests keys are present # sometimes, versions are invalid slist = [] vcls = matcher.version_class for k in versions: if k in ('urls', 'digests'): continue try: if not matcher.match(k): pass # logger.debug('%s did not match %r', matcher, k) else: if prereleases or not vcls(k).is_prerelease: slist.append(k) # else: # logger.debug('skipping pre-release ' # 'version %s of %s', k, matcher.name) except Exception: # pragma: no cover logger.warning('error matching %s with %r', matcher, k) pass # slist.append(k) if len(slist) > 1: slist = sorted(slist, key=scheme.key) if slist: logger.debug('sorted list: %s', slist) version = slist[-1] result = versions[version] if result: if r.extras: result.extras = r.extras result.download_urls = versions.get('urls', {}).get(version, set()) d = {} sd = versions.get('digests', {}) for url in result.download_urls: if url in sd: # pragma: no cover d[url] = sd[url] result.digests = d self.matcher = None return result class PyPIRPCLocator(Locator): """ This locator uses XML-RPC to locate distributions. It therefore cannot be used with simple mirrors (that only mirror file content). """ def __init__(self, url, **kwargs): """ Initialise an instance. :param url: The URL to use for XML-RPC. :param kwargs: Passed to the superclass constructor. """ super(PyPIRPCLocator, self).__init__(**kwargs) self.base_url = url self.client = ServerProxy(url, timeout=3.0) def get_distribution_names(self): """ Return all the distribution names known to this locator. """ return set(self.client.list_packages()) def _get_project(self, name): result = {'urls': {}, 'digests': {}} versions = self.client.package_releases(name, True) for v in versions: urls = self.client.release_urls(name, v) data = self.client.release_data(name, v) metadata = Metadata(scheme=self.scheme) metadata.name = data['name'] metadata.version = data['version'] metadata.license = data.get('license') metadata.keywords = data.get('keywords', []) metadata.summary = data.get('summary') dist = Distribution(metadata) if urls: info = urls[0] metadata.source_url = info['url'] dist.digest = self._get_digest(info) dist.locator = self result[v] = dist for info in urls: url = info['url'] digest = self._get_digest(info) result['urls'].setdefault(v, set()).add(url) result['digests'][url] = digest return result class PyPIJSONLocator(Locator): """ This locator uses PyPI's JSON interface. It's very limited in functionality and probably not worth using. """ def __init__(self, url, **kwargs): super(PyPIJSONLocator, self).__init__(**kwargs) self.base_url = ensure_slash(url) def get_distribution_names(self): """ Return all the distribution names known to this locator. """ raise NotImplementedError('Not available from this locator') def _get_project(self, name): result = {'urls': {}, 'digests': {}} url = urljoin(self.base_url, '%s/json' % quote(name)) try: resp = self.opener.open(url) data = resp.read().decode() # for now d = json.loads(data) md = Metadata(scheme=self.scheme) data = d['info'] md.name = data['name'] md.version = data['version'] md.license = data.get('license') md.keywords = data.get('keywords', []) md.summary = data.get('summary') dist = Distribution(md) dist.locator = self urls = d['urls'] result[md.version] = dist for info in d['urls']: url = info['url'] dist.download_urls.add(url) dist.digests[url] = self._get_digest(info) result['urls'].setdefault(md.version, set()).add(url) result['digests'][url] = self._get_digest(info) # Now get other releases for version, infos in d['releases'].items(): if version == md.version: continue # already done omd = Metadata(scheme=self.scheme) omd.name = md.name omd.version = version odist = Distribution(omd) odist.locator = self result[version] = odist for info in infos: url = info['url'] odist.download_urls.add(url) odist.digests[url] = self._get_digest(info) result['urls'].setdefault(version, set()).add(url) result['digests'][url] = self._get_digest(info) # for info in urls: # md.source_url = info['url'] # dist.digest = self._get_digest(info) # dist.locator = self # for info in urls: # url = info['url'] # result['urls'].setdefault(md.version, set()).add(url) # result['digests'][url] = self._get_digest(info) except Exception as e: self.errors.put(text_type(e)) logger.exception('JSON fetch failed: %s', e) return result class Page(object): """ This class represents a scraped HTML page. """ # The following slightly hairy-looking regex just looks for the contents of # an anchor link, which has an attribute "href" either immediately preceded # or immediately followed by a "rel" attribute. The attribute values can be # declared with double quotes, single quotes or no quotes - which leads to # the length of the expression. _href = re.compile(""" (rel\\s*=\\s*(?:"(?P[^"]*)"|'(?P[^']*)'|(?P[^>\\s\n]*))\\s+)? href\\s*=\\s*(?:"(?P[^"]*)"|'(?P[^']*)'|(?P[^>\\s\n]*)) (\\s+rel\\s*=\\s*(?:"(?P[^"]*)"|'(?P[^']*)'|(?P[^>\\s\n]*)))? """, re.I | re.S | re.X) _base = re.compile(r"""]+)""", re.I | re.S) def __init__(self, data, url): """ Initialise an instance with the Unicode page contents and the URL they came from. """ self.data = data self.base_url = self.url = url m = self._base.search(self.data) if m: self.base_url = m.group(1) _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) @cached_property def links(self): """ Return the URLs of all the links on a page together with information about their "rel" attribute, for determining which ones to treat as downloads and which ones to queue for further scraping. """ def clean(url): "Tidy up an URL." scheme, netloc, path, params, query, frag = urlparse(url) return urlunparse((scheme, netloc, quote(path), params, query, frag)) result = set() for match in self._href.finditer(self.data): d = match.groupdict('') rel = (d['rel1'] or d['rel2'] or d['rel3'] or d['rel4'] or d['rel5'] or d['rel6']) url = d['url1'] or d['url2'] or d['url3'] url = urljoin(self.base_url, url) url = unescape(url) url = self._clean_re.sub(lambda m: '%%%2x' % ord(m.group(0)), url) result.add((url, rel)) # We sort the result, hoping to bring the most recent versions # to the front result = sorted(result, key=lambda t: t[0], reverse=True) return result class SimpleScrapingLocator(Locator): """ A locator which scrapes HTML pages to locate downloads for a distribution. This runs multiple threads to do the I/O; performance is at least as good as pip's PackageFinder, which works in an analogous fashion. """ # These are used to deal with various Content-Encoding schemes. decoders = { 'deflate': zlib.decompress, 'gzip': lambda b: gzip.GzipFile(fileobj=BytesIO(b)).read(), 'none': lambda b: b, } def __init__(self, url, timeout=None, num_workers=10, **kwargs): """ Initialise an instance. :param url: The root URL to use for scraping. :param timeout: The timeout, in seconds, to be applied to requests. This defaults to ``None`` (no timeout specified). :param num_workers: The number of worker threads you want to do I/O, This defaults to 10. :param kwargs: Passed to the superclass. """ super(SimpleScrapingLocator, self).__init__(**kwargs) self.base_url = ensure_slash(url) self.timeout = timeout self._page_cache = {} self._seen = set() self._to_fetch = queue.Queue() self._bad_hosts = set() self.skip_externals = False self.num_workers = num_workers self._lock = threading.RLock() # See issue #45: we need to be resilient when the locator is used # in a thread, e.g. with concurrent.futures. We can't use self._lock # as it is for coordinating our internal threads - the ones created # in _prepare_threads. self._gplock = threading.RLock() self.platform_check = False # See issue #112 def _prepare_threads(self): """ Threads are created only when get_project is called, and terminate before it returns. They are there primarily to parallelise I/O (i.e. fetching web pages). """ self._threads = [] for i in range(self.num_workers): t = threading.Thread(target=self._fetch) t.setDaemon(True) t.start() self._threads.append(t) def _wait_threads(self): """ Tell all the threads to terminate (by sending a sentinel value) and wait for them to do so. """ # Note that you need two loops, since you can't say which # thread will get each sentinel for t in self._threads: self._to_fetch.put(None) # sentinel for t in self._threads: t.join() self._threads = [] def _get_project(self, name): result = {'urls': {}, 'digests': {}} with self._gplock: self.result = result self.project_name = name url = urljoin(self.base_url, '%s/' % quote(name)) self._seen.clear() self._page_cache.clear() self._prepare_threads() try: logger.debug('Queueing %s', url) self._to_fetch.put(url) self._to_fetch.join() finally: self._wait_threads() del self.result return result platform_dependent = re.compile(r'\b(linux_(i\d86|x86_64|arm\w+)|' r'win(32|_amd64)|macosx_?\d+)\b', re.I) def _is_platform_dependent(self, url): """ Does an URL refer to a platform-specific download? """ return self.platform_dependent.search(url) def _process_download(self, url): """ See if an URL is a suitable download for a project. If it is, register information in the result dictionary (for _get_project) about the specific version it's for. Note that the return value isn't actually used other than as a boolean value. """ if self.platform_check and self._is_platform_dependent(url): info = None else: info = self.convert_url_to_download_info(url, self.project_name) logger.debug('process_download: %s -> %s', url, info) if info: with self._lock: # needed because self.result is shared self._update_version_data(self.result, info) return info def _should_queue(self, link, referrer, rel): """ Determine whether a link URL from a referring page and with a particular "rel" attribute should be queued for scraping. """ scheme, netloc, path, _, _, _ = urlparse(link) if path.endswith(self.source_extensions + self.binary_extensions + self.excluded_extensions): result = False elif self.skip_externals and not link.startswith(self.base_url): result = False elif not referrer.startswith(self.base_url): result = False elif rel not in ('homepage', 'download'): result = False elif scheme not in ('http', 'https', 'ftp'): result = False elif self._is_platform_dependent(link): result = False else: host = netloc.split(':', 1)[0] if host.lower() == 'localhost': result = False else: result = True logger.debug('should_queue: %s (%s) from %s -> %s', link, rel, referrer, result) return result def _fetch(self): """ Get a URL to fetch from the work queue, get the HTML page, examine its links for download candidates and candidates for further scraping. This is a handy method to run in a thread. """ while True: url = self._to_fetch.get() try: if url: page = self.get_page(url) if page is None: # e.g. after an error continue for link, rel in page.links: if link not in self._seen: try: self._seen.add(link) if (not self._process_download(link) and self._should_queue(link, url, rel)): logger.debug('Queueing %s from %s', link, url) self._to_fetch.put(link) except MetadataInvalidError: # e.g. invalid versions pass except Exception as e: # pragma: no cover self.errors.put(text_type(e)) finally: # always do this, to avoid hangs :-) self._to_fetch.task_done() if not url: #logger.debug('Sentinel seen, quitting.') break def get_page(self, url): """ Get the HTML for an URL, possibly from an in-memory cache. XXX TODO Note: this cache is never actually cleared. It's assumed that the data won't get stale over the lifetime of a locator instance (not necessarily true for the default_locator). """ # http://peak.telecommunity.com/DevCenter/EasyInstall#package-index-api scheme, netloc, path, _, _, _ = urlparse(url) if scheme == 'file' and os.path.isdir(url2pathname(path)): url = urljoin(ensure_slash(url), 'index.html') if url in self._page_cache: result = self._page_cache[url] logger.debug('Returning %s from cache: %s', url, result) else: host = netloc.split(':', 1)[0] result = None if host in self._bad_hosts: logger.debug('Skipping %s due to bad host %s', url, host) else: req = Request(url, headers={'Accept-encoding': 'identity'}) try: logger.debug('Fetching %s', url) resp = self.opener.open(req, timeout=self.timeout) logger.debug('Fetched %s', url) headers = resp.info() content_type = headers.get('Content-Type', '') if HTML_CONTENT_TYPE.match(content_type): final_url = resp.geturl() data = resp.read() encoding = headers.get('Content-Encoding') if encoding: decoder = self.decoders[encoding] # fail if not found data = decoder(data) encoding = 'utf-8' m = CHARSET.search(content_type) if m: encoding = m.group(1) try: data = data.decode(encoding) except UnicodeError: # pragma: no cover data = data.decode('latin-1') # fallback result = Page(data, final_url) self._page_cache[final_url] = result except HTTPError as e: if e.code != 404: logger.exception('Fetch failed: %s: %s', url, e) except URLError as e: # pragma: no cover logger.exception('Fetch failed: %s: %s', url, e) with self._lock: self._bad_hosts.add(host) except Exception as e: # pragma: no cover logger.exception('Fetch failed: %s: %s', url, e) finally: self._page_cache[url] = result # even if None (failure) return result _distname_re = re.compile(']*>([^<]+)<') def get_distribution_names(self): """ Return all the distribution names known to this locator. """ result = set() page = self.get_page(self.base_url) if not page: raise DistlibException('Unable to get %s' % self.base_url) for match in self._distname_re.finditer(page.data): result.add(match.group(1)) return result class DirectoryLocator(Locator): """ This class locates distributions in a directory tree. """ def __init__(self, path, **kwargs): """ Initialise an instance. :param path: The root of the directory tree to search. :param kwargs: Passed to the superclass constructor, except for: * recursive - if True (the default), subdirectories are recursed into. If False, only the top-level directory is searched, """ self.recursive = kwargs.pop('recursive', True) super(DirectoryLocator, self).__init__(**kwargs) path = os.path.abspath(path) if not os.path.isdir(path): # pragma: no cover raise DistlibException('Not a directory: %r' % path) self.base_dir = path def should_include(self, filename, parent): """ Should a filename be considered as a candidate for a distribution archive? As well as the filename, the directory which contains it is provided, though not used by the current implementation. """ return filename.endswith(self.downloadable_extensions) def _get_project(self, name): result = {'urls': {}, 'digests': {}} for root, dirs, files in os.walk(self.base_dir): for fn in files: if self.should_include(fn, root): fn = os.path.join(root, fn) url = urlunparse(('file', '', pathname2url(os.path.abspath(fn)), '', '', '')) info = self.convert_url_to_download_info(url, name) if info: self._update_version_data(result, info) if not self.recursive: break return result def get_distribution_names(self): """ Return all the distribution names known to this locator. """ result = set() for root, dirs, files in os.walk(self.base_dir): for fn in files: if self.should_include(fn, root): fn = os.path.join(root, fn) url = urlunparse(('file', '', pathname2url(os.path.abspath(fn)), '', '', '')) info = self.convert_url_to_download_info(url, None) if info: result.add(info['name']) if not self.recursive: break return result class JSONLocator(Locator): """ This locator uses special extended metadata (not available on PyPI) and is the basis of performant dependency resolution in distlib. Other locators require archive downloads before dependencies can be determined! As you might imagine, that can be slow. """ def get_distribution_names(self): """ Return all the distribution names known to this locator. """ raise NotImplementedError('Not available from this locator') def _get_project(self, name): result = {'urls': {}, 'digests': {}} data = get_project_data(name) if data: for info in data.get('files', []): if info['ptype'] != 'sdist' or info['pyversion'] != 'source': continue # We don't store summary in project metadata as it makes # the data bigger for no benefit during dependency # resolution dist = make_dist(data['name'], info['version'], summary=data.get('summary', 'Placeholder for summary'), scheme=self.scheme) md = dist.metadata md.source_url = info['url'] # TODO SHA256 digest if 'digest' in info and info['digest']: dist.digest = ('md5', info['digest']) md.dependencies = info.get('requirements', {}) dist.exports = info.get('exports', {}) result[dist.version] = dist result['urls'].setdefault(dist.version, set()).add(info['url']) return result class DistPathLocator(Locator): """ This locator finds installed distributions in a path. It can be useful for adding to an :class:`AggregatingLocator`. """ def __init__(self, distpath, **kwargs): """ Initialise an instance. :param distpath: A :class:`DistributionPath` instance to search. """ super(DistPathLocator, self).__init__(**kwargs) assert isinstance(distpath, DistributionPath) self.distpath = distpath def _get_project(self, name): dist = self.distpath.get_distribution(name) if dist is None: result = {'urls': {}, 'digests': {}} else: result = { dist.version: dist, 'urls': {dist.version: set([dist.source_url])}, 'digests': {dist.version: set([None])} } return result class AggregatingLocator(Locator): """ This class allows you to chain and/or merge a list of locators. """ def __init__(self, *locators, **kwargs): """ Initialise an instance. :param locators: The list of locators to search. :param kwargs: Passed to the superclass constructor, except for: * merge - if False (the default), the first successful search from any of the locators is returned. If True, the results from all locators are merged (this can be slow). """ self.merge = kwargs.pop('merge', False) self.locators = locators super(AggregatingLocator, self).__init__(**kwargs) def clear_cache(self): super(AggregatingLocator, self).clear_cache() for locator in self.locators: locator.clear_cache() def _set_scheme(self, value): self._scheme = value for locator in self.locators: locator.scheme = value scheme = property(Locator.scheme.fget, _set_scheme) def _get_project(self, name): result = {} for locator in self.locators: d = locator.get_project(name) if d: if self.merge: files = result.get('urls', {}) digests = result.get('digests', {}) # next line could overwrite result['urls'], result['digests'] result.update(d) df = result.get('urls') if files and df: for k, v in files.items(): if k in df: df[k] |= v else: df[k] = v dd = result.get('digests') if digests and dd: dd.update(digests) else: # See issue #18. If any dists are found and we're looking # for specific constraints, we only return something if # a match is found. For example, if a DirectoryLocator # returns just foo (1.0) while we're looking for # foo (>= 2.0), we'll pretend there was nothing there so # that subsequent locators can be queried. Otherwise we # would just return foo (1.0) which would then lead to a # failure to find foo (>= 2.0), because other locators # weren't searched. Note that this only matters when # merge=False. if self.matcher is None: found = True else: found = False for k in d: if self.matcher.match(k): found = True break if found: result = d break return result def get_distribution_names(self): """ Return all the distribution names known to this locator. """ result = set() for locator in self.locators: try: result |= locator.get_distribution_names() except NotImplementedError: pass return result # We use a legacy scheme simply because most of the dists on PyPI use legacy # versions which don't conform to PEP 426 / PEP 440. default_locator = AggregatingLocator( JSONLocator(), SimpleScrapingLocator('https://pypi.org/simple/', timeout=3.0), scheme='legacy') locate = default_locator.locate class DependencyFinder(object): """ Locate dependencies for distributions. """ def __init__(self, locator=None): """ Initialise an instance, using the specified locator to locate distributions. """ self.locator = locator or default_locator self.scheme = get_scheme(self.locator.scheme) def add_distribution(self, dist): """ Add a distribution to the finder. This will update internal information about who provides what. :param dist: The distribution to add. """ logger.debug('adding distribution %s', dist) name = dist.key self.dists_by_name[name] = dist self.dists[(name, dist.version)] = dist for p in dist.provides: name, version = parse_name_and_version(p) logger.debug('Add to provided: %s, %s, %s', name, version, dist) self.provided.setdefault(name, set()).add((version, dist)) def remove_distribution(self, dist): """ Remove a distribution from the finder. This will update internal information about who provides what. :param dist: The distribution to remove. """ logger.debug('removing distribution %s', dist) name = dist.key del self.dists_by_name[name] del self.dists[(name, dist.version)] for p in dist.provides: name, version = parse_name_and_version(p) logger.debug('Remove from provided: %s, %s, %s', name, version, dist) s = self.provided[name] s.remove((version, dist)) if not s: del self.provided[name] def get_matcher(self, reqt): """ Get a version matcher for a requirement. :param reqt: The requirement :type reqt: str :return: A version matcher (an instance of :class:`distlib.version.Matcher`). """ try: matcher = self.scheme.matcher(reqt) except UnsupportedVersionError: # pragma: no cover # XXX compat-mode if cannot read the version name = reqt.split()[0] matcher = self.scheme.matcher(name) return matcher def find_providers(self, reqt): """ Find the distributions which can fulfill a requirement. :param reqt: The requirement. :type reqt: str :return: A set of distribution which can fulfill the requirement. """ matcher = self.get_matcher(reqt) name = matcher.key # case-insensitive result = set() provided = self.provided if name in provided: for version, provider in provided[name]: try: match = matcher.match(version) except UnsupportedVersionError: match = False if match: result.add(provider) break return result def try_to_replace(self, provider, other, problems): """ Attempt to replace one provider with another. This is typically used when resolving dependencies from multiple sources, e.g. A requires (B >= 1.0) while C requires (B >= 1.1). For successful replacement, ``provider`` must meet all the requirements which ``other`` fulfills. :param provider: The provider we are trying to replace with. :param other: The provider we're trying to replace. :param problems: If False is returned, this will contain what problems prevented replacement. This is currently a tuple of the literal string 'cantreplace', ``provider``, ``other`` and the set of requirements that ``provider`` couldn't fulfill. :return: True if we can replace ``other`` with ``provider``, else False. """ rlist = self.reqts[other] unmatched = set() for s in rlist: matcher = self.get_matcher(s) if not matcher.match(provider.version): unmatched.add(s) if unmatched: # can't replace other with provider problems.add(('cantreplace', provider, other, frozenset(unmatched))) result = False else: # can replace other with provider self.remove_distribution(other) del self.reqts[other] for s in rlist: self.reqts.setdefault(provider, set()).add(s) self.add_distribution(provider) result = True return result def find(self, requirement, meta_extras=None, prereleases=False): """ Find a distribution and all distributions it depends on. :param requirement: The requirement specifying the distribution to find, or a Distribution instance. :param meta_extras: A list of meta extras such as :test:, :build: and so on. :param prereleases: If ``True``, allow pre-release versions to be returned - otherwise, don't return prereleases unless they're all that's available. Return a set of :class:`Distribution` instances and a set of problems. The distributions returned should be such that they have the :attr:`required` attribute set to ``True`` if they were from the ``requirement`` passed to ``find()``, and they have the :attr:`build_time_dependency` attribute set to ``True`` unless they are post-installation dependencies of the ``requirement``. The problems should be a tuple consisting of the string ``'unsatisfied'`` and the requirement which couldn't be satisfied by any distribution known to the locator. """ self.provided = {} self.dists = {} self.dists_by_name = {} self.reqts = {} meta_extras = set(meta_extras or []) if ':*:' in meta_extras: meta_extras.remove(':*:') # :meta: and :run: are implicitly included meta_extras |= set([':test:', ':build:', ':dev:']) if isinstance(requirement, Distribution): dist = odist = requirement logger.debug('passed %s as requirement', odist) else: dist = odist = self.locator.locate(requirement, prereleases=prereleases) if dist is None: raise DistlibException('Unable to locate %r' % requirement) logger.debug('located %s', odist) dist.requested = True problems = set() todo = set([dist]) install_dists = set([odist]) while todo: dist = todo.pop() name = dist.key # case-insensitive if name not in self.dists_by_name: self.add_distribution(dist) else: #import pdb; pdb.set_trace() other = self.dists_by_name[name] if other != dist: self.try_to_replace(dist, other, problems) ireqts = dist.run_requires | dist.meta_requires sreqts = dist.build_requires ereqts = set() if meta_extras and dist in install_dists: for key in ('test', 'build', 'dev'): e = ':%s:' % key if e in meta_extras: ereqts |= getattr(dist, '%s_requires' % key) all_reqts = ireqts | sreqts | ereqts for r in all_reqts: providers = self.find_providers(r) if not providers: logger.debug('No providers found for %r', r) provider = self.locator.locate(r, prereleases=prereleases) # If no provider is found and we didn't consider # prereleases, consider them now. if provider is None and not prereleases: provider = self.locator.locate(r, prereleases=True) if provider is None: logger.debug('Cannot satisfy %r', r) problems.add(('unsatisfied', r)) else: n, v = provider.key, provider.version if (n, v) not in self.dists: todo.add(provider) providers.add(provider) if r in ireqts and dist in install_dists: install_dists.add(provider) logger.debug('Adding %s to install_dists', provider.name_and_version) for p in providers: name = p.key if name not in self.dists_by_name: self.reqts.setdefault(p, set()).add(r) else: other = self.dists_by_name[name] if other != p: # see if other can be replaced by p self.try_to_replace(p, other, problems) dists = set(self.dists.values()) for dist in dists: dist.build_time_dependency = dist not in install_dists if dist.build_time_dependency: logger.debug('%s is a build-time dependency only.', dist.name_and_version) logger.debug('find done for %s', odist) return dists, problems PKH]2[[7python3.10/site-packages/pip/_vendor/distlib/version.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2012-2017 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # """ Implementation of a flexible versioning scheme providing support for PEP-440, setuptools-compatible and semantic versioning. """ import logging import re from .compat import string_types from .util import parse_requirement __all__ = ['NormalizedVersion', 'NormalizedMatcher', 'LegacyVersion', 'LegacyMatcher', 'SemanticVersion', 'SemanticMatcher', 'UnsupportedVersionError', 'get_scheme'] logger = logging.getLogger(__name__) class UnsupportedVersionError(ValueError): """This is an unsupported version.""" pass class Version(object): def __init__(self, s): self._string = s = s.strip() self._parts = parts = self.parse(s) assert isinstance(parts, tuple) assert len(parts) > 0 def parse(self, s): raise NotImplementedError('please implement in a subclass') def _check_compatible(self, other): if type(self) != type(other): raise TypeError('cannot compare %r and %r' % (self, other)) def __eq__(self, other): self._check_compatible(other) return self._parts == other._parts def __ne__(self, other): return not self.__eq__(other) def __lt__(self, other): self._check_compatible(other) return self._parts < other._parts def __gt__(self, other): return not (self.__lt__(other) or self.__eq__(other)) def __le__(self, other): return self.__lt__(other) or self.__eq__(other) def __ge__(self, other): return self.__gt__(other) or self.__eq__(other) # See http://docs.python.org/reference/datamodel#object.__hash__ def __hash__(self): return hash(self._parts) def __repr__(self): return "%s('%s')" % (self.__class__.__name__, self._string) def __str__(self): return self._string @property def is_prerelease(self): raise NotImplementedError('Please implement in subclasses.') class Matcher(object): version_class = None # value is either a callable or the name of a method _operators = { '<': lambda v, c, p: v < c, '>': lambda v, c, p: v > c, '<=': lambda v, c, p: v == c or v < c, '>=': lambda v, c, p: v == c or v > c, '==': lambda v, c, p: v == c, '===': lambda v, c, p: v == c, # by default, compatible => >=. '~=': lambda v, c, p: v == c or v > c, '!=': lambda v, c, p: v != c, } # this is a method only to support alternative implementations # via overriding def parse_requirement(self, s): return parse_requirement(s) def __init__(self, s): if self.version_class is None: raise ValueError('Please specify a version class') self._string = s = s.strip() r = self.parse_requirement(s) if not r: raise ValueError('Not valid: %r' % s) self.name = r.name self.key = self.name.lower() # for case-insensitive comparisons clist = [] if r.constraints: # import pdb; pdb.set_trace() for op, s in r.constraints: if s.endswith('.*'): if op not in ('==', '!='): raise ValueError('\'.*\' not allowed for ' '%r constraints' % op) # Could be a partial version (e.g. for '2.*') which # won't parse as a version, so keep it as a string vn, prefix = s[:-2], True # Just to check that vn is a valid version self.version_class(vn) else: # Should parse as a version, so we can create an # instance for the comparison vn, prefix = self.version_class(s), False clist.append((op, vn, prefix)) self._parts = tuple(clist) def match(self, version): """ Check if the provided version matches the constraints. :param version: The version to match against this instance. :type version: String or :class:`Version` instance. """ if isinstance(version, string_types): version = self.version_class(version) for operator, constraint, prefix in self._parts: f = self._operators.get(operator) if isinstance(f, string_types): f = getattr(self, f) if not f: msg = ('%r not implemented ' 'for %s' % (operator, self.__class__.__name__)) raise NotImplementedError(msg) if not f(version, constraint, prefix): return False return True @property def exact_version(self): result = None if len(self._parts) == 1 and self._parts[0][0] in ('==', '==='): result = self._parts[0][1] return result def _check_compatible(self, other): if type(self) != type(other) or self.name != other.name: raise TypeError('cannot compare %s and %s' % (self, other)) def __eq__(self, other): self._check_compatible(other) return self.key == other.key and self._parts == other._parts def __ne__(self, other): return not self.__eq__(other) # See http://docs.python.org/reference/datamodel#object.__hash__ def __hash__(self): return hash(self.key) + hash(self._parts) def __repr__(self): return "%s(%r)" % (self.__class__.__name__, self._string) def __str__(self): return self._string PEP440_VERSION_RE = re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|b|c|rc)(\d+))?' r'(\.(post)(\d+))?(\.(dev)(\d+))?' r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$') def _pep_440_key(s): s = s.strip() m = PEP440_VERSION_RE.match(s) if not m: raise UnsupportedVersionError('Not a valid version: %s' % s) groups = m.groups() nums = tuple(int(v) for v in groups[1].split('.')) while len(nums) > 1 and nums[-1] == 0: nums = nums[:-1] if not groups[0]: epoch = 0 else: epoch = int(groups[0][:-1]) pre = groups[4:6] post = groups[7:9] dev = groups[10:12] local = groups[13] if pre == (None, None): pre = () else: pre = pre[0], int(pre[1]) if post == (None, None): post = () else: post = post[0], int(post[1]) if dev == (None, None): dev = () else: dev = dev[0], int(dev[1]) if local is None: local = () else: parts = [] for part in local.split('.'): # to ensure that numeric compares as > lexicographic, avoid # comparing them directly, but encode a tuple which ensures # correct sorting if part.isdigit(): part = (1, int(part)) else: part = (0, part) parts.append(part) local = tuple(parts) if not pre: # either before pre-release, or final release and after if not post and dev: # before pre-release pre = ('a', -1) # to sort before a0 else: pre = ('z',) # to sort after all pre-releases # now look at the state of post and dev. if not post: post = ('_',) # sort before 'a' if not dev: dev = ('final',) #print('%s -> %s' % (s, m.groups())) return epoch, nums, pre, post, dev, local _normalized_key = _pep_440_key class NormalizedVersion(Version): """A rational version. Good: 1.2 # equivalent to "1.2.0" 1.2.0 1.2a1 1.2.3a2 1.2.3b1 1.2.3c1 1.2.3.4 TODO: fill this out Bad: 1 # minimum two numbers 1.2a # release level must have a release serial 1.2.3b """ def parse(self, s): result = _normalized_key(s) # _normalized_key loses trailing zeroes in the release # clause, since that's needed to ensure that X.Y == X.Y.0 == X.Y.0.0 # However, PEP 440 prefix matching needs it: for example, # (~= 1.4.5.0) matches differently to (~= 1.4.5.0.0). m = PEP440_VERSION_RE.match(s) # must succeed groups = m.groups() self._release_clause = tuple(int(v) for v in groups[1].split('.')) return result PREREL_TAGS = set(['a', 'b', 'c', 'rc', 'dev']) @property def is_prerelease(self): return any(t[0] in self.PREREL_TAGS for t in self._parts if t) def _match_prefix(x, y): x = str(x) y = str(y) if x == y: return True if not x.startswith(y): return False n = len(y) return x[n] == '.' class NormalizedMatcher(Matcher): version_class = NormalizedVersion # value is either a callable or the name of a method _operators = { '~=': '_match_compatible', '<': '_match_lt', '>': '_match_gt', '<=': '_match_le', '>=': '_match_ge', '==': '_match_eq', '===': '_match_arbitrary', '!=': '_match_ne', } def _adjust_local(self, version, constraint, prefix): if prefix: strip_local = '+' not in constraint and version._parts[-1] else: # both constraint and version are # NormalizedVersion instances. # If constraint does not have a local component, # ensure the version doesn't, either. strip_local = not constraint._parts[-1] and version._parts[-1] if strip_local: s = version._string.split('+', 1)[0] version = self.version_class(s) return version, constraint def _match_lt(self, version, constraint, prefix): version, constraint = self._adjust_local(version, constraint, prefix) if version >= constraint: return False release_clause = constraint._release_clause pfx = '.'.join([str(i) for i in release_clause]) return not _match_prefix(version, pfx) def _match_gt(self, version, constraint, prefix): version, constraint = self._adjust_local(version, constraint, prefix) if version <= constraint: return False release_clause = constraint._release_clause pfx = '.'.join([str(i) for i in release_clause]) return not _match_prefix(version, pfx) def _match_le(self, version, constraint, prefix): version, constraint = self._adjust_local(version, constraint, prefix) return version <= constraint def _match_ge(self, version, constraint, prefix): version, constraint = self._adjust_local(version, constraint, prefix) return version >= constraint def _match_eq(self, version, constraint, prefix): version, constraint = self._adjust_local(version, constraint, prefix) if not prefix: result = (version == constraint) else: result = _match_prefix(version, constraint) return result def _match_arbitrary(self, version, constraint, prefix): return str(version) == str(constraint) def _match_ne(self, version, constraint, prefix): version, constraint = self._adjust_local(version, constraint, prefix) if not prefix: result = (version != constraint) else: result = not _match_prefix(version, constraint) return result def _match_compatible(self, version, constraint, prefix): version, constraint = self._adjust_local(version, constraint, prefix) if version == constraint: return True if version < constraint: return False # if not prefix: # return True release_clause = constraint._release_clause if len(release_clause) > 1: release_clause = release_clause[:-1] pfx = '.'.join([str(i) for i in release_clause]) return _match_prefix(version, pfx) _REPLACEMENTS = ( (re.compile('[.+-]$'), ''), # remove trailing puncts (re.compile(r'^[.](\d)'), r'0.\1'), # .N -> 0.N at start (re.compile('^[.-]'), ''), # remove leading puncts (re.compile(r'^\((.*)\)$'), r'\1'), # remove parentheses (re.compile(r'^v(ersion)?\s*(\d+)'), r'\2'), # remove leading v(ersion) (re.compile(r'^r(ev)?\s*(\d+)'), r'\2'), # remove leading v(ersion) (re.compile('[.]{2,}'), '.'), # multiple runs of '.' (re.compile(r'\b(alfa|apha)\b'), 'alpha'), # misspelt alpha (re.compile(r'\b(pre-alpha|prealpha)\b'), 'pre.alpha'), # standardise (re.compile(r'\(beta\)$'), 'beta'), # remove parentheses ) _SUFFIX_REPLACEMENTS = ( (re.compile('^[:~._+-]+'), ''), # remove leading puncts (re.compile('[,*")([\\]]'), ''), # remove unwanted chars (re.compile('[~:+_ -]'), '.'), # replace illegal chars (re.compile('[.]{2,}'), '.'), # multiple runs of '.' (re.compile(r'\.$'), ''), # trailing '.' ) _NUMERIC_PREFIX = re.compile(r'(\d+(\.\d+)*)') def _suggest_semantic_version(s): """ Try to suggest a semantic form for a version for which _suggest_normalized_version couldn't come up with anything. """ result = s.strip().lower() for pat, repl in _REPLACEMENTS: result = pat.sub(repl, result) if not result: result = '0.0.0' # Now look for numeric prefix, and separate it out from # the rest. #import pdb; pdb.set_trace() m = _NUMERIC_PREFIX.match(result) if not m: prefix = '0.0.0' suffix = result else: prefix = m.groups()[0].split('.') prefix = [int(i) for i in prefix] while len(prefix) < 3: prefix.append(0) if len(prefix) == 3: suffix = result[m.end():] else: suffix = '.'.join([str(i) for i in prefix[3:]]) + result[m.end():] prefix = prefix[:3] prefix = '.'.join([str(i) for i in prefix]) suffix = suffix.strip() if suffix: #import pdb; pdb.set_trace() # massage the suffix. for pat, repl in _SUFFIX_REPLACEMENTS: suffix = pat.sub(repl, suffix) if not suffix: result = prefix else: sep = '-' if 'dev' in suffix else '+' result = prefix + sep + suffix if not is_semver(result): result = None return result def _suggest_normalized_version(s): """Suggest a normalized version close to the given version string. If you have a version string that isn't rational (i.e. NormalizedVersion doesn't like it) then you might be able to get an equivalent (or close) rational version from this function. This does a number of simple normalizations to the given string, based on observation of versions currently in use on PyPI. Given a dump of those version during PyCon 2009, 4287 of them: - 2312 (53.93%) match NormalizedVersion without change with the automatic suggestion - 3474 (81.04%) match when using this suggestion method @param s {str} An irrational version string. @returns A rational version string, or None, if couldn't determine one. """ try: _normalized_key(s) return s # already rational except UnsupportedVersionError: pass rs = s.lower() # part of this could use maketrans for orig, repl in (('-alpha', 'a'), ('-beta', 'b'), ('alpha', 'a'), ('beta', 'b'), ('rc', 'c'), ('-final', ''), ('-pre', 'c'), ('-release', ''), ('.release', ''), ('-stable', ''), ('+', '.'), ('_', '.'), (' ', ''), ('.final', ''), ('final', '')): rs = rs.replace(orig, repl) # if something ends with dev or pre, we add a 0 rs = re.sub(r"pre$", r"pre0", rs) rs = re.sub(r"dev$", r"dev0", rs) # if we have something like "b-2" or "a.2" at the end of the # version, that is probably beta, alpha, etc # let's remove the dash or dot rs = re.sub(r"([abc]|rc)[\-\.](\d+)$", r"\1\2", rs) # 1.0-dev-r371 -> 1.0.dev371 # 0.1-dev-r79 -> 0.1.dev79 rs = re.sub(r"[\-\.](dev)[\-\.]?r?(\d+)$", r".\1\2", rs) # Clean: 2.0.a.3, 2.0.b1, 0.9.0~c1 rs = re.sub(r"[.~]?([abc])\.?", r"\1", rs) # Clean: v0.3, v1.0 if rs.startswith('v'): rs = rs[1:] # Clean leading '0's on numbers. #TODO: unintended side-effect on, e.g., "2003.05.09" # PyPI stats: 77 (~2%) better rs = re.sub(r"\b0+(\d+)(?!\d)", r"\1", rs) # Clean a/b/c with no version. E.g. "1.0a" -> "1.0a0". Setuptools infers # zero. # PyPI stats: 245 (7.56%) better rs = re.sub(r"(\d+[abc])$", r"\g<1>0", rs) # the 'dev-rNNN' tag is a dev tag rs = re.sub(r"\.?(dev-r|dev\.r)\.?(\d+)$", r".dev\2", rs) # clean the - when used as a pre delimiter rs = re.sub(r"-(a|b|c)(\d+)$", r"\1\2", rs) # a terminal "dev" or "devel" can be changed into ".dev0" rs = re.sub(r"[\.\-](dev|devel)$", r".dev0", rs) # a terminal "dev" can be changed into ".dev0" rs = re.sub(r"(?![\.\-])dev$", r".dev0", rs) # a terminal "final" or "stable" can be removed rs = re.sub(r"(final|stable)$", "", rs) # The 'r' and the '-' tags are post release tags # 0.4a1.r10 -> 0.4a1.post10 # 0.9.33-17222 -> 0.9.33.post17222 # 0.9.33-r17222 -> 0.9.33.post17222 rs = re.sub(r"\.?(r|-|-r)\.?(\d+)$", r".post\2", rs) # Clean 'r' instead of 'dev' usage: # 0.9.33+r17222 -> 0.9.33.dev17222 # 1.0dev123 -> 1.0.dev123 # 1.0.git123 -> 1.0.dev123 # 1.0.bzr123 -> 1.0.dev123 # 0.1a0dev.123 -> 0.1a0.dev123 # PyPI stats: ~150 (~4%) better rs = re.sub(r"\.?(dev|git|bzr)\.?(\d+)$", r".dev\2", rs) # Clean '.pre' (normalized from '-pre' above) instead of 'c' usage: # 0.2.pre1 -> 0.2c1 # 0.2-c1 -> 0.2c1 # 1.0preview123 -> 1.0c123 # PyPI stats: ~21 (0.62%) better rs = re.sub(r"\.?(pre|preview|-c)(\d+)$", r"c\g<2>", rs) # Tcl/Tk uses "px" for their post release markers rs = re.sub(r"p(\d+)$", r".post\1", rs) try: _normalized_key(rs) except UnsupportedVersionError: rs = None return rs # # Legacy version processing (distribute-compatible) # _VERSION_PART = re.compile(r'([a-z]+|\d+|[\.-])', re.I) _VERSION_REPLACE = { 'pre': 'c', 'preview': 'c', '-': 'final-', 'rc': 'c', 'dev': '@', '': None, '.': None, } def _legacy_key(s): def get_parts(s): result = [] for p in _VERSION_PART.split(s.lower()): p = _VERSION_REPLACE.get(p, p) if p: if '0' <= p[:1] <= '9': p = p.zfill(8) else: p = '*' + p result.append(p) result.append('*final') return result result = [] for p in get_parts(s): if p.startswith('*'): if p < '*final': while result and result[-1] == '*final-': result.pop() while result and result[-1] == '00000000': result.pop() result.append(p) return tuple(result) class LegacyVersion(Version): def parse(self, s): return _legacy_key(s) @property def is_prerelease(self): result = False for x in self._parts: if (isinstance(x, string_types) and x.startswith('*') and x < '*final'): result = True break return result class LegacyMatcher(Matcher): version_class = LegacyVersion _operators = dict(Matcher._operators) _operators['~='] = '_match_compatible' numeric_re = re.compile(r'^(\d+(\.\d+)*)') def _match_compatible(self, version, constraint, prefix): if version < constraint: return False m = self.numeric_re.match(str(constraint)) if not m: logger.warning('Cannot compute compatible match for version %s ' ' and constraint %s', version, constraint) return True s = m.groups()[0] if '.' in s: s = s.rsplit('.', 1)[0] return _match_prefix(version, s) # # Semantic versioning # _SEMVER_RE = re.compile(r'^(\d+)\.(\d+)\.(\d+)' r'(-[a-z0-9]+(\.[a-z0-9-]+)*)?' r'(\+[a-z0-9]+(\.[a-z0-9-]+)*)?$', re.I) def is_semver(s): return _SEMVER_RE.match(s) def _semantic_key(s): def make_tuple(s, absent): if s is None: result = (absent,) else: parts = s[1:].split('.') # We can't compare ints and strings on Python 3, so fudge it # by zero-filling numeric values so simulate a numeric comparison result = tuple([p.zfill(8) if p.isdigit() else p for p in parts]) return result m = is_semver(s) if not m: raise UnsupportedVersionError(s) groups = m.groups() major, minor, patch = [int(i) for i in groups[:3]] # choose the '|' and '*' so that versions sort correctly pre, build = make_tuple(groups[3], '|'), make_tuple(groups[5], '*') return (major, minor, patch), pre, build class SemanticVersion(Version): def parse(self, s): return _semantic_key(s) @property def is_prerelease(self): return self._parts[1][0] != '|' class SemanticMatcher(Matcher): version_class = SemanticVersion class VersionScheme(object): def __init__(self, key, matcher, suggester=None): self.key = key self.matcher = matcher self.suggester = suggester def is_valid_version(self, s): try: self.matcher.version_class(s) result = True except UnsupportedVersionError: result = False return result def is_valid_matcher(self, s): try: self.matcher(s) result = True except UnsupportedVersionError: result = False return result def is_valid_constraint_list(self, s): """ Used for processing some metadata fields """ # See issue #140. Be tolerant of a single trailing comma. if s.endswith(','): s = s[:-1] return self.is_valid_matcher('dummy_name (%s)' % s) def suggest(self, s): if self.suggester is None: result = None else: result = self.suggester(s) return result _SCHEMES = { 'normalized': VersionScheme(_normalized_key, NormalizedMatcher, _suggest_normalized_version), 'legacy': VersionScheme(_legacy_key, LegacyMatcher, lambda self, s: s), 'semantic': VersionScheme(_semantic_key, SemanticMatcher, _suggest_semantic_version), } _SCHEMES['default'] = _SCHEMES['normalized'] def get_scheme(name): if name not in _SCHEMES: raise ValueError('unknown scheme name: %r' % name) return _SCHEMES[name] PKH],ӽ6python3.10/site-packages/pip/_vendor/distlib/compat.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2013-2017 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # from __future__ import absolute_import import os import re import sys try: import ssl except ImportError: # pragma: no cover ssl = None if sys.version_info[0] < 3: # pragma: no cover from StringIO import StringIO string_types = basestring, text_type = unicode from types import FileType as file_type import __builtin__ as builtins import ConfigParser as configparser from ._backport import shutil from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit from urllib import (urlretrieve, quote as _quote, unquote, url2pathname, pathname2url, ContentTooShortError, splittype) def quote(s): if isinstance(s, unicode): s = s.encode('utf-8') return _quote(s) import urllib2 from urllib2 import (Request, urlopen, URLError, HTTPError, HTTPBasicAuthHandler, HTTPPasswordMgr, HTTPHandler, HTTPRedirectHandler, build_opener) if ssl: from urllib2 import HTTPSHandler import httplib import xmlrpclib import Queue as queue from HTMLParser import HTMLParser import htmlentitydefs raw_input = raw_input from itertools import ifilter as filter from itertools import ifilterfalse as filterfalse # Leaving this around for now, in case it needs resurrecting in some way # _userprog = None # def splituser(host): # """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" # global _userprog # if _userprog is None: # import re # _userprog = re.compile('^(.*)@(.*)$') # match = _userprog.match(host) # if match: return match.group(1, 2) # return None, host else: # pragma: no cover from io import StringIO string_types = str, text_type = str from io import TextIOWrapper as file_type import builtins import configparser import shutil from urllib.parse import (urlparse, urlunparse, urljoin, quote, unquote, urlsplit, urlunsplit, splittype) from urllib.request import (urlopen, urlretrieve, Request, url2pathname, pathname2url, HTTPBasicAuthHandler, HTTPPasswordMgr, HTTPHandler, HTTPRedirectHandler, build_opener) if ssl: from urllib.request import HTTPSHandler from urllib.error import HTTPError, URLError, ContentTooShortError import http.client as httplib import urllib.request as urllib2 import xmlrpc.client as xmlrpclib import queue from html.parser import HTMLParser import html.entities as htmlentitydefs raw_input = input from itertools import filterfalse filter = filter try: from ssl import match_hostname, CertificateError except ImportError: # pragma: no cover class CertificateError(ValueError): pass def _dnsname_match(dn, hostname, max_wildcards=1): """Matching according to RFC 6125, section 6.4.3 http://tools.ietf.org/html/rfc6125#section-6.4.3 """ pats = [] if not dn: return False parts = dn.split('.') leftmost, remainder = parts[0], parts[1:] wildcards = leftmost.count('*') if wildcards > max_wildcards: # Issue #17980: avoid denials of service by refusing more # than one wildcard per fragment. A survey of established # policy among SSL implementations showed it to be a # reasonable choice. raise CertificateError( "too many wildcards in certificate DNS name: " + repr(dn)) # speed up common case w/o wildcards if not wildcards: return dn.lower() == hostname.lower() # RFC 6125, section 6.4.3, subitem 1. # The client SHOULD NOT attempt to match a presented identifier in which # the wildcard character comprises a label other than the left-most label. if leftmost == '*': # When '*' is a fragment by itself, it matches a non-empty dotless # fragment. pats.append('[^.]+') elif leftmost.startswith('xn--') or hostname.startswith('xn--'): # RFC 6125, section 6.4.3, subitem 3. # The client SHOULD NOT attempt to match a presented identifier # where the wildcard character is embedded within an A-label or # U-label of an internationalized domain name. pats.append(re.escape(leftmost)) else: # Otherwise, '*' matches any dotless string, e.g. www* pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) # add the remaining fragments, ignore any wildcards for frag in remainder: pats.append(re.escape(frag)) pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) return pat.match(hostname) def match_hostname(cert, hostname): """Verify that *cert* (in decoded format as returned by SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 rules are followed, but IP addresses are not accepted for *hostname*. CertificateError is raised on failure. On success, the function returns nothing. """ if not cert: raise ValueError("empty or no certificate, match_hostname needs a " "SSL socket or SSL context with either " "CERT_OPTIONAL or CERT_REQUIRED") dnsnames = [] san = cert.get('subjectAltName', ()) for key, value in san: if key == 'DNS': if _dnsname_match(value, hostname): return dnsnames.append(value) if not dnsnames: # The subject is only checked when there is no dNSName entry # in subjectAltName for sub in cert.get('subject', ()): for key, value in sub: # XXX according to RFC 2818, the most specific Common Name # must be used. if key == 'commonName': if _dnsname_match(value, hostname): return dnsnames.append(value) if len(dnsnames) > 1: raise CertificateError("hostname %r " "doesn't match either of %s" % (hostname, ', '.join(map(repr, dnsnames)))) elif len(dnsnames) == 1: raise CertificateError("hostname %r " "doesn't match %r" % (hostname, dnsnames[0])) else: raise CertificateError("no appropriate commonName or " "subjectAltName fields were found") try: from types import SimpleNamespace as Container except ImportError: # pragma: no cover class Container(object): """ A generic container for when multiple values need to be returned """ def __init__(self, **kwargs): self.__dict__.update(kwargs) try: from shutil import which except ImportError: # pragma: no cover # Implementation from Python 3.3 def which(cmd, mode=os.F_OK | os.X_OK, path=None): """Given a command, mode, and a PATH string, return the path which conforms to the given mode on the PATH, or None if there is no such file. `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result of os.environ.get("PATH"), or can be overridden with a custom search path. """ # Check that a given file can be accessed with the correct mode. # Additionally check that `file` is not a directory, as on Windows # directories pass the os.access check. def _access_check(fn, mode): return (os.path.exists(fn) and os.access(fn, mode) and not os.path.isdir(fn)) # If we're given a path with a directory part, look it up directly rather # than referring to PATH directories. This includes checking relative to the # current directory, e.g. ./script if os.path.dirname(cmd): if _access_check(cmd, mode): return cmd return None if path is None: path = os.environ.get("PATH", os.defpath) if not path: return None path = path.split(os.pathsep) if sys.platform == "win32": # The current directory takes precedence on Windows. if not os.curdir in path: path.insert(0, os.curdir) # PATHEXT is necessary to check on Windows. pathext = os.environ.get("PATHEXT", "").split(os.pathsep) # See if the given file matches any of the expected path extensions. # This will allow us to short circuit when given "python.exe". # If it does match, only test that one, otherwise we have to try # others. if any(cmd.lower().endswith(ext.lower()) for ext in pathext): files = [cmd] else: files = [cmd + ext for ext in pathext] else: # On other platforms you don't have things like PATHEXT to tell you # what file suffixes are executable, so just pass on cmd as-is. files = [cmd] seen = set() for dir in path: normdir = os.path.normcase(dir) if not normdir in seen: seen.add(normdir) for thefile in files: name = os.path.join(dir, thefile) if _access_check(name, mode): return name return None # ZipFile is a context manager in 2.7, but not in 2.6 from zipfile import ZipFile as BaseZipFile if hasattr(BaseZipFile, '__enter__'): # pragma: no cover ZipFile = BaseZipFile else: # pragma: no cover from zipfile import ZipExtFile as BaseZipExtFile class ZipExtFile(BaseZipExtFile): def __init__(self, base): self.__dict__.update(base.__dict__) def __enter__(self): return self def __exit__(self, *exc_info): self.close() # return None, so if an exception occurred, it will propagate class ZipFile(BaseZipFile): def __enter__(self): return self def __exit__(self, *exc_info): self.close() # return None, so if an exception occurred, it will propagate def open(self, *args, **kwargs): base = BaseZipFile.open(self, *args, **kwargs) return ZipExtFile(base) try: from platform import python_implementation except ImportError: # pragma: no cover def python_implementation(): """Return a string identifying the Python implementation.""" if 'PyPy' in sys.version: return 'PyPy' if os.name == 'java': return 'Jython' if sys.version.startswith('IronPython'): return 'IronPython' return 'CPython' try: import sysconfig except ImportError: # pragma: no cover from ._backport import sysconfig try: callable = callable except NameError: # pragma: no cover from collections.abc import Callable def callable(obj): return isinstance(obj, Callable) try: fsencode = os.fsencode fsdecode = os.fsdecode except AttributeError: # pragma: no cover # Issue #99: on some systems (e.g. containerised), # sys.getfilesystemencoding() returns None, and we need a real value, # so fall back to utf-8. From the CPython 2.7 docs relating to Unix and # sys.getfilesystemencoding(): the return value is "the user’s preference # according to the result of nl_langinfo(CODESET), or None if the # nl_langinfo(CODESET) failed." _fsencoding = sys.getfilesystemencoding() or 'utf-8' if _fsencoding == 'mbcs': _fserrors = 'strict' else: _fserrors = 'surrogateescape' def fsencode(filename): if isinstance(filename, bytes): return filename elif isinstance(filename, text_type): return filename.encode(_fsencoding, _fserrors) else: raise TypeError("expect bytes or str, not %s" % type(filename).__name__) def fsdecode(filename): if isinstance(filename, text_type): return filename elif isinstance(filename, bytes): return filename.decode(_fsencoding, _fserrors) else: raise TypeError("expect bytes or str, not %s" % type(filename).__name__) try: from tokenize import detect_encoding except ImportError: # pragma: no cover from codecs import BOM_UTF8, lookup import re cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)") def _get_normal_name(orig_enc): """Imitates get_normal_name in tokenizer.c.""" # Only care about the first 12 characters. enc = orig_enc[:12].lower().replace("_", "-") if enc == "utf-8" or enc.startswith("utf-8-"): return "utf-8" if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): return "iso-8859-1" return orig_enc def detect_encoding(readline): """ The detect_encoding() function is used to detect the encoding that should be used to decode a Python source file. It requires one argument, readline, in the same way as the tokenize() generator. It will call readline a maximum of twice, and return the encoding used (as a string) and a list of any lines (left as bytes) it has read in. It detects the encoding from the presence of a utf-8 bom or an encoding cookie as specified in pep-0263. If both a bom and a cookie are present, but disagree, a SyntaxError will be raised. If the encoding cookie is an invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, 'utf-8-sig' is returned. If no encoding is specified, then the default of 'utf-8' will be returned. """ try: filename = readline.__self__.name except AttributeError: filename = None bom_found = False encoding = None default = 'utf-8' def read_or_stop(): try: return readline() except StopIteration: return b'' def find_cookie(line): try: # Decode as UTF-8. Either the line is an encoding declaration, # in which case it should be pure ASCII, or it must be UTF-8 # per default encoding. line_string = line.decode('utf-8') except UnicodeDecodeError: msg = "invalid or missing encoding declaration" if filename is not None: msg = '{} for {!r}'.format(msg, filename) raise SyntaxError(msg) matches = cookie_re.findall(line_string) if not matches: return None encoding = _get_normal_name(matches[0]) try: codec = lookup(encoding) except LookupError: # This behaviour mimics the Python interpreter if filename is None: msg = "unknown encoding: " + encoding else: msg = "unknown encoding for {!r}: {}".format(filename, encoding) raise SyntaxError(msg) if bom_found: if codec.name != 'utf-8': # This behaviour mimics the Python interpreter if filename is None: msg = 'encoding problem: utf-8' else: msg = 'encoding problem for {!r}: utf-8'.format(filename) raise SyntaxError(msg) encoding += '-sig' return encoding first = read_or_stop() if first.startswith(BOM_UTF8): bom_found = True first = first[3:] default = 'utf-8-sig' if not first: return default, [] encoding = find_cookie(first) if encoding: return encoding, [first] second = read_or_stop() if not second: return default, [first] encoding = find_cookie(second) if encoding: return encoding, [first, second] return default, [first, second] # For converting & <-> & etc. try: from html import escape except ImportError: from cgi import escape if sys.version_info[:2] < (3, 4): unescape = HTMLParser().unescape else: from html import unescape try: from collections import ChainMap except ImportError: # pragma: no cover from collections import MutableMapping try: from reprlib import recursive_repr as _recursive_repr except ImportError: def _recursive_repr(fillvalue='...'): ''' Decorator to make a repr function return fillvalue for a recursive call ''' def decorating_function(user_function): repr_running = set() def wrapper(self): key = id(self), get_ident() if key in repr_running: return fillvalue repr_running.add(key) try: result = user_function(self) finally: repr_running.discard(key) return result # Can't use functools.wraps() here because of bootstrap issues wrapper.__module__ = getattr(user_function, '__module__') wrapper.__doc__ = getattr(user_function, '__doc__') wrapper.__name__ = getattr(user_function, '__name__') wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) return wrapper return decorating_function class ChainMap(MutableMapping): ''' A ChainMap groups multiple dicts (or other mappings) together to create a single, updateable view. The underlying mappings are stored in a list. That list is public and can accessed or updated using the *maps* attribute. There is no other state. Lookups search the underlying mappings successively until a key is found. In contrast, writes, updates, and deletions only operate on the first mapping. ''' def __init__(self, *maps): '''Initialize a ChainMap by setting *maps* to the given mappings. If no mappings are provided, a single empty dictionary is used. ''' self.maps = list(maps) or [{}] # always at least one map def __missing__(self, key): raise KeyError(key) def __getitem__(self, key): for mapping in self.maps: try: return mapping[key] # can't use 'key in mapping' with defaultdict except KeyError: pass return self.__missing__(key) # support subclasses that define __missing__ def get(self, key, default=None): return self[key] if key in self else default def __len__(self): return len(set().union(*self.maps)) # reuses stored hash values if possible def __iter__(self): return iter(set().union(*self.maps)) def __contains__(self, key): return any(key in m for m in self.maps) def __bool__(self): return any(self.maps) @_recursive_repr() def __repr__(self): return '{0.__class__.__name__}({1})'.format( self, ', '.join(map(repr, self.maps))) @classmethod def fromkeys(cls, iterable, *args): 'Create a ChainMap with a single dict created from the iterable.' return cls(dict.fromkeys(iterable, *args)) def copy(self): 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' return self.__class__(self.maps[0].copy(), *self.maps[1:]) __copy__ = copy def new_child(self): # like Django's Context.push() 'New ChainMap with a new dict followed by all previous maps.' return self.__class__({}, *self.maps) @property def parents(self): # like Django's Context.pop() 'New ChainMap from maps[1:].' return self.__class__(*self.maps[1:]) def __setitem__(self, key, value): self.maps[0][key] = value def __delitem__(self, key): try: del self.maps[0][key] except KeyError: raise KeyError('Key not found in the first mapping: {!r}'.format(key)) def popitem(self): 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' try: return self.maps[0].popitem() except KeyError: raise KeyError('No keys found in the first mapping.') def pop(self, key, *args): 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' try: return self.maps[0].pop(key, *args) except KeyError: raise KeyError('Key not found in the first mapping: {!r}'.format(key)) def clear(self): 'Clear maps[0], leaving maps[1:] intact.' self.maps[0].clear() try: from importlib.util import cache_from_source # Python >= 3.4 except ImportError: # pragma: no cover try: from imp import cache_from_source except ImportError: # pragma: no cover def cache_from_source(path, debug_override=None): assert path.endswith('.py') if debug_override is None: debug_override = __debug__ if debug_override: suffix = 'c' else: suffix = 'o' return path + suffix try: from collections import OrderedDict except ImportError: # pragma: no cover ## {{{ http://code.activestate.com/recipes/576693/ (r9) # Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. # Passes Python2.7's test suite and incorporates all the latest updates. try: from thread import get_ident as _get_ident except ImportError: from dummy_thread import get_ident as _get_ident try: from _abcoll import KeysView, ValuesView, ItemsView except ImportError: pass class OrderedDict(dict): 'Dictionary that remembers insertion order' # An inherited dict maps keys to values. # The inherited dict provides __getitem__, __len__, __contains__, and get. # The remaining methods are order-aware. # Big-O running times for all methods are the same as for regular dictionaries. # The internal self.__map dictionary maps keys to links in a doubly linked list. # The circular doubly linked list starts and ends with a sentinel element. # The sentinel element never gets deleted (this simplifies the algorithm). # Each link is stored as a list of length three: [PREV, NEXT, KEY]. def __init__(self, *args, **kwds): '''Initialize an ordered dictionary. Signature is the same as for regular dictionaries, but keyword arguments are not recommended because their insertion order is arbitrary. ''' if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: self.__root except AttributeError: self.__root = root = [] # sentinel node root[:] = [root, root, None] self.__map = {} self.__update(*args, **kwds) def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link which goes at the end of the linked # list, and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root last = root[0] last[1] = root[0] = self.__map[key] = [last, root, key] dict_setitem(self, key, value) def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which is # then removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) link_prev[1] = link_next link_next[0] = link_prev def __iter__(self): 'od.__iter__() <==> iter(od)' root = self.__root curr = root[1] while curr is not root: yield curr[2] curr = curr[1] def __reversed__(self): 'od.__reversed__() <==> reversed(od)' root = self.__root curr = root[0] while curr is not root: yield curr[2] curr = curr[0] def clear(self): 'od.clear() -> None. Remove all items from od.' try: for node in self.__map.itervalues(): del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() except AttributeError: pass dict.clear(self) def popitem(self, last=True): '''od.popitem() -> (k, v), return and remove a (key, value) pair. Pairs are returned in LIFO order if last is true or FIFO order if false. ''' if not self: raise KeyError('dictionary is empty') root = self.__root if last: link = root[0] link_prev = link[0] link_prev[1] = root root[0] = link_prev else: link = root[1] link_next = link[1] root[1] = link_next link_next[0] = root key = link[2] del self.__map[key] value = dict.pop(self, key) return key, value # -- the following methods do not depend on the internal structure -- def keys(self): 'od.keys() -> list of keys in od' return list(self) def values(self): 'od.values() -> list of values in od' return [self[key] for key in self] def items(self): 'od.items() -> list of (key, value) pairs in od' return [(key, self[key]) for key in self] def iterkeys(self): 'od.iterkeys() -> an iterator over the keys in od' return iter(self) def itervalues(self): 'od.itervalues -> an iterator over the values in od' for k in self: yield self[k] def iteritems(self): 'od.iteritems -> an iterator over the (key, value) items in od' for k in self: yield (k, self[k]) def update(*args, **kwds): '''od.update(E, **F) -> None. Update od from dict/iterable E and F. If E is a dict instance, does: for k in E: od[k] = E[k] If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] Or if E is an iterable of items, does: for k, v in E: od[k] = v In either case, this is followed by: for k, v in F.items(): od[k] = v ''' if len(args) > 2: raise TypeError('update() takes at most 2 positional ' 'arguments (%d given)' % (len(args),)) elif not args: raise TypeError('update() takes at least 1 argument (0 given)') self = args[0] # Make progressively weaker assumptions about "other" other = () if len(args) == 2: other = args[1] if isinstance(other, dict): for key in other: self[key] = other[key] elif hasattr(other, 'keys'): for key in other.keys(): self[key] = other[key] else: for key, value in other: self[key] = value for key, value in kwds.items(): self[key] = value __update = update # let subclasses override update without breaking __init__ __marker = object() def pop(self, key, default=__marker): '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised. ''' if key in self: result = self[key] del self[key] return result if default is self.__marker: raise KeyError(key) return default def setdefault(self, key, default=None): 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' if key in self: return self[key] self[key] = default return default def __repr__(self, _repr_running=None): 'od.__repr__() <==> repr(od)' if not _repr_running: _repr_running = {} call_key = id(self), _get_ident() if call_key in _repr_running: return '...' _repr_running[call_key] = 1 try: if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, self.items()) finally: del _repr_running[call_key] def __reduce__(self): 'Return state information for pickling' items = [[k, self[k]] for k in self] inst_dict = vars(self).copy() for k in vars(OrderedDict()): inst_dict.pop(k, None) if inst_dict: return (self.__class__, (items,), inst_dict) return self.__class__, (items,) def copy(self): 'od.copy() -> a shallow copy of od' return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S and values equal to v (which defaults to None). ''' d = cls() for key in iterable: d[key] = value return d def __eq__(self, other): '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive while comparison to a regular mapping is order-insensitive. ''' if isinstance(other, OrderedDict): return len(self)==len(other) and self.items() == other.items() return dict.__eq__(self, other) def __ne__(self, other): return not self == other # -- the following methods are only used in Python 2.7 -- def viewkeys(self): "od.viewkeys() -> a set-like object providing a view on od's keys" return KeysView(self) def viewvalues(self): "od.viewvalues() -> an object providing a view on od's values" return ValuesView(self) def viewitems(self): "od.viewitems() -> a set-like object providing a view on od's items" return ItemsView(self) try: from logging.config import BaseConfigurator, valid_ident except ImportError: # pragma: no cover IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) def valid_ident(s): m = IDENTIFIER.match(s) if not m: raise ValueError('Not a valid Python identifier: %r' % s) return True # The ConvertingXXX classes are wrappers around standard Python containers, # and they serve to convert any suitable values in the container. The # conversion converts base dicts, lists and tuples to their wrapped # equivalents, whereas strings which match a conversion format are converted # appropriately. # # Each wrapper should have a configurator attribute holding the actual # configurator to use for conversion. class ConvertingDict(dict): """A converting dictionary wrapper.""" def __getitem__(self, key): value = dict.__getitem__(self, key) result = self.configurator.convert(value) #If the converted value is different, save for next time if value is not result: self[key] = result if type(result) in (ConvertingDict, ConvertingList, ConvertingTuple): result.parent = self result.key = key return result def get(self, key, default=None): value = dict.get(self, key, default) result = self.configurator.convert(value) #If the converted value is different, save for next time if value is not result: self[key] = result if type(result) in (ConvertingDict, ConvertingList, ConvertingTuple): result.parent = self result.key = key return result def pop(self, key, default=None): value = dict.pop(self, key, default) result = self.configurator.convert(value) if value is not result: if type(result) in (ConvertingDict, ConvertingList, ConvertingTuple): result.parent = self result.key = key return result class ConvertingList(list): """A converting list wrapper.""" def __getitem__(self, key): value = list.__getitem__(self, key) result = self.configurator.convert(value) #If the converted value is different, save for next time if value is not result: self[key] = result if type(result) in (ConvertingDict, ConvertingList, ConvertingTuple): result.parent = self result.key = key return result def pop(self, idx=-1): value = list.pop(self, idx) result = self.configurator.convert(value) if value is not result: if type(result) in (ConvertingDict, ConvertingList, ConvertingTuple): result.parent = self return result class ConvertingTuple(tuple): """A converting tuple wrapper.""" def __getitem__(self, key): value = tuple.__getitem__(self, key) result = self.configurator.convert(value) if value is not result: if type(result) in (ConvertingDict, ConvertingList, ConvertingTuple): result.parent = self result.key = key return result class BaseConfigurator(object): """ The configurator base class which defines some useful defaults. """ CONVERT_PATTERN = re.compile(r'^(?P[a-z]+)://(?P.*)$') WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') DIGIT_PATTERN = re.compile(r'^\d+$') value_converters = { 'ext' : 'ext_convert', 'cfg' : 'cfg_convert', } # We might want to use a different one, e.g. importlib importer = staticmethod(__import__) def __init__(self, config): self.config = ConvertingDict(config) self.config.configurator = self def resolve(self, s): """ Resolve strings to objects using standard import and attribute syntax. """ name = s.split('.') used = name.pop(0) try: found = self.importer(used) for frag in name: used += '.' + frag try: found = getattr(found, frag) except AttributeError: self.importer(used) found = getattr(found, frag) return found except ImportError: e, tb = sys.exc_info()[1:] v = ValueError('Cannot resolve %r: %s' % (s, e)) v.__cause__, v.__traceback__ = e, tb raise v def ext_convert(self, value): """Default converter for the ext:// protocol.""" return self.resolve(value) def cfg_convert(self, value): """Default converter for the cfg:// protocol.""" rest = value m = self.WORD_PATTERN.match(rest) if m is None: raise ValueError("Unable to convert %r" % value) else: rest = rest[m.end():] d = self.config[m.groups()[0]] #print d, rest while rest: m = self.DOT_PATTERN.match(rest) if m: d = d[m.groups()[0]] else: m = self.INDEX_PATTERN.match(rest) if m: idx = m.groups()[0] if not self.DIGIT_PATTERN.match(idx): d = d[idx] else: try: n = int(idx) # try as number first (most likely) d = d[n] except TypeError: d = d[idx] if m: rest = rest[m.end():] else: raise ValueError('Unable to convert ' '%r at %r' % (value, rest)) #rest should be empty return d def convert(self, value): """ Convert values to an appropriate type. dicts, lists and tuples are replaced by their converting alternatives. Strings are checked to see if they have a conversion format and are converted if they do. """ if not isinstance(value, ConvertingDict) and isinstance(value, dict): value = ConvertingDict(value) value.configurator = self elif not isinstance(value, ConvertingList) and isinstance(value, list): value = ConvertingList(value) value.configurator = self elif not isinstance(value, ConvertingTuple) and\ isinstance(value, tuple): value = ConvertingTuple(value) value.configurator = self elif isinstance(value, string_types): m = self.CONVERT_PATTERN.match(value) if m: d = m.groupdict() prefix = d['prefix'] converter = self.value_converters.get(prefix, None) if converter: suffix = d['suffix'] converter = getattr(self, converter) value = converter(suffix) return value def configure_custom(self, config): """Configure an object with a user-supplied factory.""" c = config.pop('()') if not callable(c): c = self.resolve(c) props = config.pop('.', None) # Check for valid identifiers kwargs = dict([(k, config[k]) for k in config if valid_ident(k)]) result = c(**kwargs) if props: for name, value in props.items(): setattr(result, name, value) return result def as_tuple(self, value): """Utility function which converts lists to tuples.""" if isinstance(value, list): value = tuple(value) return value PKH]=XŘŘ8python3.10/site-packages/pip/_vendor/distlib/metadata.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2012 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # """Implementation of the Metadata for Python packages PEPs. Supports all metadata formats (1.0, 1.1, 1.2, 1.3/2.1 and withdrawn 2.0). """ from __future__ import unicode_literals import codecs from email import message_from_file import json import logging import re from . import DistlibException, __version__ from .compat import StringIO, string_types, text_type from .markers import interpret from .util import extract_by_key, get_extras from .version import get_scheme, PEP440_VERSION_RE logger = logging.getLogger(__name__) class MetadataMissingError(DistlibException): """A required metadata is missing""" class MetadataConflictError(DistlibException): """Attempt to read or write metadata fields that are conflictual.""" class MetadataUnrecognizedVersionError(DistlibException): """Unknown metadata version number.""" class MetadataInvalidError(DistlibException): """A metadata value is invalid""" # public API of this module __all__ = ['Metadata', 'PKG_INFO_ENCODING', 'PKG_INFO_PREFERRED_VERSION'] # Encoding used for the PKG-INFO files PKG_INFO_ENCODING = 'utf-8' # preferred version. Hopefully will be changed # to 1.2 once PEP 345 is supported everywhere PKG_INFO_PREFERRED_VERSION = '1.1' _LINE_PREFIX_1_2 = re.compile('\n \\|') _LINE_PREFIX_PRE_1_2 = re.compile('\n ') _241_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', 'Summary', 'Description', 'Keywords', 'Home-page', 'Author', 'Author-email', 'License') _314_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', 'Supported-Platform', 'Summary', 'Description', 'Keywords', 'Home-page', 'Author', 'Author-email', 'License', 'Classifier', 'Download-URL', 'Obsoletes', 'Provides', 'Requires') _314_MARKERS = ('Obsoletes', 'Provides', 'Requires', 'Classifier', 'Download-URL') _345_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', 'Supported-Platform', 'Summary', 'Description', 'Keywords', 'Home-page', 'Author', 'Author-email', 'Maintainer', 'Maintainer-email', 'License', 'Classifier', 'Download-URL', 'Obsoletes-Dist', 'Project-URL', 'Provides-Dist', 'Requires-Dist', 'Requires-Python', 'Requires-External') _345_MARKERS = ('Provides-Dist', 'Requires-Dist', 'Requires-Python', 'Obsoletes-Dist', 'Requires-External', 'Maintainer', 'Maintainer-email', 'Project-URL') _426_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', 'Supported-Platform', 'Summary', 'Description', 'Keywords', 'Home-page', 'Author', 'Author-email', 'Maintainer', 'Maintainer-email', 'License', 'Classifier', 'Download-URL', 'Obsoletes-Dist', 'Project-URL', 'Provides-Dist', 'Requires-Dist', 'Requires-Python', 'Requires-External', 'Private-Version', 'Obsoleted-By', 'Setup-Requires-Dist', 'Extension', 'Provides-Extra') _426_MARKERS = ('Private-Version', 'Provides-Extra', 'Obsoleted-By', 'Setup-Requires-Dist', 'Extension') # See issue #106: Sometimes 'Requires' and 'Provides' occur wrongly in # the metadata. Include them in the tuple literal below to allow them # (for now). # Ditto for Obsoletes - see issue #140. _566_FIELDS = _426_FIELDS + ('Description-Content-Type', 'Requires', 'Provides', 'Obsoletes') _566_MARKERS = ('Description-Content-Type',) _ALL_FIELDS = set() _ALL_FIELDS.update(_241_FIELDS) _ALL_FIELDS.update(_314_FIELDS) _ALL_FIELDS.update(_345_FIELDS) _ALL_FIELDS.update(_426_FIELDS) _ALL_FIELDS.update(_566_FIELDS) EXTRA_RE = re.compile(r'''extra\s*==\s*("([^"]+)"|'([^']+)')''') def _version2fieldlist(version): if version == '1.0': return _241_FIELDS elif version == '1.1': return _314_FIELDS elif version == '1.2': return _345_FIELDS elif version in ('1.3', '2.1'): # avoid adding field names if already there return _345_FIELDS + tuple(f for f in _566_FIELDS if f not in _345_FIELDS) elif version == '2.0': return _426_FIELDS raise MetadataUnrecognizedVersionError(version) def _best_version(fields): """Detect the best version depending on the fields used.""" def _has_marker(keys, markers): for marker in markers: if marker in keys: return True return False keys = [] for key, value in fields.items(): if value in ([], 'UNKNOWN', None): continue keys.append(key) possible_versions = ['1.0', '1.1', '1.2', '1.3', '2.0', '2.1'] # first let's try to see if a field is not part of one of the version for key in keys: if key not in _241_FIELDS and '1.0' in possible_versions: possible_versions.remove('1.0') logger.debug('Removed 1.0 due to %s', key) if key not in _314_FIELDS and '1.1' in possible_versions: possible_versions.remove('1.1') logger.debug('Removed 1.1 due to %s', key) if key not in _345_FIELDS and '1.2' in possible_versions: possible_versions.remove('1.2') logger.debug('Removed 1.2 due to %s', key) if key not in _566_FIELDS and '1.3' in possible_versions: possible_versions.remove('1.3') logger.debug('Removed 1.3 due to %s', key) if key not in _566_FIELDS and '2.1' in possible_versions: if key != 'Description': # In 2.1, description allowed after headers possible_versions.remove('2.1') logger.debug('Removed 2.1 due to %s', key) if key not in _426_FIELDS and '2.0' in possible_versions: possible_versions.remove('2.0') logger.debug('Removed 2.0 due to %s', key) # possible_version contains qualified versions if len(possible_versions) == 1: return possible_versions[0] # found ! elif len(possible_versions) == 0: logger.debug('Out of options - unknown metadata set: %s', fields) raise MetadataConflictError('Unknown metadata set') # let's see if one unique marker is found is_1_1 = '1.1' in possible_versions and _has_marker(keys, _314_MARKERS) is_1_2 = '1.2' in possible_versions and _has_marker(keys, _345_MARKERS) is_2_1 = '2.1' in possible_versions and _has_marker(keys, _566_MARKERS) is_2_0 = '2.0' in possible_versions and _has_marker(keys, _426_MARKERS) if int(is_1_1) + int(is_1_2) + int(is_2_1) + int(is_2_0) > 1: raise MetadataConflictError('You used incompatible 1.1/1.2/2.0/2.1 fields') # we have the choice, 1.0, or 1.2, or 2.0 # - 1.0 has a broken Summary field but works with all tools # - 1.1 is to avoid # - 1.2 fixes Summary but has little adoption # - 2.0 adds more features and is very new if not is_1_1 and not is_1_2 and not is_2_1 and not is_2_0: # we couldn't find any specific marker if PKG_INFO_PREFERRED_VERSION in possible_versions: return PKG_INFO_PREFERRED_VERSION if is_1_1: return '1.1' if is_1_2: return '1.2' if is_2_1: return '2.1' return '2.0' # This follows the rules about transforming keys as described in # https://www.python.org/dev/peps/pep-0566/#id17 _ATTR2FIELD = { name.lower().replace("-", "_"): name for name in _ALL_FIELDS } _FIELD2ATTR = {field: attr for attr, field in _ATTR2FIELD.items()} _PREDICATE_FIELDS = ('Requires-Dist', 'Obsoletes-Dist', 'Provides-Dist') _VERSIONS_FIELDS = ('Requires-Python',) _VERSION_FIELDS = ('Version',) _LISTFIELDS = ('Platform', 'Classifier', 'Obsoletes', 'Requires', 'Provides', 'Obsoletes-Dist', 'Provides-Dist', 'Requires-Dist', 'Requires-External', 'Project-URL', 'Supported-Platform', 'Setup-Requires-Dist', 'Provides-Extra', 'Extension') _LISTTUPLEFIELDS = ('Project-URL',) _ELEMENTSFIELD = ('Keywords',) _UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description') _MISSING = object() _FILESAFE = re.compile('[^A-Za-z0-9.]+') def _get_name_and_version(name, version, for_filename=False): """Return the distribution name with version. If for_filename is true, return a filename-escaped form.""" if for_filename: # For both name and version any runs of non-alphanumeric or '.' # characters are replaced with a single '-'. Additionally any # spaces in the version string become '.' name = _FILESAFE.sub('-', name) version = _FILESAFE.sub('-', version.replace(' ', '.')) return '%s-%s' % (name, version) class LegacyMetadata(object): """The legacy metadata of a release. Supports versions 1.0, 1.1, 1.2, 2.0 and 1.3/2.1 (auto-detected). You can instantiate the class with one of these arguments (or none): - *path*, the path to a metadata file - *fileobj* give a file-like object with metadata as content - *mapping* is a dict-like object - *scheme* is a version scheme name """ # TODO document the mapping API and UNKNOWN default key def __init__(self, path=None, fileobj=None, mapping=None, scheme='default'): if [path, fileobj, mapping].count(None) < 2: raise TypeError('path, fileobj and mapping are exclusive') self._fields = {} self.requires_files = [] self._dependencies = None self.scheme = scheme if path is not None: self.read(path) elif fileobj is not None: self.read_file(fileobj) elif mapping is not None: self.update(mapping) self.set_metadata_version() def set_metadata_version(self): self._fields['Metadata-Version'] = _best_version(self._fields) def _write_field(self, fileobj, name, value): fileobj.write('%s: %s\n' % (name, value)) def __getitem__(self, name): return self.get(name) def __setitem__(self, name, value): return self.set(name, value) def __delitem__(self, name): field_name = self._convert_name(name) try: del self._fields[field_name] except KeyError: raise KeyError(name) def __contains__(self, name): return (name in self._fields or self._convert_name(name) in self._fields) def _convert_name(self, name): if name in _ALL_FIELDS: return name name = name.replace('-', '_').lower() return _ATTR2FIELD.get(name, name) def _default_value(self, name): if name in _LISTFIELDS or name in _ELEMENTSFIELD: return [] return 'UNKNOWN' def _remove_line_prefix(self, value): if self.metadata_version in ('1.0', '1.1'): return _LINE_PREFIX_PRE_1_2.sub('\n', value) else: return _LINE_PREFIX_1_2.sub('\n', value) def __getattr__(self, name): if name in _ATTR2FIELD: return self[name] raise AttributeError(name) # # Public API # # dependencies = property(_get_dependencies, _set_dependencies) def get_fullname(self, filesafe=False): """Return the distribution name with version. If filesafe is true, return a filename-escaped form.""" return _get_name_and_version(self['Name'], self['Version'], filesafe) def is_field(self, name): """return True if name is a valid metadata key""" name = self._convert_name(name) return name in _ALL_FIELDS def is_multi_field(self, name): name = self._convert_name(name) return name in _LISTFIELDS def read(self, filepath): """Read the metadata values from a file path.""" fp = codecs.open(filepath, 'r', encoding='utf-8') try: self.read_file(fp) finally: fp.close() def read_file(self, fileob): """Read the metadata values from a file object.""" msg = message_from_file(fileob) self._fields['Metadata-Version'] = msg['metadata-version'] # When reading, get all the fields we can for field in _ALL_FIELDS: if field not in msg: continue if field in _LISTFIELDS: # we can have multiple lines values = msg.get_all(field) if field in _LISTTUPLEFIELDS and values is not None: values = [tuple(value.split(',')) for value in values] self.set(field, values) else: # single line value = msg[field] if value is not None and value != 'UNKNOWN': self.set(field, value) # PEP 566 specifies that the body be used for the description, if # available body = msg.get_payload() self["Description"] = body if body else self["Description"] # logger.debug('Attempting to set metadata for %s', self) # self.set_metadata_version() def write(self, filepath, skip_unknown=False): """Write the metadata fields to filepath.""" fp = codecs.open(filepath, 'w', encoding='utf-8') try: self.write_file(fp, skip_unknown) finally: fp.close() def write_file(self, fileobject, skip_unknown=False): """Write the PKG-INFO format data to a file object.""" self.set_metadata_version() for field in _version2fieldlist(self['Metadata-Version']): values = self.get(field) if skip_unknown and values in ('UNKNOWN', [], ['UNKNOWN']): continue if field in _ELEMENTSFIELD: self._write_field(fileobject, field, ','.join(values)) continue if field not in _LISTFIELDS: if field == 'Description': if self.metadata_version in ('1.0', '1.1'): values = values.replace('\n', '\n ') else: values = values.replace('\n', '\n |') values = [values] if field in _LISTTUPLEFIELDS: values = [','.join(value) for value in values] for value in values: self._write_field(fileobject, field, value) def update(self, other=None, **kwargs): """Set metadata values from the given iterable `other` and kwargs. Behavior is like `dict.update`: If `other` has a ``keys`` method, they are looped over and ``self[key]`` is assigned ``other[key]``. Else, ``other`` is an iterable of ``(key, value)`` iterables. Keys that don't match a metadata field or that have an empty value are dropped. """ def _set(key, value): if key in _ATTR2FIELD and value: self.set(self._convert_name(key), value) if not other: # other is None or empty container pass elif hasattr(other, 'keys'): for k in other.keys(): _set(k, other[k]) else: for k, v in other: _set(k, v) if kwargs: for k, v in kwargs.items(): _set(k, v) def set(self, name, value): """Control then set a metadata field.""" name = self._convert_name(name) if ((name in _ELEMENTSFIELD or name == 'Platform') and not isinstance(value, (list, tuple))): if isinstance(value, string_types): value = [v.strip() for v in value.split(',')] else: value = [] elif (name in _LISTFIELDS and not isinstance(value, (list, tuple))): if isinstance(value, string_types): value = [value] else: value = [] if logger.isEnabledFor(logging.WARNING): project_name = self['Name'] scheme = get_scheme(self.scheme) if name in _PREDICATE_FIELDS and value is not None: for v in value: # check that the values are valid if not scheme.is_valid_matcher(v.split(';')[0]): logger.warning( "'%s': '%s' is not valid (field '%s')", project_name, v, name) # FIXME this rejects UNKNOWN, is that right? elif name in _VERSIONS_FIELDS and value is not None: if not scheme.is_valid_constraint_list(value): logger.warning("'%s': '%s' is not a valid version (field '%s')", project_name, value, name) elif name in _VERSION_FIELDS and value is not None: if not scheme.is_valid_version(value): logger.warning("'%s': '%s' is not a valid version (field '%s')", project_name, value, name) if name in _UNICODEFIELDS: if name == 'Description': value = self._remove_line_prefix(value) self._fields[name] = value def get(self, name, default=_MISSING): """Get a metadata field.""" name = self._convert_name(name) if name not in self._fields: if default is _MISSING: default = self._default_value(name) return default if name in _UNICODEFIELDS: value = self._fields[name] return value elif name in _LISTFIELDS: value = self._fields[name] if value is None: return [] res = [] for val in value: if name not in _LISTTUPLEFIELDS: res.append(val) else: # That's for Project-URL res.append((val[0], val[1])) return res elif name in _ELEMENTSFIELD: value = self._fields[name] if isinstance(value, string_types): return value.split(',') return self._fields[name] def check(self, strict=False): """Check if the metadata is compliant. If strict is True then raise if no Name or Version are provided""" self.set_metadata_version() # XXX should check the versions (if the file was loaded) missing, warnings = [], [] for attr in ('Name', 'Version'): # required by PEP 345 if attr not in self: missing.append(attr) if strict and missing != []: msg = 'missing required metadata: %s' % ', '.join(missing) raise MetadataMissingError(msg) for attr in ('Home-page', 'Author'): if attr not in self: missing.append(attr) # checking metadata 1.2 (XXX needs to check 1.1, 1.0) if self['Metadata-Version'] != '1.2': return missing, warnings scheme = get_scheme(self.scheme) def are_valid_constraints(value): for v in value: if not scheme.is_valid_matcher(v.split(';')[0]): return False return True for fields, controller in ((_PREDICATE_FIELDS, are_valid_constraints), (_VERSIONS_FIELDS, scheme.is_valid_constraint_list), (_VERSION_FIELDS, scheme.is_valid_version)): for field in fields: value = self.get(field, None) if value is not None and not controller(value): warnings.append("Wrong value for '%s': %s" % (field, value)) return missing, warnings def todict(self, skip_missing=False): """Return fields as a dict. Field names will be converted to use the underscore-lowercase style instead of hyphen-mixed case (i.e. home_page instead of Home-page). This is as per https://www.python.org/dev/peps/pep-0566/#id17. """ self.set_metadata_version() fields = _version2fieldlist(self['Metadata-Version']) data = {} for field_name in fields: if not skip_missing or field_name in self._fields: key = _FIELD2ATTR[field_name] if key != 'project_url': data[key] = self[field_name] else: data[key] = [','.join(u) for u in self[field_name]] return data def add_requirements(self, requirements): if self['Metadata-Version'] == '1.1': # we can't have 1.1 metadata *and* Setuptools requires for field in ('Obsoletes', 'Requires', 'Provides'): if field in self: del self[field] self['Requires-Dist'] += requirements # Mapping API # TODO could add iter* variants def keys(self): return list(_version2fieldlist(self['Metadata-Version'])) def __iter__(self): for key in self.keys(): yield key def values(self): return [self[key] for key in self.keys()] def items(self): return [(key, self[key]) for key in self.keys()] def __repr__(self): return '<%s %s %s>' % (self.__class__.__name__, self.name, self.version) METADATA_FILENAME = 'pydist.json' WHEEL_METADATA_FILENAME = 'metadata.json' LEGACY_METADATA_FILENAME = 'METADATA' class Metadata(object): """ The metadata of a release. This implementation uses 2.0 (JSON) metadata where possible. If not possible, it wraps a LegacyMetadata instance which handles the key-value metadata format. """ METADATA_VERSION_MATCHER = re.compile(r'^\d+(\.\d+)*$') NAME_MATCHER = re.compile('^[0-9A-Z]([0-9A-Z_.-]*[0-9A-Z])?$', re.I) VERSION_MATCHER = PEP440_VERSION_RE SUMMARY_MATCHER = re.compile('.{1,2047}') METADATA_VERSION = '2.0' GENERATOR = 'distlib (%s)' % __version__ MANDATORY_KEYS = { 'name': (), 'version': (), 'summary': ('legacy',), } INDEX_KEYS = ('name version license summary description author ' 'author_email keywords platform home_page classifiers ' 'download_url') DEPENDENCY_KEYS = ('extras run_requires test_requires build_requires ' 'dev_requires provides meta_requires obsoleted_by ' 'supports_environments') SYNTAX_VALIDATORS = { 'metadata_version': (METADATA_VERSION_MATCHER, ()), 'name': (NAME_MATCHER, ('legacy',)), 'version': (VERSION_MATCHER, ('legacy',)), 'summary': (SUMMARY_MATCHER, ('legacy',)), } __slots__ = ('_legacy', '_data', 'scheme') def __init__(self, path=None, fileobj=None, mapping=None, scheme='default'): if [path, fileobj, mapping].count(None) < 2: raise TypeError('path, fileobj and mapping are exclusive') self._legacy = None self._data = None self.scheme = scheme #import pdb; pdb.set_trace() if mapping is not None: try: self._validate_mapping(mapping, scheme) self._data = mapping except MetadataUnrecognizedVersionError: self._legacy = LegacyMetadata(mapping=mapping, scheme=scheme) self.validate() else: data = None if path: with open(path, 'rb') as f: data = f.read() elif fileobj: data = fileobj.read() if data is None: # Initialised with no args - to be added self._data = { 'metadata_version': self.METADATA_VERSION, 'generator': self.GENERATOR, } else: if not isinstance(data, text_type): data = data.decode('utf-8') try: self._data = json.loads(data) self._validate_mapping(self._data, scheme) except ValueError: # Note: MetadataUnrecognizedVersionError does not # inherit from ValueError (it's a DistlibException, # which should not inherit from ValueError). # The ValueError comes from the json.load - if that # succeeds and we get a validation error, we want # that to propagate self._legacy = LegacyMetadata(fileobj=StringIO(data), scheme=scheme) self.validate() common_keys = set(('name', 'version', 'license', 'keywords', 'summary')) none_list = (None, list) none_dict = (None, dict) mapped_keys = { 'run_requires': ('Requires-Dist', list), 'build_requires': ('Setup-Requires-Dist', list), 'dev_requires': none_list, 'test_requires': none_list, 'meta_requires': none_list, 'extras': ('Provides-Extra', list), 'modules': none_list, 'namespaces': none_list, 'exports': none_dict, 'commands': none_dict, 'classifiers': ('Classifier', list), 'source_url': ('Download-URL', None), 'metadata_version': ('Metadata-Version', None), } del none_list, none_dict def __getattribute__(self, key): common = object.__getattribute__(self, 'common_keys') mapped = object.__getattribute__(self, 'mapped_keys') if key in mapped: lk, maker = mapped[key] if self._legacy: if lk is None: result = None if maker is None else maker() else: result = self._legacy.get(lk) else: value = None if maker is None else maker() if key not in ('commands', 'exports', 'modules', 'namespaces', 'classifiers'): result = self._data.get(key, value) else: # special cases for PEP 459 sentinel = object() result = sentinel d = self._data.get('extensions') if d: if key == 'commands': result = d.get('python.commands', value) elif key == 'classifiers': d = d.get('python.details') if d: result = d.get(key, value) else: d = d.get('python.exports') if not d: d = self._data.get('python.exports') if d: result = d.get(key, value) if result is sentinel: result = value elif key not in common: result = object.__getattribute__(self, key) elif self._legacy: result = self._legacy.get(key) else: result = self._data.get(key) return result def _validate_value(self, key, value, scheme=None): if key in self.SYNTAX_VALIDATORS: pattern, exclusions = self.SYNTAX_VALIDATORS[key] if (scheme or self.scheme) not in exclusions: m = pattern.match(value) if not m: raise MetadataInvalidError("'%s' is an invalid value for " "the '%s' property" % (value, key)) def __setattr__(self, key, value): self._validate_value(key, value) common = object.__getattribute__(self, 'common_keys') mapped = object.__getattribute__(self, 'mapped_keys') if key in mapped: lk, _ = mapped[key] if self._legacy: if lk is None: raise NotImplementedError self._legacy[lk] = value elif key not in ('commands', 'exports', 'modules', 'namespaces', 'classifiers'): self._data[key] = value else: # special cases for PEP 459 d = self._data.setdefault('extensions', {}) if key == 'commands': d['python.commands'] = value elif key == 'classifiers': d = d.setdefault('python.details', {}) d[key] = value else: d = d.setdefault('python.exports', {}) d[key] = value elif key not in common: object.__setattr__(self, key, value) else: if key == 'keywords': if isinstance(value, string_types): value = value.strip() if value: value = value.split() else: value = [] if self._legacy: self._legacy[key] = value else: self._data[key] = value @property def name_and_version(self): return _get_name_and_version(self.name, self.version, True) @property def provides(self): if self._legacy: result = self._legacy['Provides-Dist'] else: result = self._data.setdefault('provides', []) s = '%s (%s)' % (self.name, self.version) if s not in result: result.append(s) return result @provides.setter def provides(self, value): if self._legacy: self._legacy['Provides-Dist'] = value else: self._data['provides'] = value def get_requirements(self, reqts, extras=None, env=None): """ Base method to get dependencies, given a set of extras to satisfy and an optional environment context. :param reqts: A list of sometimes-wanted dependencies, perhaps dependent on extras and environment. :param extras: A list of optional components being requested. :param env: An optional environment for marker evaluation. """ if self._legacy: result = reqts else: result = [] extras = get_extras(extras or [], self.extras) for d in reqts: if 'extra' not in d and 'environment' not in d: # unconditional include = True else: if 'extra' not in d: # Not extra-dependent - only environment-dependent include = True else: include = d.get('extra') in extras if include: # Not excluded because of extras, check environment marker = d.get('environment') if marker: include = interpret(marker, env) if include: result.extend(d['requires']) for key in ('build', 'dev', 'test'): e = ':%s:' % key if e in extras: extras.remove(e) # A recursive call, but it should terminate since 'test' # has been removed from the extras reqts = self._data.get('%s_requires' % key, []) result.extend(self.get_requirements(reqts, extras=extras, env=env)) return result @property def dictionary(self): if self._legacy: return self._from_legacy() return self._data @property def dependencies(self): if self._legacy: raise NotImplementedError else: return extract_by_key(self._data, self.DEPENDENCY_KEYS) @dependencies.setter def dependencies(self, value): if self._legacy: raise NotImplementedError else: self._data.update(value) def _validate_mapping(self, mapping, scheme): if mapping.get('metadata_version') != self.METADATA_VERSION: raise MetadataUnrecognizedVersionError() missing = [] for key, exclusions in self.MANDATORY_KEYS.items(): if key not in mapping: if scheme not in exclusions: missing.append(key) if missing: msg = 'Missing metadata items: %s' % ', '.join(missing) raise MetadataMissingError(msg) for k, v in mapping.items(): self._validate_value(k, v, scheme) def validate(self): if self._legacy: missing, warnings = self._legacy.check(True) if missing or warnings: logger.warning('Metadata: missing: %s, warnings: %s', missing, warnings) else: self._validate_mapping(self._data, self.scheme) def todict(self): if self._legacy: return self._legacy.todict(True) else: result = extract_by_key(self._data, self.INDEX_KEYS) return result def _from_legacy(self): assert self._legacy and not self._data result = { 'metadata_version': self.METADATA_VERSION, 'generator': self.GENERATOR, } lmd = self._legacy.todict(True) # skip missing ones for k in ('name', 'version', 'license', 'summary', 'description', 'classifier'): if k in lmd: if k == 'classifier': nk = 'classifiers' else: nk = k result[nk] = lmd[k] kw = lmd.get('Keywords', []) if kw == ['']: kw = [] result['keywords'] = kw keys = (('requires_dist', 'run_requires'), ('setup_requires_dist', 'build_requires')) for ok, nk in keys: if ok in lmd and lmd[ok]: result[nk] = [{'requires': lmd[ok]}] result['provides'] = self.provides author = {} maintainer = {} return result LEGACY_MAPPING = { 'name': 'Name', 'version': 'Version', ('extensions', 'python.details', 'license'): 'License', 'summary': 'Summary', 'description': 'Description', ('extensions', 'python.project', 'project_urls', 'Home'): 'Home-page', ('extensions', 'python.project', 'contacts', 0, 'name'): 'Author', ('extensions', 'python.project', 'contacts', 0, 'email'): 'Author-email', 'source_url': 'Download-URL', ('extensions', 'python.details', 'classifiers'): 'Classifier', } def _to_legacy(self): def process_entries(entries): reqts = set() for e in entries: extra = e.get('extra') env = e.get('environment') rlist = e['requires'] for r in rlist: if not env and not extra: reqts.add(r) else: marker = '' if extra: marker = 'extra == "%s"' % extra if env: if marker: marker = '(%s) and %s' % (env, marker) else: marker = env reqts.add(';'.join((r, marker))) return reqts assert self._data and not self._legacy result = LegacyMetadata() nmd = self._data # import pdb; pdb.set_trace() for nk, ok in self.LEGACY_MAPPING.items(): if not isinstance(nk, tuple): if nk in nmd: result[ok] = nmd[nk] else: d = nmd found = True for k in nk: try: d = d[k] except (KeyError, IndexError): found = False break if found: result[ok] = d r1 = process_entries(self.run_requires + self.meta_requires) r2 = process_entries(self.build_requires + self.dev_requires) if self.extras: result['Provides-Extra'] = sorted(self.extras) result['Requires-Dist'] = sorted(r1) result['Setup-Requires-Dist'] = sorted(r2) # TODO: any other fields wanted return result def write(self, path=None, fileobj=None, legacy=False, skip_unknown=True): if [path, fileobj].count(None) != 1: raise ValueError('Exactly one of path and fileobj is needed') self.validate() if legacy: if self._legacy: legacy_md = self._legacy else: legacy_md = self._to_legacy() if path: legacy_md.write(path, skip_unknown=skip_unknown) else: legacy_md.write_file(fileobj, skip_unknown=skip_unknown) else: if self._legacy: d = self._from_legacy() else: d = self._data if fileobj: json.dump(d, fileobj, ensure_ascii=True, indent=2, sort_keys=True) else: with codecs.open(path, 'w', 'utf-8') as f: json.dump(d, f, ensure_ascii=True, indent=2, sort_keys=True) def add_requirements(self, requirements): if self._legacy: self._legacy.add_requirements(requirements) else: run_requires = self._data.setdefault('run_requires', []) always = None for entry in run_requires: if 'environment' not in entry and 'extra' not in entry: always = entry break if always is None: always = { 'requires': requirements } run_requires.insert(0, always) else: rset = set(always['requires']) | set(requirements) always['requires'] = sorted(rset) def __repr__(self): name = self.name or '(no name)' version = self.version or 'no version' return '<%s %s %s (%s)>' % (self.__class__.__name__, self.metadata_version, name, version) PKH]]oEE8python3.10/site-packages/pip/_vendor/distlib/__init__.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2012-2019 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # import logging __version__ = '0.3.3' class DistlibException(Exception): pass try: from logging import NullHandler except ImportError: # pragma: no cover class NullHandler(logging.Handler): def handle(self, record): pass def emit(self, record): pass def createLock(self): self.lock = None logger = logging.getLogger(__name__) logger.addHandler(NullHandler()) PKH]y}}7python3.10/site-packages/pip/_vendor/distlib/markers.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2012-2017 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # """ Parser for the environment markers micro-language defined in PEP 508. """ # Note: In PEP 345, the micro-language was Python compatible, so the ast # module could be used to parse it. However, PEP 508 introduced operators such # as ~= and === which aren't in Python, necessitating a different approach. import os import re import sys import platform from .compat import string_types from .util import in_venv, parse_marker from .version import NormalizedVersion as NV __all__ = ['interpret'] _VERSION_PATTERN = re.compile(r'((\d+(\.\d+)*\w*)|\'(\d+(\.\d+)*\w*)\'|\"(\d+(\.\d+)*\w*)\")') def _is_literal(o): if not isinstance(o, string_types) or not o: return False return o[0] in '\'"' def _get_versions(s): result = [] for m in _VERSION_PATTERN.finditer(s): result.append(NV(m.groups()[0])) return set(result) class Evaluator(object): """ This class is used to evaluate marker expessions. """ operations = { '==': lambda x, y: x == y, '===': lambda x, y: x == y, '~=': lambda x, y: x == y or x > y, '!=': lambda x, y: x != y, '<': lambda x, y: x < y, '<=': lambda x, y: x == y or x < y, '>': lambda x, y: x > y, '>=': lambda x, y: x == y or x > y, 'and': lambda x, y: x and y, 'or': lambda x, y: x or y, 'in': lambda x, y: x in y, 'not in': lambda x, y: x not in y, } def evaluate(self, expr, context): """ Evaluate a marker expression returned by the :func:`parse_requirement` function in the specified context. """ if isinstance(expr, string_types): if expr[0] in '\'"': result = expr[1:-1] else: if expr not in context: raise SyntaxError('unknown variable: %s' % expr) result = context[expr] else: assert isinstance(expr, dict) op = expr['op'] if op not in self.operations: raise NotImplementedError('op not implemented: %s' % op) elhs = expr['lhs'] erhs = expr['rhs'] if _is_literal(expr['lhs']) and _is_literal(expr['rhs']): raise SyntaxError('invalid comparison: %s %s %s' % (elhs, op, erhs)) lhs = self.evaluate(elhs, context) rhs = self.evaluate(erhs, context) if ((elhs == 'python_version' or erhs == 'python_version') and op in ('<', '<=', '>', '>=', '===', '==', '!=', '~=')): lhs = NV(lhs) rhs = NV(rhs) elif elhs == 'python_version' and op in ('in', 'not in'): lhs = NV(lhs) rhs = _get_versions(rhs) result = self.operations[op](lhs, rhs) return result def default_context(): def format_full_version(info): version = '%s.%s.%s' % (info.major, info.minor, info.micro) kind = info.releaselevel if kind != 'final': version += kind[0] + str(info.serial) return version if hasattr(sys, 'implementation'): implementation_version = format_full_version(sys.implementation.version) implementation_name = sys.implementation.name else: implementation_version = '0' implementation_name = '' result = { 'implementation_name': implementation_name, 'implementation_version': implementation_version, 'os_name': os.name, 'platform_machine': platform.machine(), 'platform_python_implementation': platform.python_implementation(), 'platform_release': platform.release(), 'platform_system': platform.system(), 'platform_version': platform.version(), 'platform_in_venv': str(in_venv()), 'python_full_version': platform.python_version(), 'python_version': platform.python_version()[:3], 'sys_platform': sys.platform, } return result DEFAULT_CONTEXT = default_context() del default_context evaluator = Evaluator() def interpret(marker, execution_context=None): """ Interpret a marker and return a result depending on environment. :param marker: The marker to interpret. :type marker: str :param execution_context: The context used for name lookup. :type execution_context: mapping """ try: expr, rest = parse_marker(marker) except Exception as e: raise SyntaxError('Unable to interpret marker syntax: %s: %s' % (marker, e)) if rest and rest[0] != '#': raise SyntaxError('unexpected trailing data in marker: %s: %s' % (marker, rest)) context = dict(DEFAULT_CONTEXT) if execution_context: context.update(execution_context) return evaluator.evaluate(expr, context) PKH]ՀD*D*9python3.10/site-packages/pip/_vendor/distlib/resources.pynu[# -*- coding: utf-8 -*- # # Copyright (C) 2013-2017 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # from __future__ import unicode_literals import bisect import io import logging import os import pkgutil import sys import types import zipimport from . import DistlibException from .util import cached_property, get_cache_base, Cache logger = logging.getLogger(__name__) cache = None # created when needed class ResourceCache(Cache): def __init__(self, base=None): if base is None: # Use native string to avoid issues on 2.x: see Python #20140. base = os.path.join(get_cache_base(), str('resource-cache')) super(ResourceCache, self).__init__(base) def is_stale(self, resource, path): """ Is the cache stale for the given resource? :param resource: The :class:`Resource` being cached. :param path: The path of the resource in the cache. :return: True if the cache is stale. """ # Cache invalidation is a hard problem :-) return True def get(self, resource): """ Get a resource into the cache, :param resource: A :class:`Resource` instance. :return: The pathname of the resource in the cache. """ prefix, path = resource.finder.get_cache_info(resource) if prefix is None: result = path else: result = os.path.join(self.base, self.prefix_to_dir(prefix), path) dirname = os.path.dirname(result) if not os.path.isdir(dirname): os.makedirs(dirname) if not os.path.exists(result): stale = True else: stale = self.is_stale(resource, path) if stale: # write the bytes of the resource to the cache location with open(result, 'wb') as f: f.write(resource.bytes) return result class ResourceBase(object): def __init__(self, finder, name): self.finder = finder self.name = name class Resource(ResourceBase): """ A class representing an in-package resource, such as a data file. This is not normally instantiated by user code, but rather by a :class:`ResourceFinder` which manages the resource. """ is_container = False # Backwards compatibility def as_stream(self): """ Get the resource as a stream. This is not a property to make it obvious that it returns a new stream each time. """ return self.finder.get_stream(self) @cached_property def file_path(self): global cache if cache is None: cache = ResourceCache() return cache.get(self) @cached_property def bytes(self): return self.finder.get_bytes(self) @cached_property def size(self): return self.finder.get_size(self) class ResourceContainer(ResourceBase): is_container = True # Backwards compatibility @cached_property def resources(self): return self.finder.get_resources(self) class ResourceFinder(object): """ Resource finder for file system resources. """ if sys.platform.startswith('java'): skipped_extensions = ('.pyc', '.pyo', '.class') else: skipped_extensions = ('.pyc', '.pyo') def __init__(self, module): self.module = module self.loader = getattr(module, '__loader__', None) self.base = os.path.dirname(getattr(module, '__file__', '')) def _adjust_path(self, path): return os.path.realpath(path) def _make_path(self, resource_name): # Issue #50: need to preserve type of path on Python 2.x # like os.path._get_sep if isinstance(resource_name, bytes): # should only happen on 2.x sep = b'/' else: sep = '/' parts = resource_name.split(sep) parts.insert(0, self.base) result = os.path.join(*parts) return self._adjust_path(result) def _find(self, path): return os.path.exists(path) def get_cache_info(self, resource): return None, resource.path def find(self, resource_name): path = self._make_path(resource_name) if not self._find(path): result = None else: if self._is_directory(path): result = ResourceContainer(self, resource_name) else: result = Resource(self, resource_name) result.path = path return result def get_stream(self, resource): return open(resource.path, 'rb') def get_bytes(self, resource): with open(resource.path, 'rb') as f: return f.read() def get_size(self, resource): return os.path.getsize(resource.path) def get_resources(self, resource): def allowed(f): return (f != '__pycache__' and not f.endswith(self.skipped_extensions)) return set([f for f in os.listdir(resource.path) if allowed(f)]) def is_container(self, resource): return self._is_directory(resource.path) _is_directory = staticmethod(os.path.isdir) def iterator(self, resource_name): resource = self.find(resource_name) if resource is not None: todo = [resource] while todo: resource = todo.pop(0) yield resource if resource.is_container: rname = resource.name for name in resource.resources: if not rname: new_name = name else: new_name = '/'.join([rname, name]) child = self.find(new_name) if child.is_container: todo.append(child) else: yield child class ZipResourceFinder(ResourceFinder): """ Resource finder for resources in .zip files. """ def __init__(self, module): super(ZipResourceFinder, self).__init__(module) archive = self.loader.archive self.prefix_len = 1 + len(archive) # PyPy doesn't have a _files attr on zipimporter, and you can't set one if hasattr(self.loader, '_files'): self._files = self.loader._files else: self._files = zipimport._zip_directory_cache[archive] self.index = sorted(self._files) def _adjust_path(self, path): return path def _find(self, path): path = path[self.prefix_len:] if path in self._files: result = True else: if path and path[-1] != os.sep: path = path + os.sep i = bisect.bisect(self.index, path) try: result = self.index[i].startswith(path) except IndexError: result = False if not result: logger.debug('_find failed: %r %r', path, self.loader.prefix) else: logger.debug('_find worked: %r %r', path, self.loader.prefix) return result def get_cache_info(self, resource): prefix = self.loader.archive path = resource.path[1 + len(prefix):] return prefix, path def get_bytes(self, resource): return self.loader.get_data(resource.path) def get_stream(self, resource): return io.BytesIO(self.get_bytes(resource)) def get_size(self, resource): path = resource.path[self.prefix_len:] return self._files[path][3] def get_resources(self, resource): path = resource.path[self.prefix_len:] if path and path[-1] != os.sep: path += os.sep plen = len(path) result = set() i = bisect.bisect(self.index, path) while i < len(self.index): if not self.index[i].startswith(path): break s = self.index[i][plen:] result.add(s.split(os.sep, 1)[0]) # only immediate children i += 1 return result def _is_directory(self, path): path = path[self.prefix_len:] if path and path[-1] != os.sep: path += os.sep i = bisect.bisect(self.index, path) try: result = self.index[i].startswith(path) except IndexError: result = False return result _finder_registry = { type(None): ResourceFinder, zipimport.zipimporter: ZipResourceFinder } try: # In Python 3.6, _frozen_importlib -> _frozen_importlib_external try: import _frozen_importlib_external as _fi except ImportError: import _frozen_importlib as _fi _finder_registry[_fi.SourceFileLoader] = ResourceFinder _finder_registry[_fi.FileFinder] = ResourceFinder # See issue #146 _finder_registry[_fi.SourcelessFileLoader] = ResourceFinder del _fi except (ImportError, AttributeError): pass def register_finder(loader, finder_maker): _finder_registry[type(loader)] = finder_maker _finder_cache = {} def finder(package): """ Return a resource finder for a package. :param package: The name of the package. :return: A :class:`ResourceFinder` instance for the package. """ if package in _finder_cache: result = _finder_cache[package] else: if package not in sys.modules: __import__(package) module = sys.modules[package] path = getattr(module, '__path__', None) if path is None: raise DistlibException('You cannot get a finder for a module, ' 'only for a package') loader = getattr(module, '__loader__', None) finder_maker = _finder_registry.get(type(loader)) if finder_maker is None: raise DistlibException('Unable to locate finder for %r' % package) result = finder_maker(module) _finder_cache[package] = result return result _dummy_module = types.ModuleType(str('__dummy__')) def finder_for_path(path): """ Return a resource finder for a path, which should represent a container. :param path: The path. :return: A :class:`ResourceFinder` instance for the path. """ result = None # calls any path hooks, gets importer into cache pkgutil.get_importer(path) loader = sys.path_importer_cache.get(path) finder = _finder_registry.get(type(loader)) if finder: module = _dummy_module module.__file__ = os.path.join(path, '') module.__loader__ = loader result = finder(module) return result PKH]V0tt=python3.10/site-packages/pip/_vendor/platformdirs/__main__.pynu[from pip._vendor.platformdirs import PlatformDirs, __version__ PROPS = ( "user_data_dir", "user_config_dir", "user_cache_dir", "user_state_dir", "user_log_dir", "user_documents_dir", "user_runtime_dir", "site_data_dir", "site_config_dir", ) def main() -> None: app_name = "MyApp" app_author = "MyCompany" print(f"-- platformdirs {__version__} --") print("-- app dirs (with optional 'version')") dirs = PlatformDirs(app_name, app_author, version="1.0") for prop in PROPS: print(f"{prop}: {getattr(dirs, prop)}") print("\n-- app dirs (without optional 'version')") dirs = PlatformDirs(app_name, app_author) for prop in PROPS: print(f"{prop}: {getattr(dirs, prop)}") print("\n-- app dirs (without optional 'appauthor')") dirs = PlatformDirs(app_name) for prop in PROPS: print(f"{prop}: {getattr(dirs, prop)}") print("\n-- app dirs (with disabled 'appauthor')") dirs = PlatformDirs(app_name, appauthor=False) for prop in PROPS: print(f"{prop}: {getattr(dirs, prop)}") if __name__ == "__main__": main() PKH]SSUpython3.10/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-310.pycnu[o aiP@sdZdZdZdS)z Version information z2.4.0)N)__doc__ __version____version_info__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/platformdirs/version.pysPKH] x Spython3.10/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-310.pycnu[o ai; @s.ddlZddlmZGdddeZdgZdS)N)PlatformDirsABCc@seZdZdZedefddZedefddZedefddZedefd d Z edefd d Z edefd dZ edefddZ edefddZ edefddZdS)MacOSa Platform directories for the macOS operating system. Follows the guidance from `Apple documentation `_. Makes use of the `appname ` and `version `. returncC|tjdS)zb:return: data directory tied to the user, e.g. ``~/Library/Application Support/$appname/$version``z~/Library/Application Support/_append_app_name_and_versionospath expanduserselfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/platformdirs/macos.py user_data_dirzMacOS.user_data_dircC |dS)z`:return: data directory shared by users, e.g. ``/Library/Application Support/$appname/$version``z/Library/Application Supportrr rrr site_data_dir zMacOS.site_data_dircCr)z\:return: config directory tied to the user, e.g. ``~/Library/Preferences/$appname/$version``z~/Library/Preferences/rr rrruser_config_dirrzMacOS.user_config_dircCr)zU:return: config directory shared by the users, e.g. ``/Library/Preferences/$appname``z/Library/Preferencesrr rrrsite_config_dirrzMacOS.site_config_dircCr)zV:return: cache directory tied to the user, e.g. ``~/Library/Caches/$appname/$version``z~/Library/Cachesrr rrruser_cache_dir"rzMacOS.user_cache_dircCs|jS)zB:return: state directory tied to the user, same as `user_data_dir`)rr rrruser_state_dir'szMacOS.user_state_dircCr)zR:return: log directory tied to the user, e.g. ``~/Library/Logs/$appname/$version``z~/Library/Logsrr rrr user_log_dir,rzMacOS.user_log_dircCs tjdS)zC:return: documents directory tied to the user, e.g. ``~/Documents``z ~/Documents)r r r r rrruser_documents_dir1s zMacOS.user_documents_dircCr)zg:return: runtime directory tied to the user, e.g. ``~/Library/Caches/TemporaryItems/$appname/$version``z~/Library/Caches/TemporaryItemsrr rrruser_runtime_dir6rzMacOS.user_runtime_dirN)__name__ __module__ __qualname____doc__propertystrrrrrrrrrrrrrrrs(r)r apirr__all__rrrrs  7PKH]_""Upython3.10/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-310.pycnu[o ai@sddlZddlZddlmZddlmZmZddlmZGdddeZ de d e fd d Z de d e fd d Z de d e fddZ d ee ge ffddZeddeZdgZdS)N) lru_cache)CallableOptional)PlatformDirsABCc@seZdZdZedefddZdddedeedefd d Zedefd d Z edefd dZ edefddZ edefddZ edefddZ edefddZedefddZedefddZdS)Windowsa`MSDN on where to store app data files `_. Makes use of the `appname `, `appauthor `, `version `, `roaming `, `opinion `.returncCs(|jrdnd}tjt|}||S)z :return: data directory tied to the user, e.g. ``%USERPROFILE%\AppData\Local\$appauthor\$appname`` (not roaming) or ``%USERPROFILE%\AppData\Roaming\$appauthor\$appname`` (roaming) CSIDL_APPDATACSIDL_LOCAL_APPDATA)roamingospathnormpathget_win_folder _append_parts)selfconstr r/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/platformdirs/windows.py user_data_dirs zWindows.user_data_dirN opinion_valuer rcCstg}|jr0|jdur|jp|j}||||j|dur'|jr'|||jr0||jtjj|g|RS)NF)appname appauthorappendopinionversionr r join)rr rparamsauthorrrrrs      zWindows._append_partscCstjtd}||S)zT:return: data directory shared by users, e.g. ``C:\ProgramData\$appauthor\$appname``CSIDL_COMMON_APPDATAr r rrrrr rrr site_data_dir+s zWindows.site_data_dircC|jS)zC:return: config directory tied to the user, same as `user_data_dir`rrrrruser_config_dir1zWindows.user_config_dircCr$)zF:return: config directory shared by the users, same as `site_data_dir`)r#r&rrrsite_config_dir6r(zWindows.site_config_dircCstjtd}|j|ddS)z :return: cache directory tied to the user (if opinionated with ``Cache`` folder within ``$appname``) e.g. ``%USERPROFILE%\AppData\Local\$appauthor\$appname\Cache\$version`` r Cacherr!r"rrruser_cache_dir;szWindows.user_cache_dircCr$)zB:return: state directory tied to the user, same as `user_data_dir`r%r&rrruser_state_dirDr(zWindows.user_state_dircCs|j}|jr tj|d}|S)zy :return: log directory tied to the user, same as `user_data_dir` if not opinionated else ``Logs`` in it ZLogs)rrr r rr"rrr user_log_dirIszWindows.user_log_dircCstjtdS)z` :return: documents directory tied to the user e.g. ``%USERPROFILE%\Documents`` CSIDL_PERSONAL)r r rrr&rrruser_documents_dirSszWindows.user_documents_dircCs$tjtjtdd}||S)z :return: runtime directory tied to the user, e.g. ``%USERPROFILE%\AppData\Local\Temp\$appauthor\$appname`` r ZTemp)r r rrrrr"rrruser_runtime_dirZs zWindows.user_runtime_dir)__name__ __module__ __qualname____doc__propertystrrrrr#r'r)r+r,r-r/r0rrrrr s*    r csidl_namercCsr|dkrtjtjtjddSdddd|}|dur&td |tj|}|dur7td ||S) z&Get folder from environment variables.r. USERPROFILEZ DocumentsAPPDATAZALLUSERSPROFILE LOCALAPPDATA)r r r NUnknown CSIDL name: zUnset environment variable: )r r rrenvironget ValueError)r7Z env_var_nameresultrrrget_win_folder_from_env_varsds r@cCsXddddd|}|durtd|ddl}||jd }|||\}}t|S) zGet folder from the registry. This is a fallback technique at best. I'm not sure if using the registry for this guarantees us the correct answer for all CSIDL_* names. ZAppDatazCommon AppDataz Local AppDataZPersonalr r r r.Nr;rz@Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders)r=r>winregOpenKeyHKEY_CURRENT_USER QueryValueExr6)r7Zshell_folder_namerBkey directory_rrrget_win_folder_from_registryvsrIcCsddddd|}|durtd|td}ttd }|jd|dd |td d |DrBtd}|j |j |drB|}|j S) zGet folder with ctypes.#rANr;iwindllrcss|] }t|dkVqdS)N)ord).0crrr sz,get_win_folder_via_ctypes..) r=r>ctypescreate_unicode_buffergetattrZshell32ZSHGetFolderPathWanyZkernel32ZGetShortPathNameWvalue)r7Z csidl_constbufrNZbuf2rrrget_win_folder_via_ctypess"   rZcCs4ttdrtSzddl}WtStytYSw)NrNr)hasattrrTrZrB ImportErrorr@rI)rBrrr_pick_get_win_folders   r])maxsize)rTr functoolsrtypingrrapirrr6r@rIrZr]r__all__rrrrs  [ PKH]4ŧVpython3.10/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-310.pycnu[o ait@s4ddlmZmZdZdddZedkredSdS) ) PlatformDirs __version__) user_data_diruser_config_diruser_cache_diruser_state_dir user_log_diruser_documents_diruser_runtime_dir site_data_dirsite_config_dirreturnNcCsd}d}tdtdtdt||dd}tD]}t|dt||qtd t||}tD]}t|dt||q3td t|}tD]}t|dt||qLtd t|d d }tD]}t|dt||qgdS)NZMyAppZ MyCompanyz-- platformdirs z --z%-- app dirs (with optional 'version')z1.0)versionz: z) -- app dirs (without optional 'version')z+ -- app dirs (without optional 'appauthor')z( -- app dirs (with disabled 'appauthor')F) appauthor)printrrPROPSgetattr)Zapp_nameZ app_authordirspropr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/platformdirs/__main__.pymains(  r__main__)r N)Zpip._vendor.platformdirsrrrr__name__rrrrs   PKH]]U/+/+Vpython3.10/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-310.pycnu[o ai;2 @sPdZddlZddlZddlZddlmZddlmZmZm Z m Z er(ddl m Z ddl mZddlmZmZd e efd d ZeZeZ    d:d eede eddfdeeded ef ddZ    d:d eede eddfdeeded ef ddZ    d:d eede eddfdeeded ef ddZ    d:d eede eddfdeeded ef ddZ    d;d eede eddfdeeded ef ddZ    d:d eede eddfdeeded ef dd Z    d;d eede eddfdeeded ef d!d"Zd efd#d$Z    d;d eede eddfdeeded ef d%d&Z    d:d eede eddfdeeded ef d'd(Z    d:d eede eddfdeeded ef d)d*Z!    d:d eede eddfdeeded ef d+d,Z"    d:d eede eddfdeeded ef d-d.Z#    d;d eede eddfdeeded ef d/d0Z$    d:d eede eddfdeeded ef d1d2Z%    d;d eede eddfdeeded ef d3d4Z&d efd5d6Z'    d;d eede eddfdeeded ef d7d8Z(gd9Z)dS) for details and usage. N)Path) TYPE_CHECKINGOptionalTypeUnion)Literal)PlatformDirsABC) __version____version_info__returncCsjtddkrtddkrd\}}ntjdkrd\}}ntjdkr'd \}}nd \}}tt||}|S) N ANDROID_DATAz/data ANDROID_ROOTz/system)z pip._vendor.platformdirs.androidAndroidwin32)z pip._vendor.platformdirs.windowsWindowsdarwin)zpip._vendor.platformdirs.macosMacOS)zpip._vendor.platformdirs.unixUnix)osgetenvsysplatformgetattr importlib import_module)modulenameresultr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/platformdirs/__init__.py_set_platform_dir_classs     r!Fappname appauthorzLiteral[False]versionroamingcCt||||djS)aq :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: data directory tied to the user r"r#r$r%) PlatformDirs user_data_dirr'rrr r)# r) multipathcCr&)at :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param multipath: See `roaming `. :returns: data directory shared by users r"r#r$r+)r( site_data_dirr,rrr r-3r*r-cCr&)as :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: config directory tied to the user r')r(user_config_dirr'rrr r.Cr*r.cCr&)az :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param multipath: See `roaming `. :returns: config directory shared by the users r,)r(site_config_dirr,rrr r/Sr*r/TopinioncCr&)ar :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `roaming `. :returns: cache directory tied to the user r"r#r$r0)r(user_cache_dirr1rrr r2cr*r2cCr&)ar :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: state directory tied to the user r')r(user_state_dirr'rrr r3sr*r3cCr&)ap :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `roaming `. :returns: log directory tied to the user r1)r( user_log_dirr1rrr r4r*r4cCtjS)z8 :returns: documents directory tied to the user )r(user_documents_dirrrrr r6r6cCr&)at :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `opinion `. :returns: runtime directory tied to the user r1)r(user_runtime_dirr1rrr r8r*r8cCr&)al :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: data path tied to the user r')r(user_data_pathr'rrr r9r*r9cCr&)aq :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param multipath: See `multipath `. :returns: data path shared by users r,)r(site_data_pathr,rrr r:r*r:cCr&)an :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: config path tied to the user r')r(user_config_pathr'rrr r;r*r;cCr&)au :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param multipath: See `roaming `. :returns: config path shared by the users r,)r(site_config_pathr,rrr r<r*r<cCr&)am :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `roaming `. :returns: cache path tied to the user r1)r(user_cache_pathr1rrr r=r*r=cCr&)am :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: state path tied to the user r')r(user_state_pathr'rrr r>r*r>cCr&)ak :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `roaming `. :returns: log path tied to the user r1)r( user_log_pathr1rrr r? r*r?cCr5)z3 :returns: documents path tied to the user )r(user_documents_pathrrrr r@r7r@cCr&)ao :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `opinion `. :returns: runtime path tied to the user r1)r(user_runtime_pathr1rrr rA!r*rA)r r r(AppDirsr r)r.r2r3r4r6r8r-r/r9r;r=r>r?r@rAr:r<)NNNF)NNNT)*__doc__rrrpathlibrtypingrrrrZtyping_extensionsrapir r$r r r!r(rBstrboolr)r-r.r/r2r3r4r6r8r9r:r;r<r=r>r?r@rA__all__rrrr s                                    PKH]쏻Qpython3.10/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-310.pycnu[o ai:@sfddlZddlZddlmZmZddlmZddlmZm Z ej dkr)ddlm Z GdddeZ dS) N)ABCabstractmethod)Path)OptionalUnion))Literalc @seZdZdZ      d6deedeeddfdeed ed ed ef d d ZdedefddZ e e defddZ e e defddZ e e defddZe e defddZe e defddZe e defddZe e defddZe e defd d!Ze e defd"d#Ze defd$d%Ze defd&d'Ze defd(d)Ze defd*d+Ze defd,d-Ze defd.d/Ze defd0d1Ze defd2d3Ze defd4d5ZdS)7PlatformDirsABCz7 Abstract base class for platform directories. NFTappname appauthorzLiteral[False]versionroaming multipathopinioncCs0||_||_ ||_ ||_ ||_ ||_dS)a% Create a new platform directory. :param appname: See `appname`. :param appauthor: See `appauthor`. :param version: See `version`. :param roaming: See `roaming`. :param multipath: See `multipath`. :param opinion: See `opinion`. N)r r r rrr)selfr r r rrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/platformdirs/api.py__init__s zPlatformDirsABC.__init__basereturncGsLt|dd}|jr||j|jr||jtjj|dg|RS)Nr)listr appendr ospathjoin)rrparamsrrr_append_app_name_and_version;s   z,PlatformDirsABC._append_app_name_and_versioncCdS)z(:return: data directory tied to the userNrrrrr user_data_dirCzPlatformDirsABC.user_data_dircCr)z':return: data directory shared by usersNrr rrr site_data_dirHr"zPlatformDirsABC.site_data_dircCr)z*:return: config directory tied to the userNrr rrruser_config_dirMr"zPlatformDirsABC.user_config_dircCr)z-:return: config directory shared by the usersNrr rrrsite_config_dirRr"zPlatformDirsABC.site_config_dircCr)z):return: cache directory tied to the userNrr rrruser_cache_dirWr"zPlatformDirsABC.user_cache_dircCr)z):return: state directory tied to the userNrr rrruser_state_dir\r"zPlatformDirsABC.user_state_dircCr)z':return: log directory tied to the userNrr rrr user_log_dirar"zPlatformDirsABC.user_log_dircCr)z-:return: documents directory tied to the userNrr rrruser_documents_dirfr"z"PlatformDirsABC.user_documents_dircCr)z+:return: runtime directory tied to the userNrr rrruser_runtime_dirkr"z PlatformDirsABC.user_runtime_dircC t|jS)z#:return: data path tied to the user)rr!r rrruser_data_pathp zPlatformDirsABC.user_data_pathcCr+)z":return: data path shared by users)rr#r rrrsite_data_pathur-zPlatformDirsABC.site_data_pathcCr+)z%:return: config path tied to the user)rr$r rrruser_config_pathzr-z PlatformDirsABC.user_config_pathcCr+)z(:return: config path shared by the users)rr%r rrrsite_config_pathr-z PlatformDirsABC.site_config_pathcCr+)z$:return: cache path tied to the user)rr&r rrruser_cache_pathr-zPlatformDirsABC.user_cache_pathcCr+)z$:return: state path tied to the user)rr'r rrruser_state_pathr-zPlatformDirsABC.user_state_pathcCr+)z":return: log path tied to the user)rr(r rrr user_log_pathr-zPlatformDirsABC.user_log_pathcCr+)z(:return: documents path tied to the user)rr)r rrruser_documents_pathr-z#PlatformDirsABC.user_documents_pathcCr+)z&:return: runtime path tied to the user)rr*r rrruser_runtime_pathr-z!PlatformDirsABC.user_runtime_path)NNNFFT)__name__ __module__ __qualname____doc__rstrrboolrrpropertyrr!r#r$r%r&r'r(r)r*rr,r.r/r0r1r2r3r4r5rrrrr s  +r ) rsysabcrrpathlibrtypingrr version_infor r rrrrs   PKH]VRpython3.10/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-310.pycnu[o ai@sddlZddlZddlmZddlmZddlmZddlm Z ej dr-ddlm Z nd e fd d Z Gd d d e Zded eefddZd gZdS)N) ConfigParser)Path)Optional)PlatformDirsABClinux)getuidreturncCstd)Nzshould only be used on Linux) RuntimeErrorr r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/platformdirs/unix.pyr src@seZdZdZedefddZedefddZdedefdd Zedefd d Z edefd d Z edefddZ edefddZ edefddZ edefddZedefddZedefddZedefddZdedefddZdS) UnixaD On Unix/Linux, we follow the `XDG Basedir Spec `_. The spec allows overriding directories with environment variables. The examples show are the default values, alongside the name of the environment variable that overrides them. Makes use of the `appname `, `version `, `multipath `, `opinion `. r cC,tjdd}|stjd}||S)z :return: data directory tied to the user, e.g. ``~/.local/share/$appname/$version`` or ``$XDG_DATA_HOME/$appname/$version`` XDG_DATA_HOMEz~/.local/shareosenvirongetstrippath expanduser_append_app_name_and_versionselfrr r r user_data_dir  zUnix.user_data_dircCs.tjdd}|sdtjd}||S)aY :return: data directories shared by users (if `multipath ` is enabled and ``XDG_DATA_DIR`` is set and a multi path the response is also a multi path separated by the OS path separator), e.g. ``/usr/local/share/$appname/$version`` or ``/usr/share/$appname/$version`` XDG_DATA_DIRSrz/usr/local/sharez /usr/share)rrrrpathsep_with_multi_pathrr r r site_data_dir(s zUnix.site_data_dirrcs<|tj}js|dd}fdd|D}tj|S)Nrrcsg|] }tj|qSr )rrrr).0prr r 9sz)Unix._with_multi_path..)splitrr multipathjoin)rr path_listr r#r r5s   zUnix._with_multi_pathcCr)z :return: config directory tied to the user, e.g. ``~/.config/$appname/$version`` or ``$XDG_CONFIG_HOME/$appname/$version`` XDG_CONFIG_HOMErz ~/.configrrr r r user_config_dir<rzUnix.user_config_dircCs$tjdd}|s d}||S)a/ :return: config directories shared by users (if `multipath ` is enabled and ``XDG_DATA_DIR`` is set and a multi path the response is also a multi path separated by the OS path separator), e.g. ``/etc/xdg/$appname/$version`` XDG_CONFIG_DIRSrz/etc/xdg)rrrrrrr r r site_config_dirGs zUnix.site_config_dircCr)z :return: cache directory tied to the user, e.g. ``~/.cache/$appname/$version`` or ``~/$XDG_CACHE_HOME/$appname/$version`` XDG_CACHE_HOMErz~/.cacherrr r r user_cache_dirTrzUnix.user_cache_dircCr)z :return: state directory tied to the user, e.g. ``~/.local/state/$appname/$version`` or ``$XDG_STATE_HOME/$appname/$version`` XDG_STATE_HOMErz~/.local/staterrr r r user_state_dir_rzUnix.user_state_dircCs|j}|jr tj|d}|S)zx :return: log directory tied to the user, same as `user_data_dir` if not opinionated else ``log`` in it log)r.opinionrrr'rr r r user_log_dirjszUnix.user_log_dircCs6td}|durtjdd}|stjd}|S)zU :return: documents directory tied to the user, e.g. ``~/Documents`` XDG_DOCUMENTS_DIRNrz ~/Documents)_get_user_dirs_folderrrrrrr)r documents_dirr r r user_documents_dirts  zUnix.user_documents_dircCs,tjdd}|sdt}||S)z :return: runtime directory tied to the user, e.g. ``/run/user/$(id -u)/$appname/$version`` or ``$XDG_RUNTIME_DIR/$appname/$version`` XDG_RUNTIME_DIRrz /run/user/)rrrrrrrr r r user_runtime_dirrzUnix.user_runtime_dircC ||jS)zd:return: data path shared by users. Only return first item, even if ``multipath`` is set to ``True``) _first_item_as_path_if_multipathr r#r r r site_data_path zUnix.site_data_pathcCr:)zj:return: config path shared by the users. Only return first item, even if ``multipath`` is set to ``True``)r;r,r#r r r site_config_pathr=zUnix.site_config_path directorycCs|jr |tjd}t|S)Nr)r&r%rrr)rr?r r r r;sz%Unix._first_item_as_path_if_multipathN)__name__ __module__ __qualname____doc__propertystrrr rr*r,r.r0r3r7r9rr<r>r;r r r r r s4          r keycCstjtjd}tj|rMt}t|}|d| Wdn1s+wY||dvr8dS|d| d}| dtj d}|SdS)zjReturn directory from user-dirs.dirs config file. See https://freedesktop.org/wiki/Software/xdg-user-dirs/zuser-dirs.dirsz[top] Ntop"z$HOME~) rrr'r r*existsropen read_stringreadrreplacer)rFuser_dirs_config_pathparserstreamrr r r r5s   r5)rsys configparserrpathlibrtypingrapirplatform startswithrintr rEr5__all__r r r r s      PKH]`_. Makes use of the `appname ` and `version `. returncC|tdS)zd:return: data directory tied to the user, e.g. ``/data/user///files/``files_append_app_name_and_version_android_folderselfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/platformdirs/android.py user_data_dirzAndroid.user_data_dircC|jS)z@:return: data directory shared by users, same as `user_data_dir`rr rrr site_data_dirzAndroid.site_data_dircCr)z :return: config directory tied to the user, e.g. ``/data/user///shared_prefs/`` Z shared_prefsr r rrruser_config_dirszAndroid.user_config_dircCr)zH:return: config directory shared by the users, same as `user_config_dir`)rr rrrsite_config_dir!rzAndroid.site_config_dircCr)zj:return: cache directory tied to the user, e.g. e.g. ``/data/user///cache/``cacher r rrruser_cache_dir&rzAndroid.user_cache_dircCr)zB:return: state directory tied to the user, same as `user_data_dir`rr rrruser_state_dir+rzAndroid.user_state_dircC|j}|jr tj|d}|S)z :return: log directory tied to the user, same as `user_cache_dir` if not opinionated else ``log`` in it, e.g. ``/data/user///cache//log`` logropinionospathjoinr r rrr user_log_dir0zAndroid.user_log_dircCstS)zf :return: documents directory tied to the user e.g. ``/storage/emulated/0/Documents`` )_android_documents_folderr rrruser_documents_dir;szAndroid.user_documents_dircCr)z :return: runtime directory tied to the user, same as `user_cache_dir` if not opinionated else ``tmp`` in it, e.g. ``/data/user///cache//tmp`` tmprr"rrruser_runtime_dirBr$zAndroid.user_runtime_dirN)__name__ __module__ __qualname____doc__propertystrrrrrrrr#r&r(rrrrr s( r)maxsizercCsxzddlm}|d}|}W|Sty;td}tj D]}| |r6| dd}Y|Sq$t dw)z':return: base folder for the Android OSr autoclassandroid.content.Contextz /data/(data|user/\d+)/(.+)/filesz/filesz&Cannot find path to android app folder) jniusr1Z getFilesDirZ getParentFilegetAbsolutePath Exceptionrecompilesysr matchsplitOSError)r1Contextresultpatternr rrrr Ns    r cCsLzddlm}|d}|d}||j}W|Sty%d}Y|Sw)z,:return: documents folder for the Android OSrr0r2zandroid.os.Environmentz/storage/emulated/0/Documents)r3r1ZgetExternalFilesDirZDIRECTORY_DOCUMENTSr4r5)r1r< Environment documents_dirrrrr%cs  r%) rr6r8 functoolsrapirrr.r r%__all__rrrrs  EPKH]Ū.; ; :python3.10/site-packages/pip/_vendor/platformdirs/macos.pynu[import os from .api import PlatformDirsABC class MacOS(PlatformDirsABC): """ Platform directories for the macOS operating system. Follows the guidance from `Apple documentation `_. Makes use of the `appname ` and `version `. """ @property def user_data_dir(self) -> str: """:return: data directory tied to the user, e.g. ``~/Library/Application Support/$appname/$version``""" return self._append_app_name_and_version(os.path.expanduser("~/Library/Application Support/")) @property def site_data_dir(self) -> str: """:return: data directory shared by users, e.g. ``/Library/Application Support/$appname/$version``""" return self._append_app_name_and_version("/Library/Application Support") @property def user_config_dir(self) -> str: """:return: config directory tied to the user, e.g. ``~/Library/Preferences/$appname/$version``""" return self._append_app_name_and_version(os.path.expanduser("~/Library/Preferences/")) @property def site_config_dir(self) -> str: """:return: config directory shared by the users, e.g. ``/Library/Preferences/$appname``""" return self._append_app_name_and_version("/Library/Preferences") @property def user_cache_dir(self) -> str: """:return: cache directory tied to the user, e.g. ``~/Library/Caches/$appname/$version``""" return self._append_app_name_and_version(os.path.expanduser("~/Library/Caches")) @property def user_state_dir(self) -> str: """:return: state directory tied to the user, same as `user_data_dir`""" return self.user_data_dir @property def user_log_dir(self) -> str: """:return: log directory tied to the user, e.g. ``~/Library/Logs/$appname/$version``""" return self._append_app_name_and_version(os.path.expanduser("~/Library/Logs")) @property def user_documents_dir(self) -> str: """:return: documents directory tied to the user, e.g. ``~/Documents``""" return os.path.expanduser("~/Documents") @property def user_runtime_dir(self) -> str: """:return: runtime directory tied to the user, e.g. ``~/Library/Caches/TemporaryItems/$appname/$version``""" return self._append_app_name_and_version(os.path.expanduser("~/Library/Caches/TemporaryItems")) __all__ = [ "MacOS", ] PKH]j?}::8python3.10/site-packages/pip/_vendor/platformdirs/api.pynu[import os import sys from abc import ABC, abstractmethod from pathlib import Path from typing import Optional, Union if sys.version_info >= (3, 8): # pragma: no branch from typing import Literal # pragma: no cover class PlatformDirsABC(ABC): """ Abstract base class for platform directories. """ def __init__( self, appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, roaming: bool = False, multipath: bool = False, opinion: bool = True, ): """ Create a new platform directory. :param appname: See `appname`. :param appauthor: See `appauthor`. :param version: See `version`. :param roaming: See `roaming`. :param multipath: See `multipath`. :param opinion: See `opinion`. """ self.appname = appname #: The name of application. self.appauthor = appauthor """ The name of the app author or distributing body for this application. Typically, it is the owning company name. Defaults to `appname`. You may pass ``False`` to disable it. """ self.version = version """ An optional version path element to append to the path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be ``.``. """ self.roaming = roaming """ Whether to use the roaming appdata directory on Windows. That means that for users on a Windows network setup for roaming profiles, this user data will be synced on login (see `here `_). """ self.multipath = multipath """ An optional parameter only applicable to Unix/Linux which indicates that the entire list of data dirs should be returned. By default, the first item would only be returned. """ self.opinion = opinion #: A flag to indicating to use opinionated values. def _append_app_name_and_version(self, *base: str) -> str: params = list(base[1:]) if self.appname: params.append(self.appname) if self.version: params.append(self.version) return os.path.join(base[0], *params) @property @abstractmethod def user_data_dir(self) -> str: """:return: data directory tied to the user""" @property @abstractmethod def site_data_dir(self) -> str: """:return: data directory shared by users""" @property @abstractmethod def user_config_dir(self) -> str: """:return: config directory tied to the user""" @property @abstractmethod def site_config_dir(self) -> str: """:return: config directory shared by the users""" @property @abstractmethod def user_cache_dir(self) -> str: """:return: cache directory tied to the user""" @property @abstractmethod def user_state_dir(self) -> str: """:return: state directory tied to the user""" @property @abstractmethod def user_log_dir(self) -> str: """:return: log directory tied to the user""" @property @abstractmethod def user_documents_dir(self) -> str: """:return: documents directory tied to the user""" @property @abstractmethod def user_runtime_dir(self) -> str: """:return: runtime directory tied to the user""" @property def user_data_path(self) -> Path: """:return: data path tied to the user""" return Path(self.user_data_dir) @property def site_data_path(self) -> Path: """:return: data path shared by users""" return Path(self.site_data_dir) @property def user_config_path(self) -> Path: """:return: config path tied to the user""" return Path(self.user_config_dir) @property def site_config_path(self) -> Path: """:return: config path shared by the users""" return Path(self.site_config_dir) @property def user_cache_path(self) -> Path: """:return: cache path tied to the user""" return Path(self.user_cache_dir) @property def user_state_path(self) -> Path: """:return: state path tied to the user""" return Path(self.user_state_dir) @property def user_log_path(self) -> Path: """:return: log path tied to the user""" return Path(self.user_log_dir) @property def user_documents_path(self) -> Path: """:return: documents path tied to the user""" return Path(self.user_documents_dir) @property def user_runtime_path(self) -> Path: """:return: runtime path tied to the user""" return Path(self.user_runtime_dir) PKH] -Қ<python3.10/site-packages/pip/_vendor/platformdirs/android.pynu[import os import re import sys from functools import lru_cache from .api import PlatformDirsABC class Android(PlatformDirsABC): """ Follows the guidance `from here `_. Makes use of the `appname ` and `version `. """ @property def user_data_dir(self) -> str: """:return: data directory tied to the user, e.g. ``/data/user///files/``""" return self._append_app_name_and_version(_android_folder(), "files") @property def site_data_dir(self) -> str: """:return: data directory shared by users, same as `user_data_dir`""" return self.user_data_dir @property def user_config_dir(self) -> str: """ :return: config directory tied to the user, e.g. ``/data/user///shared_prefs/`` """ return self._append_app_name_and_version(_android_folder(), "shared_prefs") @property def site_config_dir(self) -> str: """:return: config directory shared by the users, same as `user_config_dir`""" return self.user_config_dir @property def user_cache_dir(self) -> str: """:return: cache directory tied to the user, e.g. e.g. ``/data/user///cache/``""" return self._append_app_name_and_version(_android_folder(), "cache") @property def user_state_dir(self) -> str: """:return: state directory tied to the user, same as `user_data_dir`""" return self.user_data_dir @property def user_log_dir(self) -> str: """ :return: log directory tied to the user, same as `user_cache_dir` if not opinionated else ``log`` in it, e.g. ``/data/user///cache//log`` """ path = self.user_cache_dir if self.opinion: path = os.path.join(path, "log") return path @property def user_documents_dir(self) -> str: """ :return: documents directory tied to the user e.g. ``/storage/emulated/0/Documents`` """ return _android_documents_folder() @property def user_runtime_dir(self) -> str: """ :return: runtime directory tied to the user, same as `user_cache_dir` if not opinionated else ``tmp`` in it, e.g. ``/data/user///cache//tmp`` """ path = self.user_cache_dir if self.opinion: path = os.path.join(path, "tmp") return path @lru_cache(maxsize=1) def _android_folder() -> str: """:return: base folder for the Android OS""" try: # First try to get path to android app via pyjnius from jnius import autoclass # noqa: SC200 Context = autoclass("android.content.Context") # noqa: SC200 result: str = Context.getFilesDir().getParentFile().getAbsolutePath() except Exception: # if fails find an android folder looking path on the sys.path pattern = re.compile(r"/data/(data|user/\d+)/(.+)/files") for path in sys.path: if pattern.match(path): result = path.split("/files")[0] break else: raise OSError("Cannot find path to android app folder") return result @lru_cache(maxsize=1) def _android_documents_folder() -> str: """:return: documents folder for the Android OS""" # Get directories with pyjnius try: from jnius import autoclass # noqa: SC200 Context = autoclass("android.content.Context") # noqa: SC200 Environment = autoclass("android.os.Environment") documents_dir: str = Context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() except Exception: documents_dir = "/storage/emulated/0/Documents" return documents_dir __all__ = [ "Android", ] PKH]99python3.10/site-packages/pip/_vendor/platformdirs/unix.pynu[import os import sys from configparser import ConfigParser from pathlib import Path from typing import Optional from .api import PlatformDirsABC if sys.platform.startswith("linux"): # pragma: no branch # no op check, only to please the type checker from os import getuid else: def getuid() -> int: raise RuntimeError("should only be used on Linux") class Unix(PlatformDirsABC): """ On Unix/Linux, we follow the `XDG Basedir Spec `_. The spec allows overriding directories with environment variables. The examples show are the default values, alongside the name of the environment variable that overrides them. Makes use of the `appname `, `version `, `multipath `, `opinion `. """ @property def user_data_dir(self) -> str: """ :return: data directory tied to the user, e.g. ``~/.local/share/$appname/$version`` or ``$XDG_DATA_HOME/$appname/$version`` """ path = os.environ.get("XDG_DATA_HOME", "") if not path.strip(): path = os.path.expanduser("~/.local/share") return self._append_app_name_and_version(path) @property def site_data_dir(self) -> str: """ :return: data directories shared by users (if `multipath ` is enabled and ``XDG_DATA_DIR`` is set and a multi path the response is also a multi path separated by the OS path separator), e.g. ``/usr/local/share/$appname/$version`` or ``/usr/share/$appname/$version`` """ # XDG default for $XDG_DATA_DIRS; only first, if multipath is False path = os.environ.get("XDG_DATA_DIRS", "") if not path.strip(): path = f"/usr/local/share{os.pathsep}/usr/share" return self._with_multi_path(path) def _with_multi_path(self, path: str) -> str: path_list = path.split(os.pathsep) if not self.multipath: path_list = path_list[0:1] path_list = [self._append_app_name_and_version(os.path.expanduser(p)) for p in path_list] return os.pathsep.join(path_list) @property def user_config_dir(self) -> str: """ :return: config directory tied to the user, e.g. ``~/.config/$appname/$version`` or ``$XDG_CONFIG_HOME/$appname/$version`` """ path = os.environ.get("XDG_CONFIG_HOME", "") if not path.strip(): path = os.path.expanduser("~/.config") return self._append_app_name_and_version(path) @property def site_config_dir(self) -> str: """ :return: config directories shared by users (if `multipath ` is enabled and ``XDG_DATA_DIR`` is set and a multi path the response is also a multi path separated by the OS path separator), e.g. ``/etc/xdg/$appname/$version`` """ # XDG default for $XDG_CONFIG_DIRS only first, if multipath is False path = os.environ.get("XDG_CONFIG_DIRS", "") if not path.strip(): path = "/etc/xdg" return self._with_multi_path(path) @property def user_cache_dir(self) -> str: """ :return: cache directory tied to the user, e.g. ``~/.cache/$appname/$version`` or ``~/$XDG_CACHE_HOME/$appname/$version`` """ path = os.environ.get("XDG_CACHE_HOME", "") if not path.strip(): path = os.path.expanduser("~/.cache") return self._append_app_name_and_version(path) @property def user_state_dir(self) -> str: """ :return: state directory tied to the user, e.g. ``~/.local/state/$appname/$version`` or ``$XDG_STATE_HOME/$appname/$version`` """ path = os.environ.get("XDG_STATE_HOME", "") if not path.strip(): path = os.path.expanduser("~/.local/state") return self._append_app_name_and_version(path) @property def user_log_dir(self) -> str: """ :return: log directory tied to the user, same as `user_data_dir` if not opinionated else ``log`` in it """ path = self.user_cache_dir if self.opinion: path = os.path.join(path, "log") return path @property def user_documents_dir(self) -> str: """ :return: documents directory tied to the user, e.g. ``~/Documents`` """ documents_dir = _get_user_dirs_folder("XDG_DOCUMENTS_DIR") if documents_dir is None: documents_dir = os.environ.get("XDG_DOCUMENTS_DIR", "").strip() if not documents_dir: documents_dir = os.path.expanduser("~/Documents") return documents_dir @property def user_runtime_dir(self) -> str: """ :return: runtime directory tied to the user, e.g. ``/run/user/$(id -u)/$appname/$version`` or ``$XDG_RUNTIME_DIR/$appname/$version`` """ path = os.environ.get("XDG_RUNTIME_DIR", "") if not path.strip(): path = f"/run/user/{getuid()}" return self._append_app_name_and_version(path) @property def site_data_path(self) -> Path: """:return: data path shared by users. Only return first item, even if ``multipath`` is set to ``True``""" return self._first_item_as_path_if_multipath(self.site_data_dir) @property def site_config_path(self) -> Path: """:return: config path shared by the users. Only return first item, even if ``multipath`` is set to ``True``""" return self._first_item_as_path_if_multipath(self.site_config_dir) def _first_item_as_path_if_multipath(self, directory: str) -> Path: if self.multipath: # If multipath is True, the first path is returned. directory = directory.split(os.pathsep)[0] return Path(directory) def _get_user_dirs_folder(key: str) -> Optional[str]: """Return directory from user-dirs.dirs config file. See https://freedesktop.org/wiki/Software/xdg-user-dirs/""" user_dirs_config_path = os.path.join(Unix().user_config_dir, "user-dirs.dirs") if os.path.exists(user_dirs_config_path): parser = ConfigParser() with open(user_dirs_config_path) as stream: # Add fake section header, so ConfigParser doesn't complain parser.read_string(f"[top]\n{stream.read()}") if key not in parser["top"]: return None path = parser["top"][key].strip('"') # Handle relative home paths path = path.replace("$HOME", os.path.expanduser("~")) return path return None __all__ = [ "Unix", ] PKH]jPP<python3.10/site-packages/pip/_vendor/platformdirs/version.pynu[""" Version information """ __version__ = "2.4.0" __version_info__ = (2, 4, 0) PKH]80<python3.10/site-packages/pip/_vendor/platformdirs/windows.pynu[import ctypes import os from functools import lru_cache from typing import Callable, Optional from .api import PlatformDirsABC class Windows(PlatformDirsABC): """`MSDN on where to store app data files `_. Makes use of the `appname `, `appauthor `, `version `, `roaming `, `opinion `.""" @property def user_data_dir(self) -> str: """ :return: data directory tied to the user, e.g. ``%USERPROFILE%\\AppData\\Local\\$appauthor\\$appname`` (not roaming) or ``%USERPROFILE%\\AppData\\Roaming\\$appauthor\\$appname`` (roaming) """ const = "CSIDL_APPDATA" if self.roaming else "CSIDL_LOCAL_APPDATA" path = os.path.normpath(get_win_folder(const)) return self._append_parts(path) def _append_parts(self, path: str, *, opinion_value: Optional[str] = None) -> str: params = [] if self.appname: if self.appauthor is not False: author = self.appauthor or self.appname params.append(author) params.append(self.appname) if opinion_value is not None and self.opinion: params.append(opinion_value) if self.version: params.append(self.version) return os.path.join(path, *params) @property def site_data_dir(self) -> str: """:return: data directory shared by users, e.g. ``C:\\ProgramData\\$appauthor\\$appname``""" path = os.path.normpath(get_win_folder("CSIDL_COMMON_APPDATA")) return self._append_parts(path) @property def user_config_dir(self) -> str: """:return: config directory tied to the user, same as `user_data_dir`""" return self.user_data_dir @property def site_config_dir(self) -> str: """:return: config directory shared by the users, same as `site_data_dir`""" return self.site_data_dir @property def user_cache_dir(self) -> str: """ :return: cache directory tied to the user (if opinionated with ``Cache`` folder within ``$appname``) e.g. ``%USERPROFILE%\\AppData\\Local\\$appauthor\\$appname\\Cache\\$version`` """ path = os.path.normpath(get_win_folder("CSIDL_LOCAL_APPDATA")) return self._append_parts(path, opinion_value="Cache") @property def user_state_dir(self) -> str: """:return: state directory tied to the user, same as `user_data_dir`""" return self.user_data_dir @property def user_log_dir(self) -> str: """ :return: log directory tied to the user, same as `user_data_dir` if not opinionated else ``Logs`` in it """ path = self.user_data_dir if self.opinion: path = os.path.join(path, "Logs") return path @property def user_documents_dir(self) -> str: """ :return: documents directory tied to the user e.g. ``%USERPROFILE%\\Documents`` """ return os.path.normpath(get_win_folder("CSIDL_PERSONAL")) @property def user_runtime_dir(self) -> str: """ :return: runtime directory tied to the user, e.g. ``%USERPROFILE%\\AppData\\Local\\Temp\\$appauthor\\$appname`` """ path = os.path.normpath(os.path.join(get_win_folder("CSIDL_LOCAL_APPDATA"), "Temp")) return self._append_parts(path) def get_win_folder_from_env_vars(csidl_name: str) -> str: """Get folder from environment variables.""" if csidl_name == "CSIDL_PERSONAL": # does not have an environment name return os.path.join(os.path.normpath(os.environ["USERPROFILE"]), "Documents") env_var_name = { "CSIDL_APPDATA": "APPDATA", "CSIDL_COMMON_APPDATA": "ALLUSERSPROFILE", "CSIDL_LOCAL_APPDATA": "LOCALAPPDATA", }.get(csidl_name) if env_var_name is None: raise ValueError(f"Unknown CSIDL name: {csidl_name}") result = os.environ.get(env_var_name) if result is None: raise ValueError(f"Unset environment variable: {env_var_name}") return result def get_win_folder_from_registry(csidl_name: str) -> str: """Get folder from the registry. This is a fallback technique at best. I'm not sure if using the registry for this guarantees us the correct answer for all CSIDL_* names. """ shell_folder_name = { "CSIDL_APPDATA": "AppData", "CSIDL_COMMON_APPDATA": "Common AppData", "CSIDL_LOCAL_APPDATA": "Local AppData", "CSIDL_PERSONAL": "Personal", }.get(csidl_name) if shell_folder_name is None: raise ValueError(f"Unknown CSIDL name: {csidl_name}") import winreg key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders") directory, _ = winreg.QueryValueEx(key, shell_folder_name) return str(directory) def get_win_folder_via_ctypes(csidl_name: str) -> str: """Get folder with ctypes.""" csidl_const = { "CSIDL_APPDATA": 26, "CSIDL_COMMON_APPDATA": 35, "CSIDL_LOCAL_APPDATA": 28, "CSIDL_PERSONAL": 5, }.get(csidl_name) if csidl_const is None: raise ValueError(f"Unknown CSIDL name: {csidl_name}") buf = ctypes.create_unicode_buffer(1024) windll = getattr(ctypes, "windll") # noqa: B009 # using getattr to avoid false positive with mypy type checker windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) # Downgrade to short path name if it has highbit chars. if any(ord(c) > 255 for c in buf): buf2 = ctypes.create_unicode_buffer(1024) if windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): buf = buf2 return buf.value def _pick_get_win_folder() -> Callable[[str], str]: if hasattr(ctypes, "windll"): return get_win_folder_via_ctypes try: import winreg # noqa: F401 except ImportError: return get_win_folder_from_env_vars else: return get_win_folder_from_registry get_win_folder = lru_cache(maxsize=None)(_pick_get_win_folder()) __all__ = [ "Windows", ] PKH]T;2;2=python3.10/site-packages/pip/_vendor/platformdirs/__init__.pynu[""" Utilities for determining application-specific dirs. See for details and usage. """ import importlib import os import sys from pathlib import Path from typing import TYPE_CHECKING, Optional, Type, Union if TYPE_CHECKING: from typing_extensions import Literal # pragma: no cover from .api import PlatformDirsABC from .version import __version__, __version_info__ def _set_platform_dir_class() -> Type[PlatformDirsABC]: if os.getenv("ANDROID_DATA") == "/data" and os.getenv("ANDROID_ROOT") == "/system": module, name = "pip._vendor.platformdirs.android", "Android" elif sys.platform == "win32": module, name = "pip._vendor.platformdirs.windows", "Windows" elif sys.platform == "darwin": module, name = "pip._vendor.platformdirs.macos", "MacOS" else: module, name = "pip._vendor.platformdirs.unix", "Unix" result: Type[PlatformDirsABC] = getattr(importlib.import_module(module), name) return result PlatformDirs = _set_platform_dir_class() #: Currently active platform AppDirs = PlatformDirs #: Backwards compatibility with appdirs def user_data_dir( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, roaming: bool = False, ) -> str: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: data directory tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_data_dir def site_data_dir( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, multipath: bool = False, ) -> str: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param multipath: See `roaming `. :returns: data directory shared by users """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, multipath=multipath).site_data_dir def user_config_dir( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, roaming: bool = False, ) -> str: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: config directory tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_config_dir def site_config_dir( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, multipath: bool = False, ) -> str: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param multipath: See `roaming `. :returns: config directory shared by the users """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, multipath=multipath).site_config_dir def user_cache_dir( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, opinion: bool = True, ) -> str: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `roaming `. :returns: cache directory tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_cache_dir def user_state_dir( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, roaming: bool = False, ) -> str: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: state directory tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_state_dir def user_log_dir( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, opinion: bool = True, ) -> str: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `roaming `. :returns: log directory tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_log_dir def user_documents_dir() -> str: """ :returns: documents directory tied to the user """ return PlatformDirs().user_documents_dir def user_runtime_dir( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, opinion: bool = True, ) -> str: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `opinion `. :returns: runtime directory tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_runtime_dir def user_data_path( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, roaming: bool = False, ) -> Path: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: data path tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_data_path def site_data_path( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, multipath: bool = False, ) -> Path: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param multipath: See `multipath `. :returns: data path shared by users """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, multipath=multipath).site_data_path def user_config_path( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, roaming: bool = False, ) -> Path: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: config path tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_config_path def site_config_path( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, multipath: bool = False, ) -> Path: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param multipath: See `roaming `. :returns: config path shared by the users """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, multipath=multipath).site_config_path def user_cache_path( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, opinion: bool = True, ) -> Path: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `roaming `. :returns: cache path tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_cache_path def user_state_path( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, roaming: bool = False, ) -> Path: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param roaming: See `roaming `. :returns: state path tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, roaming=roaming).user_state_path def user_log_path( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, opinion: bool = True, ) -> Path: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `roaming `. :returns: log path tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_log_path def user_documents_path() -> Path: """ :returns: documents path tied to the user """ return PlatformDirs().user_documents_path def user_runtime_path( appname: Optional[str] = None, appauthor: Union[str, None, "Literal[False]"] = None, version: Optional[str] = None, opinion: bool = True, ) -> Path: """ :param appname: See `appname `. :param appauthor: See `appauthor `. :param version: See `version `. :param opinion: See `opinion `. :returns: runtime path tied to the user """ return PlatformDirs(appname=appname, appauthor=appauthor, version=version, opinion=opinion).user_runtime_path __all__ = [ "__version__", "__version_info__", "PlatformDirs", "AppDirs", "PlatformDirsABC", "user_data_dir", "user_config_dir", "user_cache_dir", "user_state_dir", "user_log_dir", "user_documents_dir", "user_runtime_dir", "site_data_dir", "site_config_dir", "user_data_path", "user_config_path", "user_cache_path", "user_state_path", "user_log_path", "user_documents_path", "user_runtime_path", "site_data_path", "site_config_path", ] PKH]2bpython3.10/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-310.pycnu[o ai@sDddgZz ddlmZmZWdSey!ddlmZmZYdSw)MappingSequence)rrN)__all__collections.abcrr ImportError collectionsrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/collections_abc.pys  PKH].+[python3.10/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-310.pycnu[o ai@sdS)Nrrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/__init__.pysPKH].gIpython3.10/site-packages/pip/_vendor/resolvelib/compat/collections_abc.pynu[__all__ = ["Mapping", "Sequence"] try: from collections.abc import Mapping, Sequence except ImportError: from collections import Mapping, Sequence PKH]Bpython3.10/site-packages/pip/_vendor/resolvelib/compat/__init__.pynu[PKH]OTpython3.10/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-310.pycnu[o ai@sLgdZdZddlmZmZddlmZddlmZm Z m Z m Z m Z m Z dS)) __version__AbstractProviderAbstractResolver BaseReporterInconsistentCandidateResolverRequirementsConflictedResolutionErrorResolutionImpossibleResolutionTooDeepz0.8.0)rr)r)rrrrr r N)__all__r providersrr reportersr resolversrrrrr r rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/resolvelib/__init__.pys   $PKH]S;;Upython3.10/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-310.pycnu[o aiD@sddlZddlZddlmZddlmZmZmZedddgZ Gdd d e Z Gd d d e Z Gd d d e Z GdddeZGddde ZGdddeZGdddeZeddZGdddeZddZeddZddZGd d!d!eZdS)"N)AbstractResolver) DirectedGraphIteratorMappingbuild_iter_viewRequirementInformation requirementparentc@seZdZdZdS)ResolverExceptionzA base class for all exceptions raised by this module. Exceptions derived by this class should all be handled in this module. Any bubbling pass the resolver should be treated as a bug. N)__name__ __module__ __qualname____doc__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.pyr sr c$eZdZfddZddZZS)RequirementsConflictedctt||||_dSN)superr__init__ criterion)selfr __class__rrr zRequirementsConflicted.__init__cCs dddd|jDS)NzRequirements conflict: {}, cs|]}t|VqdSrrepr.0rrrr z1RequirementsConflicted.__str__..)formatjoinriter_requirementrrrr__str__szRequirementsConflicted.__str__r r r rr) __classcell__rrrrrs rcr)InconsistentCandidatecs"tt|||||_||_dSr)rr,r candidater)rr-rrrrr!s zInconsistentCandidate.__init__cCs$d|jddd|jDS)Nz+Provided candidate {!r} does not satisfy {}rcsrrrr rrrr#)r$z0InconsistentCandidate.__str__..)r%r-r&rr'r(rrrr)&szInconsistentCandidate.__str__r*rrrrr, s r,c@s0eZdZdZddZddZddZdd Zd S) CriterionaQRepresentation of possible resolution results of a package. This holds three attributes: * `information` is a collection of `RequirementInformation` pairs. Each pair is a requirement contributing to this criterion, and the candidate that provides the requirement. * `incompatibilities` is a collection of all known not-to-work candidates to exclude from consideration. * `candidates` is a collection containing all possible candidates deducted from the union of contributing requirements and known incompatibilities. It should never be empty, except when the criterion is an attribute of a raised `RequirementsConflicted` (in which case it is always empty). .. note:: This class is intended to be externally immutable. **Do not** mutate any of its attribute containers. cCs||_||_||_dSr candidates informationincompatibilities)rr0r1r2rrrrA zCriterion.__init__cCs ddd|jD}d|S)Nrcss |] \}}d||VqdS)z({!r}, via={!r})N)r%)r!reqr rrrr#Gs  z%Criterion.__repr__..z Criterion({}))r&r1r%)r requirementsrrr__repr__Fs  zCriterion.__repr__cCdd|jDS)Ncs|]}|jVqdSr)rr!irrrr#Nz-Criterion.iter_requirement..r1r(rrrr'MzCriterion.iter_requirementcCr7)Ncsr8rr r9rrrr#Qr;z(Criterion.iter_parent..r<r(rrr iter_parentPr=zCriterion.iter_parentN)r r r rrr6r'r?rrrrr.-s  r.c@s eZdZdS)ResolutionErrorN)r r r rrrrr@Tsr@ceZdZfddZZS)ResolutionImpossiblecrr)rrBrcauses)rrCrrrrYs zResolutionImpossible.__init__r r r rr+rrrrrBXrBcrA)ResolutionTooDeepcrr)rrFr round_count)rrGrrrr`rzResolutionTooDeep.__init__rDrrrrrF_rErFStatez!mapping criteria backtrack_causesc@sdeZdZdZddZeddZddZdd Zd d Z d d Z ddZ ddZ ddZ ddZdS) ResolutionzStateful resolution object. This is designed as a one-off object that holds information to kick start the resolution process, and holds the results afterwards. cCs||_||_g|_dSr)_p_r_states)rproviderreporterrrrrpr3zResolution.__init__cCs$z|jdWStytdw)Nstate)rL IndexErrorAttributeErrorr(rrrrPus   zResolution.statecCs>|jd}t|j|j|jddd}|j|dS)zPush a new state into history. This new state will be used to hold resolution results of the next coming round. rONmappingcriteriabacktrack_causes)rLrHrTcopyrUrVappend)rbaserPrrr_push_new_state|s  zResolution._push_new_statec Cs|jj||d|jj|d}||}|rt|j}ng}|jj|t|t d||git|t d||id}|rJt|j }| t||nt||g}tt|||d}|js`t||||<dS)N)rr )requirement_or_candidater'r2 identifierr5r2r/)rKadding_requirementrJidentifygetlistr2 find_matchesroperator methodcaller attrgetterr1rXrr.rr0r) rrUrr r]rr2matchesr1rrr_add_to_criterias>     zResolution._add_to_criteriac Cs>|jj||jjt|jjtdt|jjtd|jjdS)Nr0r1)r] resolutionsr0r1rV) rJget_preferencerPrTrrUrcrerV)rnamerrr_get_preferenceszResolution._get_preferencecsBzjj|Wn tyYdSwtfdd|DS)NFc3 |] }jj|dVqdS)rr-NrJis_satisfied_byr  current_pinrrrr#  z8Resolution._is_current_pin_satisfying..)rPrTKeyErrorallr')rrjrrrpr_is_current_pin_satisfyings z%Resolution._is_current_pin_satisfyingcCs4|jj}|jj|dD] }|j|||dq |S)Nr-r>)rPrUrWrJget_dependenciesrg)rr-rUrrrr_get_updated_criterias z Resolution._get_updated_criteriac sjj|}g}|jD]Vz}Wnty,}z ||jWYd}~q d}~wwtfdd|D}|sBt |j j djj |jj |djj |<gS|S)Nc3rlrmrnr r-rrrr#rrz7Resolution._attempt_to_pin_criterion..rv)rPrUr0rxrrXrrtr'r,rKpinningupdaterTpop)rrjrrCrUe satisfiedrryr_attempt_to_pin_criterions*      z$Resolution._attempt_to_pin_criterioncstjdkrIjd=j}|j\}}dd|jD||gfjj |dfdd} |}|rBdStjdksd S) aPerform backtracking. When we enter here, the stack is like this:: [ state Z ] [ state Y ] [ state X ] .... earlier states are irrelevant. 1. No pins worked for Z, so it does not have a pin. 2. We want to reset state Y to unpinned, and pin another candidate. 3. State X holds what state Y was before the pin, but does not have the incompatibility information gathered in state Y. Each iteration of the loop will: 1. Discard Z. 2. Discard Y but remember its incompatibility information gathered previously, and the failure we're dealing with right now. 3. Push a new state Y' based on X, and apply the incompatibility information from Y to Y'. 4a. If this causes Y' to conflict, we need to backtrack again. Make Y' the new Z and go back to step 2. 4b. If the incompatibilities apply cleanly, end backtracking. rOcSsg|] \}}|t|jfqSr)rar2r!kvrrr s z)Resolution._backtrack..rvc sD]R\}}|s qzjj|}Wn tyYqwjj|tjjtdtjjtd||id}t |}|s@dS| |j t |t |j|djj|<qdS)Nr'r2r\Fr/T)rPrUrsrJrbrrcrdrerextendr2r.rar1)rr2rrfr0incompatibilities_from_brokenrrr_patch_criteria!s<    z.Resolution._backtrack.._patch_criteriaTF) lenrLr|rTpopitemrUitemsrXrK backtrackingrZ)r broken_staterjr-rsuccessrrr _backtracks  =zResolution._backtrackc sBjrtdjttigdg_|D] }z jjj |ddWqt y9}zt |j j d}~wwt|D]Z}jj|dfddjj D}|sgjjjdjSt|jd}|}|r} d d|Djjdd<| st jjnjj|jd qBt|) Nzalready resolvedrSr>)indexcs g|] \}}||s|qSr)ru)r!keyrr(rrris  z&Resolution.resolve..)rP)rcSsg|] }|jD]}|qqSrr<)r!cr:rrrr|s )rrP)rL RuntimeErrorrKstartingrH collections OrderedDictrgrPrUrrBrr1rZrangestarting_roundrendingminrkrrrV ending_roundrF) rr5 max_roundsr"r} round_indexunsatisfied_namesrjfailure_causesrrr(rresolveMsL        zResolution.resolveN)r r r rrpropertyrPrZrgrkrurxrrrrrrrrIis ' $ YrIc Cs||vrdS||vr dS||D]/}z|t|}Wn ty%Yqw||vr2||dSt||||rA||dSqdS)NTF)r?idrsadd_has_route_to_root)rUrall_keys connectedppkeyrrrrs$   rResultzmapping graph criteriac s|j}dd|D}d|td<t}|ddh|jD]>\}}t|j||s/q"||vr8|||D]#}z|t|}Wn tyOYqsz!_build_result..csi|] \}}|vr||qSrrrrrrrs)rTgraphrU) rTrrrrrUrr?rsconnectr)rPrTrrrrrrrrr _build_results4       rc@seZdZdZeZdddZdS)Resolverz3The thing that performs the actual resolution work.dcCs$t|j|j}|j||d}t|S)aTake a collection of constraints, spit out the resolution result. The return value is a representation to the final resolution result. It is a tuple subclass with three public members: * `mapping`: A dict of resolved candidates. Each key is an identifier of a requirement (as returned by the provider's `identify` method), and the value is the resolved candidate. * `graph`: A `DirectedGraph` instance representing the dependency tree. The vertices are keys of `mapping`, and each edge represents *why* a particular package is included. A special vertex `None` is included to represent parents of user-supplied requirements. * `criteria`: A dict of "criteria" that hold detailed information on how edges in the graph are derived. Each key is an identifier of a requirement, and the value is a `Criterion` instance. The following exceptions may be raised if a resolution cannot be found: * `ResolutionImpossible`: A resolution cannot be found for the given combination of requirements. The `causes` attribute of the exception is a list of (requirement, parent), giving the requirements that could not be satisfied. * `ResolutionTooDeep`: The dependency tree is too deeply nested and the resolver gave up. This is usually caused by a circular dependency, but you can try to resolve this by increasing the `max_rounds` argument. )r)rIrMrNrr)rr5r resolutionrPrrrrszResolver.resolveN)r)r r r rr base_exceptionrrrrrrsr)rrc providersrstructsrrr namedtupler Exceptionr rr,objectr.r@rBrFrHrIrrrrrrrrs,   ' % PKH]}--Upython3.10/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-310.pycnu[o ai@s$GdddeZGdddeZdS)c@s8eZdZdZddZddZddZdd Zd d Zd S) AbstractProviderzADelegate class to provide requirement interface for the resolver.cCt)zGiven a requirement, return an identifier for it. This is used to identify a requirement, e.g. whether two requirements should have their specifier parts merged. NotImplementedError)selfrequirement_or_candidater/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/resolvelib/providers.pyidentifyzAbstractProvider.identifycCr)aProduce a sort key for given requirement based on preference. The preference is defined as "I think this requirement should be resolved first". The lower the return value is, the more preferred this group of arguments is. :param identifier: An identifier as returned by ``identify()``. This identifies the dependency matches of which should be returned. :param resolutions: Mapping of candidates currently pinned by the resolver. Each key is an identifier, and the value a candidate. The candidate may conflict with requirements from ``information``. :param candidates: Mapping of each dependency's possible candidates. Each value is an iterator of candidates. :param information: Mapping of requirement information of each package. Each value is an iterator of *requirement information*. :param backtrack_causes: Sequence of requirement information that were the requirements that caused the resolver to most recently backtrack. A *requirement information* instance is a named tuple with two members: * ``requirement`` specifies a requirement contributing to the current list of candidates. * ``parent`` specifies the candidate that provides (dependend on) the requirement, or ``None`` to indicate a root requirement. The preference could depend on a various of issues, including (not necessarily in this order): * Is this package pinned in the current resolution result? * How relaxed is the requirement? Stricter ones should probably be worked on first? (I don't know, actually.) * How many possibilities are there to satisfy this requirement? Those with few left should likely be worked on first, I guess? * Are there any known conflicts for this requirement? We should probably work on those with the most known conflicts. A sortable value should be returned (this will be used as the ``key`` parameter of the built-in sorting function). The smaller the value is, the more preferred this requirement is (i.e. the sorting function is called with ``reverse=False``). r)r identifier resolutions candidates informationbacktrack_causesrrrget_preference s1zAbstractProvider.get_preferencecCr)aFind all possible candidates that satisfy given constraints. :param identifier: An identifier as returned by ``identify()``. This identifies the dependency matches of which should be returned. :param requirements: A mapping of requirements that all returned candidates must satisfy. Each key is an identifier, and the value an iterator of requirements for that dependency. :param incompatibilities: A mapping of known incompatibilities of each dependency. Each key is an identifier, and the value an iterator of incompatibilities known to the resolver. All incompatibilities *must* be excluded from the return value. This should try to get candidates based on the requirements' types. For VCS, local, and archive requirements, the one-and-only match is returned, and for a "named" requirement, the index(es) should be consulted to find concrete candidates for this requirement. The return value should produce candidates ordered by preference; the most preferred candidate should come first. The return type may be one of the following: * A callable that returns an iterator that yields candidates. * An collection of candidates. * An iterable of candidates. This will be consumed immediately into a list of candidates. r)rr requirementsincompatibilitiesrrr find_matches?szAbstractProvider.find_matchescCr)aWhether the given requirement can be satisfied by a candidate. The candidate is guarenteed to have been generated from the requirement. A boolean should be returned to indicate whether ``candidate`` is a viable solution to the requirement. r)r requirement candidaterrris_satisfied_by\s z AbstractProvider.is_satisfied_bycCr)zGet dependencies of a candidate. This should return a collection of requirements that `candidate` specifies as its dependencies. r)rrrrrget_dependenciesgr z!AbstractProvider.get_dependenciesN) __name__ __module__ __qualname____doc__r rrrrrrrrrs3 rc@s$eZdZdZeZddZddZdS)AbstractResolverz3The thing that performs the actual resolution work.cCs||_||_dS)N)providerreporter)rrrrrr__init__us zAbstractResolver.__init__cKr)aTake a collection of constraints, spit out the resolution result. This returns a representation of the final resolution state, with one guarenteed attribute ``mapping`` that contains resolved candidates as values. The keys are their respective identifiers. :param requirements: A collection of constraints. :param kwargs: Additional keyword arguments that subclasses may accept. :raises: ``self.base_exception`` or its subclass. r)rrkwargsrrrresolveys zAbstractResolver.resolveN)rrrr Exceptionbase_exceptionrr!rrrrrps  rN)objectrrrrrrsoPKH]/W  Upython3.10/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-310.pycnu[o aiT@sGdddeZdS)c@sHeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS) BaseReporterz?Delegate class to provider progress reporting for the resolver.cCdS)z-Called before the resolution actually starts.N)selfrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/resolvelib/reporters.pystartingzBaseReporter.startingcCr)zYCalled before each round of resolution starts. The index is zero-based. Nr)rindexrrrstarting_roundrzBaseReporter.starting_roundcCr)zCalled before each round of resolution ends. This is NOT called if the resolution ends at this round. Use `ending` if you want to report finalization. The index is zero-based. Nr)rrstaterrr ending_round rzBaseReporter.ending_roundcCr)z/Called before the resolution ends successfully.Nr)rr rrrendingrzBaseReporter.endingcCr)aCalled when adding a new requirement into the resolve criteria. :param requirement: The additional requirement to be applied to filter the available candidaites. :param parent: The candidate that requires ``requirement`` as a dependency, or None if ``requirement`` is one of the root requirements passed in from ``Resolver.resolve()``. Nr)r requirementparentrrradding_requirementrzBaseReporter.adding_requirementcCr)z6Called when rejecting a candidate during backtracking.Nrr candidaterrr backtracking!rzBaseReporter.backtrackingcCr)z9Called when adding a candidate to the potential solution.Nrrrrrpinning$rzBaseReporter.pinningN) __name__ __module__ __qualname____doc__rr r r rrrrrrrrs rN)objectrrrrrsPKH]5:''Spython3.10/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-310.pycnu[o ai@sbddlZddlmZGdddeZGdddejZGdd d eZGd d d eZd d Z dS)N)collections_abcc@speZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZdS) DirectedGraphz&A graph structure with directed edges.cCst|_i|_i|_dSN)set _vertices _forwards _backwardsselfr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/resolvelib/structs.py__init__ s zDirectedGraph.__init__cC t|jSr)iterrr r r r __iter__ zDirectedGraph.__iter__cCrr)lenrr r r r __len__rzDirectedGraph.__len__cCs ||jvSr)rr keyr r r __contains__rzDirectedGraph.__contains__cCsBt}t|j|_dd|jD|_dd|jD|_|S)z$Return a shallow copy of this graph.cSi|] \}}|t|qSr r.0kvr r r z&DirectedGraph.copy..cSrr rrr r r rr)rrrritemsr )r otherr r r copys  zDirectedGraph.copycCs:||jvr td|j|t|j|<t|j|<dS)zAdd a new vertex to the graph.z vertex existsN)r ValueErroraddrrr rr r r r$s   zDirectedGraph.addcCsT|j||j|D] }|j||q |j|D] }|j||qdS)zCRemove a vertex from the graph, disconnecting all edges from/to it.N)rremoverpopr )r rftr r r r%'s zDirectedGraph.removecCs||j|vo ||j|vSr)r rr r'r(r r r connected/szDirectedGraph.connectedcCs6||jvr t||j|||j||dS)zgConnect two existing vertices. Nothing happens if the vertices are already connected. N)rKeyErrorrr$r r)r r r connect2s zDirectedGraph.connectccs.|jD]\}}|D]}||fVq qdSr)rr )r r'childrenr(r r r iter_edges<s  zDirectedGraph.iter_edgescCt|j|Sr)rrrr r r iter_childrenAzDirectedGraph.iter_childrencCr/r)rr rr r r iter_parentsDr1zDirectedGraph.iter_parentsN)__name__ __module__ __qualname____doc__rrrrr"r$r%r*r,r.r0r2r r r r rs  rc@sJeZdZdddZddZddZeZdd Zd d Zd d Z ddZ dS)IteratorMappingNcCs||_||_|p i|_dSr)_mapping _accessor_appends)r mappingaccessorappendsr r r rIszIteratorMapping.__init__cCsd|j|j|jS)Nz!IteratorMapping({!r}, {!r}, {!r}))formatr8r9r:r r r r __repr__Ns zIteratorMapping.__repr__cCst|jp|jSr)boolr8r:r r r r __bool__UszIteratorMapping.__bool__cCs||jvp ||jvSr)r8r:rr r r rZzIteratorMapping.__contains__cCsLz|j|}Wntyt|j|YSwt|||j|dS)Nr )r8r+rr: itertoolschainr9get)r rrr r r __getitem__]s  zIteratorMapping.__getitem__cs"fddjD}tj|S)Nc3s|] }|jvr|VqdSrr8rrr r r ez+IteratorMapping.__iter__..)r:rCrDr8r morer r r rdszIteratorMapping.__iter__cs&tfddjD}tj|S)Nc3s|] }|jvrdVqdS)rNrGrHr r r rIirJz*IteratorMapping.__len__..)sumr:rr8rKr r r rhszIteratorMapping.__len__r) r3r4r5rr?rA __nonzero__rrFrrr r r r r7Hs  r7c@4eZdZdZddZddZddZeZdd Zd S) _FactoryIterableViewa:Wrap an iterator factory returned by `find_matches()`. Calling `iter()` on this class would invoke the underlying iterator factory, making it a "collection with ordering" that can be iterated through multiple times, but lacks random access methods presented in built-in Python sequence types. cC ||_dSr_factory)r factoryr r r rvrz_FactoryIterableView.__init__cCsdt|jt|SNz{}({}))r>typer3listrSr r r r r?ysz_FactoryIterableView.__repr__cCs(z t|WdStyYdSw)NFT)nextrS StopIterationr r r r rA|s  z_FactoryIterableView.__bool__cCs|SrrRr r r r rsz_FactoryIterableView.__iter__N r3r4r5r6rr?rArNrr r r r rPms rPc@rO) _SequenceIterableViewzWrap an iterable returned by find_matches(). This is essentially just a proxy to the underlying sequence that provides the same interface as `_FactoryIterableView`. cCrQr) _sequence)r sequencer r r rrz_SequenceIterableView.__init__cCsdt|j|jSrU)r>rVr3r\r r r r r?rBz_SequenceIterableView.__repr__cCrr)r@r\r r r r rArz_SequenceIterableView.__bool__cCrr)rr\r r r r rrz_SequenceIterableView.__iter__NrZr r r r r[s r[cCs,t|rt|St|tjst|}t|S)zCBuild an iterable view from the value returned by `find_matches()`.)callablerP isinstancerSequencerWr[)matchesr r r build_iter_views  rb) rCcompatrobjectrMappingr7rPr[rbr r r r s B% PKH]cDD<python3.10/site-packages/pip/_vendor/resolvelib/resolvers.pynu[import collections import operator from .providers import AbstractResolver from .structs import DirectedGraph, IteratorMapping, build_iter_view RequirementInformation = collections.namedtuple( "RequirementInformation", ["requirement", "parent"] ) class ResolverException(Exception): """A base class for all exceptions raised by this module. Exceptions derived by this class should all be handled in this module. Any bubbling pass the resolver should be treated as a bug. """ class RequirementsConflicted(ResolverException): def __init__(self, criterion): super(RequirementsConflicted, self).__init__(criterion) self.criterion = criterion def __str__(self): return "Requirements conflict: {}".format( ", ".join(repr(r) for r in self.criterion.iter_requirement()), ) class InconsistentCandidate(ResolverException): def __init__(self, candidate, criterion): super(InconsistentCandidate, self).__init__(candidate, criterion) self.candidate = candidate self.criterion = criterion def __str__(self): return "Provided candidate {!r} does not satisfy {}".format( self.candidate, ", ".join(repr(r) for r in self.criterion.iter_requirement()), ) class Criterion(object): """Representation of possible resolution results of a package. This holds three attributes: * `information` is a collection of `RequirementInformation` pairs. Each pair is a requirement contributing to this criterion, and the candidate that provides the requirement. * `incompatibilities` is a collection of all known not-to-work candidates to exclude from consideration. * `candidates` is a collection containing all possible candidates deducted from the union of contributing requirements and known incompatibilities. It should never be empty, except when the criterion is an attribute of a raised `RequirementsConflicted` (in which case it is always empty). .. note:: This class is intended to be externally immutable. **Do not** mutate any of its attribute containers. """ def __init__(self, candidates, information, incompatibilities): self.candidates = candidates self.information = information self.incompatibilities = incompatibilities def __repr__(self): requirements = ", ".join( "({!r}, via={!r})".format(req, parent) for req, parent in self.information ) return "Criterion({})".format(requirements) def iter_requirement(self): return (i.requirement for i in self.information) def iter_parent(self): return (i.parent for i in self.information) class ResolutionError(ResolverException): pass class ResolutionImpossible(ResolutionError): def __init__(self, causes): super(ResolutionImpossible, self).__init__(causes) # causes is a list of RequirementInformation objects self.causes = causes class ResolutionTooDeep(ResolutionError): def __init__(self, round_count): super(ResolutionTooDeep, self).__init__(round_count) self.round_count = round_count # Resolution state in a round. State = collections.namedtuple("State", "mapping criteria backtrack_causes") class Resolution(object): """Stateful resolution object. This is designed as a one-off object that holds information to kick start the resolution process, and holds the results afterwards. """ def __init__(self, provider, reporter): self._p = provider self._r = reporter self._states = [] @property def state(self): try: return self._states[-1] except IndexError: raise AttributeError("state") def _push_new_state(self): """Push a new state into history. This new state will be used to hold resolution results of the next coming round. """ base = self._states[-1] state = State( mapping=base.mapping.copy(), criteria=base.criteria.copy(), backtrack_causes=base.backtrack_causes[:], ) self._states.append(state) def _add_to_criteria(self, criteria, requirement, parent): self._r.adding_requirement(requirement=requirement, parent=parent) identifier = self._p.identify(requirement_or_candidate=requirement) criterion = criteria.get(identifier) if criterion: incompatibilities = list(criterion.incompatibilities) else: incompatibilities = [] matches = self._p.find_matches( identifier=identifier, requirements=IteratorMapping( criteria, operator.methodcaller("iter_requirement"), {identifier: [requirement]}, ), incompatibilities=IteratorMapping( criteria, operator.attrgetter("incompatibilities"), {identifier: incompatibilities}, ), ) if criterion: information = list(criterion.information) information.append(RequirementInformation(requirement, parent)) else: information = [RequirementInformation(requirement, parent)] criterion = Criterion( candidates=build_iter_view(matches), information=information, incompatibilities=incompatibilities, ) if not criterion.candidates: raise RequirementsConflicted(criterion) criteria[identifier] = criterion def _get_preference(self, name): return self._p.get_preference( identifier=name, resolutions=self.state.mapping, candidates=IteratorMapping( self.state.criteria, operator.attrgetter("candidates"), ), information=IteratorMapping( self.state.criteria, operator.attrgetter("information"), ), backtrack_causes=self.state.backtrack_causes, ) def _is_current_pin_satisfying(self, name, criterion): try: current_pin = self.state.mapping[name] except KeyError: return False return all( self._p.is_satisfied_by(requirement=r, candidate=current_pin) for r in criterion.iter_requirement() ) def _get_updated_criteria(self, candidate): criteria = self.state.criteria.copy() for requirement in self._p.get_dependencies(candidate=candidate): self._add_to_criteria(criteria, requirement, parent=candidate) return criteria def _attempt_to_pin_criterion(self, name): criterion = self.state.criteria[name] causes = [] for candidate in criterion.candidates: try: criteria = self._get_updated_criteria(candidate) except RequirementsConflicted as e: causes.append(e.criterion) continue # Check the newly-pinned candidate actually works. This should # always pass under normal circumstances, but in the case of a # faulty provider, we will raise an error to notify the implementer # to fix find_matches() and/or is_satisfied_by(). satisfied = all( self._p.is_satisfied_by(requirement=r, candidate=candidate) for r in criterion.iter_requirement() ) if not satisfied: raise InconsistentCandidate(candidate, criterion) self._r.pinning(candidate=candidate) self.state.criteria.update(criteria) # Put newly-pinned candidate at the end. This is essential because # backtracking looks at this mapping to get the last pin. self.state.mapping.pop(name, None) self.state.mapping[name] = candidate return [] # All candidates tried, nothing works. This criterion is a dead # end, signal for backtracking. return causes def _backtrack(self): """Perform backtracking. When we enter here, the stack is like this:: [ state Z ] [ state Y ] [ state X ] .... earlier states are irrelevant. 1. No pins worked for Z, so it does not have a pin. 2. We want to reset state Y to unpinned, and pin another candidate. 3. State X holds what state Y was before the pin, but does not have the incompatibility information gathered in state Y. Each iteration of the loop will: 1. Discard Z. 2. Discard Y but remember its incompatibility information gathered previously, and the failure we're dealing with right now. 3. Push a new state Y' based on X, and apply the incompatibility information from Y to Y'. 4a. If this causes Y' to conflict, we need to backtrack again. Make Y' the new Z and go back to step 2. 4b. If the incompatibilities apply cleanly, end backtracking. """ while len(self._states) >= 3: # Remove the state that triggered backtracking. del self._states[-1] # Retrieve the last candidate pin and known incompatibilities. broken_state = self._states.pop() name, candidate = broken_state.mapping.popitem() incompatibilities_from_broken = [ (k, list(v.incompatibilities)) for k, v in broken_state.criteria.items() ] # Also mark the newly known incompatibility. incompatibilities_from_broken.append((name, [candidate])) self._r.backtracking(candidate=candidate) # Create a new state from the last known-to-work one, and apply # the previously gathered incompatibility information. def _patch_criteria(): for k, incompatibilities in incompatibilities_from_broken: if not incompatibilities: continue try: criterion = self.state.criteria[k] except KeyError: continue matches = self._p.find_matches( identifier=k, requirements=IteratorMapping( self.state.criteria, operator.methodcaller("iter_requirement"), ), incompatibilities=IteratorMapping( self.state.criteria, operator.attrgetter("incompatibilities"), {k: incompatibilities}, ), ) candidates = build_iter_view(matches) if not candidates: return False incompatibilities.extend(criterion.incompatibilities) self.state.criteria[k] = Criterion( candidates=candidates, information=list(criterion.information), incompatibilities=incompatibilities, ) return True self._push_new_state() success = _patch_criteria() # It works! Let's work on this new state. if success: return True # State does not work after applying known incompatibilities. # Try the still previous state. # No way to backtrack anymore. return False def resolve(self, requirements, max_rounds): if self._states: raise RuntimeError("already resolved") self._r.starting() # Initialize the root state. self._states = [ State( mapping=collections.OrderedDict(), criteria={}, backtrack_causes=[], ) ] for r in requirements: try: self._add_to_criteria(self.state.criteria, r, parent=None) except RequirementsConflicted as e: raise ResolutionImpossible(e.criterion.information) # The root state is saved as a sentinel so the first ever pin can have # something to backtrack to if it fails. The root state is basically # pinning the virtual "root" package in the graph. self._push_new_state() for round_index in range(max_rounds): self._r.starting_round(index=round_index) unsatisfied_names = [ key for key, criterion in self.state.criteria.items() if not self._is_current_pin_satisfying(key, criterion) ] # All criteria are accounted for. Nothing more to pin, we are done! if not unsatisfied_names: self._r.ending(state=self.state) return self.state # Choose the most preferred unpinned criterion to try. name = min(unsatisfied_names, key=self._get_preference) failure_causes = self._attempt_to_pin_criterion(name) if failure_causes: # Backtrack if pinning fails. The backtrack process puts us in # an unpinned state, so we can work on it in the next round. success = self._backtrack() self.state.backtrack_causes[:] = [ i for c in failure_causes for i in c.information ] # Dead ends everywhere. Give up. if not success: raise ResolutionImpossible(self.state.backtrack_causes) else: # Pinning was successful. Push a new state to do another pin. self._push_new_state() self._r.ending_round(index=round_index, state=self.state) raise ResolutionTooDeep(max_rounds) def _has_route_to_root(criteria, key, all_keys, connected): if key in connected: return True if key not in criteria: return False for p in criteria[key].iter_parent(): try: pkey = all_keys[id(p)] except KeyError: continue if pkey in connected: connected.add(key) return True if _has_route_to_root(criteria, pkey, all_keys, connected): connected.add(key) return True return False Result = collections.namedtuple("Result", "mapping graph criteria") def _build_result(state): mapping = state.mapping all_keys = {id(v): k for k, v in mapping.items()} all_keys[id(None)] = None graph = DirectedGraph() graph.add(None) # Sentinel as root dependencies' parent. connected = {None} for key, criterion in state.criteria.items(): if not _has_route_to_root(state.criteria, key, all_keys, connected): continue if key not in graph: graph.add(key) for p in criterion.iter_parent(): try: pkey = all_keys[id(p)] except KeyError: continue if pkey not in graph: graph.add(pkey) graph.connect(pkey, key) return Result( mapping={k: v for k, v in mapping.items() if k in connected}, graph=graph, criteria=state.criteria, ) class Resolver(AbstractResolver): """The thing that performs the actual resolution work.""" base_exception = ResolverException def resolve(self, requirements, max_rounds=100): """Take a collection of constraints, spit out the resolution result. The return value is a representation to the final resolution result. It is a tuple subclass with three public members: * `mapping`: A dict of resolved candidates. Each key is an identifier of a requirement (as returned by the provider's `identify` method), and the value is the resolved candidate. * `graph`: A `DirectedGraph` instance representing the dependency tree. The vertices are keys of `mapping`, and each edge represents *why* a particular package is included. A special vertex `None` is included to represent parents of user-supplied requirements. * `criteria`: A dict of "criteria" that hold detailed information on how edges in the graph are derived. Each key is an identifier of a requirement, and the value is a `Criterion` instance. The following exceptions may be raised if a resolution cannot be found: * `ResolutionImpossible`: A resolution cannot be found for the given combination of requirements. The `causes` attribute of the exception is a list of (requirement, parent), giving the requirements that could not be satisfied. * `ResolutionTooDeep`: The dependency tree is too deeply nested and the resolver gave up. This is usually caused by a circular dependency, but you can try to resolve this by increasing the `max_rounds` argument. """ resolution = Resolution(self.provider, self.reporter) state = resolution.resolve(requirements, max_rounds=max_rounds) return _build_result(state) PKH]Tp:python3.10/site-packages/pip/_vendor/resolvelib/structs.pynu[import itertools from .compat import collections_abc class DirectedGraph(object): """A graph structure with directed edges.""" def __init__(self): self._vertices = set() self._forwards = {} # -> Set[] self._backwards = {} # -> Set[] def __iter__(self): return iter(self._vertices) def __len__(self): return len(self._vertices) def __contains__(self, key): return key in self._vertices def copy(self): """Return a shallow copy of this graph.""" other = DirectedGraph() other._vertices = set(self._vertices) other._forwards = {k: set(v) for k, v in self._forwards.items()} other._backwards = {k: set(v) for k, v in self._backwards.items()} return other def add(self, key): """Add a new vertex to the graph.""" if key in self._vertices: raise ValueError("vertex exists") self._vertices.add(key) self._forwards[key] = set() self._backwards[key] = set() def remove(self, key): """Remove a vertex from the graph, disconnecting all edges from/to it.""" self._vertices.remove(key) for f in self._forwards.pop(key): self._backwards[f].remove(key) for t in self._backwards.pop(key): self._forwards[t].remove(key) def connected(self, f, t): return f in self._backwards[t] and t in self._forwards[f] def connect(self, f, t): """Connect two existing vertices. Nothing happens if the vertices are already connected. """ if t not in self._vertices: raise KeyError(t) self._forwards[f].add(t) self._backwards[t].add(f) def iter_edges(self): for f, children in self._forwards.items(): for t in children: yield f, t def iter_children(self, key): return iter(self._forwards[key]) def iter_parents(self, key): return iter(self._backwards[key]) class IteratorMapping(collections_abc.Mapping): def __init__(self, mapping, accessor, appends=None): self._mapping = mapping self._accessor = accessor self._appends = appends or {} def __repr__(self): return "IteratorMapping({!r}, {!r}, {!r})".format( self._mapping, self._accessor, self._appends, ) def __bool__(self): return bool(self._mapping or self._appends) __nonzero__ = __bool__ # XXX: Python 2. def __contains__(self, key): return key in self._mapping or key in self._appends def __getitem__(self, k): try: v = self._mapping[k] except KeyError: return iter(self._appends[k]) return itertools.chain(self._accessor(v), self._appends.get(k, ())) def __iter__(self): more = (k for k in self._appends if k not in self._mapping) return itertools.chain(self._mapping, more) def __len__(self): more = sum(1 for k in self._appends if k not in self._mapping) return len(self._mapping) + more class _FactoryIterableView(object): """Wrap an iterator factory returned by `find_matches()`. Calling `iter()` on this class would invoke the underlying iterator factory, making it a "collection with ordering" that can be iterated through multiple times, but lacks random access methods presented in built-in Python sequence types. """ def __init__(self, factory): self._factory = factory def __repr__(self): return "{}({})".format(type(self).__name__, list(self._factory())) def __bool__(self): try: next(self._factory()) except StopIteration: return False return True __nonzero__ = __bool__ # XXX: Python 2. def __iter__(self): return self._factory() class _SequenceIterableView(object): """Wrap an iterable returned by find_matches(). This is essentially just a proxy to the underlying sequence that provides the same interface as `_FactoryIterableView`. """ def __init__(self, sequence): self._sequence = sequence def __repr__(self): return "{}({})".format(type(self).__name__, self._sequence) def __bool__(self): return bool(self._sequence) __nonzero__ = __bool__ # XXX: Python 2. def __iter__(self): return iter(self._sequence) def build_iter_view(matches): """Build an iterable view from the value returned by `find_matches()`.""" if callable(matches): return _FactoryIterableView(matches) if not isinstance(matches, collections_abc.Sequence): matches = list(matches) return _SequenceIterableView(matches) PKH]e<python3.10/site-packages/pip/_vendor/resolvelib/providers.pynu[class AbstractProvider(object): """Delegate class to provide requirement interface for the resolver.""" def identify(self, requirement_or_candidate): """Given a requirement, return an identifier for it. This is used to identify a requirement, e.g. whether two requirements should have their specifier parts merged. """ raise NotImplementedError def get_preference( self, identifier, resolutions, candidates, information, backtrack_causes, ): """Produce a sort key for given requirement based on preference. The preference is defined as "I think this requirement should be resolved first". The lower the return value is, the more preferred this group of arguments is. :param identifier: An identifier as returned by ``identify()``. This identifies the dependency matches of which should be returned. :param resolutions: Mapping of candidates currently pinned by the resolver. Each key is an identifier, and the value a candidate. The candidate may conflict with requirements from ``information``. :param candidates: Mapping of each dependency's possible candidates. Each value is an iterator of candidates. :param information: Mapping of requirement information of each package. Each value is an iterator of *requirement information*. :param backtrack_causes: Sequence of requirement information that were the requirements that caused the resolver to most recently backtrack. A *requirement information* instance is a named tuple with two members: * ``requirement`` specifies a requirement contributing to the current list of candidates. * ``parent`` specifies the candidate that provides (dependend on) the requirement, or ``None`` to indicate a root requirement. The preference could depend on a various of issues, including (not necessarily in this order): * Is this package pinned in the current resolution result? * How relaxed is the requirement? Stricter ones should probably be worked on first? (I don't know, actually.) * How many possibilities are there to satisfy this requirement? Those with few left should likely be worked on first, I guess? * Are there any known conflicts for this requirement? We should probably work on those with the most known conflicts. A sortable value should be returned (this will be used as the ``key`` parameter of the built-in sorting function). The smaller the value is, the more preferred this requirement is (i.e. the sorting function is called with ``reverse=False``). """ raise NotImplementedError def find_matches(self, identifier, requirements, incompatibilities): """Find all possible candidates that satisfy given constraints. :param identifier: An identifier as returned by ``identify()``. This identifies the dependency matches of which should be returned. :param requirements: A mapping of requirements that all returned candidates must satisfy. Each key is an identifier, and the value an iterator of requirements for that dependency. :param incompatibilities: A mapping of known incompatibilities of each dependency. Each key is an identifier, and the value an iterator of incompatibilities known to the resolver. All incompatibilities *must* be excluded from the return value. This should try to get candidates based on the requirements' types. For VCS, local, and archive requirements, the one-and-only match is returned, and for a "named" requirement, the index(es) should be consulted to find concrete candidates for this requirement. The return value should produce candidates ordered by preference; the most preferred candidate should come first. The return type may be one of the following: * A callable that returns an iterator that yields candidates. * An collection of candidates. * An iterable of candidates. This will be consumed immediately into a list of candidates. """ raise NotImplementedError def is_satisfied_by(self, requirement, candidate): """Whether the given requirement can be satisfied by a candidate. The candidate is guarenteed to have been generated from the requirement. A boolean should be returned to indicate whether ``candidate`` is a viable solution to the requirement. """ raise NotImplementedError def get_dependencies(self, candidate): """Get dependencies of a candidate. This should return a collection of requirements that `candidate` specifies as its dependencies. """ raise NotImplementedError class AbstractResolver(object): """The thing that performs the actual resolution work.""" base_exception = Exception def __init__(self, provider, reporter): self.provider = provider self.reporter = reporter def resolve(self, requirements, **kwargs): """Take a collection of constraints, spit out the resolution result. This returns a representation of the final resolution state, with one guarenteed attribute ``mapping`` that contains resolved candidates as values. The keys are their respective identifiers. :param requirements: A collection of constraints. :param kwargs: Additional keyword arguments that subclasses may accept. :raises: ``self.base_exception`` or its subclass. """ raise NotImplementedError PKH]_TT<python3.10/site-packages/pip/_vendor/resolvelib/reporters.pynu[class BaseReporter(object): """Delegate class to provider progress reporting for the resolver.""" def starting(self): """Called before the resolution actually starts.""" def starting_round(self, index): """Called before each round of resolution starts. The index is zero-based. """ def ending_round(self, index, state): """Called before each round of resolution ends. This is NOT called if the resolution ends at this round. Use `ending` if you want to report finalization. The index is zero-based. """ def ending(self, state): """Called before the resolution ends successfully.""" def adding_requirement(self, requirement, parent): """Called when adding a new requirement into the resolve criteria. :param requirement: The additional requirement to be applied to filter the available candidaites. :param parent: The candidate that requires ``requirement`` as a dependency, or None if ``requirement`` is one of the root requirements passed in from ``Resolver.resolve()``. """ def backtracking(self, candidate): """Called when rejecting a candidate during backtracking.""" def pinning(self, candidate): """Called when adding a candidate to the potential solution.""" PKH]5;python3.10/site-packages/pip/_vendor/resolvelib/__init__.pynu[__all__ = [ "__version__", "AbstractProvider", "AbstractResolver", "BaseReporter", "InconsistentCandidate", "Resolver", "RequirementsConflicted", "ResolutionError", "ResolutionImpossible", "ResolutionTooDeep", ] __version__ = "0.8.0" from .providers import AbstractProvider, AbstractResolver from .reporters import BaseReporter from .resolvers import ( InconsistentCandidate, RequirementsConflicted, Resolver, ResolutionError, ResolutionImpossible, ResolutionTooDeep, ) PKH]rV Ppython3.10/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-310.pycnu[o ai@sddZddlZddlZzddlZWn eydZYnwddZGdddejZejfddZ dS) zONicer log formatting with colours. Code copied from Tornado, Apache licensed. NcCs^d}tr-ttjdr-tjr-zttddkr d}W|SW|Sty,Y|Sw|S)NFisattycolorsrT)curseshasattrsysstderrrZ setuptermZtigetnum Exception)colorr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pep517/colorlog.py_stderr_supports_colors r c@s>eZdZdZejdejdejdejdiZ d ddZ d d Z dS) LogFormatterz&Log formatter with colour support TNcCstjj||di|_|r^tr^tdptdpd}dtjkr'dkr.nnt |d}|j D]\}}t t ||d|j|<q3t tdd|_ t}|d |_td Sd|_ d |_d S) aO :arg bool color: Enables color support. :arg string fmt: Log message format. It will be applied to the attributes dict of log records. The text between ``%(color)s`` and ``%(end_color)s`` will be colored depending on the level if color support is on. :arg dict colors: color mappings from logging level to terminal color code :arg string datefmt: Datetime format. Used for formatting ``(asctime)`` placeholder in ``prefix_fmt``. .. versionchanged:: 3.2 Added ``fmt`` and ``datefmt`` arguments. )datefmtZsetafZsetf)rr)rrrasciiZsgr0rFN)logging Formatter__init___colorsr rZtigetstrr version_infostrDEFAULT_COLORSitemsZtparm_normalZinitscrZgetmaxyx termwidthZendwin)selfr rZfg_colorlevelnocodeZscrr r r r2s(       zLogFormatter.__init__cCst|j}dj|jd|jd}|t||jkr%d|j|t|}nd}|j|jvr7|j|j}|j}nd}}|j||||S)Nz{initial}-{name}r)initialname z r) lenmessageformat levelnamer#rr rr)rrecordmlenZ right_textspaceZ start_colorZ end_colorr r r formatMessage]s    zLogFormatter.formatMessage)TN) __name__ __module__ __qualname____doc__rINFOWARNINGERRORCRITICALrrr,r r r r r (s  +r cCs0t}|ttj|tj|dS)N)r StreamHandler setFormatterr root addHandlersetLevel)levelhandlerr r r enable_colourful_outputos  r<) r0rrr ImportErrorr rr r1r<r r r r s   GPKH]!wwPpython3.10/site-packages/pip/_vendor/pep517/__pycache__/dirtools.cpython-310.pycnu[o aii@sZddlZddlZddlZddlZddlZddlZddlZejddZddZ ddZ dS)Nc cs.t}z |VWt|dSt|w)z2Create a temporary directory in a context manager.N)tempfilemkdtempshutilrmtree)tdr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pep517/dirtools.pytempdir s r c OsHz tj|i|WSty#}z|jtjkrWYd}~dSd}~ww)zWLike `mkdir`, but does not raise an exception if the directory already exists. N)osmkdirOSErrorerrnoEEXIST)argskwargsexcrrrmkdir_ps rcCst}t|d}t|D]9\}}}|D]}tj||}tj||}| |ddq|D]}tj||}tj||}| ||q1q|S)z0Construct an in-memory zip file for a directory.w/) ioBytesIOzipfileZipFiler walkpathjoinrelpathwritestrwrite)rootbufferzip_filedirsfilesrZfs_pathrel_pathrrrdir_to_zipfiles r&) r r contextlibrrr rcontextmanagerr rr&rrrrs  PKH]S88Mpython3.10/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-310.pycnu[o ai @sdZddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z m Z ddl mZmZeeZdd Zd d Zd d ZddZd"ddZeZejdddejdddddejdddddejdddddd Zed!kreedSdS)#z%Build a project using PEP 517 hooks. N)BuildEnvironment)Pep517HookCaller)tempdirmkdir_p)FileNotFoundError toml_loadcCs4ddh}|t|ksdj|t|d}t|dS)z7 Ensure build system has the requisite fields. requires build-backendz"Missing required fields: {missing})missingN)setformat ValueError)systemrequiredmessager/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pep517/build.pyvalidate_systems  rcCsPtj|d}t|d}t|}Wd|dS1swY|dS)zC Load the build system from a source dir (pyproject.toml). zpyproject.tomlrbNz build-system)ospathjoinioopenr) source_dir pyprojectfZpyproject_datarrr load_systems  rc CsHzt|}Wn ttfyi}Ynw|dd|dddg|S)z Given a source dir, attempt to get a build system backend and requirements from pyproject.toml. Fallback to setuptools but only if the file was not found or a build system was not indicated. r z setuptools.build_meta:__legacy__r setuptoolswheel)rrKeyError setdefault)rrrrr compat_system's r#c Csdjdit}t||}|i}td|||tdt9}td||djdit}t||} | |i} tj || } t | tj |tj | WddS1sawYdS)Nzget_requires_for_build_{dist}zGot build requires: %sz$Installed dynamic build dependencieszTrying to build %s in %sz build_{dist}r) r localsgetattrloginfo pip_installrrrrshutilmovebasename) hooksenvdistdestZget_requires_name get_requiresreqstdZ build_namebuildfilenamesourcerrr _do_build:s       "r6cCs|pt|}tj||p d}t|t|t||d|d}t}| |dt ||||WddS1s?wYdS)Nr.r z backend-pathr ) rrrrrrrgetrr(r6)rr.r/rr,r-rrrr3Ls "r3rz%A directory containing pyproject.toml)helpz--binaryz-b store_trueF)actiondefaultz--sourcez-sz --out-dirz-oz>Destination in which to save the builds relative to source dircCsZtdttd|js|jsdnd|js|jsdndf}|D] }t|j||jq dS)NzQpep517.build is deprecated. Consider switching to https://pypi.org/project/build/sdistr ) r&warninglistfilterr5binaryr3rZout_dir)argsdistsr.rrrmainps rC__main__)NN)__doc__argparserloggingrr)ZenvbuildrwrappersrZdirtoolsrrcompatrr getLogger__name__r&rrr#r6r3ArgumentParserparser add_argumentrC parse_argsrrrrsN      PKH]cy^eePpython3.10/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-310.pycnu[o ai@sdZdZddlTdS)z6Wrappers to build Python packages using PEP 517 hooks z0.12.0)*N)__doc__ __version__wrappersrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pep517/__init__.pys PKH]mFFPpython3.10/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-310.pycnu[o ai@sdZddlZddlZddlZddlZddlmZddlZddlm Z ddl m Z ddl m Z ddlmZmZeeZd d ZGd d d eZdd dZdddZdS)zIBuild wheels/sdists by installing build deps to a temporary environment. N) check_call) get_paths)mkdtemp) toml_load)Pep517HookCaller LoggerWrappercCs^ttj|dd }t|}Wdn1swY|d}|d|d|dfS)Nzpyproject.tomlrbz build-systemrequiresz build-backendz backend-path)ioopenospathjoinrget) source_dirfZpyproject_dataZbuildsysr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pep517/envbuild.py_load_pyprojects  rc@s6eZdZdZdZd ddZddZdd Zd d ZdS) BuildEnvironmentzContext manager to install build deps in a simple temporary environment Based on code I wrote for pip, which is MIT licensed. NTcCs ||_dSN)_cleanup)selfcleanuprrr__init__=s zBuildEnvironment.__init__cCstdd|_td|jtjdd|_tjdd|_tj dkr$dnd}t ||j|jdd }|d }|jrD|tj |jtjd<n |tj tj tjd<|d |d kr\|d }n |d tj |d }|jrw|tj |jtjd<|S|tjd<|S) Nzpep517-build-env-)prefixzTemporary build environment: %sPATH PYTHONPATHnt posix_prefix)baseplatbase)varsscriptspurelibplatlib) rrloginfor environr save_pathsave_pythonpathnamerpathsepdefpath)rZinstall_schemeZ install_dirsr$lib_dirsrrr __enter__@s2      zBuildEnvironment.__enter__cCsT|sdStd|tjddddd|jgt|}t|tttj tttj ddS) zAInstall dependencies into this env by calling pip in a subprocessNzCalling pip to install %sz-mpipinstallz--ignore-installedz--prefix)stdoutstderr) r'r(sys executablerlistrrloggingINFOERROR)rreqscmdrrr pip_install`s     zBuildEnvironment.pip_installcCs|jo|jduotj|j}|rt|j|jdur$tjddn|jtjd<|j dur8tjdddS|j tjd<dS)Nrr) rrr isdirshutilrmtreer*r)popr+)rexc_typeexc_valexc_tbZ needs_cleanuprrr__exit__ns     zBuildEnvironment.__exit__)T) __name__ __module__ __qualname____doc__rrr0r=rErrrrr!s  rc Cz|duri}t|\}}}t|||}t}||||}|||||WdS1s6wYdS)amBuild a wheel from a source directory using PEP 517 hooks. :param str source_dir: Source directory containing pyproject.toml :param str wheel_dir: Target directory to create wheel in :param dict config_settings: Options to pass to build backend This is a blocking function which will run pip in a subprocess to install build requirements. N)rrrr=get_requires_for_build_wheel build_wheel) r wheel_dirconfig_settingsr backend backend_pathhooksenvr;rrrrL      $rLc CrJ)amBuild an sdist from a source directory using PEP 517 hooks. :param str source_dir: Source directory containing pyproject.toml :param str sdist_dir: Target directory to place sdist in :param dict config_settings: Options to pass to build backend This is a blocking function which will run pip in a subprocess to install build requirements. N)rrrr=get_requires_for_build_sdist build_sdist) rZ sdist_dirrNr rOrPrQrRr;rrrrUrSrUr)rIr r r8r? subprocessrr5 sysconfigrtempfilercompatrwrappersrr getLoggerrFr'robjectrrLrUrrrrs       aPKH]) Lpython3.10/site-packages/pip/_vendor/pep517/__pycache__/meta.cpython-310.pycnu[o ai @s@dZddlZddlZddlZddlZddlZzddlmZWn e y+ddl ZYnwzddl m Z Wne yCddl m Z YnwddlmZddlmZmZddlmZmZmZddlmZmZmZeeZd d Zdd d ZefddZddZ e!Z"e"j#ddde"j#ddddddZ$edkre$dSdS)z2Build metadata for a project using PEP 517 hooks. N)Path)BuildEnvironment)Pep517HookCallerquiet_subprocess_runner)tempdirmkdir_pdir_to_zipfile)validate_system load_system compat_systemc Cs|i}td|||tdt+}td|||i}tj||}t |tj|tj |WddS1sFwYdS)NzGot build requires: %sz$Installed dynamic build dependencieszTrying to build metadata in %s) get_requires_for_build_wheelloginfo pip_installr prepare_metadata_for_build_wheelospathjoinshutilmovebasename)hooksenvdestreqstdfilenamesourcer/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pep517/meta.py _prep_metas       "r!.c Cs|pt|}tj||p d}t|t|t||d|d}|t 1t }| |dt |||Wdn1sCwYWddSWddS1s[wYdS)Ndistz build-backendz backend-pathrequires) r rrrrr rgetsubprocess_runnerrrrr!) source_dirrsystemrrrrr build)s  "r)cCs<t}||dt|WdS1swYdS)N)r)rr )builderout_dirrrr build_as_zip8s $r,cCs:tj|}t|}tjt||d}tt|}t |S)z Given a source directory (root) of a package, return an importlib.metadata.Distribution object with metadata build from that package. )r'r() rr expanduserr functoolspartialr)rr,imp_metaZPathDistribution)rootr(r*rrrr load>s   r2r'z%A directory containing pyproject.toml)helpz --out-dirz-oz>Destination in which to save the builds relative to source dircCst}t|j|jdS)N)parser parse_argsr)r'r+)argsrrr mainVsr7__main__)r"NN)%__doc__argparseloggingrrr.importlib.metadatametadatar0 ImportErrorZimportlib_metadatazipfilerZzippZenvbuildrwrappersrrZdirtoolsrrr r)r r r getLogger__name__rr!r,r2ArgumentParserr4 add_argumentr7rrrr sL         PKH]GMpython3.10/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-310.pycnu[o ai@sdZddlZddlZddlZddlZddlmZmZddl Z ddl m Z ddl Z ddl Z ddlmZddlZddlmZddlmZmZdd lmZdd lmZeeZd d Zd dZddZdddZ dddddZ!ddZ"edkrze dSdS)zHCheck a project and backend by attempting to build using PEP 517 hooks. N)isfilejoin)CalledProcessError)mkdtemp)enable_colourful_output)TOMLDecodeError toml_load)BuildEnvironment)Pep517HookCallerc C@t}z ||tdWnty&tdYWddSwz |i}td|WntyKtjdddYWddSwz ||tdWntymtd YWddSwt}td |zz| |i}td |Wntytjd ddYWt |WddSw| d std|Wt |WddSt ||}t|rtd|ntd|Wt |WddSt|rtdntdWt |WddSWt |nt |w WddS1swYdS)N#Installed static build dependencies+Failed to install static build dependenciesFGot build requires: %s'Failure in get_requires_for_build_sdistTexc_info$Installed dynamic build dependencies,Failed to install dynamic build dependencieszTrying to build sdist in %szbuild_sdist returned %rzFailure in build_sdistz.tar.gzz*Filename %s doesn't have .tar.gz extensionOutput file %s existsOutput file %s does not existzOutput file is a tar filezOutput file is not a tar file)r pip_installloginforerrorget_requires_for_build_sdist Exceptionr build_sdistshutilrmtreeendswithpjoinrtarfile is_tarfilehooksZbuild_sys_requiresenvreqstdfilenamepathr+/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pep517/check.pycheck_build_sdistsz                 %   ,   -&r-c Cr )Nr rFrrTrrrzTrying to build wheel in %szbuild_wheel returned %rzFailure in build_wheelz.whlz'Filename %s doesn't have .whl extensionrrzOutput file is a zip filezOutput file is not a zip file)r rrrrrget_requires_for_build_wheelrr build_wheelrrr r!rzipfile is_zipfiler$r+r+r,check_build_wheelPsv                  $   +   ,&r2c Cst|d}t|rtdntddSz2t|d }t|}Wdn1s,wY|d}|d}|d}|d }td Wnt t fy[tjd d d YdSwt |||}t ||} t ||} | sstd| sztd| S)Nzpyproject.tomlzFound pyproject.tomlzMissing pyproject.tomlFrbz build-systemrequiresz build-backendz backend-pathzLoaded pyproject.tomlzInvalid pyproject.tomlTrz%Sdist checks failed; scroll up to seezWheel checks failed)r!rrrrioopenr getrKeyErrorr r-r2warning) source_dir pyprojectfZpyproject_dataZbuildsysr4backend backend_pathr%Zsdist_okZwheel_okr+r+r,checks4          r?cCsltdt}|jddd||}tt|j}|r(t t dddSt t ddt d dS) NzQpep517.check is deprecated. Consider switching to https://pypi.org/project/build/r:z%A directory containing pyproject.toml)helpz Checks passedgreenz Checks failedredr) rr9argparseArgumentParser add_argument parse_argsrr?r:printansisysexit)argvZapargsokr+r+r,mains   rNzzzz)resetboldrBrAcCs4tjdkrtjrt|t|tdSt|S)NntrO)osnamerIstdoutisatty ansi_codesstr)sattrr+r+r,rHsrH__main__)N)#__doc__rCr5loggingrRos.pathrrr!r subprocessrrIr"tempfilerr0Zcolorlogrcompatrr Zenvbuildr wrappersr getLogger__name__rr-r2r?rNrVrHr+r+r+r,s<      98 " PKH]̳>0>0Ppython3.10/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-310.pycnu[o aiu4@s ddlZddlmZddlZddlmZmZddlZddl m Z m Z m Z ddl Z ddlmZddlmZddlmZgd Zed d ZGd d d eZGdddeZGdddeZGdddeZdddZdddZddZGdddeZGdddej Z!dS)N)contextmanager)abspathjoin) check_call check_outputSTDOUT)mkdtemp)compat)_in_proc_script_path)BackendUnavailableBackendInvalid HookMissingUnsupportedOperationdefault_subprocess_runnerquiet_subprocess_runnerPep517HookCallerc cs,t}z |VWt|dSt|wN)rshutilrmtree)tdr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pep517/wrappers.pytempdirs rc@eZdZdZddZdS)r zEWill be raised if the backend cannot be imported in the hook process.cC ||_dSr tracebackselfrrrr__init__# zBackendUnavailable.__init__N__name__ __module__ __qualname____doc__r rrrrr ! r c@r)r z)Will be raised if the backend is invalid.cCs||_||_||_dSr backend_name backend_pathmessage)rr)r*r+rrrr )s zBackendInvalid.__init__Nr"rrrrr 'r'r cs eZdZdZfddZZS)rz Will be raised on missing hooks.cstt||||_dSr)superrr hook_name)rr- __class__rrr 1s zHookMissing.__init__)r#r$r%r&r __classcell__rrr.rr/src@r)rzDMay be raised by build_sdist if the backend indicates that it can't.cCrrrrrrrr 8r!zUnsupportedOperation.__init__Nr"rrrrr6r'rcCs*tj}|r ||t|||ddS)z5The default method of calling the wrapper subprocess.)cwdenvN)osenvironcopyupdatercmdr1 extra_environr2rrrr<s  rcCs,tj}|r ||t|||tddS)zDA method of calling the wrapper subprocess while suppressing output.)r1r2stderrN)r3r4r5r6rrr7rrrrEs  rcCsntj|r tdtj|}tjtj||}tj|}tj|}tj||g|kr5td|S)zNormalise and check a backend path. Ensure that the requested backend path is specified as a relative path, and resolves to a location under the given source tree. Return an absolute version of the requested path. zpaths must be relativez paths must be inside source tree) r3pathisabs ValueErrorrnormpathrnormcase commonprefix) source_tree requested abs_source abs_requested norm_sourcenorm_requestedrrrnorm_and_checkNs    rGc@seZdZdZ   dddZeddZddZdd d Z  dd d Z  dddZ dddZ  dddZ  dddZ dddZdddZddZdS) raA wrapper around a source directory to be built with a PEP 517 backend. :param source_dir: The path to the source directory, containing pyproject.toml. :param build_backend: The build backend spec, as per PEP 517, from pyproject.toml. :param backend_path: The backend path, as per PEP 517, from pyproject.toml. :param runner: A callable that invokes the wrapper subprocess. :param python_executable: The Python executable used to invoke the backend The 'runner', if provided, must expect the following: - cmd: a list of strings representing the command and arguments to execute, as would be passed to e.g. 'subprocess.check_call'. - cwd: a string representing the working directory that must be used for the subprocess. Corresponds to the provided source_dir. - extra_environ: a dict mapping environment variable names to values which must be set for the subprocess execution. NcsR|durt}t|_|_|rfdd|D}|_|_|s$tj}|_dS)Ncsg|]}tj|qSr)rG source_dir).0prrr s z-Pep517HookCaller.__init__..) rrrH build_backendr*_subprocess_runnersys executablepython_executable)rrHrMr*runnerrQrrKrr zs   zPep517HookCaller.__init__ccs*|j}||_z dVW||_dS||_w)z\A context manager for temporarily overriding the default subprocess runner. N)rN)rrRprevrrrsubprocess_runners z"Pep517HookCaller.subprocess_runnercCs |diS)z>Return the list of optional features supported by the backend._supported_features _call_hookrKrrrrUs z$Pep517HookCaller._supported_featurescC|dd|iS)aIIdentify packages required for building a wheel Returns a list of dependency specifications, e.g.:: ["wheel >= 0.25", "setuptools"] This does not include requirements specified in pyproject.toml. It returns the result of calling the equivalently named hook in a subprocess. get_requires_for_build_wheelconfig_settingsrVrrZrrrrY z-Pep517HookCaller.get_requires_for_build_wheelTcC|dt|||dS)auPrepare a ``*.dist-info`` folder with metadata for this project. Returns the name of the newly created folder. If the build backend defines a hook with this name, it will be called in a subprocess. If not, the backend will be asked to build a wheel, and the dist-info extracted from that (unless _allow_fallback is False). prepare_metadata_for_build_wheelmetadata_directoryrZ_allow_fallbackrWrrr`rZrarrrr^  z1Pep517HookCaller.prepare_metadata_for_build_wheelcC(|durt|}|dt|||dS)avBuild a wheel from this project. Returns the name of the newly created file. In general, this will call the 'build_wheel' hook in the backend. However, if that was previously called by 'prepare_metadata_for_build_wheel', and the same metadata_directory is used, the previously built wheel will be copied to wheel_directory. N build_wheelwheel_directoryrZr`rrWrrhrZr`rrrrf zPep517HookCaller.build_wheelcCrX)aSIdentify packages required for building an editable wheel Returns a list of dependency specifications, e.g.:: ["wheel >= 0.25", "setuptools"] This does not include requirements specified in pyproject.toml. It returns the result of calling the equivalently named hook in a subprocess. get_requires_for_build_editablerZrVr[rrrrlr\z0Pep517HookCaller.get_requires_for_build_editablecCr])aPrepare a ``*.dist-info`` folder with metadata for this project. Returns the name of the newly created folder. If the build backend defines a hook with this name, it will be called in a subprocess. If not, the backend will be asked to build an editable wheel, and the dist-info extracted from that (unless _allow_fallback is False). #prepare_metadata_for_build_editabler_rbrcrrrrmrdz4Pep517HookCaller.prepare_metadata_for_build_editablecCre)aBuild an editable wheel from this project. Returns the name of the newly created file. In general, this will call the 'build_editable' hook in the backend. However, if that was previously called by 'prepare_metadata_for_build_editable', and the same metadata_directory is used, the previously built wheel will be copied to wheel_directory. Nbuild_editablergrirjrrrrnrkzPep517HookCaller.build_editablecCrX)a>Identify packages required for building a wheel Returns a list of dependency specifications, e.g.:: ["setuptools >= 26"] This does not include requirements specified in pyproject.toml. It returns the result of calling the equivalently named hook in a subprocess. get_requires_for_build_sdistrZrVr[rrrro r\z-Pep517HookCaller.get_requires_for_build_sdistcCs|dt||dS)zBuild an sdist from this project. Returns the name of the newly created file. This calls the 'build_sdist' backend hook in a subprocess. build_sdist)sdist_directoryrZrb)rrqrZrrrrpszPep517HookCaller.build_sdistc Cstjddkr|jd}n|j}d|i}|jr1tj|j}tjddkr-|t}||d<t }d|i}t j |t |dddt }|j} |j| tt|||g|j|d Wdn1sfwYt t |d } | d rt| d d | drt| d d | drt|j|j| dd d| drt| dp|| dWdS1swYdS)NrASCIIPEP517_BUILD_BACKENDPEP517_BACKEND_PATHkwargsz input.json)indent)r1r9z output.json unsupportedr no_backendbackend_invalid backend_errorr( hook_missingmissing_hook_name return_val)rO version_inforMencoder*r3pathseprgetfilesystemencodingrr write_jsonpjoinr rQrNrstrrH read_jsongetrr r r) rr-rvrMr9r*r hook_inputscriptpythondatarrrrW&sJ     $zPep517HookCaller._call_hook)NNNrNTNN)r#r$r%r&r rrTrUrYr^rfrlrmrnrorprWrrrrrfs4         rc@s<eZdZdZddZddZeddZdd Zd d Z d S) LoggerWrapperzd Read messages from a pipe and redirect them to a logger (see python's logging module). cCsHtj|d|_||_||_t\|_|_ t |j|_ | dSr) threadingThreadr daemonloggerlevelr3pipefd_readfd_writefdopenreaderstart)rrrrrrr ^s  zLoggerWrapper.__init__cCs|jSr)rrKrrrfilenokszLoggerWrapper.filenocCs|tjr |ddS|S)N)endswithr3linesep)msgrrrremove_newlinenszLoggerWrapper.remove_newlinecCs |jD] }|||qdSr)r_writer)rlinerrrrunrs zLoggerWrapper.runcCs|j|j|dSr)rlogr)rr+rrrrvszLoggerWrapper._writeN) r#r$r%r&r r staticmethodrrrrrrrrXs   rr)"r contextlibrr3os.pathrrrr subprocessrrrrOtempfilerryr in_processr __all__r Exceptionr r rrrrrGobjectrrrrrrrs.        sPKH]6 @--Npython3.10/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-310.pycnu[o ai@sdZddlZddlZddlZejddkrddZddZnddZd dZzeZWn ey5e ZYnwejd krMdd l m Z d d Z ddl mZdSdd lm Z ddlmZdS)zPython 2/3 compatibilityNcKsHt|ddd}tj||fi|WddS1swYdS)Nwutf-8encodingopenjsondumpobjpathkwargsfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pep517/compat.py write_json s"rcCs<t|ddd }t|WdS1swYdS)Nrrrrr loadr rrrr read_jsons$rcKsHt|d}tj||fddi|WddS1swYdS)Nwbrrrr rrrrs "cCs8t|d }t|WdS1swYdS)Nrbrrrrrrs $)r)rcCs.tj|ddd}z t|W|S|w)Nutf8)rnewline)io TextIOWrapper _toml_loaddetach)rrrrr toml_load)sr")TomlDecodeError)TOMLDecodeError)__doc__rr sys version_inforrFileNotFoundError NameErrorIOErrorZtomlrr r"r#r$pip._vendor.tomlirrrrs(     PKH]>R 4python3.10/site-packages/pip/_vendor/pep517/build.pynu["""Build a project using PEP 517 hooks. """ import argparse import io import logging import os import shutil from .envbuild import BuildEnvironment from .wrappers import Pep517HookCaller from .dirtools import tempdir, mkdir_p from .compat import FileNotFoundError, toml_load log = logging.getLogger(__name__) def validate_system(system): """ Ensure build system has the requisite fields. """ required = {'requires', 'build-backend'} if not (required <= set(system)): message = "Missing required fields: {missing}".format( missing=required-set(system), ) raise ValueError(message) def load_system(source_dir): """ Load the build system from a source dir (pyproject.toml). """ pyproject = os.path.join(source_dir, 'pyproject.toml') with io.open(pyproject, 'rb') as f: pyproject_data = toml_load(f) return pyproject_data['build-system'] def compat_system(source_dir): """ Given a source dir, attempt to get a build system backend and requirements from pyproject.toml. Fallback to setuptools but only if the file was not found or a build system was not indicated. """ try: system = load_system(source_dir) except (FileNotFoundError, KeyError): system = {} system.setdefault( 'build-backend', 'setuptools.build_meta:__legacy__', ) system.setdefault('requires', ['setuptools', 'wheel']) return system def _do_build(hooks, env, dist, dest): get_requires_name = 'get_requires_for_build_{dist}'.format(**locals()) get_requires = getattr(hooks, get_requires_name) reqs = get_requires({}) log.info('Got build requires: %s', reqs) env.pip_install(reqs) log.info('Installed dynamic build dependencies') with tempdir() as td: log.info('Trying to build %s in %s', dist, td) build_name = 'build_{dist}'.format(**locals()) build = getattr(hooks, build_name) filename = build(td, {}) source = os.path.join(td, filename) shutil.move(source, os.path.join(dest, os.path.basename(filename))) def build(source_dir, dist, dest=None, system=None): system = system or load_system(source_dir) dest = os.path.join(source_dir, dest or 'dist') mkdir_p(dest) validate_system(system) hooks = Pep517HookCaller( source_dir, system['build-backend'], system.get('backend-path') ) with BuildEnvironment() as env: env.pip_install(system['requires']) _do_build(hooks, env, dist, dest) parser = argparse.ArgumentParser() parser.add_argument( 'source_dir', help="A directory containing pyproject.toml", ) parser.add_argument( '--binary', '-b', action='store_true', default=False, ) parser.add_argument( '--source', '-s', action='store_true', default=False, ) parser.add_argument( '--out-dir', '-o', help="Destination in which to save the builds relative to source dir", ) def main(args): log.warning('pep517.build is deprecated. ' 'Consider switching to https://pypi.org/project/build/') # determine which dists to build dists = list(filter(None, ( 'sdist' if args.source or not args.binary else None, 'wheel' if args.binary or not args.source else None, ))) for dist in dists: build(args.source_dir, dist, args.out_dir) if __name__ == '__main__': main(parser.parse_args()) PKH]Uxu4u47python3.10/site-packages/pip/_vendor/pep517/wrappers.pynu[import threading from contextlib import contextmanager import os from os.path import abspath, join as pjoin import shutil from subprocess import check_call, check_output, STDOUT import sys from tempfile import mkdtemp from . import compat from .in_process import _in_proc_script_path __all__ = [ 'BackendUnavailable', 'BackendInvalid', 'HookMissing', 'UnsupportedOperation', 'default_subprocess_runner', 'quiet_subprocess_runner', 'Pep517HookCaller', ] @contextmanager def tempdir(): td = mkdtemp() try: yield td finally: shutil.rmtree(td) class BackendUnavailable(Exception): """Will be raised if the backend cannot be imported in the hook process.""" def __init__(self, traceback): self.traceback = traceback class BackendInvalid(Exception): """Will be raised if the backend is invalid.""" def __init__(self, backend_name, backend_path, message): self.backend_name = backend_name self.backend_path = backend_path self.message = message class HookMissing(Exception): """Will be raised on missing hooks.""" def __init__(self, hook_name): super(HookMissing, self).__init__(hook_name) self.hook_name = hook_name class UnsupportedOperation(Exception): """May be raised by build_sdist if the backend indicates that it can't.""" def __init__(self, traceback): self.traceback = traceback def default_subprocess_runner(cmd, cwd=None, extra_environ=None): """The default method of calling the wrapper subprocess.""" env = os.environ.copy() if extra_environ: env.update(extra_environ) check_call(cmd, cwd=cwd, env=env) def quiet_subprocess_runner(cmd, cwd=None, extra_environ=None): """A method of calling the wrapper subprocess while suppressing output.""" env = os.environ.copy() if extra_environ: env.update(extra_environ) check_output(cmd, cwd=cwd, env=env, stderr=STDOUT) def norm_and_check(source_tree, requested): """Normalise and check a backend path. Ensure that the requested backend path is specified as a relative path, and resolves to a location under the given source tree. Return an absolute version of the requested path. """ if os.path.isabs(requested): raise ValueError("paths must be relative") abs_source = os.path.abspath(source_tree) abs_requested = os.path.normpath(os.path.join(abs_source, requested)) # We have to use commonprefix for Python 2.7 compatibility. So we # normalise case to avoid problems because commonprefix is a character # based comparison :-( norm_source = os.path.normcase(abs_source) norm_requested = os.path.normcase(abs_requested) if os.path.commonprefix([norm_source, norm_requested]) != norm_source: raise ValueError("paths must be inside source tree") return abs_requested class Pep517HookCaller(object): """A wrapper around a source directory to be built with a PEP 517 backend. :param source_dir: The path to the source directory, containing pyproject.toml. :param build_backend: The build backend spec, as per PEP 517, from pyproject.toml. :param backend_path: The backend path, as per PEP 517, from pyproject.toml. :param runner: A callable that invokes the wrapper subprocess. :param python_executable: The Python executable used to invoke the backend The 'runner', if provided, must expect the following: - cmd: a list of strings representing the command and arguments to execute, as would be passed to e.g. 'subprocess.check_call'. - cwd: a string representing the working directory that must be used for the subprocess. Corresponds to the provided source_dir. - extra_environ: a dict mapping environment variable names to values which must be set for the subprocess execution. """ def __init__( self, source_dir, build_backend, backend_path=None, runner=None, python_executable=None, ): if runner is None: runner = default_subprocess_runner self.source_dir = abspath(source_dir) self.build_backend = build_backend if backend_path: backend_path = [ norm_and_check(self.source_dir, p) for p in backend_path ] self.backend_path = backend_path self._subprocess_runner = runner if not python_executable: python_executable = sys.executable self.python_executable = python_executable @contextmanager def subprocess_runner(self, runner): """A context manager for temporarily overriding the default subprocess runner. """ prev = self._subprocess_runner self._subprocess_runner = runner try: yield finally: self._subprocess_runner = prev def _supported_features(self): """Return the list of optional features supported by the backend.""" return self._call_hook('_supported_features', {}) def get_requires_for_build_wheel(self, config_settings=None): """Identify packages required for building a wheel Returns a list of dependency specifications, e.g.:: ["wheel >= 0.25", "setuptools"] This does not include requirements specified in pyproject.toml. It returns the result of calling the equivalently named hook in a subprocess. """ return self._call_hook('get_requires_for_build_wheel', { 'config_settings': config_settings }) def prepare_metadata_for_build_wheel( self, metadata_directory, config_settings=None, _allow_fallback=True): """Prepare a ``*.dist-info`` folder with metadata for this project. Returns the name of the newly created folder. If the build backend defines a hook with this name, it will be called in a subprocess. If not, the backend will be asked to build a wheel, and the dist-info extracted from that (unless _allow_fallback is False). """ return self._call_hook('prepare_metadata_for_build_wheel', { 'metadata_directory': abspath(metadata_directory), 'config_settings': config_settings, '_allow_fallback': _allow_fallback, }) def build_wheel( self, wheel_directory, config_settings=None, metadata_directory=None): """Build a wheel from this project. Returns the name of the newly created file. In general, this will call the 'build_wheel' hook in the backend. However, if that was previously called by 'prepare_metadata_for_build_wheel', and the same metadata_directory is used, the previously built wheel will be copied to wheel_directory. """ if metadata_directory is not None: metadata_directory = abspath(metadata_directory) return self._call_hook('build_wheel', { 'wheel_directory': abspath(wheel_directory), 'config_settings': config_settings, 'metadata_directory': metadata_directory, }) def get_requires_for_build_editable(self, config_settings=None): """Identify packages required for building an editable wheel Returns a list of dependency specifications, e.g.:: ["wheel >= 0.25", "setuptools"] This does not include requirements specified in pyproject.toml. It returns the result of calling the equivalently named hook in a subprocess. """ return self._call_hook('get_requires_for_build_editable', { 'config_settings': config_settings }) def prepare_metadata_for_build_editable( self, metadata_directory, config_settings=None, _allow_fallback=True): """Prepare a ``*.dist-info`` folder with metadata for this project. Returns the name of the newly created folder. If the build backend defines a hook with this name, it will be called in a subprocess. If not, the backend will be asked to build an editable wheel, and the dist-info extracted from that (unless _allow_fallback is False). """ return self._call_hook('prepare_metadata_for_build_editable', { 'metadata_directory': abspath(metadata_directory), 'config_settings': config_settings, '_allow_fallback': _allow_fallback, }) def build_editable( self, wheel_directory, config_settings=None, metadata_directory=None): """Build an editable wheel from this project. Returns the name of the newly created file. In general, this will call the 'build_editable' hook in the backend. However, if that was previously called by 'prepare_metadata_for_build_editable', and the same metadata_directory is used, the previously built wheel will be copied to wheel_directory. """ if metadata_directory is not None: metadata_directory = abspath(metadata_directory) return self._call_hook('build_editable', { 'wheel_directory': abspath(wheel_directory), 'config_settings': config_settings, 'metadata_directory': metadata_directory, }) def get_requires_for_build_sdist(self, config_settings=None): """Identify packages required for building a wheel Returns a list of dependency specifications, e.g.:: ["setuptools >= 26"] This does not include requirements specified in pyproject.toml. It returns the result of calling the equivalently named hook in a subprocess. """ return self._call_hook('get_requires_for_build_sdist', { 'config_settings': config_settings }) def build_sdist(self, sdist_directory, config_settings=None): """Build an sdist from this project. Returns the name of the newly created file. This calls the 'build_sdist' backend hook in a subprocess. """ return self._call_hook('build_sdist', { 'sdist_directory': abspath(sdist_directory), 'config_settings': config_settings, }) def _call_hook(self, hook_name, kwargs): # On Python 2, pytoml returns Unicode values (which is correct) but the # environment passed to check_call needs to contain string values. We # convert here by encoding using ASCII (the backend can only contain # letters, digits and _, . and : characters, and will be used as a # Python identifier, so non-ASCII content is wrong on Python 2 in # any case). # For backend_path, we use sys.getfilesystemencoding. if sys.version_info[0] == 2: build_backend = self.build_backend.encode('ASCII') else: build_backend = self.build_backend extra_environ = {'PEP517_BUILD_BACKEND': build_backend} if self.backend_path: backend_path = os.pathsep.join(self.backend_path) if sys.version_info[0] == 2: backend_path = backend_path.encode(sys.getfilesystemencoding()) extra_environ['PEP517_BACKEND_PATH'] = backend_path with tempdir() as td: hook_input = {'kwargs': kwargs} compat.write_json(hook_input, pjoin(td, 'input.json'), indent=2) # Run the hook in a subprocess with _in_proc_script_path() as script: python = self.python_executable self._subprocess_runner( [python, abspath(str(script)), hook_name, td], cwd=self.source_dir, extra_environ=extra_environ ) data = compat.read_json(pjoin(td, 'output.json')) if data.get('unsupported'): raise UnsupportedOperation(data.get('traceback', '')) if data.get('no_backend'): raise BackendUnavailable(data.get('traceback', '')) if data.get('backend_invalid'): raise BackendInvalid( backend_name=self.build_backend, backend_path=self.backend_path, message=data.get('backend_error', '') ) if data.get('hook_missing'): raise HookMissing(data.get('missing_hook_name') or hook_name) return data['return_val'] class LoggerWrapper(threading.Thread): """ Read messages from a pipe and redirect them to a logger (see python's logging module). """ def __init__(self, logger, level): threading.Thread.__init__(self) self.daemon = True self.logger = logger self.level = level # create the pipe and reader self.fd_read, self.fd_write = os.pipe() self.reader = os.fdopen(self.fd_read) self.start() def fileno(self): return self.fd_write @staticmethod def remove_newline(msg): return msg[:-1] if msg.endswith(os.linesep) else msg def run(self): for line in self.reader: self._write(self.remove_newline(line)) def _write(self, message): self.logger.log(self.level, message) PKH]ޟ 3python3.10/site-packages/pip/_vendor/pep517/meta.pynu["""Build metadata for a project using PEP 517 hooks. """ import argparse import logging import os import shutil import functools try: import importlib.metadata as imp_meta except ImportError: import importlib_metadata as imp_meta try: from zipfile import Path except ImportError: from zipp import Path from .envbuild import BuildEnvironment from .wrappers import Pep517HookCaller, quiet_subprocess_runner from .dirtools import tempdir, mkdir_p, dir_to_zipfile from .build import validate_system, load_system, compat_system log = logging.getLogger(__name__) def _prep_meta(hooks, env, dest): reqs = hooks.get_requires_for_build_wheel({}) log.info('Got build requires: %s', reqs) env.pip_install(reqs) log.info('Installed dynamic build dependencies') with tempdir() as td: log.info('Trying to build metadata in %s', td) filename = hooks.prepare_metadata_for_build_wheel(td, {}) source = os.path.join(td, filename) shutil.move(source, os.path.join(dest, os.path.basename(filename))) def build(source_dir='.', dest=None, system=None): system = system or load_system(source_dir) dest = os.path.join(source_dir, dest or 'dist') mkdir_p(dest) validate_system(system) hooks = Pep517HookCaller( source_dir, system['build-backend'], system.get('backend-path') ) with hooks.subprocess_runner(quiet_subprocess_runner): with BuildEnvironment() as env: env.pip_install(system['requires']) _prep_meta(hooks, env, dest) def build_as_zip(builder=build): with tempdir() as out_dir: builder(dest=out_dir) return dir_to_zipfile(out_dir) def load(root): """ Given a source directory (root) of a package, return an importlib.metadata.Distribution object with metadata build from that package. """ root = os.path.expanduser(root) system = compat_system(root) builder = functools.partial(build, source_dir=root, system=system) path = Path(build_as_zip(builder)) return imp_meta.PathDistribution(path) parser = argparse.ArgumentParser() parser.add_argument( 'source_dir', help="A directory containing pyproject.toml", ) parser.add_argument( '--out-dir', '-o', help="Destination in which to save the builds relative to source dir", ) def main(): args = parser.parse_args() build(args.source_dir, args.out_dir) if __name__ == '__main__': main() PKH]s 4python3.10/site-packages/pip/_vendor/pep517/check.pynu["""Check a project and backend by attempting to build using PEP 517 hooks. """ import argparse import io import logging import os from os.path import isfile, join as pjoin import shutil from subprocess import CalledProcessError import sys import tarfile from tempfile import mkdtemp import zipfile from .colorlog import enable_colourful_output from .compat import TOMLDecodeError, toml_load from .envbuild import BuildEnvironment from .wrappers import Pep517HookCaller log = logging.getLogger(__name__) def check_build_sdist(hooks, build_sys_requires): with BuildEnvironment() as env: try: env.pip_install(build_sys_requires) log.info('Installed static build dependencies') except CalledProcessError: log.error('Failed to install static build dependencies') return False try: reqs = hooks.get_requires_for_build_sdist({}) log.info('Got build requires: %s', reqs) except Exception: log.error('Failure in get_requires_for_build_sdist', exc_info=True) return False try: env.pip_install(reqs) log.info('Installed dynamic build dependencies') except CalledProcessError: log.error('Failed to install dynamic build dependencies') return False td = mkdtemp() log.info('Trying to build sdist in %s', td) try: try: filename = hooks.build_sdist(td, {}) log.info('build_sdist returned %r', filename) except Exception: log.info('Failure in build_sdist', exc_info=True) return False if not filename.endswith('.tar.gz'): log.error( "Filename %s doesn't have .tar.gz extension", filename) return False path = pjoin(td, filename) if isfile(path): log.info("Output file %s exists", path) else: log.error("Output file %s does not exist", path) return False if tarfile.is_tarfile(path): log.info("Output file is a tar file") else: log.error("Output file is not a tar file") return False finally: shutil.rmtree(td) return True def check_build_wheel(hooks, build_sys_requires): with BuildEnvironment() as env: try: env.pip_install(build_sys_requires) log.info('Installed static build dependencies') except CalledProcessError: log.error('Failed to install static build dependencies') return False try: reqs = hooks.get_requires_for_build_wheel({}) log.info('Got build requires: %s', reqs) except Exception: log.error('Failure in get_requires_for_build_sdist', exc_info=True) return False try: env.pip_install(reqs) log.info('Installed dynamic build dependencies') except CalledProcessError: log.error('Failed to install dynamic build dependencies') return False td = mkdtemp() log.info('Trying to build wheel in %s', td) try: try: filename = hooks.build_wheel(td, {}) log.info('build_wheel returned %r', filename) except Exception: log.info('Failure in build_wheel', exc_info=True) return False if not filename.endswith('.whl'): log.error("Filename %s doesn't have .whl extension", filename) return False path = pjoin(td, filename) if isfile(path): log.info("Output file %s exists", path) else: log.error("Output file %s does not exist", path) return False if zipfile.is_zipfile(path): log.info("Output file is a zip file") else: log.error("Output file is not a zip file") return False finally: shutil.rmtree(td) return True def check(source_dir): pyproject = pjoin(source_dir, 'pyproject.toml') if isfile(pyproject): log.info('Found pyproject.toml') else: log.error('Missing pyproject.toml') return False try: with io.open(pyproject, 'rb') as f: pyproject_data = toml_load(f) # Ensure the mandatory data can be loaded buildsys = pyproject_data['build-system'] requires = buildsys['requires'] backend = buildsys['build-backend'] backend_path = buildsys.get('backend-path') log.info('Loaded pyproject.toml') except (TOMLDecodeError, KeyError): log.error("Invalid pyproject.toml", exc_info=True) return False hooks = Pep517HookCaller(source_dir, backend, backend_path) sdist_ok = check_build_sdist(hooks, requires) wheel_ok = check_build_wheel(hooks, requires) if not sdist_ok: log.warning('Sdist checks failed; scroll up to see') if not wheel_ok: log.warning('Wheel checks failed') return sdist_ok def main(argv=None): log.warning('pep517.check is deprecated. ' 'Consider switching to https://pypi.org/project/build/') ap = argparse.ArgumentParser() ap.add_argument( 'source_dir', help="A directory containing pyproject.toml") args = ap.parse_args(argv) enable_colourful_output() ok = check(args.source_dir) if ok: print(ansi('Checks passed', 'green')) else: print(ansi('Checks failed', 'red')) sys.exit(1) ansi_codes = { 'reset': '\x1b[0m', 'bold': '\x1b[1m', 'red': '\x1b[31m', 'green': '\x1b[32m', } def ansi(s, attr): if os.name != 'nt' and sys.stdout.isatty(): return ansi_codes[attr] + str(s) + ansi_codes['reset'] else: return str(s) if __name__ == '__main__': main() PKH]uE''^python3.10/site-packages/pip/_vendor/pep517/in_process/__pycache__/_in_process.cpython-310.pycnu[o ai+@s~dZddlmZddlmZddlZddlZddlZddlmZddl Z ddl Z ddl Z ddl Z e j ddkr@ddZd d Znd dZd d ZGd ddeZGdddeZGdddeZddZddZddZddZddZddZdd Zd!Zd"d#Zd$d%Zd&d'Zd8d(d)Zd8d*d+Z d,d-Z!Gd.d/d/eZ"Gd0d1d1eZ#d2d3Z$hd4Z%d5d6Z&e'd7kre&dSdS)9agThis is invoked in a subprocess to call the build backend hooks. It expects: - Command line args: hook_name, control_dir - Environment variables: PEP517_BUILD_BACKEND=entry.point:spec PEP517_BACKEND_PATH=paths (separated with os.pathsep) - control_dir/input.json: - {"kwargs": {...}} Results: - control_dir/output.json - {"return_val": ...} )glob) import_moduleN)joincKsHt|ddd}tj||fi|WddS1swYdS)Nwutf-8encodingopenjsondumpobjpathkwargsfr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py write_json!s"rcCs<t|ddd }t|WdS1swYdS)Nrrrr r loadrrrrr read_json%s$rcKsHt|d}tj||fddi|WddS1swYdS)Nwbr rr rrrrr+s "cCs8t|d }t|WdS1swYdS)Nrbrrrrrr/s $c@eZdZdZddZdS)BackendUnavailablez&Raised if we cannot import the backendcC ||_dSN tracebackselfr"rrr__init__6 zBackendUnavailable.__init__N__name__ __module__ __qualname____doc__r%rrrrr4 rc@r)BackendInvalidz Raised if the backend is invalidcCrr )message)r$r.rrrr%<r&zBackendInvalid.__init__Nr'rrrrr-:r,r-cs"eZdZdZdfdd ZZS) HookMissingzARaised if a hook is missing and we are not executing the fallbackNcstt||||_dSr )superr/r% hook_name)r$r1 __class__rrr%Bs zHookMissing.__init__r )r(r)r*r+r% __classcell__rrr2rr/@sr/cCs<tjtj|}tjtj|}tj||g|kS)z5Test if a file is located within the given directory.)osrnormcaseabspath commonprefix)filename directoryrrr contained_inGsr;cstjd}|r|tj}|tjdd<tjd}|d\}}}zt|Wn t y5t t w|rGt fdd|DsGtd|rV|d D]}t|qNS) zFind and load the build backendPEP517_BACKEND_PATHNrPEP517_BUILD_BACKEND:c3s|] }tj|VqdSr )r;__file__).0rrrr ^s  z!_build_backend..z(Backend was not loaded from backend-path.)r5environgetsplitpathsepsysr partitionr ImportErrorrr" format_excanyr-getattr) backend_pathZextra_pathitemsepZmod_path_Zobj_pathZ path_partrrAr_build_backendNs(        rQcCs"t}g}t|dr|d|S)zReturn the list of options features supported by the backend. Returns a list of strings. The only possible value is 'build_editable'. build_editable)rQhasattrappend)backendfeaturesrrr_supported_featuresjs   rWcC.t}z|j}W||StygYSwzfInvoke the optional get_requires_for_build_wheel hook Returns [] if the hook is not defined. )rQget_requires_for_build_wheelAttributeErrorconfig_settingsrUhookrrrrZw rZcCrX)ziInvoke the optional get_requires_for_build_editable hook Returns [] if the hook is not defined. )rQget_requires_for_build_editabler[r\rrrr`r_r`cCsPt}z|j}Wnty"|st|||}t|||YSw|||S)zInvoke optional prepare_metadata_for_build_wheel Implements a fallback by building a wheel if the hook isn't defined, unless _allow_fallback is False in which case HookMissing is raised. )rQ prepare_metadata_for_build_wheelr[r/ build_wheel_get_wheel_metadata_from_wheel)metadata_directoryr]_allow_fallbackrUr^ whl_basenamerrrras    rac Csrt}z|j}Wn+ty3|stz|j}Wn ty%tddw|||}t|||YSw|||S)zInvoke optional prepare_metadata_for_build_editable Implements a fallback by building an editable wheel if the hook isn't defined, unless _allow_fallback is False in which case HookMissing is raised. rR)r1)rQ#prepare_metadata_for_build_editabler[r/rRrc)rdr]rerUr^Z build_hookrfrrrrgs$       rgZPEP517_ALREADY_BUILT_WHEELcCs<g}|D]}td|}|r||q|r|Std)z6Identify the .dist-info folder inside a wheel ZipFile.z[^/\\]+-[^/\\]+\.dist-info/z#No .dist-info folder found in wheel)namelistrematchrT Exception)Zwhl_zipresrmrrr_dist_info_filess   rncCsddlm}ttj|tdWdn1swYtj||}||}t|}|j||dWdn1sAwY|d ddS)zExtract the metadata from a wheel. Fallback for when the build backend does not define the 'get_wheel_metadata' hook. r)ZipFilerN)rmembers/) zipfileror r5rrWHEEL_BUILT_MARKERrn extractallrF)rfrdr]roZwhl_fileZzipfZ dist_inforrrrcs  rccCsl|sdStj|}tjt|tsdSttj|d}|s&tddSt |dkr2tddS|dS)zHCheck for a wheel already built during the get_wheel_metadata hook. Nz*.whlz+Found wheel built marker, but no .whl fileszHFound multiple .whl files; unspecified behaviour. Will call build_wheel.r) r5rdirnameisfilepjoinrsrrprintlen)rdZmetadata_parentZ whl_filesrrr_find_already_built_wheels  r{cCs4t|}|rt||tj|St|||S)zInvoke the mandatory build_wheel hook. If a wheel was already built in the prepare_metadata_for_build_wheel fallback, this will copy it rather than rebuilding the wheel. )r{shutilcopy2r5rbasenamerQrb)wheel_directoryr]rd prebuilt_whlrrrrbs   rbcCsVt}z|j}Wn tytwt|}|r%t||tj |S||||S)zInvoke the optional build_editable hook. If a wheel was already built in the prepare_metadata_for_build_editable fallback, this will copy it rather than rebuilding the wheel. ) rQrRr[r/r{r|r}r5rr~)rr]rdrUr^rrrrrR s     rRcCrXrY)rQget_requires_for_build_sdistr[r\rrrrr_rc@seZdZdZdS)_DummyExceptionz(Nothing should ever raise this exceptionN)r(r)r*r+rrrrr,src@r)GotUnsupportedOperationz9For internal use when backend raises UnsupportedOperationcCrr r!r#rrrr%2r&z GotUnsupportedOperation.__init__Nr'rrrrr0r,rc Cs8t}z|||WSt|dtyttw)z&Invoke the mandatory build_sdist hook.UnsupportedOperation)rQ build_sdistrMrrr"rK)sdist_directoryr]rUrrrr6s  r> rRrgrarbrr`rZrrWc Csnttjdkr tdtjd}tjd}|tvr!td|t|}tt|d}ddd}z |di|d |d <WnktyZ}zd |d <|j |d <WYd}~nUd}~wt yt}zd |d<|j |d<WYd}~n;d}~wt y}zd |d<|j |d <WYd}~n!d}~wt y}zd |d<|jp||d<WYd}~nd}~wwt|t|ddddS)Nrz"Needs args: hook_name, control_dirruzUnknown hook: %sz input.jsonF) unsupported return_valrrT no_backendr"backend_invalid backend_errorr hook_missingmissing_hook_namez output.json)indentr)rzrHargvexit HOOK_NAMESglobalsrrxrr"r-r.rr/r1r)r1Z control_dirr^ hook_inputZjson_outerrrmainLs:     r__main__r )(r+r importlibrr r5os.pathrrxrir|rHr" version_inforrrkrr-r/r;rQrWrZr`rargrsrnrcr{rbrRrrrrrrr(rrrrsR           PKH]m9@[python3.10/site-packages/pip/_vendor/pep517/in_process/__pycache__/__init__.cpython-310.pycnu[o ai3@s`dZddlmZmZmZddlmZz ddlm Z ddZ WdSe y/eddZ YdSw)zThis is a subpackage because the directory is on sys.path for _in_process.py The subpackage should stay as empty as possible to avoid shadowing modules that the backend might import. )dirnameabspathjoin)contextmanagerNcCs ttdSNz_in_process.py) resourcespath __package__r r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/__init__.py_in_proc_script_path s r ccsttttdVdSr)pjoinrr__file__r r r r r s) __doc__os.pathrrrr contextlibrimportlib.resourcesrr ImportErrorr r r r s   PKH]"++Epython3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.pynu["""This is invoked in a subprocess to call the build backend hooks. It expects: - Command line args: hook_name, control_dir - Environment variables: PEP517_BUILD_BACKEND=entry.point:spec PEP517_BACKEND_PATH=paths (separated with os.pathsep) - control_dir/input.json: - {"kwargs": {...}} Results: - control_dir/output.json - {"return_val": ...} """ from glob import glob from importlib import import_module import json import os import os.path from os.path import join as pjoin import re import shutil import sys import traceback # This file is run as a script, and `import compat` is not zip-safe, so we # include write_json() and read_json() from compat.py. # # Handle reading and writing JSON in UTF-8, on Python 3 and 2. if sys.version_info[0] >= 3: # Python 3 def write_json(obj, path, **kwargs): with open(path, 'w', encoding='utf-8') as f: json.dump(obj, f, **kwargs) def read_json(path): with open(path, 'r', encoding='utf-8') as f: return json.load(f) else: # Python 2 def write_json(obj, path, **kwargs): with open(path, 'wb') as f: json.dump(obj, f, encoding='utf-8', **kwargs) def read_json(path): with open(path, 'rb') as f: return json.load(f) class BackendUnavailable(Exception): """Raised if we cannot import the backend""" def __init__(self, traceback): self.traceback = traceback class BackendInvalid(Exception): """Raised if the backend is invalid""" def __init__(self, message): self.message = message class HookMissing(Exception): """Raised if a hook is missing and we are not executing the fallback""" def __init__(self, hook_name=None): super(HookMissing, self).__init__(hook_name) self.hook_name = hook_name def contained_in(filename, directory): """Test if a file is located within the given directory.""" filename = os.path.normcase(os.path.abspath(filename)) directory = os.path.normcase(os.path.abspath(directory)) return os.path.commonprefix([filename, directory]) == directory def _build_backend(): """Find and load the build backend""" # Add in-tree backend directories to the front of sys.path. backend_path = os.environ.get('PEP517_BACKEND_PATH') if backend_path: extra_pathitems = backend_path.split(os.pathsep) sys.path[:0] = extra_pathitems ep = os.environ['PEP517_BUILD_BACKEND'] mod_path, _, obj_path = ep.partition(':') try: obj = import_module(mod_path) except ImportError: raise BackendUnavailable(traceback.format_exc()) if backend_path: if not any( contained_in(obj.__file__, path) for path in extra_pathitems ): raise BackendInvalid("Backend was not loaded from backend-path") if obj_path: for path_part in obj_path.split('.'): obj = getattr(obj, path_part) return obj def _supported_features(): """Return the list of options features supported by the backend. Returns a list of strings. The only possible value is 'build_editable'. """ backend = _build_backend() features = [] if hasattr(backend, "build_editable"): features.append("build_editable") return features def get_requires_for_build_wheel(config_settings): """Invoke the optional get_requires_for_build_wheel hook Returns [] if the hook is not defined. """ backend = _build_backend() try: hook = backend.get_requires_for_build_wheel except AttributeError: return [] else: return hook(config_settings) def get_requires_for_build_editable(config_settings): """Invoke the optional get_requires_for_build_editable hook Returns [] if the hook is not defined. """ backend = _build_backend() try: hook = backend.get_requires_for_build_editable except AttributeError: return [] else: return hook(config_settings) def prepare_metadata_for_build_wheel( metadata_directory, config_settings, _allow_fallback): """Invoke optional prepare_metadata_for_build_wheel Implements a fallback by building a wheel if the hook isn't defined, unless _allow_fallback is False in which case HookMissing is raised. """ backend = _build_backend() try: hook = backend.prepare_metadata_for_build_wheel except AttributeError: if not _allow_fallback: raise HookMissing() whl_basename = backend.build_wheel(metadata_directory, config_settings) return _get_wheel_metadata_from_wheel(whl_basename, metadata_directory, config_settings) else: return hook(metadata_directory, config_settings) def prepare_metadata_for_build_editable( metadata_directory, config_settings, _allow_fallback): """Invoke optional prepare_metadata_for_build_editable Implements a fallback by building an editable wheel if the hook isn't defined, unless _allow_fallback is False in which case HookMissing is raised. """ backend = _build_backend() try: hook = backend.prepare_metadata_for_build_editable except AttributeError: if not _allow_fallback: raise HookMissing() try: build_hook = backend.build_editable except AttributeError: raise HookMissing(hook_name='build_editable') else: whl_basename = build_hook(metadata_directory, config_settings) return _get_wheel_metadata_from_wheel(whl_basename, metadata_directory, config_settings) else: return hook(metadata_directory, config_settings) WHEEL_BUILT_MARKER = 'PEP517_ALREADY_BUILT_WHEEL' def _dist_info_files(whl_zip): """Identify the .dist-info folder inside a wheel ZipFile.""" res = [] for path in whl_zip.namelist(): m = re.match(r'[^/\\]+-[^/\\]+\.dist-info/', path) if m: res.append(path) if res: return res raise Exception("No .dist-info folder found in wheel") def _get_wheel_metadata_from_wheel( whl_basename, metadata_directory, config_settings): """Extract the metadata from a wheel. Fallback for when the build backend does not define the 'get_wheel_metadata' hook. """ from zipfile import ZipFile with open(os.path.join(metadata_directory, WHEEL_BUILT_MARKER), 'wb'): pass # Touch marker file whl_file = os.path.join(metadata_directory, whl_basename) with ZipFile(whl_file) as zipf: dist_info = _dist_info_files(zipf) zipf.extractall(path=metadata_directory, members=dist_info) return dist_info[0].split('/')[0] def _find_already_built_wheel(metadata_directory): """Check for a wheel already built during the get_wheel_metadata hook. """ if not metadata_directory: return None metadata_parent = os.path.dirname(metadata_directory) if not os.path.isfile(pjoin(metadata_parent, WHEEL_BUILT_MARKER)): return None whl_files = glob(os.path.join(metadata_parent, '*.whl')) if not whl_files: print('Found wheel built marker, but no .whl files') return None if len(whl_files) > 1: print('Found multiple .whl files; unspecified behaviour. ' 'Will call build_wheel.') return None # Exactly one .whl file return whl_files[0] def build_wheel(wheel_directory, config_settings, metadata_directory=None): """Invoke the mandatory build_wheel hook. If a wheel was already built in the prepare_metadata_for_build_wheel fallback, this will copy it rather than rebuilding the wheel. """ prebuilt_whl = _find_already_built_wheel(metadata_directory) if prebuilt_whl: shutil.copy2(prebuilt_whl, wheel_directory) return os.path.basename(prebuilt_whl) return _build_backend().build_wheel(wheel_directory, config_settings, metadata_directory) def build_editable(wheel_directory, config_settings, metadata_directory=None): """Invoke the optional build_editable hook. If a wheel was already built in the prepare_metadata_for_build_editable fallback, this will copy it rather than rebuilding the wheel. """ backend = _build_backend() try: hook = backend.build_editable except AttributeError: raise HookMissing() else: prebuilt_whl = _find_already_built_wheel(metadata_directory) if prebuilt_whl: shutil.copy2(prebuilt_whl, wheel_directory) return os.path.basename(prebuilt_whl) return hook(wheel_directory, config_settings, metadata_directory) def get_requires_for_build_sdist(config_settings): """Invoke the optional get_requires_for_build_wheel hook Returns [] if the hook is not defined. """ backend = _build_backend() try: hook = backend.get_requires_for_build_sdist except AttributeError: return [] else: return hook(config_settings) class _DummyException(Exception): """Nothing should ever raise this exception""" class GotUnsupportedOperation(Exception): """For internal use when backend raises UnsupportedOperation""" def __init__(self, traceback): self.traceback = traceback def build_sdist(sdist_directory, config_settings): """Invoke the mandatory build_sdist hook.""" backend = _build_backend() try: return backend.build_sdist(sdist_directory, config_settings) except getattr(backend, 'UnsupportedOperation', _DummyException): raise GotUnsupportedOperation(traceback.format_exc()) HOOK_NAMES = { 'get_requires_for_build_wheel', 'prepare_metadata_for_build_wheel', 'build_wheel', 'get_requires_for_build_editable', 'prepare_metadata_for_build_editable', 'build_editable', 'get_requires_for_build_sdist', 'build_sdist', '_supported_features', } def main(): if len(sys.argv) < 3: sys.exit("Needs args: hook_name, control_dir") hook_name = sys.argv[1] control_dir = sys.argv[2] if hook_name not in HOOK_NAMES: sys.exit("Unknown hook: %s" % hook_name) hook = globals()[hook_name] hook_input = read_json(pjoin(control_dir, 'input.json')) json_out = {'unsupported': False, 'return_val': None} try: json_out['return_val'] = hook(**hook_input['kwargs']) except BackendUnavailable as e: json_out['no_backend'] = True json_out['traceback'] = e.traceback except BackendInvalid as e: json_out['backend_invalid'] = True json_out['backend_error'] = e.message except GotUnsupportedOperation as e: json_out['unsupported'] = True json_out['traceback'] = e.traceback except HookMissing as e: json_out['hook_missing'] = True json_out['missing_hook_name'] = e.hook_name or hook_name write_json(json_out, pjoin(control_dir, 'output.json'), indent=2) if __name__ == '__main__': main() PKH]33Bpython3.10/site-packages/pip/_vendor/pep517/in_process/__init__.pynu["""This is a subpackage because the directory is on sys.path for _in_process.py The subpackage should stay as empty as possible to avoid shadowing modules that the backend might import. """ from os.path import dirname, abspath, join as pjoin from contextlib import contextmanager try: import importlib.resources as resources def _in_proc_script_path(): return resources.path(__package__, '_in_process.py') except ImportError: @contextmanager def _in_proc_script_path(): yield pjoin(dirname(abspath(__file__)), '_in_process.py') PKH] 55python3.10/site-packages/pip/_vendor/pep517/compat.pynu["""Python 2/3 compatibility""" import io import json import sys # Handle reading and writing JSON in UTF-8, on Python 3 and 2. if sys.version_info[0] >= 3: # Python 3 def write_json(obj, path, **kwargs): with open(path, 'w', encoding='utf-8') as f: json.dump(obj, f, **kwargs) def read_json(path): with open(path, 'r', encoding='utf-8') as f: return json.load(f) else: # Python 2 def write_json(obj, path, **kwargs): with open(path, 'wb') as f: json.dump(obj, f, encoding='utf-8', **kwargs) def read_json(path): with open(path, 'rb') as f: return json.load(f) # FileNotFoundError try: FileNotFoundError = FileNotFoundError except NameError: FileNotFoundError = IOError if sys.version_info < (3, 6): from toml import load as _toml_load # noqa: F401 def toml_load(f): w = io.TextIOWrapper(f, encoding="utf8", newline="") try: return _toml_load(w) finally: w.detach() from toml import TomlDecodeError as TOMLDecodeError # noqa: F401 else: from pip._vendor.tomli import load as toml_load # noqa: F401 from pip._vendor.tomli import TOMLDecodeError # noqa: F401 PKH]"7python3.10/site-packages/pip/_vendor/pep517/envbuild.pynu["""Build wheels/sdists by installing build deps to a temporary environment. """ import io import os import logging import shutil from subprocess import check_call import sys from sysconfig import get_paths from tempfile import mkdtemp from .compat import toml_load from .wrappers import Pep517HookCaller, LoggerWrapper log = logging.getLogger(__name__) def _load_pyproject(source_dir): with io.open( os.path.join(source_dir, 'pyproject.toml'), 'rb', ) as f: pyproject_data = toml_load(f) buildsys = pyproject_data['build-system'] return ( buildsys['requires'], buildsys['build-backend'], buildsys.get('backend-path'), ) class BuildEnvironment(object): """Context manager to install build deps in a simple temporary environment Based on code I wrote for pip, which is MIT licensed. """ # Copyright (c) 2008-2016 The pip developers (see AUTHORS.txt file) # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. path = None def __init__(self, cleanup=True): self._cleanup = cleanup def __enter__(self): self.path = mkdtemp(prefix='pep517-build-env-') log.info('Temporary build environment: %s', self.path) self.save_path = os.environ.get('PATH', None) self.save_pythonpath = os.environ.get('PYTHONPATH', None) install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix' install_dirs = get_paths(install_scheme, vars={ 'base': self.path, 'platbase': self.path, }) scripts = install_dirs['scripts'] if self.save_path: os.environ['PATH'] = scripts + os.pathsep + self.save_path else: os.environ['PATH'] = scripts + os.pathsep + os.defpath if install_dirs['purelib'] == install_dirs['platlib']: lib_dirs = install_dirs['purelib'] else: lib_dirs = install_dirs['purelib'] + os.pathsep + \ install_dirs['platlib'] if self.save_pythonpath: os.environ['PYTHONPATH'] = lib_dirs + os.pathsep + \ self.save_pythonpath else: os.environ['PYTHONPATH'] = lib_dirs return self def pip_install(self, reqs): """Install dependencies into this env by calling pip in a subprocess""" if not reqs: return log.info('Calling pip to install %s', reqs) cmd = [ sys.executable, '-m', 'pip', 'install', '--ignore-installed', '--prefix', self.path] + list(reqs) check_call( cmd, stdout=LoggerWrapper(log, logging.INFO), stderr=LoggerWrapper(log, logging.ERROR), ) def __exit__(self, exc_type, exc_val, exc_tb): needs_cleanup = ( self._cleanup and self.path is not None and os.path.isdir(self.path) ) if needs_cleanup: shutil.rmtree(self.path) if self.save_path is None: os.environ.pop('PATH', None) else: os.environ['PATH'] = self.save_path if self.save_pythonpath is None: os.environ.pop('PYTHONPATH', None) else: os.environ['PYTHONPATH'] = self.save_pythonpath def build_wheel(source_dir, wheel_dir, config_settings=None): """Build a wheel from a source directory using PEP 517 hooks. :param str source_dir: Source directory containing pyproject.toml :param str wheel_dir: Target directory to create wheel in :param dict config_settings: Options to pass to build backend This is a blocking function which will run pip in a subprocess to install build requirements. """ if config_settings is None: config_settings = {} requires, backend, backend_path = _load_pyproject(source_dir) hooks = Pep517HookCaller(source_dir, backend, backend_path) with BuildEnvironment() as env: env.pip_install(requires) reqs = hooks.get_requires_for_build_wheel(config_settings) env.pip_install(reqs) return hooks.build_wheel(wheel_dir, config_settings) def build_sdist(source_dir, sdist_dir, config_settings=None): """Build an sdist from a source directory using PEP 517 hooks. :param str source_dir: Source directory containing pyproject.toml :param str sdist_dir: Target directory to place sdist in :param dict config_settings: Options to pass to build backend This is a blocking function which will run pip in a subprocess to install build requirements. """ if config_settings is None: config_settings = {} requires, backend, backend_path = _load_pyproject(source_dir) hooks = Pep517HookCaller(source_dir, backend, backend_path) with BuildEnvironment() as env: env.pip_install(requires) reqs = hooks.get_requires_for_build_sdist(config_settings) env.pip_install(reqs) return hooks.build_sdist(sdist_dir, config_settings) PKH] V7python3.10/site-packages/pip/_vendor/pep517/colorlog.pynu["""Nicer log formatting with colours. Code copied from Tornado, Apache licensed. """ # Copyright 2012 Facebook # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging import sys try: import curses except ImportError: curses = None def _stderr_supports_color(): color = False if curses and hasattr(sys.stderr, 'isatty') and sys.stderr.isatty(): try: curses.setupterm() if curses.tigetnum("colors") > 0: color = True except Exception: pass return color class LogFormatter(logging.Formatter): """Log formatter with colour support """ DEFAULT_COLORS = { logging.INFO: 2, # Green logging.WARNING: 3, # Yellow logging.ERROR: 1, # Red logging.CRITICAL: 1, } def __init__(self, color=True, datefmt=None): r""" :arg bool color: Enables color support. :arg string fmt: Log message format. It will be applied to the attributes dict of log records. The text between ``%(color)s`` and ``%(end_color)s`` will be colored depending on the level if color support is on. :arg dict colors: color mappings from logging level to terminal color code :arg string datefmt: Datetime format. Used for formatting ``(asctime)`` placeholder in ``prefix_fmt``. .. versionchanged:: 3.2 Added ``fmt`` and ``datefmt`` arguments. """ logging.Formatter.__init__(self, datefmt=datefmt) self._colors = {} if color and _stderr_supports_color(): # The curses module has some str/bytes confusion in # python3. Until version 3.2.3, most methods return # bytes, but only accept strings. In addition, we want to # output these strings with the logging module, which # works with unicode strings. The explicit calls to # unicode() below are harmless in python2 but will do the # right conversion in python 3. fg_color = (curses.tigetstr("setaf") or curses.tigetstr("setf") or "") if (3, 0) < sys.version_info < (3, 2, 3): fg_color = str(fg_color, "ascii") for levelno, code in self.DEFAULT_COLORS.items(): self._colors[levelno] = str( curses.tparm(fg_color, code), "ascii") self._normal = str(curses.tigetstr("sgr0"), "ascii") scr = curses.initscr() self.termwidth = scr.getmaxyx()[1] curses.endwin() else: self._normal = '' # Default width is usually 80, but too wide is # worse than too narrow self.termwidth = 70 def formatMessage(self, record): mlen = len(record.message) right_text = '{initial}-{name}'.format(initial=record.levelname[0], name=record.name) if mlen + len(right_text) < self.termwidth: space = ' ' * (self.termwidth - (mlen + len(right_text))) else: space = ' ' if record.levelno in self._colors: start_color = self._colors[record.levelno] end_color = self._normal else: start_color = end_color = '' return record.message + space + start_color + right_text + end_color def enable_colourful_output(level=logging.INFO): handler = logging.StreamHandler() handler.setFormatter(LogFormatter()) logging.root.addHandler(handler) logging.root.setLevel(level) PKH]B7python3.10/site-packages/pip/_vendor/pep517/__init__.pynu["""Wrappers to build Python packages using PEP 517 hooks """ __version__ = '0.12.0' from .wrappers import * # noqa: F401, F403 PKH];ϸFii7python3.10/site-packages/pip/_vendor/pep517/dirtools.pynu[import os import io import contextlib import tempfile import shutil import errno import zipfile @contextlib.contextmanager def tempdir(): """Create a temporary directory in a context manager.""" td = tempfile.mkdtemp() try: yield td finally: shutil.rmtree(td) def mkdir_p(*args, **kwargs): """Like `mkdir`, but does not raise an exception if the directory already exists. """ try: return os.mkdir(*args, **kwargs) except OSError as exc: if exc.errno != errno.EEXIST: raise def dir_to_zipfile(root): """Construct an in-memory zip file for a directory.""" buffer = io.BytesIO() zip_file = zipfile.ZipFile(buffer, 'w') for root, dirs, files in os.walk(root): for path in dirs: fs_path = os.path.join(root, path) rel_path = os.path.relpath(fs_path, root) zip_file.writestr(rel_path + '/', '') for path in files: fs_path = os.path.join(root, path) rel_path = os.path.relpath(fs_path, root) zip_file.write(fs_path, rel_path) return zip_file PKH]EeL L \python3.10/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-310.pycnu[o ai @sdZddlmZddlZGdddejZGdddejZGdd d ejZGd d d eejZGd d d eejZej dej ej eeeedZ dZ ee ZdS)z webencodings.x_user_defined ~~~~~~~~~~~~~~~~~~~~~~~~~~~ An implementation of the x-user-defined encoding. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. )unicode_literalsNc@s eZdZdddZdddZdS)CodecstrictcCt||tSN)codecscharmap_encodeencoding_tableselfinputerrorsr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/webencodings/x_user_defined.pyencodez Codec.encodecCrr)rcharmap_decodedecoding_tabler rrrdecoderz Codec.decodeN)r)__name__ __module__ __qualname__rrrrrrrs rc@eZdZdddZdS)IncrementalEncoderFcCt||jtdSNr)rrr r r r finalrrrrzIncrementalEncoder.encodeNF)rrrrrrrrrrc@r)IncrementalDecoderFcCrr)rrr rrrrrr$rzIncrementalDecoder.decodeNr)rrrrrrrrr!#r r!c@ eZdZdS) StreamWriterNrrrrrrrr#(r#c@r") StreamReaderNr$rrrrr&,r%r&zx-user-defined)namerrincrementalencoderincrementaldecoder streamreader streamwriteru  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)__doc__ __future__rrrrr!r#r& CodecInforr codec_infor charmap_buildr rrrrs,  PKH];>&>&Vpython3.10/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-310.pycnu[o aiS)@sdZddlmZddlZddlmZdZddd d d ZiZd d Z ddZ ddZ Gddde Z e dZe dZe dZd+ddZddZedfddZd+dd Zd!d"Zedfd#d$Zd%d&ZGd'd(d(e ZGd)d*d*e ZdS),a webencodings ~~~~~~~~~~~~ This is a Python implementation of the `WHATWG Encoding standard `. See README for details. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. )unicode_literalsN)LABELSz0.5.1z iso-8859-8z mac-cyrillicz mac-romancp874)z iso-8859-8-izx-mac-cyrillic macintoshz windows-874cCs|ddS)a9Transform (only) ASCII letters to lower case: A-Z is mapped to a-z. :param string: An Unicode string. :returns: A new Unicode string. This is used for `ASCII case-insensitive `_ matching of encoding labels. The same matching is also used, among other things, for `CSS keywords `_. This is different from the :meth:`~py:str.lower` method of Unicode strings which also affect non-ASCII characters, sometimes mapping them into the ASCII range: >>> keyword = u'Bac\N{KELVIN SIGN}ground' >>> assert keyword.lower() == u'background' >>> assert ascii_lower(keyword) != keyword.lower() >>> assert ascii_lower(keyword) == u'bac\N{KELVIN SIGN}ground' utf8)encodelowerdecode)stringr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/webencodings/__init__.py ascii_lower#srcCsxt|d}t|}|durdSt|}|dur:|dkr&ddlm}n t||}t |}t ||}|t|<|S)u< Look for an encoding by its label. This is the spec’s `get an encoding `_ algorithm. Supported labels are listed there. :param label: A string. :returns: An :class:`Encoding` object, or :obj:`None` for an unknown label. z Nzx-user-definedr) codec_info) rstriprgetCACHEx_user_definedr PYTHON_NAMEScodecslookupEncoding)labelnameencodingr python_namer r r r=s     rcCs.t|dr|St|}|durtd||S)z Accept either an encoding object or label. :param encoding: An :class:`Encoding` object or a label string. :returns: An :class:`Encoding` object. :raises: :exc:`~exceptions.LookupError` for an unknown label. rNzUnknown encoding label: %r)hasattrr LookupError)encoding_or_labelrr r r _get_encoding[s  rc@s eZdZdZddZddZdS)raOReresents a character encoding such as UTF-8, that can be used for decoding or encoding. .. attribute:: name Canonical name of the encoding .. attribute:: codec_info The actual implementation of the encoding, a stdlib :class:`~codecs.CodecInfo` object. See :func:`codecs.register`. cCs||_||_dSN)rr)selfrrr r r __init__|s zEncoding.__init__cCs d|jS)Nz )r)r!r r r __repr__s zEncoding.__repr__N)__name__ __module__ __qualname____doc__r"r#r r r r rms rzutf-8zutf-16lezutf-16bereplacecCs2t|}t|\}}|p |}|j||d|fS)a Decode a single string. :param input: A byte string :param fallback_encoding: An :class:`Encoding` object or a label string. The encoding to use if :obj:`input` does note have a BOM. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :return: A ``(output, encoding)`` tuple of an Unicode string and an :obj:`Encoding`. r)r _detect_bomrr )inputfallback_encodingerrors bom_encodingrr r r r s r cCsV|dr t|ddfS|drt|ddfS|dr't|ddfSd|fS)zBReturn (bom_encoding, input), with any BOM removed from the input.sNss) startswith_UTF16LE_UTF16BEUTF8)r*r r r r)s   r)strictcCst|j||dS)a; Encode a single string. :param input: An Unicode string. :param encoding: An :class:`Encoding` object or a label string. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :return: A byte string. r)rrr)r*rr,r r r rs rcCs$t||}t||}t|}||fS)a "Pull"-based decoder. :param input: An iterable of byte strings. The input is first consumed just enough to determine the encoding based on the precense of a BOM, then consumed on demand when the return value is. :param fallback_encoding: An :class:`Encoding` object or a label string. The encoding to use if :obj:`input` does note have a BOM. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :returns: An ``(output, encoding)`` tuple. :obj:`output` is an iterable of Unicode strings, :obj:`encoding` is the :obj:`Encoding` that is being used. )IncrementalDecoder_iter_decode_generatornext)r*r+r,decoder generatorrr r r iter_decodes  r:ccs|j}t|}|D]}||}|r"|jdusJ|jV|Vnq |ddd}|jdus0J|jV|r9|VdS|D] }||}|rH|Vq=|ddd}|rV|VdSdS)zqReturn a generator that first yields the :obj:`Encoding`, then yields output chukns as Unicode strings. NTfinal)r iterr)r*r8r chunckoutputr r r r6s4   r6cCst||j}t||S)uY “Pull”-based encoder. :param input: An iterable of Unicode strings. :param encoding: An :class:`Encoding` object or a label string. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :returns: An iterable of byte strings. )IncrementalEncoderr_iter_encode_generator)r*rr,rr r r iter_encodes rCccs<|D] }||}|r|Vq|ddd}|r|VdSdS)NTr<r )r*rr?r@r r r rBs  rBc@s$eZdZdZd ddZd ddZdS) r5uO “Push”-based decoder. :param fallback_encoding: An :class:`Encoding` object or a label string. The encoding to use if :obj:`input` does note have a BOM. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. r(cCs&t||_||_d|_d|_d|_dS)Nr;)r_fallback_encoding_errors_buffer_decoderr)r!r+r,r r r r"s  zIncrementalDecoder.__init__FcCs||j}|dur |||S|j|}t|\}}|dur+t|dkr(|s(||_dS|j}|j|jj}||_||_ |||S)zDecode one chunk of the input. :param input: A byte string. :param final: Indicate that no more input is available. Must be :obj:`True` if this is the last call. :returns: An Unicode string. Nr/rD) rHrGr)lenrErincrementaldecoderrFr r)r!r*r=r8rr r r r 's     zIncrementalDecoder.decodeNr()F)r$r%r&r'r"r r r r r r5s  r5c@seZdZdZedfddZdS)rAu “Push”-based encoder. :param encoding: An :class:`Encoding` object or a label string. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. .. method:: encode(input, final=False) :param input: An Unicode string. :param final: Indicate that no more input is available. Must be :obj:`True` if this is the last call. :returns: A byte string. r4cCst|}|j|j|_dSr )rrincrementalencoderr)r!rr,r r r r"TszIncrementalEncoder.__init__N)r$r%r&r'r3r"r r r r rACsrArK)r' __future__rrlabelsrVERSIONrrrrrobjectrr3r1r2r r)rr:r6rCrBr5rAr r r r s6      3PKH]VޠTpython3.10/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-310.pycnu[o ai# @sdZidddddddddddddddd d d d d d d d d d d dd dd dd ddiddddddddddddddddddddddddddddd dd!dd"did#d$d%d$d$d$d&d$d'd$d(d$d)d$d*d$d+d,d-d,d.d,d/d,d0d,d1d,d,d,d2d,d3d,id4d,d5d,d6d,d7d,d8d,d9d:d;d:dd:d:d:d?d:d@d:dAd:dBd:dCd:dDd:idEdFdGdFdHdFdFdFdIdFdJdFdKdFdLdFdMdFdNdFdOdFdPdQdQdQdRdQdSdTdTdTdUdTidVdTdWdTdXdTdYdTdZdZd[dZd\dZd]d]d^d]d_d]d`dadadadbdadcdadddadedadfdfidgdhdidhdjdhdhdhdkdhdldldmdndodndndndpdndqdrdsdrdtdrdudrdvdrdrdrdwdxidxdxdydxdzd{d{d{d|d{d}d~dd~dd~dd~dd~dd~dd~dd~dd~dd~dd~dd~idd~dd~dd~d~d~dd~ddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddddddddddddiddddddddddddddddddddddddȓddȓddȓddȓddȓddȓdddddddddddќ ZdS)z webencodings.labels ~~~~~~~~~~~~~~~~~~~ Map encoding labels to their name. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. zunicode-1-1-utf-8zutf-8utf8866ibm866cp866csibm866 csisolatin2z iso-8859-2z iso-ir-101z iso8859-2iso88592z iso_8859-2ziso_8859-2:1987l2latin2 csisolatin3z iso-8859-3z iso-ir-109z iso8859-3iso88593z iso_8859-3ziso_8859-3:1988l3latin3 csisolatin4z iso-8859-4z iso-ir-110z iso8859-4iso88594z iso_8859-4ziso_8859-4:1988l4latin4csisolatincyrillicz iso-8859-5cyrillicz iso-ir-144z iso8859-5iso88595z iso_8859-5ziso_8859-5:1988arabicz iso-8859-6zasmo-708 csiso88596e csiso88596icsisolatinarabiczecma-114z iso-8859-6-ez iso-8859-6-iz iso-ir-127z iso8859-6iso88596z iso_8859-6ziso_8859-6:1987csisolatingreekz iso-8859-7zecma-118elot_928greekgreek8z iso-ir-126z iso8859-7iso88597z iso_8859-7ziso_8859-7:1987 sun_eu_greek csiso88598ez iso-8859-8csisolatinhebrewhebrewz iso-8859-8-ez iso-ir-138z iso8859-8iso88598z iso_8859-8ziso_8859-8:1988visual csiso88598iz iso-8859-8-ilogical csisolatin6z iso-8859-10z iso-ir-157z iso8859-10 iso885910l6latin6z iso-8859-13z iso8859-13 iso885913z iso-8859-14z iso8859-14 iso885914 csisolatin9z iso-8859-15z iso8859-15 iso885915z iso_8859-15l9z iso-8859-16cskoi8rzkoi8-rkoikoi8koi8_rzkoi8-u csmacintosh macintoshmacz x-mac-romanzdos-874z windows-874z iso-8859-11z iso8859-11 iso885911ztis-620cp1250z windows-1250zx-cp1250cp1251z windows-1251zx-cp1251zansi_x3.4-1968z windows-1252asciicp1252cp819 csisolatin1ibm819z iso-8859-1z iso-ir-100z iso8859-1iso88591z iso_8859-1ziso_8859-1:1987l1latin1zus-asciizx-cp1252cp1253z windows-1253zx-cp1253cp1254z windows-1254 csisolatin5z iso-8859-9z iso-ir-148z iso8859-9iso88599z iso_8859-9ziso_8859-9:1989l5latin5zx-cp1254cp1255z windows-1255zx-cp1255cp1256z windows-1256zx-cp1256cp1257z windows-1257zx-cp1257cp1258z windows-1258zx-cp1258zx-mac-cyrilliczx-mac-ukrainianchinesegbkcsgb2312csiso58gb231280gb2312gb_2312z gb_2312-80z iso-ir-58zx-gbkgb18030z hz-gb-2312big5z big5-hkscszcn-big5csbig5zx-x-big5cseucpkdfmtjapanesezeuc-jpzx-euc-jp csiso2022jpz iso-2022-jp csshiftjis shift_jisms_kanjiz shift-jissjisz windows-31jzx-sjiscseuckrzeuc-kr csksc56011987z iso-ir-149koreanzks_c_5601-1987 iso-2022-krutf-16beutf-16lex-user-defined) zks_c_5601-1989ksc5601ksc_5601z windows-949 csiso2022krr^r_zutf-16r`raN)__doc__LABELSrgrg/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/webencodings/labels.pys      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN PKH]GVpython3.10/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-310.pycnu[o ai@shdZddlZzddlmZWneyddlmZYnwddZddZedkr2e ed dSdS) z webencodings.mklabels ~~~~~~~~~~~~~~~~~~~~~ Regenarate the webencodings.labels module. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. N)urlopencCs||ksJ|SN)lower)stringr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/webencodings/mklabels.py assert_lowersrcsfdg}ddtt|dD}tdd|D|fdd|D|dd |S) Na""" webencodings.labels ~~~~~~~~~~~~~~~~~~~ Map encoding labels to their name. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. """ # XXX Do not edit! # This file is automatically generated by mklabels.py LABELS = { cSsLg|]"}|dD]}|dD]}tt|dt|ddfqqqS) encodingslabelsuname)reprrlstrip).0categoryencodinglabelrrr ,s zgenerate..asciicss|] \}}t|VqdSrlenrrr rrr 2szgenerate..c3s.|]\}}d|dt||fVqdS)z %s:%s %s,  Nrrmax_lenrrr3s  }) jsonloadsrreaddecodemaxextendappendjoin)urlpartsr rrrgenerates  r(__main__z.http://encoding.spec.whatwg.org/encodings.json) __doc__rurllibr ImportErrorurllib.requestrr(__name__printrrrrs  !PKH]Spython3.10/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-310.pycnu[o ai@sdZddlmZddlmZmZmZmZmZm Z m Z m Z m Z ddZ ddZd d Zd d Zd dZddZddZddZddZdS)z webencodings.tests ~~~~~~~~~~~~~~~~~~ A basic test suite for Encoding. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. )unicode_literals) lookupLABELSdecodeencode iter_decode iter_encodeIncrementalDecoderIncrementalEncoderUTF8cOs4z ||i|Wn |yYdSwtd|)NzDid not raise %s.)AssertionError) exceptionfunctionargskwargsr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/webencodings/tests.py assert_raisess   rcCs tdjdks JtdjdksJtdjdksJtdjdks$Jtdjdks-Jtdjdks6Jtdjdks?JtddusGJtddusOJtd jd ksXJtd jd ksaJtd jd ksjJtd jd kssJtddus{JtddusJdS)Nzutf-8zUtf-8zUTF-8utf8zutf8 z utf8 u8uutf-8 zUS-ASCIIz windows-1252z iso-8859-1latin1ZLATIN1zlatin-1uLATİN1)rnamerrrr test_labelssrcCstD]m}td|dt|fksJtd|dksJdD]"}tdg||\}}t|gks0Jttdg||gks>Jqt|}|ddksLJ|jddddksWJt|}|ddksdJ|jddddksoJqt t D] }t|j |ksJqvdS)N)rr T)final) rrrrrlistr r r setvaluesr)labelrepeatoutput_decoderencoderrrrrtest_all_labels0s r'cCsTtttddtttddtttgdtttgdtttdtttddS)Néinvalidé)r LookupErrorrrrr r r rrrrtest_invalid_labelCs  r,cCstdddtdfks JtdtddtdfksJtdddtdfks)Jtdtdtdfks6JtdddtdfksCJtd ddtdfksPJtd ddtd fks]Jtd ddtd fksjJtdddtd fkswJtdddtd fksJtdddtd fksJtdddtd fksJtdddtd fksJtdddtd fksJtdddtd fksJtdddtd fksJdS)Nru€érr*asciiér(utf-16beutf-16lesuszUTF-16BEzUTF-16LEzUTF-16)rrr rrrr test_decodeLs r7cCsptdddks JtdddksJtdddksJtdddks$Jtdddks-Jtdd d ks6JdS) Nr*rrr.utf-16r6r4r2r5)rrrrr test_encodebs r:cCsldd}|gddks J|dgddksJ|dgddks!J|dgdd ks+J|d d gdd ks6J|d d gdd ksAJ|dgddksKJ|dgddksUJ|gdddks`J|gdddkskJ|gdddksvJ|dgddksJ|dgddksJ|dgddksJ|dgddksJ|gdddksJ|gdddksJdS)NcSst||\}}d|S)Nr)rjoin)inputfallback_encodingr# _encodingrrriter_decode_to_stringls z/test_iter_decode..iter_decode_to_stringrrrr8r*shelloZhelloshelloshellor.r0r())rBarCua�)rrrsrDrBsuï»r1r3)rrrs)rshr@x-user-defineduhllor)r?rrrtest_iter_decodeksL rJcCsdtgddks JdtdgddksJdtdgddks&Jdtgdddks4JdtgdddksBJdtgdd dksPJdtgdd d ks^Jdtgd d dkslJdS)Nrrrr*r8)rr*rrr9r6r4r2r5)ruhrZllorIshllo)r;r rrrrtest_iter_encodes  rKcCs@d}d}d}d}t|d|tdfksJt|d|ksJdS)Ns2, O#ɻtϨu2, O#tsaaZaarI)rrr)encodeddecodedrrrtest_x_user_defineds rNN)__doc__ __future__rrrrrrrr r r r rrr'r,r7r:rJrKrNrrrrs ,    PKH]P1=python3.10/site-packages/pip/_vendor/webencodings/mklabels.pynu[""" webencodings.mklabels ~~~~~~~~~~~~~~~~~~~~~ Regenarate the webencodings.labels module. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. """ import json try: from urllib import urlopen except ImportError: from urllib.request import urlopen def assert_lower(string): assert string == string.lower() return string def generate(url): parts = ['''\ """ webencodings.labels ~~~~~~~~~~~~~~~~~~~ Map encoding labels to their name. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. """ # XXX Do not edit! # This file is automatically generated by mklabels.py LABELS = { '''] labels = [ (repr(assert_lower(label)).lstrip('u'), repr(encoding['name']).lstrip('u')) for category in json.loads(urlopen(url).read().decode('ascii')) for encoding in category['encodings'] for label in encoding['labels']] max_len = max(len(label) for label, name in labels) parts.extend( ' %s:%s %s,\n' % (label, ' ' * (max_len - len(label)), name) for label, name in labels) parts.append('}') return ''.join(parts) if __name__ == '__main__': print(generate('http://encoding.spec.whatwg.org/encodings.json')) PKH]g8p:python3.10/site-packages/pip/_vendor/webencodings/tests.pynu[# coding: utf-8 """ webencodings.tests ~~~~~~~~~~~~~~~~~~ A basic test suite for Encoding. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. """ from __future__ import unicode_literals from . import (lookup, LABELS, decode, encode, iter_decode, iter_encode, IncrementalDecoder, IncrementalEncoder, UTF8) def assert_raises(exception, function, *args, **kwargs): try: function(*args, **kwargs) except exception: return else: # pragma: no cover raise AssertionError('Did not raise %s.' % exception) def test_labels(): assert lookup('utf-8').name == 'utf-8' assert lookup('Utf-8').name == 'utf-8' assert lookup('UTF-8').name == 'utf-8' assert lookup('utf8').name == 'utf-8' assert lookup('utf8').name == 'utf-8' assert lookup('utf8 ').name == 'utf-8' assert lookup(' \r\nutf8\t').name == 'utf-8' assert lookup('u8') is None # Python label. assert lookup('utf-8 ') is None # Non-ASCII white space. assert lookup('US-ASCII').name == 'windows-1252' assert lookup('iso-8859-1').name == 'windows-1252' assert lookup('latin1').name == 'windows-1252' assert lookup('LATIN1').name == 'windows-1252' assert lookup('latin-1') is None assert lookup('LATİN1') is None # ASCII-only case insensitivity. def test_all_labels(): for label in LABELS: assert decode(b'', label) == ('', lookup(label)) assert encode('', label) == b'' for repeat in [0, 1, 12]: output, _ = iter_decode([b''] * repeat, label) assert list(output) == [] assert list(iter_encode([''] * repeat, label)) == [] decoder = IncrementalDecoder(label) assert decoder.decode(b'') == '' assert decoder.decode(b'', final=True) == '' encoder = IncrementalEncoder(label) assert encoder.encode('') == b'' assert encoder.encode('', final=True) == b'' # All encoding names are valid labels too: for name in set(LABELS.values()): assert lookup(name).name == name def test_invalid_label(): assert_raises(LookupError, decode, b'\xEF\xBB\xBF\xc3\xa9', 'invalid') assert_raises(LookupError, encode, 'é', 'invalid') assert_raises(LookupError, iter_decode, [], 'invalid') assert_raises(LookupError, iter_encode, [], 'invalid') assert_raises(LookupError, IncrementalDecoder, 'invalid') assert_raises(LookupError, IncrementalEncoder, 'invalid') def test_decode(): assert decode(b'\x80', 'latin1') == ('€', lookup('latin1')) assert decode(b'\x80', lookup('latin1')) == ('€', lookup('latin1')) assert decode(b'\xc3\xa9', 'utf8') == ('é', lookup('utf8')) assert decode(b'\xc3\xa9', UTF8) == ('é', lookup('utf8')) assert decode(b'\xc3\xa9', 'ascii') == ('é', lookup('ascii')) assert decode(b'\xEF\xBB\xBF\xc3\xa9', 'ascii') == ('é', lookup('utf8')) # UTF-8 with BOM assert decode(b'\xFE\xFF\x00\xe9', 'ascii') == ('é', lookup('utf-16be')) # UTF-16-BE with BOM assert decode(b'\xFF\xFE\xe9\x00', 'ascii') == ('é', lookup('utf-16le')) # UTF-16-LE with BOM assert decode(b'\xFE\xFF\xe9\x00', 'ascii') == ('\ue900', lookup('utf-16be')) assert decode(b'\xFF\xFE\x00\xe9', 'ascii') == ('\ue900', lookup('utf-16le')) assert decode(b'\x00\xe9', 'UTF-16BE') == ('é', lookup('utf-16be')) assert decode(b'\xe9\x00', 'UTF-16LE') == ('é', lookup('utf-16le')) assert decode(b'\xe9\x00', 'UTF-16') == ('é', lookup('utf-16le')) assert decode(b'\xe9\x00', 'UTF-16BE') == ('\ue900', lookup('utf-16be')) assert decode(b'\x00\xe9', 'UTF-16LE') == ('\ue900', lookup('utf-16le')) assert decode(b'\x00\xe9', 'UTF-16') == ('\ue900', lookup('utf-16le')) def test_encode(): assert encode('é', 'latin1') == b'\xe9' assert encode('é', 'utf8') == b'\xc3\xa9' assert encode('é', 'utf8') == b'\xc3\xa9' assert encode('é', 'utf-16') == b'\xe9\x00' assert encode('é', 'utf-16le') == b'\xe9\x00' assert encode('é', 'utf-16be') == b'\x00\xe9' def test_iter_decode(): def iter_decode_to_string(input, fallback_encoding): output, _encoding = iter_decode(input, fallback_encoding) return ''.join(output) assert iter_decode_to_string([], 'latin1') == '' assert iter_decode_to_string([b''], 'latin1') == '' assert iter_decode_to_string([b'\xe9'], 'latin1') == 'é' assert iter_decode_to_string([b'hello'], 'latin1') == 'hello' assert iter_decode_to_string([b'he', b'llo'], 'latin1') == 'hello' assert iter_decode_to_string([b'hell', b'o'], 'latin1') == 'hello' assert iter_decode_to_string([b'\xc3\xa9'], 'latin1') == 'é' assert iter_decode_to_string([b'\xEF\xBB\xBF\xc3\xa9'], 'latin1') == 'é' assert iter_decode_to_string([ b'\xEF\xBB\xBF', b'\xc3', b'\xa9'], 'latin1') == 'é' assert iter_decode_to_string([ b'\xEF\xBB\xBF', b'a', b'\xc3'], 'latin1') == 'a\uFFFD' assert iter_decode_to_string([ b'', b'\xEF', b'', b'', b'\xBB\xBF\xc3', b'\xa9'], 'latin1') == 'é' assert iter_decode_to_string([b'\xEF\xBB\xBF'], 'latin1') == '' assert iter_decode_to_string([b'\xEF\xBB'], 'latin1') == 'ï»' assert iter_decode_to_string([b'\xFE\xFF\x00\xe9'], 'latin1') == 'é' assert iter_decode_to_string([b'\xFF\xFE\xe9\x00'], 'latin1') == 'é' assert iter_decode_to_string([ b'', b'\xFF', b'', b'', b'\xFE\xe9', b'\x00'], 'latin1') == 'é' assert iter_decode_to_string([ b'', b'h\xe9', b'llo'], 'x-user-defined') == 'h\uF7E9llo' def test_iter_encode(): assert b''.join(iter_encode([], 'latin1')) == b'' assert b''.join(iter_encode([''], 'latin1')) == b'' assert b''.join(iter_encode(['é'], 'latin1')) == b'\xe9' assert b''.join(iter_encode(['', 'é', '', ''], 'latin1')) == b'\xe9' assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16')) == b'\xe9\x00' assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16le')) == b'\xe9\x00' assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16be')) == b'\x00\xe9' assert b''.join(iter_encode([ '', 'h\uF7E9', '', 'llo'], 'x-user-defined')) == b'h\xe9llo' def test_x_user_defined(): encoded = b'2,\x0c\x0b\x1aO\xd9#\xcb\x0f\xc9\xbbt\xcf\xa8\xca' decoded = '2,\x0c\x0b\x1aO\uf7d9#\uf7cb\x0f\uf7c9\uf7bbt\uf7cf\uf7a8\uf7ca' encoded = b'aa' decoded = 'aa' assert decode(encoded, 'x-user-defined') == (decoded, lookup('x-user-defined')) assert encode(decoded, 'x-user-defined') == encoded PKH]Cpython3.10/site-packages/pip/_vendor/webencodings/x_user_defined.pynu[# coding: utf-8 """ webencodings.x_user_defined ~~~~~~~~~~~~~~~~~~~~~~~~~~~ An implementation of the x-user-defined encoding. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. """ from __future__ import unicode_literals import codecs ### Codec APIs class Codec(codecs.Codec): def encode(self, input, errors='strict'): return codecs.charmap_encode(input, errors, encoding_table) def decode(self, input, errors='strict'): return codecs.charmap_decode(input, errors, decoding_table) class IncrementalEncoder(codecs.IncrementalEncoder): def encode(self, input, final=False): return codecs.charmap_encode(input, self.errors, encoding_table)[0] class IncrementalDecoder(codecs.IncrementalDecoder): def decode(self, input, final=False): return codecs.charmap_decode(input, self.errors, decoding_table)[0] class StreamWriter(Codec, codecs.StreamWriter): pass class StreamReader(Codec, codecs.StreamReader): pass ### encodings module API codec_info = codecs.CodecInfo( name='x-user-defined', encode=Codec().encode, decode=Codec().decode, incrementalencoder=IncrementalEncoder, incrementaldecoder=IncrementalDecoder, streamreader=StreamReader, streamwriter=StreamWriter, ) ### Decoding Table # Python 3: # for c in range(256): print(' %r' % chr(c if c < 128 else c + 0xF700)) decoding_table = ( '\x00' '\x01' '\x02' '\x03' '\x04' '\x05' '\x06' '\x07' '\x08' '\t' '\n' '\x0b' '\x0c' '\r' '\x0e' '\x0f' '\x10' '\x11' '\x12' '\x13' '\x14' '\x15' '\x16' '\x17' '\x18' '\x19' '\x1a' '\x1b' '\x1c' '\x1d' '\x1e' '\x1f' ' ' '!' '"' '#' '$' '%' '&' "'" '(' ')' '*' '+' ',' '-' '.' '/' '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' ':' ';' '<' '=' '>' '?' '@' 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '[' '\\' ']' '^' '_' '`' 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z' '{' '|' '}' '~' '\x7f' '\uf780' '\uf781' '\uf782' '\uf783' '\uf784' '\uf785' '\uf786' '\uf787' '\uf788' '\uf789' '\uf78a' '\uf78b' '\uf78c' '\uf78d' '\uf78e' '\uf78f' '\uf790' '\uf791' '\uf792' '\uf793' '\uf794' '\uf795' '\uf796' '\uf797' '\uf798' '\uf799' '\uf79a' '\uf79b' '\uf79c' '\uf79d' '\uf79e' '\uf79f' '\uf7a0' '\uf7a1' '\uf7a2' '\uf7a3' '\uf7a4' '\uf7a5' '\uf7a6' '\uf7a7' '\uf7a8' '\uf7a9' '\uf7aa' '\uf7ab' '\uf7ac' '\uf7ad' '\uf7ae' '\uf7af' '\uf7b0' '\uf7b1' '\uf7b2' '\uf7b3' '\uf7b4' '\uf7b5' '\uf7b6' '\uf7b7' '\uf7b8' '\uf7b9' '\uf7ba' '\uf7bb' '\uf7bc' '\uf7bd' '\uf7be' '\uf7bf' '\uf7c0' '\uf7c1' '\uf7c2' '\uf7c3' '\uf7c4' '\uf7c5' '\uf7c6' '\uf7c7' '\uf7c8' '\uf7c9' '\uf7ca' '\uf7cb' '\uf7cc' '\uf7cd' '\uf7ce' '\uf7cf' '\uf7d0' '\uf7d1' '\uf7d2' '\uf7d3' '\uf7d4' '\uf7d5' '\uf7d6' '\uf7d7' '\uf7d8' '\uf7d9' '\uf7da' '\uf7db' '\uf7dc' '\uf7dd' '\uf7de' '\uf7df' '\uf7e0' '\uf7e1' '\uf7e2' '\uf7e3' '\uf7e4' '\uf7e5' '\uf7e6' '\uf7e7' '\uf7e8' '\uf7e9' '\uf7ea' '\uf7eb' '\uf7ec' '\uf7ed' '\uf7ee' '\uf7ef' '\uf7f0' '\uf7f1' '\uf7f2' '\uf7f3' '\uf7f4' '\uf7f5' '\uf7f6' '\uf7f7' '\uf7f8' '\uf7f9' '\uf7fa' '\uf7fb' '\uf7fc' '\uf7fd' '\uf7fe' '\uf7ff' ) ### Encoding table encoding_table = codecs.charmap_build(decoding_table) PKH]ǭ##;python3.10/site-packages/pip/_vendor/webencodings/labels.pynu[""" webencodings.labels ~~~~~~~~~~~~~~~~~~~ Map encoding labels to their name. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. """ # XXX Do not edit! # This file is automatically generated by mklabels.py LABELS = { 'unicode-1-1-utf-8': 'utf-8', 'utf-8': 'utf-8', 'utf8': 'utf-8', '866': 'ibm866', 'cp866': 'ibm866', 'csibm866': 'ibm866', 'ibm866': 'ibm866', 'csisolatin2': 'iso-8859-2', 'iso-8859-2': 'iso-8859-2', 'iso-ir-101': 'iso-8859-2', 'iso8859-2': 'iso-8859-2', 'iso88592': 'iso-8859-2', 'iso_8859-2': 'iso-8859-2', 'iso_8859-2:1987': 'iso-8859-2', 'l2': 'iso-8859-2', 'latin2': 'iso-8859-2', 'csisolatin3': 'iso-8859-3', 'iso-8859-3': 'iso-8859-3', 'iso-ir-109': 'iso-8859-3', 'iso8859-3': 'iso-8859-3', 'iso88593': 'iso-8859-3', 'iso_8859-3': 'iso-8859-3', 'iso_8859-3:1988': 'iso-8859-3', 'l3': 'iso-8859-3', 'latin3': 'iso-8859-3', 'csisolatin4': 'iso-8859-4', 'iso-8859-4': 'iso-8859-4', 'iso-ir-110': 'iso-8859-4', 'iso8859-4': 'iso-8859-4', 'iso88594': 'iso-8859-4', 'iso_8859-4': 'iso-8859-4', 'iso_8859-4:1988': 'iso-8859-4', 'l4': 'iso-8859-4', 'latin4': 'iso-8859-4', 'csisolatincyrillic': 'iso-8859-5', 'cyrillic': 'iso-8859-5', 'iso-8859-5': 'iso-8859-5', 'iso-ir-144': 'iso-8859-5', 'iso8859-5': 'iso-8859-5', 'iso88595': 'iso-8859-5', 'iso_8859-5': 'iso-8859-5', 'iso_8859-5:1988': 'iso-8859-5', 'arabic': 'iso-8859-6', 'asmo-708': 'iso-8859-6', 'csiso88596e': 'iso-8859-6', 'csiso88596i': 'iso-8859-6', 'csisolatinarabic': 'iso-8859-6', 'ecma-114': 'iso-8859-6', 'iso-8859-6': 'iso-8859-6', 'iso-8859-6-e': 'iso-8859-6', 'iso-8859-6-i': 'iso-8859-6', 'iso-ir-127': 'iso-8859-6', 'iso8859-6': 'iso-8859-6', 'iso88596': 'iso-8859-6', 'iso_8859-6': 'iso-8859-6', 'iso_8859-6:1987': 'iso-8859-6', 'csisolatingreek': 'iso-8859-7', 'ecma-118': 'iso-8859-7', 'elot_928': 'iso-8859-7', 'greek': 'iso-8859-7', 'greek8': 'iso-8859-7', 'iso-8859-7': 'iso-8859-7', 'iso-ir-126': 'iso-8859-7', 'iso8859-7': 'iso-8859-7', 'iso88597': 'iso-8859-7', 'iso_8859-7': 'iso-8859-7', 'iso_8859-7:1987': 'iso-8859-7', 'sun_eu_greek': 'iso-8859-7', 'csiso88598e': 'iso-8859-8', 'csisolatinhebrew': 'iso-8859-8', 'hebrew': 'iso-8859-8', 'iso-8859-8': 'iso-8859-8', 'iso-8859-8-e': 'iso-8859-8', 'iso-ir-138': 'iso-8859-8', 'iso8859-8': 'iso-8859-8', 'iso88598': 'iso-8859-8', 'iso_8859-8': 'iso-8859-8', 'iso_8859-8:1988': 'iso-8859-8', 'visual': 'iso-8859-8', 'csiso88598i': 'iso-8859-8-i', 'iso-8859-8-i': 'iso-8859-8-i', 'logical': 'iso-8859-8-i', 'csisolatin6': 'iso-8859-10', 'iso-8859-10': 'iso-8859-10', 'iso-ir-157': 'iso-8859-10', 'iso8859-10': 'iso-8859-10', 'iso885910': 'iso-8859-10', 'l6': 'iso-8859-10', 'latin6': 'iso-8859-10', 'iso-8859-13': 'iso-8859-13', 'iso8859-13': 'iso-8859-13', 'iso885913': 'iso-8859-13', 'iso-8859-14': 'iso-8859-14', 'iso8859-14': 'iso-8859-14', 'iso885914': 'iso-8859-14', 'csisolatin9': 'iso-8859-15', 'iso-8859-15': 'iso-8859-15', 'iso8859-15': 'iso-8859-15', 'iso885915': 'iso-8859-15', 'iso_8859-15': 'iso-8859-15', 'l9': 'iso-8859-15', 'iso-8859-16': 'iso-8859-16', 'cskoi8r': 'koi8-r', 'koi': 'koi8-r', 'koi8': 'koi8-r', 'koi8-r': 'koi8-r', 'koi8_r': 'koi8-r', 'koi8-u': 'koi8-u', 'csmacintosh': 'macintosh', 'mac': 'macintosh', 'macintosh': 'macintosh', 'x-mac-roman': 'macintosh', 'dos-874': 'windows-874', 'iso-8859-11': 'windows-874', 'iso8859-11': 'windows-874', 'iso885911': 'windows-874', 'tis-620': 'windows-874', 'windows-874': 'windows-874', 'cp1250': 'windows-1250', 'windows-1250': 'windows-1250', 'x-cp1250': 'windows-1250', 'cp1251': 'windows-1251', 'windows-1251': 'windows-1251', 'x-cp1251': 'windows-1251', 'ansi_x3.4-1968': 'windows-1252', 'ascii': 'windows-1252', 'cp1252': 'windows-1252', 'cp819': 'windows-1252', 'csisolatin1': 'windows-1252', 'ibm819': 'windows-1252', 'iso-8859-1': 'windows-1252', 'iso-ir-100': 'windows-1252', 'iso8859-1': 'windows-1252', 'iso88591': 'windows-1252', 'iso_8859-1': 'windows-1252', 'iso_8859-1:1987': 'windows-1252', 'l1': 'windows-1252', 'latin1': 'windows-1252', 'us-ascii': 'windows-1252', 'windows-1252': 'windows-1252', 'x-cp1252': 'windows-1252', 'cp1253': 'windows-1253', 'windows-1253': 'windows-1253', 'x-cp1253': 'windows-1253', 'cp1254': 'windows-1254', 'csisolatin5': 'windows-1254', 'iso-8859-9': 'windows-1254', 'iso-ir-148': 'windows-1254', 'iso8859-9': 'windows-1254', 'iso88599': 'windows-1254', 'iso_8859-9': 'windows-1254', 'iso_8859-9:1989': 'windows-1254', 'l5': 'windows-1254', 'latin5': 'windows-1254', 'windows-1254': 'windows-1254', 'x-cp1254': 'windows-1254', 'cp1255': 'windows-1255', 'windows-1255': 'windows-1255', 'x-cp1255': 'windows-1255', 'cp1256': 'windows-1256', 'windows-1256': 'windows-1256', 'x-cp1256': 'windows-1256', 'cp1257': 'windows-1257', 'windows-1257': 'windows-1257', 'x-cp1257': 'windows-1257', 'cp1258': 'windows-1258', 'windows-1258': 'windows-1258', 'x-cp1258': 'windows-1258', 'x-mac-cyrillic': 'x-mac-cyrillic', 'x-mac-ukrainian': 'x-mac-cyrillic', 'chinese': 'gbk', 'csgb2312': 'gbk', 'csiso58gb231280': 'gbk', 'gb2312': 'gbk', 'gb_2312': 'gbk', 'gb_2312-80': 'gbk', 'gbk': 'gbk', 'iso-ir-58': 'gbk', 'x-gbk': 'gbk', 'gb18030': 'gb18030', 'hz-gb-2312': 'hz-gb-2312', 'big5': 'big5', 'big5-hkscs': 'big5', 'cn-big5': 'big5', 'csbig5': 'big5', 'x-x-big5': 'big5', 'cseucpkdfmtjapanese': 'euc-jp', 'euc-jp': 'euc-jp', 'x-euc-jp': 'euc-jp', 'csiso2022jp': 'iso-2022-jp', 'iso-2022-jp': 'iso-2022-jp', 'csshiftjis': 'shift_jis', 'ms_kanji': 'shift_jis', 'shift-jis': 'shift_jis', 'shift_jis': 'shift_jis', 'sjis': 'shift_jis', 'windows-31j': 'shift_jis', 'x-sjis': 'shift_jis', 'cseuckr': 'euc-kr', 'csksc56011987': 'euc-kr', 'euc-kr': 'euc-kr', 'iso-ir-149': 'euc-kr', 'korean': 'euc-kr', 'ks_c_5601-1987': 'euc-kr', 'ks_c_5601-1989': 'euc-kr', 'ksc5601': 'euc-kr', 'ksc_5601': 'euc-kr', 'windows-949': 'euc-kr', 'csiso2022kr': 'iso-2022-kr', 'iso-2022-kr': 'iso-2022-kr', 'utf-16be': 'utf-16be', 'utf-16': 'utf-16le', 'utf-16le': 'utf-16le', 'x-user-defined': 'x-user-defined', } PKH]xqS)S)=python3.10/site-packages/pip/_vendor/webencodings/__init__.pynu[# coding: utf-8 """ webencodings ~~~~~~~~~~~~ This is a Python implementation of the `WHATWG Encoding standard `. See README for details. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. """ from __future__ import unicode_literals import codecs from .labels import LABELS VERSION = '0.5.1' # Some names in Encoding are not valid Python aliases. Remap these. PYTHON_NAMES = { 'iso-8859-8-i': 'iso-8859-8', 'x-mac-cyrillic': 'mac-cyrillic', 'macintosh': 'mac-roman', 'windows-874': 'cp874'} CACHE = {} def ascii_lower(string): r"""Transform (only) ASCII letters to lower case: A-Z is mapped to a-z. :param string: An Unicode string. :returns: A new Unicode string. This is used for `ASCII case-insensitive `_ matching of encoding labels. The same matching is also used, among other things, for `CSS keywords `_. This is different from the :meth:`~py:str.lower` method of Unicode strings which also affect non-ASCII characters, sometimes mapping them into the ASCII range: >>> keyword = u'Bac\N{KELVIN SIGN}ground' >>> assert keyword.lower() == u'background' >>> assert ascii_lower(keyword) != keyword.lower() >>> assert ascii_lower(keyword) == u'bac\N{KELVIN SIGN}ground' """ # This turns out to be faster than unicode.translate() return string.encode('utf8').lower().decode('utf8') def lookup(label): """ Look for an encoding by its label. This is the spec’s `get an encoding `_ algorithm. Supported labels are listed there. :param label: A string. :returns: An :class:`Encoding` object, or :obj:`None` for an unknown label. """ # Only strip ASCII whitespace: U+0009, U+000A, U+000C, U+000D, and U+0020. label = ascii_lower(label.strip('\t\n\f\r ')) name = LABELS.get(label) if name is None: return None encoding = CACHE.get(name) if encoding is None: if name == 'x-user-defined': from .x_user_defined import codec_info else: python_name = PYTHON_NAMES.get(name, name) # Any python_name value that gets to here should be valid. codec_info = codecs.lookup(python_name) encoding = Encoding(name, codec_info) CACHE[name] = encoding return encoding def _get_encoding(encoding_or_label): """ Accept either an encoding object or label. :param encoding: An :class:`Encoding` object or a label string. :returns: An :class:`Encoding` object. :raises: :exc:`~exceptions.LookupError` for an unknown label. """ if hasattr(encoding_or_label, 'codec_info'): return encoding_or_label encoding = lookup(encoding_or_label) if encoding is None: raise LookupError('Unknown encoding label: %r' % encoding_or_label) return encoding class Encoding(object): """Reresents a character encoding such as UTF-8, that can be used for decoding or encoding. .. attribute:: name Canonical name of the encoding .. attribute:: codec_info The actual implementation of the encoding, a stdlib :class:`~codecs.CodecInfo` object. See :func:`codecs.register`. """ def __init__(self, name, codec_info): self.name = name self.codec_info = codec_info def __repr__(self): return '' % self.name #: The UTF-8 encoding. Should be used for new content and formats. UTF8 = lookup('utf-8') _UTF16LE = lookup('utf-16le') _UTF16BE = lookup('utf-16be') def decode(input, fallback_encoding, errors='replace'): """ Decode a single string. :param input: A byte string :param fallback_encoding: An :class:`Encoding` object or a label string. The encoding to use if :obj:`input` does note have a BOM. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :return: A ``(output, encoding)`` tuple of an Unicode string and an :obj:`Encoding`. """ # Fail early if `encoding` is an invalid label. fallback_encoding = _get_encoding(fallback_encoding) bom_encoding, input = _detect_bom(input) encoding = bom_encoding or fallback_encoding return encoding.codec_info.decode(input, errors)[0], encoding def _detect_bom(input): """Return (bom_encoding, input), with any BOM removed from the input.""" if input.startswith(b'\xFF\xFE'): return _UTF16LE, input[2:] if input.startswith(b'\xFE\xFF'): return _UTF16BE, input[2:] if input.startswith(b'\xEF\xBB\xBF'): return UTF8, input[3:] return None, input def encode(input, encoding=UTF8, errors='strict'): """ Encode a single string. :param input: An Unicode string. :param encoding: An :class:`Encoding` object or a label string. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :return: A byte string. """ return _get_encoding(encoding).codec_info.encode(input, errors)[0] def iter_decode(input, fallback_encoding, errors='replace'): """ "Pull"-based decoder. :param input: An iterable of byte strings. The input is first consumed just enough to determine the encoding based on the precense of a BOM, then consumed on demand when the return value is. :param fallback_encoding: An :class:`Encoding` object or a label string. The encoding to use if :obj:`input` does note have a BOM. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :returns: An ``(output, encoding)`` tuple. :obj:`output` is an iterable of Unicode strings, :obj:`encoding` is the :obj:`Encoding` that is being used. """ decoder = IncrementalDecoder(fallback_encoding, errors) generator = _iter_decode_generator(input, decoder) encoding = next(generator) return generator, encoding def _iter_decode_generator(input, decoder): """Return a generator that first yields the :obj:`Encoding`, then yields output chukns as Unicode strings. """ decode = decoder.decode input = iter(input) for chunck in input: output = decode(chunck) if output: assert decoder.encoding is not None yield decoder.encoding yield output break else: # Input exhausted without determining the encoding output = decode(b'', final=True) assert decoder.encoding is not None yield decoder.encoding if output: yield output return for chunck in input: output = decode(chunck) if output: yield output output = decode(b'', final=True) if output: yield output def iter_encode(input, encoding=UTF8, errors='strict'): """ “Pull”-based encoder. :param input: An iterable of Unicode strings. :param encoding: An :class:`Encoding` object or a label string. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :returns: An iterable of byte strings. """ # Fail early if `encoding` is an invalid label. encode = IncrementalEncoder(encoding, errors).encode return _iter_encode_generator(input, encode) def _iter_encode_generator(input, encode): for chunck in input: output = encode(chunck) if output: yield output output = encode('', final=True) if output: yield output class IncrementalDecoder(object): """ “Push”-based decoder. :param fallback_encoding: An :class:`Encoding` object or a label string. The encoding to use if :obj:`input` does note have a BOM. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. """ def __init__(self, fallback_encoding, errors='replace'): # Fail early if `encoding` is an invalid label. self._fallback_encoding = _get_encoding(fallback_encoding) self._errors = errors self._buffer = b'' self._decoder = None #: The actual :class:`Encoding` that is being used, #: or :obj:`None` if that is not determined yet. #: (Ie. if there is not enough input yet to determine #: if there is a BOM.) self.encoding = None # Not known yet. def decode(self, input, final=False): """Decode one chunk of the input. :param input: A byte string. :param final: Indicate that no more input is available. Must be :obj:`True` if this is the last call. :returns: An Unicode string. """ decoder = self._decoder if decoder is not None: return decoder(input, final) input = self._buffer + input encoding, input = _detect_bom(input) if encoding is None: if len(input) < 3 and not final: # Not enough data yet. self._buffer = input return '' else: # No BOM encoding = self._fallback_encoding decoder = encoding.codec_info.incrementaldecoder(self._errors).decode self._decoder = decoder self.encoding = encoding return decoder(input, final) class IncrementalEncoder(object): """ “Push”-based encoder. :param encoding: An :class:`Encoding` object or a label string. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. .. method:: encode(input, final=False) :param input: An Unicode string. :param final: Indicate that no more input is available. Must be :obj:`True` if this is the last call. :returns: A byte string. """ def __init__(self, encoding=UTF8, errors='strict'): encoding = _get_encoding(encoding) self.encode = encoding.codec_info.incrementalencoder(errors).encode PKH]߸Ppython3.10/site-packages/pip/_vendor/progress/__pycache__/colors.cpython-310.pycnu[o ai_ @sddlmZdZdZdddZeeddZeed dZeed dZeed dZeed dZ eed dZ eeddZ eeddZ eeddZ eeddZeeddZeeddZeeddZeeddZeeddZeeddZeeddZdS))partial)blackredgreenyellowbluemagentacyanwhite) boldfaintitalic underlineblinkblink2negative concealedcrossedNcCs:g}|r6|tvr|tdt|n!t|tr0d|kr$dkr0nn |dt|ntd||rh|tvrI|tdt|nt|trbd|krXdkrbnn|d|ntd||r|dD]}|tvr|td t|qotd ||rd d |d }d}|||S|S)Nrz38;5;%dzInvalid color "%s"(z48;5;%d+zInvalid style "%s"z[;mz) COLORSappendstrindex isinstanceint ExceptionsplitSTYLESjoin)sfgbgstylesgrstprefixsuffixr-/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/progress/colors.pycolors." "   r/r)r&rrrrrr r r )r(r r rrrrrr)NNN) functoolsrrr#r/rrrrrrr r r r r rrrrrrr-r-r-r.s*   #               PKH]|}ɳ Mpython3.10/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-310.pycnu[o ai~ @sddlmZddlZddlmZddlmZGdddeZGdd d eZGd d d eZ Gd d d eZ GdddeZ Gddde Z Gddde Z dS))unicode_literalsN)Progress)colorc@s0eZdZdZdZdZdZdZdZdZ dd Z dS) Bar z%(index)d/%(max)dz |z|  #NcCstt|j|j}|j|}|j|}t|j||jd}|j|}|j|}d||j |||j |g}| |dS)Nfg) intwidthprogressmessagerfill empty_fillsuffixjoin bar_prefix bar_suffixwriteln)self filled_length empty_lengthrbaremptyrliner/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/progress/bar.pyupdate"s    z Bar.update) __name__ __module__ __qualname__rrrrrrrr rrrrrs rc@s eZdZdZdZdZdZdZdS) ChargingBarz %(percent)d%%ru∙█N)r!r"r#rrrrrrrrrr$/s r$c@eZdZdZdZdS)FillingSquaresBaru▢u▣Nr!r"r#rrrrrrr'7r'c@r&)FillingCirclesBaru◯u◉Nr(rrrrr*<r)r*c@s*eZdZejdr dZndZddZdS)IncrementalBarwin)r▌r%) ru▏u▎u▍r-u▋u▊u▉r%c Cst|j}|j|j}t|}t|||}|j|}|j|}t|jd||jd}|dkr6|j|nd}|jtd|t|} |j |} d ||j ||| |j | g} | | dS)Nr rr )lenphasesrrr rrrmaxrrrrr) rnphases filled_lennfullphasenemptyrrcurrentrrrrrrr Gs     zIncrementalBar.updateN)r!r"r#sysplatform startswithr0r rrrrr+As   r+c@eZdZdZdS)PixelBar)u⡀u⡄u⡆u⡇u⣇u⣧u⣷u⣿Nr!r"r#r0rrrrr<Xr<c@r;)ShadyBar)ru░u▒u▓r%Nr=rrrrr?\r>r?) __future__rr8r rcolorsrrr$r'r*r+r<r?rrrrs   PKH]XCCQpython3.10/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-310.pycnu[o aiM@s`ddlmZddlmZmZGdddeZGdddeZGdd d eZGd d d eZd S) )unicode_literals)InfiniteProgressc@eZdZddZdS)CountercC,|j|}d|t|jg}||dSN)messagejoinstrindexwritelnselfr liner/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/progress/counter.pyupdate zCounter.updateN__name__ __module__ __qualname__rrrrrr rc@r) CountdowncCrr )r r r remainingrrrrrrrzCountdown.updateNrrrrrrrrc@seZdZdZddZdS)Stack)  u▁u▂u▃u▄u▅u▆u▇u█cCsNt|j}t|dt|j|}|j|}d||j|g}||dS)Nrr )lenphasesminintprogressr r r)rnphasesir rrrrr&s  z Stack.updateN)rrrr!rrrrrr#s rc@seZdZdZdS)Pie)u○u◔u◑u◕u●N)rrrr!rrrrr'.sr'N) __future__rr rrrrrr'rrrrs  PKH].Rpython3.10/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-310.pycnu[o ai@sddlmZmZddlmZddlmZddlmZddl m Z zddl m Z Wne y7ddl m Z YnwdZd Zd ZGd d d eZGd ddeZdS))divisionprint_function)deque) timedelta)ceil)stderr) monotonic)timez1.6z[?25lz[?25hc@seZdZeZdZdZdZd$ddZddZ dd Z e d d Z e d d Z ddZddZddZddZddZddZd%ddZddZdd Zd!d"Zd#S)&Infinite TcKsd|_t|_d|_|j|_|j|_t|jd|_| D] \}}t |||qd|_ d|_ ||_ |jrF|rF|jrFttd|jdd|_ |ddS)Nr)maxlenFr endfileT)indexrstart_tsavg_avg_update_ts_tsr sma_window_xputitemssetattr _max_width_hidden_cursormessageris_tty hide_cursorprint HIDE_CURSORwriteln)selfrkwargskeyvalr&/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/progress/__init__.py__init__'s zInfinite.__init__cCs|jr ttd|jddSdS)Nr r)rr SHOW_CURSORrr"r&r&r'__del__;szInfinite.__del__cCs|drdSt||dS)N_) startswithgetattr)r"r$r&r&r' __getitem__?s  zInfinite.__getitem__cCstt|jSN)intrrr*r&r&r'elapsedDszInfinite.elapsedcC t|jdSN)seconds)rr2r*r&r&r' elapsed_tdH zInfinite.elapsed_tdcCsh|dkr0t|j}|j||t}||jks ||jdkr2t|jt|j|_||_dSdSdSNr)lenrappendrrrsumr)r"ndtxput_lennowr&r&r' update_avgLs   zInfinite.update_avgcCdSr0r&r*r&r&r'updateWzInfinite.updatecCrBr0r&r*r&r&r'startZrDzInfinite.startcCsd|jr.|r0t|}||jkr|d|j|7}n||_td|d|jd|jdSdSdS)N  r r)rrr:rrflush)r"linewidthr&r&r'r!]s zInfinite.writelncCsF|jr|rt|jd|jr!ttd|jdd|_dSdSdSdS)N)rr rF)rrrrr)r*r&r&r'finishhs  zInfinite.finishcCs8z |jr |jWSdWStyd|}t|w)NTz:%s has no attribute 'isatty'. Try setting check_tty=False.) check_ttyrisattyAttributeError)r"msgr&r&r'ros  zInfinite.is_ttyr9cCs:t}||j}|||||_|j||_|dSr0)rrrArrC)r"r=r@r>r&r&r'nextvs     z Infinite.nextccsXd|_||D] }||_|V|q Wd|`dS1s#wY|`dSr0) iter_valuerPr"itxr&r&r'iter~s  z Infinite.itercCs ||Sr0)rEr*r&r&r' __enter__szInfinite.__enter__cC |dSr0)rK)r"exc_typeexc_valexc_tbr&r&r'__exit__ zInfinite.__exit__N)r )r9)__name__ __module__ __qualname__rrrrLrr(r+r/propertyr2r6rArCrEr!rKrrPrUrVr[r&r&r&r'r !s,       r cspeZdZfddZeddZeddZeddZed d Zed d Z d dZ ddZ ddZ Z S)Progresscs(tt|j|i||dd|_dS)Nmaxd)superrar(getrb)r"argsr# __class__r&r'r(szProgress.__init__cCstt|j|jSr0)r1rr remainingr*r&r&r'etasz Progress.etacCr3r4)rrjr*r&r&r'eta_tdr7zProgress.eta_tdcCs |jdS)Nrc)progressr*r&r&r'percents zProgress.percentcCs |jdkrdStd|j|jSr8)rbminrr*r&r&r'rls zProgress.progresscCst|j|jdS)Nr)rbrr*r&r&r'riszProgress.remainingcCrWr0)rCr*r&r&r'rEr\zProgress.startcCs||j}||dSr0)rrP)r"rincrr&r&r'gotos z Progress.gotoccszzt||_Wn tyYnwd|_||D] }||_|V|qWd|`dS1s4wY|`dSr0)r:rb TypeErrorrQrPrRr&r&r'rUs"   z Progress.iter)r]r^r_r(r`rjrkrmrlrirErprU __classcell__r&r&rgr'ras      raN) __future__rr collectionsrdatetimermathrsysrr r ImportError __version__r r)objectr rar&r&r&r's     nPKH]g}Qpython3.10/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-310.pycnu[o ai@slddlmZddlmZGdddeZGdddeZGdd d eZGd d d eZGd d d eZdS))unicode_literals)Infinitec@seZdZdZdZddZdS)Spinner)-\|/TcCs<|jt|j}|j|}d||j|g}||dS)N)indexlenphasesmessagejoinwriteln)selfirliner/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/progress/spinner.pyupdates zSpinner.updateN)__name__ __module__ __qualname__r hide_cursorrrrrrrs rc@eZdZgdZdS) PieSpinner)u◷u◶u◵u◴Nrrrr rrrrr  rc@r) MoonSpinner)u◑u◒u◐u◓Nrrrrrr$rrc@r) LineSpinner)u⎺⎻⎼u⎽r"r!Nrrrrrr (rr c@r) PixelSpinner)u⣾u⣷u⣯u⣟u⡿u⢿u⣻u⣽Nrrrrrr#,rr#N) __future__rr rrrrr r#rrrrs   PKH]_ _ 7python3.10/site-packages/pip/_vendor/progress/colors.pynu[# -*- coding: utf-8 -*- # Copyright (c) 2020 Georgios Verigakis # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. from functools import partial COLORS = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white') STYLES = ('bold', 'faint', 'italic', 'underline', 'blink', 'blink2', 'negative', 'concealed', 'crossed') def color(s, fg=None, bg=None, style=None): sgr = [] if fg: if fg in COLORS: sgr.append(str(30 + COLORS.index(fg))) elif isinstance(fg, int) and 0 <= fg <= 255: sgr.append('38;5;%d' % int(fg)) else: raise Exception('Invalid color "%s"' % fg) if bg: if bg in COLORS: sgr.append(str(40 + COLORS.index(bg))) elif isinstance(bg, int) and 0 <= bg <= 255: sgr.append('48;5;%d' % bg) else: raise Exception('Invalid color "%s"' % bg) if style: for st in style.split('+'): if st in STYLES: sgr.append(str(1 + STYLES.index(st))) else: raise Exception('Invalid style "%s"' % st) if sgr: prefix = '\x1b[' + ';'.join(sgr) + 'm' suffix = '\x1b[0m' return prefix + s + suffix else: return s # Foreground shortcuts black = partial(color, fg='black') red = partial(color, fg='red') green = partial(color, fg='green') yellow = partial(color, fg='yellow') blue = partial(color, fg='blue') magenta = partial(color, fg='magenta') cyan = partial(color, fg='cyan') white = partial(color, fg='white') # Style shortcuts bold = partial(color, style='bold') faint = partial(color, style='faint') italic = partial(color, style='italic') underline = partial(color, style='underline') blink = partial(color, style='blink') blink2 = partial(color, style='blink2') negative = partial(color, style='negative') concealed = partial(color, style='concealed') crossed = partial(color, style='crossed') PKH]C_~ ~ 4python3.10/site-packages/pip/_vendor/progress/bar.pynu[# -*- coding: utf-8 -*- # Copyright (c) 2012 Georgios Verigakis # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. from __future__ import unicode_literals import sys from . import Progress from .colors import color class Bar(Progress): width = 32 suffix = '%(index)d/%(max)d' bar_prefix = ' |' bar_suffix = '| ' empty_fill = ' ' fill = '#' color = None def update(self): filled_length = int(self.width * self.progress) empty_length = self.width - filled_length message = self.message % self bar = color(self.fill * filled_length, fg=self.color) empty = self.empty_fill * empty_length suffix = self.suffix % self line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix, suffix]) self.writeln(line) class ChargingBar(Bar): suffix = '%(percent)d%%' bar_prefix = ' ' bar_suffix = ' ' empty_fill = '∙' fill = '█' class FillingSquaresBar(ChargingBar): empty_fill = '▢' fill = '▣' class FillingCirclesBar(ChargingBar): empty_fill = '◯' fill = '◉' class IncrementalBar(Bar): if sys.platform.startswith('win'): phases = (u' ', u'▌', u'█') else: phases = (' ', '▏', '▎', '▍', '▌', '▋', '▊', '▉', '█') def update(self): nphases = len(self.phases) filled_len = self.width * self.progress nfull = int(filled_len) # Number of full chars phase = int((filled_len - nfull) * nphases) # Phase of last char nempty = self.width - nfull # Number of empty chars message = self.message % self bar = color(self.phases[-1] * nfull, fg=self.color) current = self.phases[phase] if phase > 0 else '' empty = self.empty_fill * max(0, nempty - len(current)) suffix = self.suffix % self line = ''.join([message, self.bar_prefix, bar, current, empty, self.bar_suffix, suffix]) self.writeln(line) class PixelBar(IncrementalBar): phases = ('⡀', '⡄', '⡆', '⡇', '⣇', '⣧', '⣷', '⣿') class ShadyBar(IncrementalBar): phases = (' ', '░', '▒', '▓', '█') PKH]8python3.10/site-packages/pip/_vendor/progress/spinner.pynu[# -*- coding: utf-8 -*- # Copyright (c) 2012 Georgios Verigakis # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. from __future__ import unicode_literals from . import Infinite class Spinner(Infinite): phases = ('-', '\\', '|', '/') hide_cursor = True def update(self): i = self.index % len(self.phases) message = self.message % self line = ''.join([message, self.phases[i]]) self.writeln(line) class PieSpinner(Spinner): phases = ['◷', '◶', '◵', '◴'] class MoonSpinner(Spinner): phases = ['◑', '◒', '◐', '◓'] class LineSpinner(Spinner): phases = ['⎺', '⎻', '⎼', '⎽', '⎼', '⎻'] class PixelSpinner(Spinner): phases = ['⣾', '⣷', '⣯', '⣟', '⡿', '⢿', '⣻', '⣽'] PKH]/9python3.10/site-packages/pip/_vendor/progress/__init__.pynu[# Copyright (c) 2012 Georgios Verigakis # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. from __future__ import division, print_function from collections import deque from datetime import timedelta from math import ceil from sys import stderr try: from time import monotonic except ImportError: from time import time as monotonic __version__ = '1.6' HIDE_CURSOR = '\x1b[?25l' SHOW_CURSOR = '\x1b[?25h' class Infinite(object): file = stderr sma_window = 10 # Simple Moving Average window check_tty = True hide_cursor = True def __init__(self, message='', **kwargs): self.index = 0 self.start_ts = monotonic() self.avg = 0 self._avg_update_ts = self.start_ts self._ts = self.start_ts self._xput = deque(maxlen=self.sma_window) for key, val in kwargs.items(): setattr(self, key, val) self._max_width = 0 self._hidden_cursor = False self.message = message if self.file and self.is_tty(): if self.hide_cursor: print(HIDE_CURSOR, end='', file=self.file) self._hidden_cursor = True self.writeln('') def __del__(self): if self._hidden_cursor: print(SHOW_CURSOR, end='', file=self.file) def __getitem__(self, key): if key.startswith('_'): return None return getattr(self, key, None) @property def elapsed(self): return int(monotonic() - self.start_ts) @property def elapsed_td(self): return timedelta(seconds=self.elapsed) def update_avg(self, n, dt): if n > 0: xput_len = len(self._xput) self._xput.append(dt / n) now = monotonic() # update when we're still filling _xput, then after every second if (xput_len < self.sma_window or now - self._avg_update_ts > 1): self.avg = sum(self._xput) / len(self._xput) self._avg_update_ts = now def update(self): pass def start(self): pass def writeln(self, line): if self.file and self.is_tty(): width = len(line) if width < self._max_width: # Add padding to cover previous contents line += ' ' * (self._max_width - width) else: self._max_width = width print('\r' + line, end='', file=self.file) self.file.flush() def finish(self): if self.file and self.is_tty(): print(file=self.file) if self._hidden_cursor: print(SHOW_CURSOR, end='', file=self.file) self._hidden_cursor = False def is_tty(self): try: return self.file.isatty() if self.check_tty else True except AttributeError: msg = "%s has no attribute 'isatty'. Try setting check_tty=False." % self raise AttributeError(msg) def next(self, n=1): now = monotonic() dt = now - self._ts self.update_avg(n, dt) self._ts = now self.index = self.index + n self.update() def iter(self, it): self.iter_value = None with self: for x in it: self.iter_value = x yield x self.next() del self.iter_value def __enter__(self): self.start() return self def __exit__(self, exc_type, exc_val, exc_tb): self.finish() class Progress(Infinite): def __init__(self, *args, **kwargs): super(Progress, self).__init__(*args, **kwargs) self.max = kwargs.get('max', 100) @property def eta(self): return int(ceil(self.avg * self.remaining)) @property def eta_td(self): return timedelta(seconds=self.eta) @property def percent(self): return self.progress * 100 @property def progress(self): if self.max == 0: return 0 return min(1, self.index / self.max) @property def remaining(self): return max(self.max - self.index, 0) def start(self): self.update() def goto(self, index): incr = index - self.index self.next(incr) def iter(self, it): try: self.max = len(it) except TypeError: pass self.iter_value = None with self: for x in it: self.iter_value = x yield x self.next() del self.iter_value PKH]N|MM8python3.10/site-packages/pip/_vendor/progress/counter.pynu[# -*- coding: utf-8 -*- # Copyright (c) 2012 Georgios Verigakis # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. from __future__ import unicode_literals from . import Infinite, Progress class Counter(Infinite): def update(self): message = self.message % self line = ''.join([message, str(self.index)]) self.writeln(line) class Countdown(Progress): def update(self): message = self.message % self line = ''.join([message, str(self.remaining)]) self.writeln(line) class Stack(Progress): phases = (' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█') def update(self): nphases = len(self.phases) i = min(nphases - 1, int(self.progress * nphases)) message = self.message % self line = ''.join([message, self.phases[i]]) self.writeln(line) class Pie(Stack): phases = ('○', '◔', '◑', '◕', '●') PKH]& YYUpython3.10/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-310.pycnu[o ai@sddlmZmZmZddlmZmZddlZddlm Z ddlm Z ddlm Z ddl m Z dd lmZdd lmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z d d dZ!d!ddZ"ddZ#Gddde$Z%ej&ddZ'ddZ(  d"ddZ)Gddde*Z+dS)#)absolute_importdivisionunicode_literals)with_metaclassviewkeysN) _inputstream) _tokenizer) treebuilders)Marker)_utils)spaceCharactersasciiUpper2LowerspecialElementsheadingElements cdataElementsrcdataElements tokenTypes tagTokenTypes namespaceshtmlIntegrationPointElements"mathmlTextIntegrationPointElementsadjustForeignAttributesadjustMathMLAttributesadjustSVGAttributesE_ReparseExceptionetreeTcKs(t|}t||d}|j|fi|S)aParse an HTML document as a string or file-like object into a tree :arg doc: the document to parse as a string or file-like object :arg treebuilder: the treebuilder to use when parsing :arg namespaceHTMLElements: whether or not to namespace HTML elements :returns: parsed tree Example: >>> from html5lib.html5parser import parse >>> parse('

This is a doc

') namespaceHTMLElements)r getTreeBuilder HTMLParserparse)doc treebuilderrkwargstbpr(/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/html5parser.pyr"s  r"divcKs,t|}t||d}|j|fd|i|S)a#Parse an HTML fragment as a string or file-like object into a tree :arg doc: the fragment to parse as a string or file-like object :arg container: the container context to parse the fragment in :arg treebuilder: the treebuilder to use when parsing :arg namespaceHTMLElements: whether or not to namespace HTML elements :returns: parsed tree Example: >>> from html5lib.html5libparser import parseFragment >>> parseFragment('this is a fragment') r container)r r r! parseFragment)r#r+r$rr%r&r'r(r(r)r,1s  r,csGfdddt}|S)NcseZdZfddZdS)z-method_decorator_metaclass..Decoratedcs>|D]\}}t|tjr|}|||<qt||||SN)items isinstancetypes FunctionTypetype__new__)meta classnamebases classDict attributeName attributefunctionr(r)r3Ls   z5method_decorator_metaclass..Decorated.__new__N)__name__ __module__ __qualname__r3r(r:r(r) DecoratedKsr?)r2)r;r?r(r:r)method_decorator_metaclassJsr@c@seZdZdZd'ddZd(dd Zd d Zed d ZddZ ddZ ddZ ddZ ddZ d)ddZddZddZdd Zd!d"Zd#d$Zd%d&ZdS)*r!z]HTML parser Generates a tree structure from a stream of (possibly malformed) HTML. NFTcsH|_|dur td}||_g_fddt|D_dS)a :arg tree: a treebuilder class controlling the type of tree that will be returned. Built in treebuilders can be accessed through html5lib.treebuilders.getTreeBuilder(treeType) :arg strict: raise an exception when a parse error is encountered :arg namespaceHTMLElements: whether or not to namespace HTML elements :arg debug: whether or not to enable debug mode which logs things Example: >>> from html5lib.html5parser import HTMLParser >>> parser = HTMLParser() # generates parser with etree builder >>> parser = HTMLParser('lxml', strict=True) # generates parser with lxml builder which is strict Nrcsi|] \}}||jqSr()tree).0nameclsselfr(r) ysz'HTMLParser.__init__..)strictr r rAerrors getPhasesr.phases)rFrArHrdebugr(rEr)__init__]s     zHTMLParser.__init__r*cKsf||_||_||_tj|fd|i||_|z|WdSty2||YdSw)Nparser) innerHTMLModer+ scriptingr HTMLTokenizer tokenizerresetmainLoopr)rFstream innerHTMLr+rPr%r(r(r)_parse|s zHTMLParser._parsecCs|jd|_g|_g|_d|_|jrO|j|_ |j t vr&|j j |j _ n|j tvr2|j j|j _ n |j dkr>|j j|j _ n |jd|_|j|n d|_ |jd|_d|_d|_d|_dS)NFz no quirks plaintext beforeHtmlinitialT)rArS firstStartTagrIlog compatModerOr+lowerrVrrR rcdataStatestater rawtextStateplaintextStaterKphaseinsertHtmlElementresetInsertionMode lastPhasebeforeRCDataPhase framesetOKrEr(r(r)rSs,          zHTMLParser.resetcCst|dsdS|jjjdjS)zName of the character encoding that was used to decode the input stream, or :obj:`None` if that is not determined yet rRNr)hasattrrRrU charEncodingrCrEr(r(r)documentEncodings zHTMLParser.documentEncodingcCsF|jdkr|jtdkrd|jvo|jdtdvS|j|jftvS)Nannotation-xmlmathmlencoding)z text/htmlzapplication/xhtml+xml)rC namespacer attributes translaterrrFelementr(r(r)isHTMLIntegrationPoints   z!HTMLParser.isHTMLIntegrationPointcCs|j|jftvSr-)rorCrrrr(r(r)isMathMLTextIntegrationPointz'HTMLParser.isMathMLTextIntegrationPointcCsRtd}td}td}td}td}td}td}|jD]}d} |} | dur| } |jjr5|jjdnd} | r<| jnd} | rC| jnd} | d }||kr\|| d | d id} nt|jjd ks| |jj ks| | r||kr}|d t ddgvs|||fvs| t dkr| dkr||kr|d dks| | r||||fvr|j}n|jd}||kr|| } n1||kr|| } n'||kr|| } n||kr|| } n||kr|| } n ||kr|| } | dus)||kr| dr| ds|dd | d iqd}g}|r'||j|j}|r"|j|vs"J|s dSdS)N CharactersSpaceCharactersStartTagEndTagCommentDoctype ParseErrorr2datadatavarsrrCmglyph malignmarkrmrlsvginForeignContent selfClosingselfClosingAcknowledgedz&non-void-element-with-trailing-solidusT)rrRrA openElementsrorC parseErrorgetlendefaultNamespaceru frozensetrrtrcrKprocessCharactersprocessSpaceCharactersprocessStartTag processEndTagprocessCommentprocessDoctypeappend processEOF)rFCharactersTokenSpaceCharactersToken StartTagToken EndTagToken CommentToken DoctypeTokenParseErrorTokentoken prev_token new_token currentNodecurrentNodeNamespacecurrentNodeNamer2rc reprocessrKr(r(r)rTs~            )   zHTMLParser.mainLoopcOs&|j|ddg|Ri||jS)aParse a HTML document into a well-formed tree :arg stream: a file-like object or string containing the HTML to be parsed The optional encoding parameter must be a string that indicates the encoding. If specified, that encoding will be used, regardless of any BOM or later declaration (such as in a meta element). :arg scripting: treat noscript elements as if JavaScript was turned on :returns: parsed tree Example: >>> from html5lib.html5parser import HTMLParser >>> parser = HTMLParser() >>> parser.parse('

This is a doc

') FN)rWrA getDocumentrFrUargsr%r(r(r)r"s zHTMLParser.parsecOs$|j|dg|Ri||jS)aZParse a HTML fragment into a well-formed tree fragment :arg container: name of the element we're setting the innerHTML property if set to None, default to 'div' :arg stream: a file-like object or string containing the HTML to be parsed The optional encoding parameter must be a string that indicates the encoding. If specified, that encoding will be used, regardless of any BOM or later declaration (such as in a meta element) :arg scripting: treat noscript elements as if JavaScript was turned on :returns: parsed tree Example: >>> from html5lib.html5libparser import HTMLParser >>> parser = HTMLParser() >>> parser.parseFragment('this is a fragment') T)rWrA getFragmentrr(r(r)r,s zHTMLParser.parseFragmentXXX-undefined-errorcCs@|duri}|j|jj||f|jrtt||dSr-)rIrrRrUpositionrHr}r)rF errorcoderr(r(r)r;s zHTMLParser.parseErrorcCt|tdSr-)adjust_attributesrrFrr(r(r)rCz!HTMLParser.adjustMathMLAttributescCrr-)rrrr(r(r)rFrzHTMLParser.adjustSVGAttributescCrr-)radjustForeignAttributesMaprr(r(r)rIrz"HTMLParser.adjustForeignAttributescCs|jdSr-)rNrcrr(r(r)reparseTokenNormalLszHTMLParser.reparseTokenNormalcCsd}ddddddddddd d d d d }|jjddd D]B}|j}d}||jjdkr5|js0Jd}|j}|dvr>|js>J|sH|j|jjkrHq||vrU|j||}n |r^|jd }nq||_dS)NFinSelectinCellinRow inTableBody inCaption inColumnGroupinTableinBody inFrameset beforeHead)selecttdthtrtbodytheadtfootcaptioncolgrouptableheadbodyframesethtmlr~rT)rrrr)rArrCrVrorrKrc)rFlastnewModesnodenodeName new_phaser(r(r)rePsF    zHTMLParser.resetInsertionModecCsR|dvsJ|j||dkr|jj|j_n|jj|j_|j|_|jd|_dS)N)RAWTEXTRCDATArtext) rA insertElementrRrar`r_rc originalPhaserK)rFr contentTyper(r(r)parseRCDataRawtext|s   zHTMLParser.parseRCDataRawtext)NFTF)Fr*F)rN)r<r=r>__doc__rMrWrSpropertyrkrtrurTr"r,rrrrrrerr(r(r(r)r!Vs&  "   C  ,r!csHdd}dd}Gdddt|||Gddd}Gd d d }Gd d d }Gd dd}Gddd}Gddd}GfdddGddd} Gfddd} GfdddGfddd} Gfddd} Gfdd d } Gfd!d"d"}Gfd#d$d$}Gfd%d&d&}Gd'd(d(}Gfd)d*d*}Gd+d,d,}Gfd-d.d.}Gfd/d0d0}Gd1d2d2}Gd3d4d4}id5|d6|d7|d8|d9|d:|d;d<| d=| d>d?| d@| dA| dB|dC|dD|dE|||||||dFS)GNcs$ddtDfdd}|S)z4Logger that records which phase processes each tokencSsi|]\}}||qSr(r()rBkeyvaluer(r(r)rGsz*getPhases..log..csjdrFt|dkrF|d}d|di}|dtvr$|d|d<|jj|jjjj|jj j j|j jj|f|g|Ri|S|g|Ri|S)Nprocessrr2rC) r< startswithrrrNr\rrRr`rc __class__)rFrr%rinfor; type_namesr(r)wrappeds   z'getPhases..log..wrapped)rr.)r;rr(rr)r\szgetPhases..logcSs|rt|StSr-)r@r2) use_metaclassmetaclass_funcr(r(r) getMetaclassszgetPhases..getMetaclassc@s\eZdZdZdZddZddZddZd d Zd d Z d dZ ddZ ddZ ddZ dS)zgetPhases..PhasezNBase class for helper object that implements each phase of processing )rNrA__startTagCache __endTagCachecSs||_||_i|_i|_dSr-)rNrA_Phase__startTagCache_Phase__endTagCache)rFrNrAr(r(r)rMs z!getPhases..Phase.__init__cSstr-)NotImplementedErrorrEr(r(r)rz#getPhases..Phase.processEOFcS|j||jjddS)Nr~rA insertCommentrrr(r(r)rz'getPhases..Phase.processCommentcS|jddS)Nzunexpected-doctyperNrrr(r(r)rrvz'getPhases..Phase.processDoctypecS|j|ddSNrrA insertTextrr(r(r)rz*getPhases..Phase.processCharacterscSrrrrr(r(r)rrz/getPhases..Phase.processSpaceCharacterscS|d}||jvr|j|}||S|j|}|j|<t|jt|jdkr?|jtt|jt|jt|jdks(||SNrCg?)rstartTagHandlerrpopnextiterrFrrCfuncr(r(r)r  z(getPhases..Phase.processStartTagcSsf|jjs|ddkr|jd|dD]\}}||jjdjvr,||jjdj|<qd|j_dS)NrCrz non-html-rootrrF)rNr[rr.rArrprFrattrrr(r(r) startTagHtmls  z%getPhases..Phase.startTagHtmlcSrr)r endTagHandlerrrrrrr(r(r)rrz&getPhases..Phase.processEndTagN)r<r=r>r __slots__rMrrrrrrrrr(r(r(r)Phases rc@sReZdZeZddZddZddZddZd d Z d d Z d dZ ddZ dS)zgetPhases..InitialPhasecSdSr-r(rr(r(r)rrz6getPhases..InitialPhase.processSpaceCharacterscS|j||jjdSr-rArdocumentrr(r(r)rz.getPhases..InitialPhase.processCommentcSs|d}|d}|d}|d}|dks |dus |dur&|dkr&|jd|dur,d}|j||dkr;|t}|r]|ddks]|d s]|d vs]|d rU|dus]|rb|d krbd |j_n|dsp|d rt|durtd|j_|jj d|j_ dS)NrCpublicIdsystemIdcorrectrzabout:legacy-compatzunknown-doctype)7z*+//silmaril//dtd html pro v0r11 19970101//z4-//advasoft ltd//dtd html 3.0 aswedit + extensions//z*-//as//dtd html 3.0 aswedit + extensions//z-//ietf//dtd html 2.0 level 1//z-//ietf//dtd html 2.0 level 2//z&-//ietf//dtd html 2.0 strict level 1//z&-//ietf//dtd html 2.0 strict level 2//z-//ietf//dtd html 2.0 strict//z-//ietf//dtd html 2.0//z-//ietf//dtd html 2.1e//z-//ietf//dtd html 3.0//z-//ietf//dtd html 3.2 final//z-//ietf//dtd html 3.2//z-//ietf//dtd html 3//z-//ietf//dtd html level 0//z-//ietf//dtd html level 1//z-//ietf//dtd html level 2//z-//ietf//dtd html level 3//z"-//ietf//dtd html strict level 0//z"-//ietf//dtd html strict level 1//z"-//ietf//dtd html strict level 2//z"-//ietf//dtd html strict level 3//z-//ietf//dtd html strict//z-//ietf//dtd html//z(-//metrius//dtd metrius presentational//z5-//microsoft//dtd internet explorer 2.0 html strict//z.-//microsoft//dtd internet explorer 2.0 html//z0-//microsoft//dtd internet explorer 2.0 tables//z5-//microsoft//dtd internet explorer 3.0 html strict//z.-//microsoft//dtd internet explorer 3.0 html//z0-//microsoft//dtd internet explorer 3.0 tables//z#-//netscape comm. corp.//dtd html//z*-//netscape comm. corp.//dtd strict html//z*-//o'reilly and associates//dtd html 2.0//z3-//o'reilly and associates//dtd html extended 1.0//z;-//o'reilly and associates//dtd html extended relaxed 1.0//zN-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//zE-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//z$-//spyglass//dtd html 2.0 extended//z+-//sq//dtd html 2.0 hotmetal + extensions//z--//sun microsystems corp.//dtd hotjava html//z4-//sun microsystems corp.//dtd hotjava strict html//z-//w3c//dtd html 3 1995-03-24//z-//w3c//dtd html 3.2 draft//z-//w3c//dtd html 3.2 final//z-//w3c//dtd html 3.2//z-//w3c//dtd html 3.2s draft//z-//w3c//dtd html 4.0 frameset//z#-//w3c//dtd html 4.0 transitional//z(-//w3c//dtd html experimental 19960712//z&-//w3c//dtd html experimental 970421//z-//w3c//dtd w3 html//z-//w3o//dtd w3 html 3.0//z#-//webtechs//dtd mozilla html 2.0//z-//webtechs//dtd mozilla html//)z$-//w3o//dtd w3 html strict 3.0//en//z"-/w3c/dtd html 4.0 transitional/enr)z -//w3c//dtd html 4.01 frameset//z$-//w3c//dtd html 4.01 transitional//z:http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtdquirks)z -//w3c//dtd xhtml 1.0 frameset//z$-//w3c//dtd xhtml 1.0 transitional//zlimited quirksrY) rNrrA insertDoctyperqrrr^r]rKrc)rFrrCrrr r(r(r)rsJ   9  z.getPhases..InitialPhase.processDoctypecSsd|j_|jjd|j_dS)Nr rY)rNr]rKrcrEr(r(r) anythingElseZsz,getPhases..InitialPhase.anythingElsecS|jd||S)Nzexpected-doctype-but-got-charsrNrr rr(r(r)r^ z1getPhases..InitialPhase.processCharacterscS"|jdd|di||S)Nz"expected-doctype-but-got-start-tagrCrrr(r(r)rc  z/getPhases..InitialPhase.processStartTagcSr)Nz expected-doctype-but-got-end-tagrCrrr(r(r)rirz-getPhases..InitialPhase.processEndTagcS|jd|dS)Nzexpected-doctype-but-got-eofTrrEr(r(r)rorz*getPhases..InitialPhase.processEOFN) r<r=r>tuplerrrrr rrrrr(r(r(r) InitialPhases_ rc@sJeZdZeZddZddZddZddZd d Z d d Z d dZ dS)z"getPhases..BeforeHtmlPhasecSs&|jtdd|jjd|j_dS)Nrryr)rA insertRootimpliedTagTokenrNrKrcrEr(r(r)rdxsz4getPhases..BeforeHtmlPhase.insertHtmlElementcS |dSNTrdrEr(r(r)r}z-getPhases..BeforeHtmlPhase.processEOFcSrr-rrr(r(r)rrz1getPhases..BeforeHtmlPhase.processCommentcSrr-r(rr(r(r)rrz9getPhases..BeforeHtmlPhase.processSpaceCharacterscS ||Sr-rrr(r(r)rrz4getPhases..BeforeHtmlPhase.processCharacterscSs |ddkr d|j_||S)NrCrT)rNr[rdrr(r(r)rs z2getPhases..BeforeHtmlPhase.processStartTagcSs2|ddvr|jdd|didS||S)NrCrrrbrzunexpected-end-tag-before-html)rNrrdrr(r(r)rs  z0getPhases..BeforeHtmlPhase.processEndTagN) r<r=r>rrrdrrrrrrr(r(r(r)BeforeHtmlPhasets rc@seZdZeZddZddZddZddZd d Z d d Z d dZ ddZ e defde fgZe e_e de fgZe e_dS)z"getPhases..BeforeHeadPhasecSs|tdddS)NrryT startTagHeadrrEr(r(r)rz-getPhases..BeforeHeadPhase.processEOFcSrr-r(rr(r(r)rrz9getPhases..BeforeHeadPhase.processSpaceCharacterscS|tdd|SNrryr rr(r(r)rr"z4getPhases..BeforeHeadPhase.processCharacterscS|jjd|SNrrNrKrrr(r(r)rz/getPhases..BeforeHeadPhase.startTagHtmlcSs0|j||jjd|j_|jjd|j_dS)Nr~inHead)rArr headPointerrNrKrcrr(r(r)r!s z/getPhases..BeforeHeadPhase.startTagHeadcSr#r$r rr(r(r) startTagOtherr"z0getPhases..BeforeHeadPhase.startTagOthercSr#r$r rr(r(r)endTagImplyHeadr"z2getPhases..BeforeHeadPhase.endTagImplyHeadcS|jdd|didS)Nzend-tag-after-implied-rootrCrrr(r(r) endTagOther z.getPhases..BeforeHeadPhase.endTagOtherrrrN)r<r=r>rrrrrrr!r+r,r.r MethodDispatcherrdefaultrr(r(r(r)BeforeHeadPhases& r2c @seZdZeZddZddZddZddZd d Z d d Z d dZ ddZ ddZ ddZddZddZddZddZddZedefd e fd!e fd"e fd#efd$e fd%e fd&efgZee_ed&efd'efgZee_d(S))zgetPhases..InHeadPhasecSrrr rEr(r(r)rrz)getPhases..InHeadPhase.processEOFcSrr-r3rr(r(r)rrz0getPhases..InHeadPhase.processCharacterscSr%r&r'rr(r(r)rr(z+getPhases..InHeadPhase.startTagHtmlcSr)Nz!two-heads-are-not-better-than-onerrr(r(r)r!rvz+getPhases..InHeadPhase.startTagHeadcS$|j||jjd|d<dSNTrrArrrrr(r(r)startTagBaseLinkCommand   z6getPhases..InHeadPhase.startTagBaseLinkCommandcSs|j||jjd|d<|d}|jjjjddkr[d|vr.|jjj|ddSd|vr]d|vr_|d d krat |d d }t |}|}|jjj|dSdSdSdSdS) NTrrr tentativecharsetcontentz http-equivz content-typezutf-8)rArrrrNrRrUrjchangeEncodingr^r EncodingBytesencodeContentAttrParserr")rFrrprrNcodecr(r(r) startTagMetas$   z+getPhases..InHeadPhase.startTagMetacS|j|ddS)NrrNrrr(r(r) startTagTitler(z,getPhases..InHeadPhase.startTagTitlecSrB)NrrCrr(r(r)startTagNoFramesStylez4getPhases..InHeadPhase.startTagNoFramesStylecSs:|jjr |j|ddS|j||jjd|j_dS)NrinHeadNoscript)rNrPrrArrKrcrr(r(r)startTagNoscripts z/getPhases..InHeadPhase.startTagNoscriptcSs<|j||jjj|jj_|jj|j_|jjd|j_dS)Nr) rArrNrRscriptDataStater`rcrrKrr(r(r)startTagScripts  z-getPhases..InHeadPhase.startTagScriptcSrr-r3rr(r(r)r+rz,getPhases..InHeadPhase.startTagOthercS:|jjj}|jdksJd|j|jjd|j_dS)NrzExpected head got %s afterHeadrNrArrrCrKrcrFrrr(r(r) endTagHead z)getPhases..InHeadPhase.endTagHeadcSrr-r3rr(r(r)endTagHtmlBodyBrrz/getPhases..InHeadPhase.endTagHtmlBodyBrcSr-Nunexpected-end-tagrCrrr(r(r)r.z*getPhases..InHeadPhase.endTagOthercS|tddS)Nr)rOrrEr(r(r)r r(z+getPhases..InHeadPhase.anythingElsertitle)noframesstylenoscriptscript)basebasefontbgsoundcommandlinkr4r)rrrN)r<r=r>rrrrrr!r7rArDrErHrJr+rOrQr.r r r0rr1rr(r(r(r) InHeadPhasesF  r`c@seZdZeZddZddZddZddZd d Z d d Z d dZ ddZ ddZ ddZddZddZede fde fde fgZe e_ede fdefgZee_dS)z&getPhases..InHeadNoscriptPhasecSr)Nzeof-in-head-noscriptTrrEr(r(r)r/rz1getPhases..InHeadNoscriptPhase.processEOFcSr%Nr))rNrKrrr(r(r)r4r(z5getPhases..InHeadNoscriptPhase.processCommentcSr)Nzchar-in-head-noscriptrrr(r(r)r7rz8getPhases..InHeadNoscriptPhase.processCharacterscSr%rarNrKrrr(r(r)r<r(z=getPhases..InHeadNoscriptPhase.processSpaceCharacterscSr%r&r'rr(r(r)r?r(z3getPhases..InHeadNoscriptPhase.startTagHtmlcSr%rar'rr(r(r)r7Br(z>getPhases..InHeadNoscriptPhase.startTagBaseLinkCommandcSr-Nunexpected-start-tagrCrrr(r(r)startTagHeadNoscriptErTz;getPhases..InHeadNoscriptPhase.startTagHeadNoscriptcSrNzunexpected-inhead-noscript-tagrCrrr(r(r)r+Hz4getPhases..InHeadNoscriptPhase.startTagOthercSrK)NrYzExpected noscript got %sr)rMrNr(r(r)endTagNoscriptMrPz5getPhases..InHeadNoscriptPhase.endTagNoscriptcSrrfrrr(r(r)endTagBrRrgz/getPhases..InHeadNoscriptPhase.endTagBrcSr-rRrrr(r(r)r.WrTz2getPhases..InHeadNoscriptPhase.endTagOthercSrU)NrY)rhrrEr(r(r)r ZrFz3getPhases..InHeadNoscriptPhase.anythingElser)r\r]r_r4rWrX)rrYrYrN)r<r=r>rrrrrrrr7rer+rhrir.r r r0rr1rr(r(r(r)InHeadNoscriptPhase,s2 rjc@seZdZeZddZddZddZddZd d Z d d Z d dZ ddZ ddZ ddZddZedefdefde fde fde fgZe e_ede fgZee_dS)z!getPhases..AfterHeadPhasecSrrr3rEr(r(r)rnrz,getPhases..AfterHeadPhase.processEOFcSrr-r3rr(r(r)rrrz3getPhases..AfterHeadPhase.processCharacterscSr%r&r'rr(r(r)rvr(z.getPhases..AfterHeadPhase.startTagHtmlcSs(d|j_|j||jjd|j_dS)NFr)rNrhrArrKrcrr(r(r) startTagBodyy z.getPhases..AfterHeadPhase.startTagBodycSs |j||jjd|j_dS)Nr)rArrNrKrcrr(r(r)startTagFrameset~s z2getPhases..AfterHeadPhase.startTagFramesetcSst|jdd|di|jj|jj|jjd||jjdddD]}|jdkr7|jj |dSq&dS)Nz#unexpected-start-tag-out-of-my-headrCr)r~r) rNrrArrr*rKrrCremoverNr(r(r)startTagFromHeads  z2getPhases..AfterHeadPhase.startTagFromHeadcSr-rcrrr(r(r)r!rTz.getPhases..AfterHeadPhase.startTagHeadcSrr-r3rr(r(r)r+rz/getPhases..AfterHeadPhase.startTagOthercSrr-r3rr(r(r)rQrz2getPhases..AfterHeadPhase.endTagHtmlBodyBrcSr-rRrrr(r(r)r.rTz-getPhases..AfterHeadPhase.endTagOthercSs.|jtdd|jjd|j_d|j_dS)NrryrT)rArrrNrKrcrhrEr(r(r)r s z.getPhases..AfterHeadPhase.anythingElserrr) r[r\r]r_r4rWrZrXrVr)rrrN)r<r=r>rrrrrrkrmror!r+rQr.r r r0rr1rr(r(r(r)AfterHeadPhaseks6   rpc seZdZdZfddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Z dd?Z"d@dAZ#dBdCZ$dDdEZ%dFdGZ&dHdIZ'dJdKZ(dLdMZ)dNdOZ*dPdQZ+dRdSZ,dTdUZ-dVdWZ.dXdYZ/dZd[Z0d\d]Z1d^d_Z2d`daZ3dbdcZ4dddeZ5dfdgZ6e78gdhj9fdie fdje fdke fdlefe:efdmefdnefdoefdpefdqefdrefdsefdtefduefdvefdwefdxefdyefdzefd{efd|efd}e fd~e!fde"fde#fde$fde&fde'fde%fde(fde)fde*fZ;e+e;_S)zgetPhases..InBodyPhase)rcs"t|j|i||j|_dSr-)superrMprocessSpaceCharactersNonPrerrFrr%) InBodyPhaserr(r)rMs z'getPhases..InBodyPhase.__init__cSs$|j|jko|j|jko|j|jkSr-)rCrorp)rFnode1node2r(r(r)isMatchingFormattingElements   z:getPhases..InBodyPhase.isMatchingFormattingElementcSs|j||jjd}g}|jjdddD]}|turn |||r*||qt|dks3Jt|dkrB|jj|d|jj|dS)Nr~) rArractiveFormattingElementsr rwrrrn)rFrrsmatchingElementsrr(r(r)addFormattingElements     z3getPhases..InBodyPhase.addFormattingElementcSs@td}|jjdddD]}|j|vr|jddSq dS)N) dddtlir'rrrrrrrrr~z expected-closing-tag-but-got-eof)rrArrCrNr)rFallowed_elementsrr(r(r)rs  z)getPhases..InBodyPhase.processEOFcSsj|d}|j|_|dr$|jjdjdvr$|jjds$|dd}|r3|j|j|dSdS)Nr r~)prelistingtextarear) rrrrrArrC hasContent#reconstructActiveFormattingElementsr)rFrrr(r(r)!processSpaceCharactersDropNewlines   z@getPhases..InBodyPhase.processSpaceCharactersDropNewlinecSs\|ddkrdS|j|j|d|jjr*tdd|dDr,d|j_dSdSdS)NrcSg|]}|tvqSr(r rBcharr(r(r) s zDgetPhases..InBodyPhase.processCharacters..F)rArrrNrhanyrr(r(r)rs   z0getPhases..InBodyPhase.processCharacterscSs|j|j|ddSr)rArrrr(r(r)rrs z;getPhases..InBodyPhase.processSpaceCharactersNonPrecSr%rar'rr(r(r)startTagProcessInHeadr(z4getPhases..InBodyPhase.startTagProcessInHeadcSs|jdddit|jjdks|jjdjdkr"|jjs JdSd|j_|dD]\}}||jjdj vrB||jjdj |<q,dS)NrdrCrrFr) rNrrrArrCrVrhr.rprr(r(r)rksz+getPhases..InBodyPhase.startTagBodycSs|jdddit|jjdks|jjdjdkr"|jjs JdS|jjs(dS|jjdjr=|jjdj |jjd|jjdjdkrU|jj |jjdjdksF|j ||jj d|j_ dS) NrdrCrrrr~rr)rNrrrArrCrVrhparent removeChildrrrKrcrr(r(r)rms"  z/getPhases..InBodyPhase.startTagFramesetcSs.|jjdddr|td|j|dSNr'buttonvariant)rAelementInScopeendTagPrrrr(r(r)startTagClosePsz-getPhases..InBodyPhase.startTagClosePcSs>|jjdddr|td|j|d|j_|j|_dS)Nr'rrF) rArrrrrNrhrrrr(r(r)startTagPreListings   z1getPhases..InBodyPhase.startTagPreListingcSs\|jjr|jdddidS|jjdddr|td|j||jjd|j_dS)NrdrCformr'rrr~) rA formPointerrNrrrrrrrr(r(r) startTagForms  z+getPhases..InBodyPhase.startTagFormcSsd|j_dgddgddgd}||d}t|jjD] }|j|vr/|jjt|jdn |j t vr;|jdvr;nq|jj d d d rN|jjtd d|j |dS) NFr~r}r|)r~r}r|rCrz)addressr*r'r'rr) rNrhreversedrArrCrcrr nameTuplerrr)rFr stopNamesMap stopNamesrr(r(r)startTagListItem&s*     z/getPhases..InBodyPhase.startTagListItemcSs>|jjdddr|td|j||jjj|jj_dSr) rArrrrrNrRrbr`rr(r(r)startTagPlaintext<s z0getPhases..InBodyPhase.startTagPlaintextcSsb|jjdddr|td|jjdjtvr)|jdd|di|jj |j |dS)Nr'rrr~rdrC) rArrrrrCrrNrrrrr(r(r)startTagHeadingBs  z.getPhases..InBodyPhase.startTagHeadingcSs~|jd}|r3|jdddd|td||jjvr&|jj|||jjvr3|jj||j | |dS)Na$unexpected-start-tag-implies-end-tag startNameendName) rA!elementInActiveFormattingElementsrNrendTagFormattingrrrnryrr{)rFr afeAElementr(r(r) startTagAJs    z(getPhases..InBodyPhase.startTagAcSs|j||dSr-)rArr{rr(r(r)startTagFormattingWs z1getPhases..InBodyPhase.startTagFormattingcSsP|j|jdr!|jdddd|td|j||dS)Nnobrrr)rArrrNrrrr{rr(r(r) startTagNobr[s   z+getPhases..InBodyPhase.startTagNobrcSsT|jdr|jdddd|td|S|j|j|d|j_dS)NrrrF) rArrNrrrrrrhrr(r(r)startTagButtones    z-getPhases..InBodyPhase.startTagButtoncSs0|j|j||jjtd|j_dSNF)rArrryrr rNrhrr(r(r)startTagAppletMarqueeObjectps   z:getPhases..InBodyPhase.startTagAppletMarqueeObjectcSsB|jjdddr|td|jd|j_|j|ddS)Nr'rrFr)rArrrrrNrhrrr(r(r) startTagXmpvs  z*getPhases..InBodyPhase.startTagXmpcSsR|jjdkr|jjdddr|td|j|d|j_|jjd|j_ dS)Nr r'rrFr) rNr]rArrrrrhrKrcrr(r(r) startTagTable}s  z,getPhases..InBodyPhase.startTagTablecSs6|j|j||jjd|d<d|j_dS)NTrF)rArrrrrNrhrr(r(r)startTagVoidFormattings    z5getPhases..InBodyPhase.startTagVoidFormattingcSsH|jj}||d|dvr |ddtdkr"||j_dSdSdS)Nr2rhidden)rNrhrrqr)rFrrhr(r(r) startTagInputs   z,getPhases..InBodyPhase.startTagInputcSr4r5r6rr(r(r)startTagParamSourcer8z2getPhases..InBodyPhase.startTagParamSourcecSsJ|jjdddr|td|j||jjd|d<d|j_dS)Nr'rrTrF) rArrrrrrrNrhrr(r(r) startTagHrs    z)getPhases..InBodyPhase.startTagHrcSs6|jdddd|tdd|d|dddS) Nzunexpected-start-tag-treated-asimageimg originalNamenewNameryrrrpr)rNrrrrr(r(r) startTagImages  z,getPhases..InBodyPhase.startTagImagecSs|jdddi|jjrdSi}d|dvr|dd|d<|tdd|d|td d|td dd |dvrF|dd }nd }|td |d|d}d|vr_|d=d |vrf|d =d|d<|tdd||dd| td |td d| tddS)Nzdeprecated-tagrCisindexactionrrry)rphrlabelpromptz3This is a searchable index. Enter search keywords: rwr2rinputrr) rNrrArrrrrcopyr)rFr form_attrsrrpr(r(r)startTagIsIndexs<      z.getPhases..InBodyPhase.startTagIsIndexcSs0|j||jjj|jj_|j|_d|j_dSr) rArrNrRr_r`rrrhrr(r(r)startTagTextareas  z/getPhases..InBodyPhase.startTagTextareacSsd|j_||dSr)rNrhstartTagRawtextrr(r(r)startTagIFramesz-getPhases..InBodyPhase.startTagIFramecSs$|jjr ||dS||dSr-)rNrPrr+rr(r(r)rHsz/getPhases..InBodyPhase.startTagNoscriptcSs|j|ddS)z8iframe, noembed noframes, noscript(if scripting enabled)rNrCrr(r(r)rrFz.getPhases..InBodyPhase.startTagRawtextcSs@|jjdjdkr|jjtd|j|jj|dSNr~option) rArrCrNrcrrrrrr(r(r) startTagOpts z*getPhases..InBodyPhase.startTagOptcSs|j|j|d|j_|jj|jjd|jjd|jjd|jjd|jjd|jjdfvr=|jjd|j_dS|jjd |j_dS) NFrrrrrrinSelectInTabler)rArrrNrhrcrKrr(r(r)startTagSelects       z-getPhases..InBodyPhase.startTagSelectcSsB|jdr|j|jjdjdkr|j|j|dS)Nrubyr~)rArgenerateImpliedEndTagsrrCrNrrrr(r(r) startTagRpRts   z+getPhases..InBodyPhase.startTagRpRtcS^|j|j||j|td|d<|j||dr-|jjd|d<dSdS)NrmrorTr) rArrNrrrrrrrr(r(r) startTagMath       z+getPhases..InBodyPhase.startTagMathcSr)NrrorTr) rArrNrrrrrrrr(r(r) startTagSvgrz*getPhases..InBodyPhase.startTagSvgcSs|jdd|didS)a5 Elements that should be children of other elements that have a different insertion mode; here they are ignored "caption", "col", "colgroup", "frame", "frameset", "head", "option", "optgroup", "tbody", "td", "tfoot", "th", "thead", "tr", "noscript" zunexpected-start-tag-ignoredrCNrrr(r(r)startTagMisplacedsz0getPhases..InBodyPhase.startTagMisplacedcSs|j|j|dSr-)rArrrr(r(r)r+s z,getPhases..InBodyPhase.startTagOthercSs|jjddds#|tdd|jdddi|tdddS|jd|jjdj dkr;|jdddi|jj }|j dkrS|jj }|j dksFdSdS) Nr'rrryrSrCrzr~) rArrrrNrrrrrCrrNr(r(r)rs    z&getPhases..InBodyPhase.endTagPcSs~|jds |jdS|jjdjdkr5|jjddD]}|jtdvr4|jdd|jdnq|jjd|j_dS)Nrr~)r|r}r~optgrouprr'rprtrrrrrrrr$expected-one-end-tag-but-got-anothergotName expectedName afterBody) rArrNrrrCrrKrcrNr(r(r) endTagBody)s    z)getPhases..InBodyPhase.endTagBodycSs"|jdr|td|SdS)Nr)rArrrrr(r(r) endTagHtml;s z)getPhases..InBodyPhase.endTagHtmlcSs|ddkr |j|_|j|d}|r|j|jjdj|dkr/|jdd|di|rM|jj }|j|dkrO|jj }|j|dks>dSdSdS)NrCrr~end-tag-too-early) rrrrArrrrCrNrr)rFrinScoperr(r(r) endTagBlockAs    z*getPhases..InBodyPhase.endTagBlockcSsx|jj}d|j_|dus|j|s|jdddidS|j|jjd|kr3|jdddi|jj|dS)NrSrCrr~zend-tag-too-early-ignored)rArrrNrrrrnrNr(r(r) endTagFormOs z)getPhases..InBodyPhase.endTagFormcSs|ddkr d}nd}|jj|d|ds"|jdd|didS|jj|dd|jjdj|dkrA|jdd|di|jj}|j|dkr]|jj}|j|dksNdSdS) NrCr~listrrSexcluder~r)rArrNrrrrCr)rFrrrr(r(r)endTagListItem\s    z-getPhases..InBodyPhase.endTagListItemcSstD]}|j|r|jnq|jjdj|dkr(|jdd|ditD]!}|j|rK|jj}|jtvrH|jj}|jtvs=dSq*dS)Nr~rCr) rrArrrrCrNrr)rFritemr(r(r) endTagHeadingms        z,getPhases..InBodyPhase.endTagHeadingcSsd}|dkr|d7}|j|d}|r"||jjvr)|j|js)||dS||jjvrC|jdd|di|jj |dS|j|jsW|jdd|didS||jjdkrj|jd d|di|jj |}d}|jj|dD] }|j t vr|}nq{|dur|jj }||kr|jj }||ks|jj |dS|jj|d}|jj |}|} } d} |jj | } | d kr(| d7} | d8} |jj| } | |jjvr|jj | q| |krn>| |kr|jj | d}| } | |jj|jj | <| |jj|jj | <| } | jr| j| | | | } | d ks| jr2| j| |jtd vrH|j\}}|| |n|| |} || || |jj ||jj|| |jj ||jj|jj |d| |dksdSdS) z)The much-feared adoption agency algorithmrrrCNzadoption-agency-1.2zadoption-agency-4.4r~zadoption-agency-1.3rxrrrrr)rArrrrCr.rNrryrnindexrrr cloneNoderr appendChildrgetTableMisnestedNodePosition insertBeforereparentChildreninsert)rFrouterLoopCounterformattingElementafeIndex furthestBlockrscommonAncestorbookmarklastNoderinnerLoopCounterrclonerrr(r(r)r|s                "    z/getPhases..InBodyPhase.endTagFormattingcSs|j|dr |j|jjdj|dkr#|jdd|di|j|drL|jj}|j|dkrE|jj}|j|dks8|jdSdS)NrCr~r) rArrrrCrNrrclearActiveFormattingElements)rFrrsr(r(r)endTagAppletMarqueeObjects   z8getPhases..InBodyPhase.endTagAppletMarqueeObjectcSs@|jdddd|j|jtdd|jjdS)Nzunexpected-end-tag-treated-asrz br elementrry)rNrrArrrrrrr(r(r)ri+s  z'getPhases..InBodyPhase.endTagBrcSs|jjdddD]O}|j|dkrE|jj|dd|jjdj|dkr1|jdd|di|jj|krB |jj|ks9dS|jtvrX|jdd|didSq dS)Nr~rCrrS) rArrCrrNrrrrrNr(r(r)r.2s z*getPhases..InBodyPhase.endTagOtherr) r[r\r]r^r_r4rZrXrVrr)rarticleaside blockquotecenterdetailsdirr*dlfieldset figcaptionfigurefooterheaderhgroupmainmenunavolr'sectionsummaryul)rrr)r~r|r}rXr) bbigcodeemfontissmallstrikestrongtturr)appletmarqueeobjectxmpr)arearembedrkeygenwbr)paramsourcetrackrrrrriframerY)noembedrWr)rr)rrmathr) rcolrframerrrrrrr)rrrrrrrdialogr r*r r r r rrrrrrrrrrrrr')r|r}r~)rrrrrrrrrrr r!r"r#r)?r<r=r>rrMrwr{rrrrrrrkrmrrrrrrrrrrrrrrrrrrrrrrHrrrrrrrr+rrrrrrrrrrir.r r0rrrr1r __classcell__r()rtrrr)rts*             $    !"#$%&'()-rtc@s`eZdZeZddZddZddZddZd d Z e gZ ee _ e d efgZe e_ d S) zgetPhases..TextPhasecSrrrrr(r(r)rrz.getPhases..TextPhase.processCharacterscSs8|jdd|jjdji|jj|jj|j_dS)Nz&expected-named-closing-tag-but-got-eofrCr~T)rNrrArrCrrrcrEr(r(r)rs   z'getPhases..TextPhase.processEOFcSsJd|d)NFz4Tried to process start tag %s in RCDATA/RAWTEXT moderCr(rr(r(r)r+rvz*getPhases..TextPhase.startTagOthercSs*|jj}|jdks J|jj|j_dS)NrZ)rArrrCrNrrcrNr(r(r) endTagScripts z)getPhases..TextPhase.endTagScriptcSs|jj|jj|j_dSr-)rArrrNrrcrr(r(r)r. z(getPhases..TextPhase.endTagOtherrZN)r<r=r>rrrrr+r7r.r r0rr1rr(r(r(r) TextPhases  r9c s eZdZeZddZddZddZddZd d Z d d Z d dZ ddZ ddZ ddZddZddZddZddZddZdd Zd!d"Zd#d$Zed%jfd&e fd'e fd(e fd)e fd*efd+efd,efd-efd.efg Zee_ed+efd/efgZee_d0S)1zgetPhases..InTablePhasecSs8|jjdjdvr|jj|jjdjdvs dSdS)Nr~)rr)rArrCrrEr(r(r)clearStackToTableContexts z8getPhases..InTablePhase.clearStackToTableContextcS2|jjdjdkr|jddS|jjsJdS)Nr~rz eof-in-tablerArrCrNrrVrEr(r(r)rz*getPhases..InTablePhase.processEOFcS4|jj}|jjd|j_||jj_|jj|dSN inTableText)rNrcrKrrrFrrr(r(r)r z6getPhases..InTablePhase.processSpaceCharacterscSr>r?)rNrcrKrrrAr(r(r)rrBz1getPhases..InTablePhase.processCharacterscSs&d|j_|jjd|d|j_dS)NTrF)rAinsertFromTablerNrKrrr(r(r)rs z*getPhases..InTablePhase.insertTextcSs6||jjt|j||jjd|j_dS)Nr) r:rAryrr rrNrKrcrr(r(r)startTagCaptions z/getPhases..InTablePhase.startTagCaptioncS(||j||jjd|j_dS)Nrr:rArrNrKrcrr(r(r)startTagColgrouprlz0getPhases..InTablePhase.startTagColgroupcSr#)Nrry)rGrrr(r(r) startTagColr"z+getPhases..InTablePhase.startTagColcSrENrrFrr(r(r)startTagRowGrouprlz0getPhases..InTablePhase.startTagRowGroupcSr#)Nrry)rJrrr(r(r)startTagImplyTbodyr"z2getPhases..InTablePhase.startTagImplyTbodycSs6|jdddd|jjtd|jjs|SdS)Nrrr)rNrrcrrrVrr(r(r)rsz-getPhases..InTablePhase.startTagTablecSr%rar'rr(r(r)startTagStyleScriptr(z3getPhases..InTablePhase.startTagStyleScriptcSsXd|dvr%|ddtdkr%|jd|j||jjdS||dS)Nr2rrz unexpected-hidden-input-in-table) rqrrNrrArrrr+rr(r(r)rs   z-getPhases..InTablePhase.startTagInputcSsH|jd|jjdur"|j||jjd|j_|jjdSdS)Nzunexpected-form-in-tabler~)rNrrArrrrrr(r(r)rs   z,getPhases..InTablePhase.startTagFormcS<|jdd|did|j_|jjd|d|j_dS)Nz)unexpected-start-tag-implies-table-voodoorCTrF)rNrrArCrKrrr(r(r)r+ z-getPhases..InTablePhase.startTagOthercSs|jjdddrJ|j|jjdjdkr%|jdd|jjdjd|jjdjdkr=|jj|jjdjdks.|jj|jdS|jj sPJ|jdS)Nrrr~zend-tag-too-early-namedr) rArrrrCrNrrrerVrr(r(r) endTagTables     z+getPhases..InTablePhase.endTagTablecSr-rRrrr(r(r) endTagIgnorerTz,getPhases..InTablePhase.endTagIgnorecSrM)Nz'unexpected-end-tag-implies-table-voodoorCTrF)rNrrArCrKrrr(r(r)r.rNz+getPhases..InTablePhase.endTagOtherrrrr2rrr)rrrr)rXrZrr) rrr2rrrrrrrrN)r<r=r>rrr:rrrrrDrGrHrJrKrrLrrr+rOrPr.r r0rrr1rr(rr(r) InTablePhasesP    rScsZeZdZdZfddZddZddZdd Zd d Zd d Z ddZ ddZ Z S)z#getPhases..InTableTextPhase)rcharacterTokenscs&t|j|i|d|_g|_dSr-)rqrMrrTrs)InTableTextPhaserr(r)rM6s z,getPhases..InTableTextPhase.__init__cSsdddd|jD}tdd|Dr%td|d}|jjd|n|r-|j|g|_dS)Nr cSsg|]}|dqS)rr(rBrr(r(r)r<zGgetPhases..InTableTextPhase.flushCharacters..cSrr(rrVr(r(r)r=rWrwrr)joinrTrrrNrKrrA)rFrrr(r(r)flushCharacters;s  z3getPhases..InTableTextPhase.flushCharacterscS||j|j_|Sr-rYrrNrcrr(r(r)rD z2getPhases..InTableTextPhase.processCommentcSs||j|j_dSrr[rEr(r(r)rIr\z.getPhases..InTableTextPhase.processEOFcSs |ddkrdS|j|dSNrrrTrrr(r(r)rNs z5getPhases..InTableTextPhase.processCharacterscS|j|dSr-r^rr(r(r)rSsz:getPhases..InTableTextPhase.processSpaceCharacterscSrZr-r[rr(r(r)rXr\z3getPhases..InTableTextPhase.processStartTagcSrZr-r[rr(r(r)r]r\z1getPhases..InTableTextPhase.processEndTag) r<r=r>rrMrYrrrrrrr5r()rUr6r)rU3s rUceZdZeZddZddZddZddZd d Z d d Z d dZ ddZ ddZ edjfdefgZe e_ede fde fde fgZe e_dS)z!getPhases..InCaptionPhasecS|jjddd S)NrrrrArrEr(r(r)ignoreEndTagCaptionfr(z5getPhases..InCaptionPhase.ignoreEndTagCaptioncS|jjddSr&rNrKrrEr(r(r)rirz,getPhases..InCaptionPhase.processEOFcSr%r&rNrKrrr(r(r)rlr(z3getPhases..InCaptionPhase.processCharacterscS0|j|}|jjtd|s|SdSNrrNrrcrcrrrFr ignoreEndTagr(r(r)startTagTableElementos z6getPhases..InCaptionPhase.startTagTableElementcSr%r&r'rr(r(r)r+wr(z/getPhases..InCaptionPhase.startTagOthercSs|sN|j|jjdjdkr!|jdd|jjdjd|jjdjdkr9|jj|jjdjdks*|jj|j|jj d|j_ dS|jj sTJ|jdS)Nr~rrrr) rcrArrrCrNrrrrKrcrVrr(r(r) endTagCaptionzs       z/getPhases..InCaptionPhase.endTagCaptioncSrgrhrirjr(r(r)rOs z-getPhases..InCaptionPhase.endTagTablecSr-rRrrr(r(r)rPrTz.getPhases..InCaptionPhase.endTagIgnorecSr%r&rNrKrrr(r(r)r.r(z-getPhases..InCaptionPhase.endTagOtherr rr2rrrrrrrrr) rr2rrrrrrrrN)r<r=r>rrrcrrrlr+rmrOrPr.r r0rrr1rr(rRr(r)InCaptionPhasebs4 rpcseZdZeZddZddZddZddZd d Z d d Z d dZ ddZ e djfdefgZe e_e de fde fgZe e_dS)z%getPhases..InColumnGroupPhasecSs|jjdjdkS)Nr~r)rArrCrEr(r(r)ignoreEndTagColgroupr(z:getPhases..InColumnGroupPhase.ignoreEndTagColgroupcSsD|jjdjdkr|jjsJdS|}|td|s dSdS)Nr~rrT)rArrCrNrVrqendTagColgroupr)rFrkr(r(r)rs z0getPhases..InColumnGroupPhase.processEOFcS"|}|td|s|SdSNrrqrrrrjr(r(r)r z7getPhases..InColumnGroupPhase.processCharacterscSr4r5r6rr(r(r)rHr8z1getPhases..InColumnGroupPhase.startTagColcSrsrtrurjr(r(r)r+rvz3getPhases..InColumnGroupPhase.startTagOthercSsB|r|jjs J|jdS|jj|jjd|j_dSNr) rqrNrVrrArrrKrcrr(r(r)rrs   z4getPhases..InColumnGroupPhase.endTagColgroupcSs|jdddidS)Nz no-end-tagrCr2rrr(r(r) endTagColrz/getPhases..InColumnGroupPhase.endTagColcSrsrtrurjr(r(r)r.rvz1getPhases..InColumnGroupPhase.endTagOtherrr2rN)r<r=r>rrrqrrrHr+rrrxr.r r0rrr1rr(rRr(r)InColumnGroupPhases(   rycseZdZeZddZddZddZddZd d Z d d Z d dZ ddZ ddZ ddZddZddZedjfde fde fde fgZe e_ede fdefdefgZee_d S)!z#getPhases..InTableBodyPhasecSsV|jjdjdvr|jj|jjdjdvs |jjdjdkr'|jjs)JdSdS)Nr~)rrrrr)rArrCrrNrVrEr(r(r)clearStackToTableBodyContexts  z@getPhases..InTableBodyPhase.clearStackToTableBodyContextcSrdrwrerEr(r(r)rrz.getPhases..InTableBodyPhase.processEOFcSr%rwrbrr(r(r)rr(z:getPhases..InTableBodyPhase.processSpaceCharacterscSr%rwrfrr(r(r)rr(z5getPhases..InTableBodyPhase.processCharacterscSrE)Nr)rzrArrNrKrcrr(r(r) startTagTrrlz.getPhases..InTableBodyPhase.startTagTrcSs*|jdd|di|tdd|S)Nzunexpected-cell-in-table-bodyrCrry)rNrr{rrr(r(r)startTagTableCell  z5getPhases..InTableBodyPhase.startTagTableCellcSn|jjddds|jjddds|jjdddr*||t|jjdj|S|jjs0J|j dSNrrrrrr~ rArrzendTagTableRowGrouprrrCrNrVrrr(r(r)startTagTableOther s z6getPhases..InTableBodyPhase.startTagTableOthercSr%rwr'rr(r(r)r+r(z1getPhases..InTableBodyPhase.startTagOthercSsV|jj|dddr||jj|jjd|j_dS|jdd|didS)NrCrrr unexpected-end-tag-in-table-body) rArrzrrrNrKrcrrr(r(r)rs  z7getPhases..InTableBodyPhase.endTagTableRowGroupcSr~rrrr(r(r)rO%s z/getPhases..InTableBodyPhase.endTagTablecSr-)NrrCrrr(r(r)rP2r/z0getPhases..InTableBodyPhase.endTagIgnorecSr%rwrnrr(r(r)r.6r(z/getPhases..InTableBodyPhase.endTagOtherrrrr)rr2rrrrrQr)rrr2rrrrrN)r<r=r>rrrzrrrr{r|rr+rrOrPr.r r0rrr1rr(rRr(r)InTableBodyPhases>    rcseZdZeZddZddZddZddZd d Z d d Z d dZ ddZ ddZ ddZddZddZddZedjfde fde fgZe e_ede fdefd efd!efgZee_d"S)#zgetPhases..InRowPhasecSsT|jjdjdvr(|jdd|jjdji|jj|jjdjdvs dSdS)Nr~)rrz'unexpected-implied-end-tag-in-table-rowrC)rArrCrNrrrEr(r(r)clearStackToTableRowContextOs  z9getPhases..InRowPhase.clearStackToTableRowContextcSra)NrrrrbrEr(r(r)ignoreEndTagTrUr(z,getPhases..InRowPhase.ignoreEndTagTrcSrdrwrerEr(r(r)rYrz(getPhases..InRowPhase.processEOFcSr%rwrbrr(r(r)r\r(z4getPhases..InRowPhase.processSpaceCharacterscSr%rwrfrr(r(r)r_r(z/getPhases..InRowPhase.processCharacterscSs6||j||jjd|j_|jjtdS)Nr) rrArrNrKrcryrr rr(r(r)r|bs z/getPhases..InRowPhase.startTagTableCellcSrsNrrendTagTrrrjr(r(r)rhs z0getPhases..InRowPhase.startTagTableOthercSr%rwr'rr(r(r)r+or(z+getPhases..InRowPhase.startTagOthercSsJ|s||jj|jjd|j_dS|jjsJ|j dSrI) rrrArrrNrKrcrVrrr(r(r)rrs   z&getPhases..InRowPhase.endTagTrcSrsrrrjr(r(r)rO|s z)getPhases..InRowPhase.endTagTablecSs4|jj|dddr|td|S|jdS)NrCrrr)rArrrrNrrr(r(r)rsz1getPhases..InRowPhase.endTagTableRowGroupcSr-)Nzunexpected-end-tag-in-table-rowrCrrr(r(r)rPr/z*getPhases..InRowPhase.endTagIgnorecSr%rwrnrr(r(r)r.r(z)getPhases..InRowPhase.endTagOtherrr)rr2rrrrrrrrQ)rrr2rrrrN)r<r=r>rrrrrrrr|rr+rrOrrPr.r r0rrr1rr(rRr(r) InRowPhaseJs@  rcr`)zgetPhases..InCellPhasecSsH|jjdddr|tddS|jjdddr"|tddSdSNrrrr)rArendTagTableCellrrEr(r(r) closeCells z(getPhases..InCellPhase.closeCellcSrdr&rerEr(r(r)rrz)getPhases..InCellPhase.processEOFcSr%r&rfrr(r(r)rr(z0getPhases..InCellPhase.processCharacterscSsF|jjddds|jjdddr||S|jjsJ|jdSr)rArrrNrVrrr(r(r)rs z1getPhases..InCellPhase.startTagTableOthercSr%r&r'rr(r(r)r+r(z,getPhases..InCellPhase.startTagOthercSs|jj|dddrN|j|d|jjdj|dkr9|jdd|di |jj}|j|dkr7nq)n|jj|j|jj d|j_ dS|jdd|didS) NrCrrr~zunexpected-cell-end-tagTrrS) rArrrrCrNrrrrKrcrNr(r(r)rs     z.getPhases..InCellPhase.endTagTableCellcSr-rRrrr(r(r)rPrTz+getPhases..InCellPhase.endTagIgnorecSs.|jj|dddr||S|jdS)NrCrr)rArrrNrrr(r(r) endTagImplysz*getPhases..InCellPhase.endTagImplycSr%r&rnrr(r(r)r.r(z*getPhases..InCellPhase.endTagOtherrror)rrr2rrrN)r<r=r>rrrrrrr+rrPrr.r r0rrr1rr(rRr(r) InCellPhases0  rc seZdZeZddZddZddZddZd d Z d d Z d dZ ddZ ddZ ddZddZddZedjfdefdefde fde fde fgZe e_ede fdefdefgZee_dS) z getPhases..InSelectPhasecSr;)Nr~rz eof-in-selectr<rEr(r(r)rr=z+getPhases..InSelectPhase.processEOFcSs$|ddkrdS|j|ddSr]rrr(r(r)rs z2getPhases..InSelectPhase.processCharacterscSs.|jjdjdkr|jj|j|dSrrArrCrrrr(r(r)startTagOptions z/getPhases..InSelectPhase.startTagOptioncSsL|jjdjdkr|jj|jjdjdkr|jj|j|dS)Nr~rrrrr(r(r)startTagOptgroup s   z1getPhases..InSelectPhase.startTagOptgroupcSs|jd|tddS)Nzunexpected-select-in-selectr)rNr endTagSelectrrr(r(r)r s z/getPhases..InSelectPhase.startTagSelectcSs>|jd|jjdddr|td|S|jjsJdS)Nzunexpected-input-in-selectrr)rNrrArrrrVrr(r(r)r s z.getPhases..InSelectPhase.startTagInputcSr%rar'rr(r(r)rJ r(z/getPhases..InSelectPhase.startTagScriptcSr-)Nzunexpected-start-tag-in-selectrCrrr(r(r)r+ r/z.getPhases..InSelectPhase.startTagOthercSs8|jjdjdkr|jjdS|jdddidS)Nr~runexpected-end-tag-in-selectrCrArrCrrNrrr(r(r) endTagOption s z-getPhases..InSelectPhase.endTagOptioncSsh|jjdjdkr|jjdjdkr|jj|jjdjdkr)|jjdS|jdddidS)Nr~rrrrCrrr(r(r)endTagOptgroup% s z/getPhases..InSelectPhase.endTagOptgroupcSsd|jjdddr%|jj}|jdkr|jj}|jdks|jdS|jjs+J|jdS)Nrr) rArrrrCrNrerVrrNr(r(r)r2 s     z-getPhases..InSelectPhase.endTagSelectcSr-)NrrCrrr(r(r)r.= r/z,getPhases..InSelectPhase.endTagOtherrrrr)rr*rrZN)r<r=r>rrrrrrrrrJr+rrrr.r r0rrr1rr(rRr(r) InSelectPhases:   rc@sneZdZeZddZddZddZddZd d Z d d Z e d efgZ ee _e d e fgZe e_dS)z'getPhases..InSelectInTablePhasecSrdNrrerEr(r(r)rU rz2getPhases..InSelectInTablePhase.processEOFcSr%rrfrr(r(r)rX r(z9getPhases..InSelectInTablePhase.processCharacterscSs(|jdd|di|td|S)Nz5unexpected-table-element-start-tag-in-select-in-tablerCr)rNrr.rrr(r(r)r[ sz5getPhases..InSelectInTablePhase.startTagTablecSr%rr'rr(r(r)r+` r(z5getPhases..InSelectInTablePhase.startTagOthercSs@|jdd|di|jj|dddr|td|SdS)Nz3unexpected-table-element-end-tag-in-select-in-tablerCrrr)rNrrArr.rrr(r(r)rOc s z3getPhases..InSelectInTablePhase.endTagTablecSr%rrnrr(r(r)r.i r(z3getPhases..InSelectInTablePhase.endTagOther)rrrrrrrrN)r<r=r>rrrrrr+rOr.r r0rr1rr(r(r(r)InSelectInTablePhaseR s( rcsBeZdZeZegdZddZfddZddZ dd Z d S) z(getPhases..InForeignContentPhase),rrrrrrrr|r*r r}rr)h1h2h3h4h5h6rrrrr~rrr4rrr'rrrrspanr!r subsuprr"r#rvarcSsiddddddddd d d d d ddddddddddddddddddd d!d"id#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdG}|dH|vr||dH|dH<dSdS)INaltglyphaltGlyph altglyphdef altGlyphDef altglyphitem altGlyphItem animatecolor animateColor animatemotion animateMotionanimatetransformanimateTransformclippathclipPathfeblendfeBlend fecolormatrix feColorMatrixfecomponenttransferfeComponentTransfer fecomposite feCompositefeconvolvematrixfeConvolveMatrixfediffuselightingfeDiffuseLightingfedisplacementmapfeDisplacementMapfedistantlightfeDistantLightfefloodfeFloodfefuncafeFuncAfefuncbfeFuncBfefuncgfeFuncGfefuncrfeFuncRfegaussianblurfeGaussianBlurfeimagefeImagefemergefeMerge femergenode feMergeNode femorphology feMorphologyfeoffsetfeOffset fepointlight fePointLightfespecularlightingfeSpecularLighting fespotlight feSpotLightfetilefeTile feturbulence feTurbulence foreignobject foreignObjectglyphrefglyphReflineargradientlinearGradientradialGradienttextPath)radialgradienttextpathrCr()rFr replacementsr(r(r)adjustSVGTagNames s      !" %z:getPhases..InForeignContentPhase.adjustSVGTagNamescsL|ddkr d|d<n|jjrtdd|dDrd|j_||dS)Nrru�css|]}|tvVqdSr-rrr(r(r) szMgetPhases..InForeignContentPhase.processCharacters..F)rNrhrrrrRr(r)r s  z:getPhases..InForeignContentPhase.processCharacterscSsf|jjd}|d|jvs|ddkrpt|dhd@rp|jdd|di|jjdj|jjkrn|j |jjdsn|j |jjdsn|jj |jjdj|jjkrn|j |jjdsn|j |jjdrI|S|jt dkr~|j |n|jt dkr|||j||j||j|d <|j||d r|jj d |d <dSdS) Nr~rCrr>sizecolorfacez*unexpected-html-element-in-foreign-contentrmrrorTr)rArbreakoutElementssetkeysrNrrorrtrurrrrrrr)rFrrr(r(r)r sH             z8getPhases..InForeignContentPhase.processStartTagcSst|jjd}|jjd}|jt|dkr#|jdd|di |jt|dkr`|jj|jj dkrE|jj |jjj |j_|jj |kr[|jjsSJ|jj |ksMd} |S|d8}|jj|}|j |jjkrrq#|jj|} |S)Nrr~rCrSTr@)rrArrCrqrrNrrcrKrYrrrorr)rFr nodeIndexrrr(r(r)r s,     z6getPhases..InForeignContentPhase.processEndTagN) r<r=r>rrrrrrrrr(rRr(r)InForeignContentPhasex s  ) rc@sveZdZeZddZddZddZddZd d Z d d Z d dZ e defgZe e_e de fgZe e_dS)z!getPhases..AfterBodyPhasecSrr-r(rEr(r(r)r z,getPhases..AfterBodyPhase.processEOFcSr)Nrrrr(r(r)r rz0getPhases..AfterBodyPhase.processCommentcS |jd|jjd|j_|S)Nzunexpected-char-after-bodyrrNrrKrcrr(r(r)r  z3getPhases..AfterBodyPhase.processCharacterscSr%r&r'rr(r(r)r r(z.getPhases..AfterBodyPhase.startTagHtmlcS*|jdd|di|jjd|j_|S)Nzunexpected-start-tag-after-bodyrCrrrr(r(r)r+ r}z/getPhases..AfterBodyPhase.startTagOthercSs,|jjr |jddS|jjd|j_dS)Nz'unexpected-end-tag-after-body-innerhtmlafterAfterBody)rNrVrrKrc)rFrCr(r(r)r sz,getPhases..AfterBodyPhase.endTagHtmlcSr)Nzunexpected-end-tag-after-bodyrCrrrr(r(r)r. r}z-getPhases..AfterBodyPhase.endTagOtherrN)r<r=r>rrrrrrr+rr.r r0rr1rr(r(r(r)AfterBodyPhase s rcseZdZeZddZddZddZddZd d Z d d Z d dZ ddZ e djfdefdefde fgZe e_e de fgZe e_dS)z"getPhases..InFramesetPhasecSr;)Nr~rzeof-in-framesetr<rEr(r(r)r r=z-getPhases..InFramesetPhase.processEOFcSr)Nzunexpected-char-in-framesetrrr(r(r)r" rvz4getPhases..InFramesetPhase.processCharacterscSr_r-)rArrr(r(r)rm% rvz3getPhases..InFramesetPhase.startTagFramesetcSs|j||jjdSr-r6rr(r(r) startTagFrame( r8z0getPhases..InFramesetPhase.startTagFramecSr%r&r'rr(r(r)startTagNoframes, r(z3getPhases..InFramesetPhase.startTagNoframescSr-)Nz unexpected-start-tag-in-framesetrCrrr(r(r)r+/ r/z0getPhases..InFramesetPhase.startTagOthercSsb|jjdjdkr|jdn|jj|jjs-|jjdjdkr/|jjd|j_dSdSdS)Nr~rz)unexpected-frameset-in-frameset-innerhtmlr afterFrameset) rArrCrNrrrVrKrcrr(r(r)endTagFrameset3 s z1getPhases..InFramesetPhase.endTagFramesetcSr-)Nzunexpected-end-tag-in-framesetrCrrr(r(r)r.? r/z.getPhases..InFramesetPhase.endTagOtherrrr3rWN)r<r=r>rrrrrmrrr+rr.r r0rrr1rr(rRr(r)InFramesetPhase s*  rcsveZdZeZddZddZddZddZd d Z d d Z e d j fdefgZee_e d e fgZe e_dS)z%getPhases..AfterFramesetPhasecSrr-r(rEr(r(r)rT rz0getPhases..AfterFramesetPhase.processEOFcSr)Nzunexpected-char-after-framesetrrr(r(r)rX rvz7getPhases..AfterFramesetPhase.processCharacterscSr%rar'rr(r(r)r[ r(z6getPhases..AfterFramesetPhase.startTagNoframescSr-)Nz#unexpected-start-tag-after-framesetrCrrr(r(r)r+^ r/z3getPhases..AfterFramesetPhase.startTagOthercSs|jjd|j_dS)NafterAfterFrameset)rNrKrcrr(r(r)rb rz0getPhases..AfterFramesetPhase.endTagHtmlcSr-)Nz!unexpected-end-tag-after-framesetrCrrr(r(r)r.e r/z1getPhases..AfterFramesetPhase.endTagOtherrrWN)r<r=r>rrrrrr+rr.r r0rrr1rr(rRr(r)AfterFramesetPhaseP s" rc@s`eZdZeZddZddZddZddZd d Z d d Z d dZ e de fgZe e_dS)z&getPhases..AfterAfterBodyPhasecSrr-r(rEr(r(r)rw rz1getPhases..AfterAfterBodyPhase.processEOFcSrr-rrr(r(r)rz rz5getPhases..AfterAfterBodyPhase.processCommentcSr%r&rbrr(r(r)r} r(z=getPhases..AfterAfterBodyPhase.processSpaceCharacterscSr)Nexpected-eof-but-got-charrrrr(r(r)r rz8getPhases..AfterAfterBodyPhase.processCharacterscSr%r&r'rr(r(r)r r(z3getPhases..AfterAfterBodyPhase.startTagHtmlcSr)Nexpected-eof-but-got-start-tagrCrrrr(r(r)r+ r}z4getPhases..AfterAfterBodyPhase.startTagOthercSr)Nexpected-eof-but-got-end-tagrCrrrr(r(r)r r}z4getPhases..AfterAfterBodyPhase.processEndTagrN)r<r=r>rrrrrrrr+rr r0rr1r(r(r(r)AfterAfterBodyPhaset s r c@sneZdZeZddZddZddZddZd d Z d d Z d dZ ddZ e de fde fgZe e_dS)z*getPhases..AfterAfterFramesetPhasecSrr-r(rEr(r(r)r rz5getPhases..AfterAfterFramesetPhase.processEOFcSrr-rrr(r(r)r rz9getPhases..AfterAfterFramesetPhase.processCommentcSr%r&rbrr(r(r)r r(zAgetPhases..AfterAfterFramesetPhase.processSpaceCharacterscSr)Nrrrr(r(r)r rvz.AfterAfterFramesetPhase.processCharacterscSr%r&r'rr(r(r)r r(z7getPhases..AfterAfterFramesetPhase.startTagHtmlcSr%rar'rr(r(r)startTagNoFrames r(z;getPhases..AfterAfterFramesetPhase.startTagNoFramescSr-)Nr rCrrr(r(r)r+ r/z8getPhases..AfterAfterFramesetPhase.startTagOthercSr-)Nr rCrrr(r(r)r r/z8getPhases..AfterAfterFramesetPhase.processEndTagrrWN)r<r=r>rrrrrrrr r+rr r0rr1r(r(r(r)AfterAfterFramesetPhase s r rZrYrr)rGrLrrrr@rrrrrrr)rrrrrr)r)rLr\rrrr2r`rjrpr9rSrpryrrrrrrrrrr r r()rtrUrr)rJsH%-f?BY!/F@bYLc&r.8$%%     rJcsJt|dt@}|r#t|dfdd|dD|d<dSdS)Nrc3s$|] \}}|||fVqdSr-)r)rBkvrr(r)r sz$adjust_attributes..)rr2r.)rrneeds_adjustmentr(rr)r s  rrzFcCs|duri}t||||dS)N)r2rCrr)r)rCr2rprr(r(r)r s  rc@seZdZdZdS)r}zError in parsed documentN)r<r=r>rr(r(r(r)r} sr})rT)r*rT)rzNF), __future__rrrZpip._vendor.sixrrr0r rr r Ztreebuilders.baser r constantsr rrrrrrrrrrrrrrrrr"r,r@r&r!memoizerJrr Exceptionr}r(r(r(r)sP     H  8 _ PKH]Q[]`**Tpython3.10/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-310.pycnu[o ai=@svddlmZmZmZddlmZddlZddlmZm Z ddl m Z m Z m Z ddl mZmZmZddlmZmZdd lmZd e d Zed ed Zed edZiZeddkZeeD]5\Z Z!erqee!dksyeszee!dkrzqee!dkree!dkre"e!Z!ne#e!Z!e!evse $re ee!<qeddZ%ede%dddZ&Gddde'Z(Gddde)Z*dS))absolute_importdivisionunicode_literals) text_typeN)register_errorxmlcharrefreplace_errors) voidElementsbooleanAttributesspaceCharacters)rcdataElementsentities xmlEntities) treewalkers_utils)escapez"'=<>`[]u_  /`  ᠎᠏           

   ]u􏿿&c Cst|ttfrg}g}d}t|j|j|jD]7\}}|r!d}q||j}t|j|t |j|dgrFt |j||d}d}nt |}| |q|D]+}t |} | rp| d| | | dso| dqR| dt|ddqRd||jfSt|S)NFrTr;z&#x%s;r) isinstanceUnicodeEncodeErrorUnicodeTranslateError enumerateobjectstartendrisSurrogatePairminsurrogatePairToCodepointordappend_encode_entity_mapgetendswithhexjoinr) excres codepointsskipicindex codepointcper3/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/serializer.pyhtmlentityreplace_errors*s2 "      r5htmlentityreplaceetreecKs(t|}tdi|}||||S)aSerializes the input token stream using the specified treewalker :arg input: the token stream to serialize :arg tree: the treewalker to use :arg encoding: the encoding to use :arg serializer_opts: any options to pass to the :py:class:`html5lib.serializer.HTMLSerializer` that gets created :returns: the tree serialized as a string Example: >>> from html5lib.html5parser import parse >>> from html5lib.serializer import serialize >>> token_stream = parse('

Hi!

') >>> serialize(token_stream, omit_optional_tags=False) '

Hi!

' Nr3)r getTreeWalkerHTMLSerializerrender)inputtreeencodingserializer_optswalkersr3r3r4 serializeKs rAc@s~eZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ dZdZdZdZddZdd Zd d Zdd dZdddZdddZd S)r9legacy"TF)quote_attr_values quote_charuse_best_quote_charomit_optional_tagsminimize_boolean_attributesuse_trailing_solidusspace_before_trailing_solidusescape_lt_in_attrs escape_rcdataresolve_entitiesalphabetical_attributesinject_meta_charsetstrip_whitespacesanitizec Ksvt|t|j}t|dkrtdtt|d|vr d|_|jD]}t||||t ||q#g|_ d|_ dS)aB Initialize HTMLSerializer :arg inject_meta_charset: Whether or not to inject the meta charset. Defaults to ``True``. :arg quote_attr_values: Whether to quote attribute values that don't require quoting per legacy browser behavior (``"legacy"``), when required by the standard (``"spec"``), or always (``"always"``). Defaults to ``"legacy"``. :arg quote_char: Use given quote character for attribute quoting. Defaults to ``"`` which will use double quotes unless attribute value contains a double quote, in which case single quotes are used. :arg escape_lt_in_attrs: Whether or not to escape ``<`` in attribute values. Defaults to ``False``. :arg escape_rcdata: Whether to escape characters that need to be escaped within normal elements within rcdata elements such as style. Defaults to ``False``. :arg resolve_entities: Whether to resolve named character entities that appear in the source tree. The XML predefined entities < > & " ' are unaffected by this setting. Defaults to ``True``. :arg strip_whitespace: Whether to remove semantically meaningless whitespace. (This compresses all whitespace to a single space except within ``pre``.) Defaults to ``False``. :arg minimize_boolean_attributes: Shortens boolean attributes to give just the attribute value, for example:: becomes:: Defaults to ``True``. :arg use_trailing_solidus: Includes a close-tag slash at the end of the start tag of void elements (empty elements whose end tag is forbidden). E.g. ``
``. Defaults to ``False``. :arg space_before_trailing_solidus: Places a space immediately before the closing slash in a tag using a trailing solidus. E.g. ``
``. Requires ``use_trailing_solidus=True``. Defaults to ``True``. :arg sanitize: Strip all unsafe or unknown constructs from output. See :py:class:`html5lib.filters.sanitizer.Filter`. Defaults to ``False``. :arg omit_optional_tags: Omit start/end tags that are optional. Defaults to ``True``. :arg alphabetical_attributes: Reorder attributes to be in alphabetical order. Defaults to ``False``. rz2__init__() got an unexpected keyword argument '%s'rEFN) frozensetoptionslen TypeErrornextiterrFsetattrr%getattrerrorsstrict)selfkwargsunexpected_argsattrr3r3r4__init__sO   zHTMLSerializer.__init__cC&t|tsJ|jr||jdS|S)Nr6rrr=encoder\stringr3r3r4rczHTMLSerializer.encodecCra)Nr[rbrdr3r3r4 encodeStrictrfzHTMLSerializer.encodeStrictNccs||_d}g|_|r|jrddlm}|||}|jr&ddlm}||}|jr3ddlm}||}|j r@ddl m}||}|j rMddl m}||}|D]}|d}|dkrd|d}|drm|d |d7}n|d ru|d 7}|d r|d  d d kr|d  dd kr|dd}nd }|d||d |f7}|d7}||VqO|dvr|dks|r|r|d dd kr|d||dVqO|t|dVqO|dvr|d} |d| V| tvr|jsd}n|r|d|dD]\\} } } | } | }|dV|| V|jr/| t| tvr| tdtvr|dV|jdksBt|d krEd}n |jdkrSt|du}n|jd krat|du}ntd!|d"d#}|j ru|d$d%}|r|j!}|j"rd|vrd |vrd }n d |vrd|vrd}|dkr|dd&}n|d d'}||V||V||Vq||Vq| t#vr|j$r|j%r|d(Vn|d)V|dVqO|d*kr |d} | tvrd}n|r|d|d+| VqO|d,kr*|d}| d-d kr|d.|d/|dVqO|d0kr\|d} | d1}|t&vrC|d2| |j'rQ|t(vrQt&|}nd3| }||VqO||dqOdS)4NFr)FiltertypeDoctypez ) CharactersSpaceCharactersrqdatazCommentz--zComment contains --z EntityrzEntity %s not recognizedz&%s;))r=rZrOfilters.inject_meta_charsetrhrNfilters.alphabeticalattributesrPfilters.whitespacerQfilters.sanitizerrGfilters.optionaltagsfindserializeErrorrgrcrr rLitemsrHr r%tuplerDrT_quoteAttributeSpecsearch_quoteAttributeLegacy ValueErrorreplacerKrErFr rIrJr rMr)r\ treewalkerr=in_cdatarhtokenridoctyperErk_ attr_name attr_valuekv quote_attrrrkeyr3r3r4rAs                                   zHTMLSerializer.serializecCs.|r dt|||Sdt||S)anSerializes the stream from the treewalker into a string :arg treewalker: the treewalker to serialize :arg encoding: the string encoding to use :returns: the serialized tree Example: >>> from html5lib import parse, getTreeWalker >>> from html5lib.serializer import HTMLSerializer >>> token_stream = parse('Hi!') >>> walker = getTreeWalker('etree') >>> serializer = HTMLSerializer(omit_optional_tags=False) >>> serializer.render(walker(token_stream)) 'Hi!' r)r(listrA)r\rr=r3r3r4r:wszHTMLSerializer.renderXXX ERROR MESSAGE NEEDEDcCs|j||jr tdSN)rZr#r[SerializeError)r\rrr3r3r4rs zHTMLSerializer.serializeErrorr)r)__name__ __module__ __qualname__rDrErFrGrHrIrJrKrLrMrNrOrPrQrSr`rcrgrAr:rr3r3r3r4r9hs.Y  r9c@seZdZdZdS)rzError in serialized treeN)rrr__doc__r3r3r3r4rsr)r7N)+ __future__rrrZpip._vendor.sixrrecodecsrr constantsr r r r r rrrrxml.sax.saxutilsrr(_quoteAttributeSpecCharscompilerrr$rT_is_ucs4rrrrr!r"islowerr5rArr9 Exceptionrr3r3r3r4sF         1PKH]d\TTVpython3.10/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-310.pycnu[o aia~@sddlmZmZmZddlmZddlmZmZddl Z ddl Z ddl m Z m Z ddlmZddlmZmZmZmZdd lmZdd lmZed d eDZed d eDZedd eDZeeddgBZdZejreddkr{eddks}Je edde!ddZ"ne eZ"hdZ#e dZ$iZ%Gddde&Z'ddZ(Gddde&Z)Gddde)Z*Gdd d e+Z,Gd!d"d"e&Z-Gd#d$d$e&Z.d%d&Z/dS)')absolute_importdivisionunicode_literals) text_type) http_clienturllibN)BytesIOStringIO) webencodings)EOFspaceCharacters asciiLettersasciiUppercase)_ReparseException)_utilscCg|]}|dqSasciiencode.0itemr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/_inputstream.py rcCrrrrrrrrrcCrrrrrrrrr> i iii iiiiiiiiii iii ii i iiiiii i i ii iiz[ - -/:-@\[-`{-~]c@sHeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS)BufferedStreamzBuffering for streams that do not have buffering of their own The buffer is implemented as a list of chunks on the assumption that joining many strings will be slow since it is O(n**2) cCs||_g|_ddg|_dS)Nr r)streambufferposition)selfr#rrr__init__:szBufferedStream.__init__cCs<d}|jd|jdD]}|t|7}q ||jd7}|SNrr )r$r%len)r&poschunkrrrtell?s zBufferedStream.tellcCsd||ksJ|}d}t|j||kr+|t|j|8}|d7}t|j||ks||g|_dSr()_bufferedBytesr)r$r%)r&r*offsetirrrseekFszBufferedStream.seekcCsP|js||S|jdt|jkr#|jdt|jdkr#||S||S)Nrr r )r$ _readStreamr%r)_readFromBufferr&bytesrrrreadOs    zBufferedStream.readcCstdd|jDS)NcSsg|]}t|qSr)r)rrrrrYsz1BufferedStream._bufferedBytes..)sumr$r&rrrr-XzBufferedStream._bufferedBytescCs<|j|}|j||jdd7<t||jd<|Sr()r#r5r$appendr%r))r&r4datarrrr1[s  zBufferedStream._readStreamcCs|}g}|jd}|jd}|t|jkrc|dkrc|dksJ|j|}|t||kr6|}|||g|_nt||}|t|g|_|d7}|||||||8}d}|t|jkrc|dks|rm|||d|S)Nrr )r%r)r$r9r1join)r&r4remainingBytesrv bufferIndex bufferOffset bufferedData bytesToReadrrrr2bs(      zBufferedStream._readFromBufferN) __name__ __module__ __qualname____doc__r'r,r0r5r-r1r2rrrrr"3s   r"cKst|tjst|tjjrt|jtjrd}nt|dr%t|dt }nt|t }|rCdd|D}|r;t d|t |fi|St |fi|S)NFr5rcSsg|] }|dr|qS) _encoding)endswith)rxrrrrsz#HTMLInputStream..z3Cannot set an encoding with a unicode input, set %r) isinstancer HTTPResponserresponseaddbasefphasattrr5r TypeErrorHTMLUnicodeInputStreamHTMLBinaryInputStream)sourcekwargs isUnicode encodingsrrrHTMLInputStream}s      rWc@speZdZdZdZddZddZddZd d Zd d Z d dZ dddZ ddZ ddZ dddZddZdS)rQProvides a unicode stream of characters to the HTMLTokenizer. This class takes care of character encoding and removing or replacing incorrect byte-sequences and also provides column and line tracking. i(cCsZtjsd|_ntddkr|j|_n|j|_dg|_tddf|_| ||_ | dS)Initialises the HTMLInputStream. HTMLInputStream(source, [encoding]) -> Normalized stream from source for use by html5lib. source can be either a file-object, local filename or a string. The optional encoding parameter must be a string that indicates the encoding. If specified, that encoding will be used, regardless of any BOM or later declaration (such as in a meta element) Nu􏿿r rutf-8certain) rsupports_lone_surrogatesreportCharacterErrorsr)characterErrorsUCS4characterErrorsUCS2newLineslookupEncoding charEncoding openStream dataStreamreset)r&rSrrrr's    zHTMLUnicodeInputStream.__init__cCs.d|_d|_d|_g|_d|_d|_d|_dS)Nr)r+ chunkSize chunkOffseterrors prevNumLines prevNumCols_bufferedCharacterr7rrrres zHTMLUnicodeInputStream.resetcCst|dr |}|St|}|SzvProduces a file object from source. source can be either a file object, local filename or a string. r5)rOr r&rSr#rrrrcs z!HTMLUnicodeInputStream.openStreamcCsZ|j}|dd|}|j|}|dd|}|dkr#|j|}||fS||d}||fS)N rr r )r+countrjrfindrk)r&r.r+nLines positionLine lastLinePospositionColumnrrr _positions   z HTMLUnicodeInputStream._positioncCs||j\}}|d|fS)z:Returns (line, col) of the current position in the stream.r )rvrh)r&linecolrrrr%s zHTMLUnicodeInputStream.positioncCs6|j|jkr |s tS|j}|j|}|d|_|S)zo Read one character from the stream or queue if available. Return EOF when EOF is reached. r )rhrg readChunkr r+)r&rhcharrrrrzs   zHTMLUnicodeInputStream.charNcCs|dur|j}||j\|_|_d|_d|_d|_|j|}|j r,|j |}d|_ n|s0dSt |dkrWt |d}|dksLd|krJdkrWnn |d|_ |dd}|j r_| || d d }| d d }||_t ||_d S) NrfrFr r iz ro T)_defaultChunkSizervrgrjrkr+rhrdr5rlr)ordr]replace)r&rgr:lastvrrrrys0           z HTMLUnicodeInputStream.readChunkcCs(ttt|D]}|jdq dS)Ninvalid-codepoint)ranger)invalid_unicode_refindallrir9)r&r:_rrrr^sz*HTMLUnicodeInputStream.characterErrorsUCS4cCsd}t|D]Q}|r qt|}|}t|||dr9t|||d}|tvr6|j dd}q|dkrP|dkrP|t |dkrP|j dqd}|j dqdS)NFrTr|ir ) rfinditerrgroupstartrisSurrogatePairsurrogatePairToCodepointnon_bmp_invalid_codepointsrir9r))r&r:skipmatch codepointr*char_valrrrr_#s"  z*HTMLUnicodeInputStream.characterErrorsUCS2Fc Cszt||f}Wn4ty< |D] }t|dksJqddd|D}|s-d|}td|}t||f<Ynwg} ||j|j}|durT|j|j krSn*n| }||j krl| |j|j|||_n| |j|jd| s|nq@d|} | S) z Returns a string of characters from the stream up to but not including any character in 'characters' or EOF. 'characters' must be a container that supports the 'in' method and iteration over its characters. TrfcSsg|]}dt|qS)z\x%02x)r)rcrrrrHsz5HTMLUnicodeInputStream.charsUntil..z^%sz[%s]+N) charsUntilRegExKeyErrorrr<recompilerr+rhrgendr9ry) r& charactersoppositecharsrregexr>mrrrrr charsUntil:s:     z!HTMLUnicodeInputStream.charsUntilcCsZ|tur)|jdkr||j|_|jd7_dS|jd8_|j|j|ks+JdSdSr()r rhr+rg)r&rzrrrungetis   zHTMLUnicodeInputStream.ungetN)F)rCrDrErFr~r'rercrvr%rzryr^r_rrrrrrrQs   &  /rQc@sReZdZdZ   dddZddZd d Zdd d Zd dZddZ ddZ dS)rRrXN windows-1252TcCsn|||_t||jd|_d|_||_||_||_||_ ||_ | ||_ |j ddus1J| dS)rYidrN)rc rawStreamrQr' numBytesMetanumBytesChardetoverride_encodingtransport_encodingsame_origin_parent_encodinglikely_encodingdefault_encodingdetermineEncodingrbre)r&rSrrrrr useChardetrrrr's   zHTMLBinaryInputStream.__init__cCs&|jdj|jd|_t|dS)Nrr)rb codec_info streamreaderrrdrQrer7rrrreszHTMLBinaryInputStream.resetcCsJt|dr|}nt|}z ||W|Sty$t|}Y|Swrm)rOrr0r, Exceptionr"rnrrrrcs  z HTMLBinaryInputStream.openStreamcCs|df}|ddur|St|jdf}|ddur|St|jdf}|ddur,|S|df}|ddur:|St|jdf}|ddurQ|djdsQ|St|jdf}|ddur`|S|rzddl m }Wn t ysYn@wg}|}|j s|j |j}t|tsJ|sn |||||j r||t|jd}|j d|dur|dfSt|jdf}|ddur|StddfS)Nr[r tentativezutf-16)UniversalDetectorencodingr) detectBOMrarrdetectEncodingMetarname startswithr%pip._vendor.chardet.universaldetectorr ImportErrordonerr5rrJr4r9feedcloseresultr0r)r&chardetrbrbuffersdetectorr$rrrrrsV             z'HTMLBinaryInputStream.determineEncodingcCs|jddks Jt|}|durdS|jdvr$td}|dus"JdS||jdkr5|jddf|_dS|jd|df|_|td|jd|f)Nr r[utf-16beutf-16lerZrzEncoding changed from %s to %s)rbrarrr0rer)r& newEncodingrrrchangeEncodings   z$HTMLBinaryInputStream.changeEncodingc Cstjdtjdtjdtjdtjdi}|jd}t|t sJ| |dd}d}|s?| |}d}|s?| |dd }d }|rK|j |t |S|j d dS) zAttempts to detect at BOM at the start of the stream. If an encoding can be determined from the BOM return the name of the encoding otherwise return NonerZrrzutf-32lezutf-32beNrr) codecsBOM_UTF8 BOM_UTF16_LE BOM_UTF16_BE BOM_UTF32_LE BOM_UTF32_BErr5rJr4getr0ra)r&bomDictstringrr0rrrrs&      zHTMLBinaryInputStream.detectBOMcCsV|j|j}t|tsJt|}|jd|}|dur)|jdvr)t d}|S)z9Report the encoding declared by the meta element rNrrZ) rr5rrJr4EncodingParserr0 getEncodingrra)r&r$parserrrrrr3s z(HTMLBinaryInputStream.detectEncodingMeta)NNNNrT)T) rCrDrErFr'rercrrrrrrrrrRzs * > "rRc@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ e e e Z ddZe eZefddZddZddZddZdS) EncodingByteszString-like object with an associated position and various extra methods If the position is ever greater than the string length then an exception is raisedcCst|tsJt||Sr)rJr4__new__lowerr&valuerrrrFszEncodingBytes.__new__cCs d|_dS)Nr )rvrrrrr'Js zEncodingBytes.__init__cCs|Srrr7rrr__iter__NszEncodingBytes.__iter__cCs<|jd}|_|t|krt|dkrt|||dS)Nr rrvr) StopIterationrPr&prrr__next__Qs  zEncodingBytes.__next__cCs|Sr)rr7rrrnextYszEncodingBytes.nextcCs@|j}|t|kr t|dkrt|d|_}|||dSr(rrrrrprevious]s zEncodingBytes.previouscCs|jt|kr t||_dSrrvr)r)r&r%rrr setPositionfs zEncodingBytes.setPositioncCs&|jt|kr t|jdkr|jSdS)Nrrr7rrr getPositionks  zEncodingBytes.getPositioncCs||j|jdSNr )r%r7rrrgetCurrentByteur8zEncodingBytes.getCurrentBytecCsR|j}|t|kr$|||d}||vr||_|S|d7}|t|ks ||_dS)zSkip past a list of charactersr Nr%r)rvr&rrrrrrrzs  zEncodingBytes.skipcCsR|j}|t|kr$|||d}||vr||_|S|d7}|t|ks ||_dSrrrrrr skipUntils  zEncodingBytes.skipUntilcCs(|||j}|r|jt|7_|S)zLook for a sequence of bytes at the start of a string. If the bytes are found return True and advance the position to the byte after the match. Otherwise return False and leave the position alone)rr%r))r&r4r>rrr matchBytesszEncodingBytes.matchBytescCs6z|||jt|d|_WdStytw)zLook for the next sequence of bytes matching a given sequence. If a match is found advance the position to the last byte of the matchr T)indexr%r)rv ValueErrorrr3rrrjumpTos  zEncodingBytes.jumpToN)rCrDrErFrr'rrrrrrpropertyr%r currentBytespaceCharactersBytesrrrrrrrrrBs"     rc@sXeZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ dS)rz?Mini parser for detecting character encoding from meta elementscCst||_d|_dS)z3string - the data to work on for encoding detectionN)rr:rr&r:rrrr's  zEncodingParser.__init__c Csd|jvrdSd|jfd|jfd|jfd|jfd|jfd|jff}|jD]?}d}z|jdWn ty<Y|j Sw|D]\}}|j|r\z|}Wn ty[d}Ynwq?|sc|j Sq$|j S) Nsr:rr7rrrrs zEncodingParser.handleCommentcCs|jjtvrdSd}d} |}|durdS|ddkr/|ddk}|r.|dur.||_dSn?|ddkrG|d}t|}|durF||_dSn'|ddkrntt|d}|}|durnt|}|durn|rl||_dS|}q ) NTFrs http-equivr s content-typecharsetscontent) r:rr getAttributerraContentAttrParserrparse)r& hasPragmapendingEncodingattrtentativeEncodingcodec contentParserrrrrs@      zEncodingParser.handleMetacCs |dS)NF)handlePossibleTagr7rrrrs z%EncodingParser.handlePossibleStartTagcCst|j|dS)NT)rr:rr7rrrrs  z#EncodingParser.handlePossibleEndTagcCsj|j}|jtvr|r||dS|t}|dkr#|dS|}|dur3|}|dus+dS)NTr)r:rasciiLettersBytesrrrspacesAngleBracketsr)r&endTagr:rrrrrrs  z EncodingParser.handlePossibleTagcCr)Nrrr7rrrrs zEncodingParser.handleOthercCs|j}|ttdgB}|dust|dksJ|dvrdSg}g} |dkr+|r+n0|tvr4|}n'|dvr?d|dfS|tvrK||n |durQdS||t |}q$|dkrj| d|dfSt ||}|d vr|} t |}||krt |d|d|fS|tvr||n||qy|d krd|dfS|tvr||n |durdS|| t |}|t vrd|d|fS|tvr||n |durdS||q) z_Return a name,value pair for the next attribute in the stream, if one is found, or None/Nr )rNT=)r rr;)'"r) r:rr frozensetr)r<asciiUppercaseBytesr9rrrr)r&r:rattrName attrValue quoteCharrrrrsn      zEncodingParser.getAttributeN) rCrDrErFr'rrrrrrrrrrrrrs$ rc@seZdZddZddZdS)rcCst|tsJ||_dSr)rJr4r:rrrrr'as zContentAttrParser.__init__cCszy|jd|jjd7_|j|jjdksWdS|jjd7_|j|jjdvrS|jj}|jjd7_|jj}|j|rP|j||jjWSWdS|jj}z|jt|j||jjWWStyy|j|dYWSwtyYdSw)Nrr r )r r )r:rr%rrrrr)r& quoteMark oldPositionrrrres2         zContentAttrParser.parseN)rCrDrEr'rrrrrr`s rcCs\t|trz|d}Wn tyYdSw|dur,zt|WSty+YdSwdS)z{Return the python codec name corresponding to an encoding or None if the string doesn't correspond to a valid encoding.rN)rJr4decodeUnicodeDecodeErrorr lookupAttributeError)rrrrras    ra)0 __future__rrrZpip._vendor.sixrpip._vendor.six.movesrrrriorr pip._vendorr constantsr r rrrrfrrrrrrinvalid_unicode_no_surrogater\rprevalrrascii_punctuation_rerobjectr"rWrQrRr4rrrrarrrrsJ      JgIb= 'PKH]2eTBBRpython3.10/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-310.pycnu[o ai@s`dZddlmZmZmZddlmZmZmZddl m Z ddl m Z ddl mZgdZd Zd S) a HTML parsing library based on the `WHATWG HTML specification `_. The parser is designed to be compatible with existing HTML found in the wild and implements well-defined error recovery that is largely compatible with modern desktop web browsers. Example usage:: from pip._vendor import html5lib with open("my_document.html", "rb") as f: tree = html5lib.parse(f) For convenience, this module re-exports the following names: * :func:`~.html5parser.parse` * :func:`~.html5parser.parseFragment` * :class:`~.html5parser.HTMLParser` * :func:`~.treebuilders.getTreeBuilder` * :func:`~.treewalkers.getTreeWalker` * :func:`~.serializer.serialize` )absolute_importdivisionunicode_literals) HTMLParserparse parseFragment)getTreeBuilder) getTreeWalker) serialize)rrrr r r z1.1N)__doc__ __future__rrr html5parserrrr treebuildersr treewalkersr serializerr __all__ __version__rr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/__init__.pys   PKH]M6M6Spython3.10/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-310.pycnu[o aiXA @sddlmZmZmZddlZddlZddlmZdZdZ dZ dZ d Z d ee gZd ee d d d e e gZd ed gZedZedZddZddZeddZddZddZddZddZedZedZed ZGd!d"d"eZ dS)#)absolute_importdivisionunicode_literalsN)DataLossWarninga^ [#x0041-#x005A] | [#x0061-#x007A] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x00FF] | [#x0100-#x0131] | [#x0134-#x013E] | [#x0141-#x0148] | [#x014A-#x017E] | [#x0180-#x01C3] | [#x01CD-#x01F0] | [#x01F4-#x01F5] | [#x01FA-#x0217] | [#x0250-#x02A8] | [#x02BB-#x02C1] | #x0386 | [#x0388-#x038A] | #x038C | [#x038E-#x03A1] | [#x03A3-#x03CE] | [#x03D0-#x03D6] | #x03DA | #x03DC | #x03DE | #x03E0 | [#x03E2-#x03F3] | [#x0401-#x040C] | [#x040E-#x044F] | [#x0451-#x045C] | [#x045E-#x0481] | [#x0490-#x04C4] | [#x04C7-#x04C8] | [#x04CB-#x04CC] | [#x04D0-#x04EB] | [#x04EE-#x04F5] | [#x04F8-#x04F9] | [#x0531-#x0556] | #x0559 | [#x0561-#x0586] | [#x05D0-#x05EA] | [#x05F0-#x05F2] | [#x0621-#x063A] | [#x0641-#x064A] | [#x0671-#x06B7] | [#x06BA-#x06BE] | [#x06C0-#x06CE] | [#x06D0-#x06D3] | #x06D5 | [#x06E5-#x06E6] | [#x0905-#x0939] | #x093D | [#x0958-#x0961] | [#x0985-#x098C] | [#x098F-#x0990] | [#x0993-#x09A8] | [#x09AA-#x09B0] | #x09B2 | [#x09B6-#x09B9] | [#x09DC-#x09DD] | [#x09DF-#x09E1] | [#x09F0-#x09F1] | [#x0A05-#x0A0A] | [#x0A0F-#x0A10] | [#x0A13-#x0A28] | [#x0A2A-#x0A30] | [#x0A32-#x0A33] | [#x0A35-#x0A36] | [#x0A38-#x0A39] | [#x0A59-#x0A5C] | #x0A5E | [#x0A72-#x0A74] | [#x0A85-#x0A8B] | #x0A8D | [#x0A8F-#x0A91] | [#x0A93-#x0AA8] | [#x0AAA-#x0AB0] | [#x0AB2-#x0AB3] | [#x0AB5-#x0AB9] | #x0ABD | #x0AE0 | [#x0B05-#x0B0C] | [#x0B0F-#x0B10] | [#x0B13-#x0B28] | [#x0B2A-#x0B30] | [#x0B32-#x0B33] | [#x0B36-#x0B39] | #x0B3D | [#x0B5C-#x0B5D] | [#x0B5F-#x0B61] | [#x0B85-#x0B8A] | [#x0B8E-#x0B90] | [#x0B92-#x0B95] | [#x0B99-#x0B9A] | #x0B9C | [#x0B9E-#x0B9F] | [#x0BA3-#x0BA4] | [#x0BA8-#x0BAA] | [#x0BAE-#x0BB5] | [#x0BB7-#x0BB9] | [#x0C05-#x0C0C] | [#x0C0E-#x0C10] | [#x0C12-#x0C28] | [#x0C2A-#x0C33] | [#x0C35-#x0C39] | [#x0C60-#x0C61] | [#x0C85-#x0C8C] | [#x0C8E-#x0C90] | [#x0C92-#x0CA8] | [#x0CAA-#x0CB3] | [#x0CB5-#x0CB9] | #x0CDE | [#x0CE0-#x0CE1] | [#x0D05-#x0D0C] | [#x0D0E-#x0D10] | [#x0D12-#x0D28] | [#x0D2A-#x0D39] | [#x0D60-#x0D61] | [#x0E01-#x0E2E] | #x0E30 | [#x0E32-#x0E33] | [#x0E40-#x0E45] | [#x0E81-#x0E82] | #x0E84 | [#x0E87-#x0E88] | #x0E8A | #x0E8D | [#x0E94-#x0E97] | [#x0E99-#x0E9F] | [#x0EA1-#x0EA3] | #x0EA5 | #x0EA7 | [#x0EAA-#x0EAB] | [#x0EAD-#x0EAE] | #x0EB0 | [#x0EB2-#x0EB3] | #x0EBD | [#x0EC0-#x0EC4] | [#x0F40-#x0F47] | [#x0F49-#x0F69] | [#x10A0-#x10C5] | [#x10D0-#x10F6] | #x1100 | [#x1102-#x1103] | [#x1105-#x1107] | #x1109 | [#x110B-#x110C] | [#x110E-#x1112] | #x113C | #x113E | #x1140 | #x114C | #x114E | #x1150 | [#x1154-#x1155] | #x1159 | [#x115F-#x1161] | #x1163 | #x1165 | #x1167 | #x1169 | [#x116D-#x116E] | [#x1172-#x1173] | #x1175 | #x119E | #x11A8 | #x11AB | [#x11AE-#x11AF] | [#x11B7-#x11B8] | #x11BA | [#x11BC-#x11C2] | #x11EB | #x11F0 | #x11F9 | [#x1E00-#x1E9B] | [#x1EA0-#x1EF9] | [#x1F00-#x1F15] | [#x1F18-#x1F1D] | [#x1F20-#x1F45] | [#x1F48-#x1F4D] | [#x1F50-#x1F57] | #x1F59 | #x1F5B | #x1F5D | [#x1F5F-#x1F7D] | [#x1F80-#x1FB4] | [#x1FB6-#x1FBC] | #x1FBE | [#x1FC2-#x1FC4] | [#x1FC6-#x1FCC] | [#x1FD0-#x1FD3] | [#x1FD6-#x1FDB] | [#x1FE0-#x1FEC] | [#x1FF2-#x1FF4] | [#x1FF6-#x1FFC] | #x2126 | [#x212A-#x212B] | #x212E | [#x2180-#x2182] | [#x3041-#x3094] | [#x30A1-#x30FA] | [#x3105-#x312C] | [#xAC00-#xD7A3]z*[#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]a [#x0300-#x0345] | [#x0360-#x0361] | [#x0483-#x0486] | [#x0591-#x05A1] | [#x05A3-#x05B9] | [#x05BB-#x05BD] | #x05BF | [#x05C1-#x05C2] | #x05C4 | [#x064B-#x0652] | #x0670 | [#x06D6-#x06DC] | [#x06DD-#x06DF] | [#x06E0-#x06E4] | [#x06E7-#x06E8] | [#x06EA-#x06ED] | [#x0901-#x0903] | #x093C | [#x093E-#x094C] | #x094D | [#x0951-#x0954] | [#x0962-#x0963] | [#x0981-#x0983] | #x09BC | #x09BE | #x09BF | [#x09C0-#x09C4] | [#x09C7-#x09C8] | [#x09CB-#x09CD] | #x09D7 | [#x09E2-#x09E3] | #x0A02 | #x0A3C | #x0A3E | #x0A3F | [#x0A40-#x0A42] | [#x0A47-#x0A48] | [#x0A4B-#x0A4D] | [#x0A70-#x0A71] | [#x0A81-#x0A83] | #x0ABC | [#x0ABE-#x0AC5] | [#x0AC7-#x0AC9] | [#x0ACB-#x0ACD] | [#x0B01-#x0B03] | #x0B3C | [#x0B3E-#x0B43] | [#x0B47-#x0B48] | [#x0B4B-#x0B4D] | [#x0B56-#x0B57] | [#x0B82-#x0B83] | [#x0BBE-#x0BC2] | [#x0BC6-#x0BC8] | [#x0BCA-#x0BCD] | #x0BD7 | [#x0C01-#x0C03] | [#x0C3E-#x0C44] | [#x0C46-#x0C48] | [#x0C4A-#x0C4D] | [#x0C55-#x0C56] | [#x0C82-#x0C83] | [#x0CBE-#x0CC4] | [#x0CC6-#x0CC8] | [#x0CCA-#x0CCD] | [#x0CD5-#x0CD6] | [#x0D02-#x0D03] | [#x0D3E-#x0D43] | [#x0D46-#x0D48] | [#x0D4A-#x0D4D] | #x0D57 | #x0E31 | [#x0E34-#x0E3A] | [#x0E47-#x0E4E] | #x0EB1 | [#x0EB4-#x0EB9] | [#x0EBB-#x0EBC] | [#x0EC8-#x0ECD] | [#x0F18-#x0F19] | #x0F35 | #x0F37 | #x0F39 | #x0F3E | #x0F3F | [#x0F71-#x0F84] | [#x0F86-#x0F8B] | [#x0F90-#x0F95] | #x0F97 | [#x0F99-#x0FAD] | [#x0FB1-#x0FB7] | #x0FB9 | [#x20D0-#x20DC] | #x20E1 | [#x302A-#x302F] | #x3099 | #x309Aa  [#x0030-#x0039] | [#x0660-#x0669] | [#x06F0-#x06F9] | [#x0966-#x096F] | [#x09E6-#x09EF] | [#x0A66-#x0A6F] | [#x0AE6-#x0AEF] | [#x0B66-#x0B6F] | [#x0BE7-#x0BEF] | [#x0C66-#x0C6F] | [#x0CE6-#x0CEF] | [#x0D66-#x0D6F] | [#x0E50-#x0E59] | [#x0ED0-#x0ED9] | [#x0F20-#x0F29]z} #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 | #x0E46 | #x0EC6 | #x3005 | #[#x3031-#x3035] | [#x309D-#x309E] | [#x30FC-#x30FE] | .-_z#x([\d|A-F]{4,4})z'\[#x([\d|A-F]{4,4})-#x([\d|A-F]{4,4})\]cCsdd|dD}g}|D]H}d}ttfD]+}||}|durA|dd|Dt|ddkr=|dd|d<d }nq|sVt|dksLJ|t|gdqt|}|S) NcSsg|]}|qS)strip.0itemr r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/_ihatexml.py hz$charStringToList..rFcSsg|]}t|qSr )hexToIntr r r rrorrT) splitreChar reCharRangematchappendgroupslenordnormaliseCharList)charsZ charRangesrvrZ foundMatchregexprr r rcharStringToListgs&  r"cCst|}|D] }|d|dksJqg}d}|t|krpd}|||||t|krf|||d|dddkrf|||d|dd<|d7}||t|krf|||d|dddks>||7}|t|ks|S)Nrrr)sortedrr)charListrr ijr r rr|s 00 rZFFFFcCsg}|ddkr|d|dddgt|ddD]\}}||dd||dddgq|ddtkrJ||dddtg|S)Nrrr)r enumerate max_unicode)r$r r%rr r r missingRangess (r*cCsng}|D]+}|d|dkr|tt|dq|tt|ddtt|dqdd|S)Nrrr z[%s])r escapeRegexpchrjoin)r$r rr r rlistToRegexpStrsr/cCs t|dS)Nr')int)hex_strr r rr rcCs"d}|D] }||d|}q|S)N)r^$*+?{}[]|()r \)replace)stringZspecialCharacterscharr r rr,sr,u[-,/:-@\[-\^`\{-¶¸-¿×÷IJ-ijĿ-ŀʼnſDŽ-njDZ-dzǶ-ǹȘ-ɏʩ-ʺ˂-ˏ˒-˿͆-͟͢-΅΋΍΢Ϗϗ-ϙϛϝϟϡϴ-ЀЍѐѝ҂҇-ҏӅ-ӆӉ-ӊӍ-ӏӬ-ӭӶ-ӷӺ-԰՗-՘՚-ՠև-֐ֺ֢־׀׃ׅ-׏׫-ׯ׳-ؠػ-ؿٓ-ٟ٪-ٯڸ-ڹڿۏ۔۩ۮ-ۯۺ-ऀऄऺ-ऻॎ-ॐॕ-ॗ।-॥॰-ঀ঄঍-঎঑-঒঩঱঳-঵঺-঻ঽ৅-৆৉-৊ৎ-৖৘-৛৞৤-৥৲-ਁਃ-਄਋-਎਑-਒਩਱਴਷਺-਻਽੃-੆੉-੊੎-੘੝੟-੥ੵ-઀઄ઌ઎઒઩઱઴઺-઻૆૊૎-૟ૡ-૥૰-଀଄଍-଎଑-଒଩଱଴-ଵ଺-଻ୄ-୆୉-୊୎-୕୘-୛୞ୢ-୥୰-஁஄஋-஍஑஖-஘஛஝஠-஢஥-஧஫-஭ஶ஺-஽௃-௅௉௎-௖௘-௦௰-ఀఄ఍఑఩ఴ఺-ఽ౅౉౎-౔౗-౟ౢ-౥౰-ಁ಄಍಑಩಴಺-ಽ೅೉೎-೔೗-ೝ೟ೢ-೥೰-ഁഄ഍഑ഩഺ-ഽൄ-൅൉ൎ-ൖ൘-ൟൢ-൥൰-฀ฯ฻-฿๏๚-຀຃຅-ຆຉ຋-ຌຎ-ຓຘຠ຤຦ຨ-ຩຬຯ຺຾-຿໅໇໎-໏໚-༗༚-༟༪-༴༶༸༺-༽཈ཪ-཰྅ྌ-ྏྖ྘ྮ-ྰྸྺ-႟჆-჏ჷ-ჿᄁᄄᄈᄊᄍᄓ-ᄻᄽᄿᅁ-ᅋᅍᅏᅑ-ᅓᅖ-ᅘᅚ-ᅞᅢᅤᅦᅨᅪ-ᅬᅯ-ᅱᅴᅶ-ᆝᆟ-ᆧᆩ-ᆪᆬ-ᆭᆰ-ᆶᆹᆻᇃ-ᇪᇬ-ᇯᇱ-ᇸᇺ-᷿ẜ-ẟỺ-ỿ἖-἗἞-἟὆-὇὎-὏὘὚὜὞὾-὿᾵᾽᾿-῁῅῍-῏῔-῕῜-῟῭-῱῵´-⃏⃝-⃠⃢-℥℧-℩ℬ-ℭℯ-ⅿↃ-〄〆〈-〠〰〶-぀ゕ-゘゛-゜ゟ-゠・ヿ-㄄ㄭ-䷿龦-꯿힤-￿]u[-@\[-\^`\{-¿×÷IJ-ijĿ-ŀʼnſDŽ-njDZ-dzǶ-ǹȘ-ɏʩ-ʺ˂-΅·΋΍΢Ϗϗ-ϙϛϝϟϡϴ-ЀЍѐѝ҂-ҏӅ-ӆӉ-ӊӍ-ӏӬ-ӭӶ-ӷӺ-԰՗-՘՚-ՠև-׏׫-ׯ׳-ؠػ-ـً-ٰڸ-ڹڿۏ۔ۖ-ۤۧ-ऄऺ-़ा-ॗॢ-঄঍-঎঑-঒঩঱঳-঵঺-৛৞ৢ-৯৲-਄਋-਎਑-਒਩਱਴਷਺-੘੝੟-ੱੵ-઄ઌ઎઒઩઱઴઺-઼ા-૟ૡ-଄଍-଎଑-଒଩଱଴-ଵ଺-଼ା-୛୞ୢ-஄஋-஍஑஖-஘஛஝஠-஢஥-஧஫-஭ஶ஺-ఄ఍఑఩ఴ఺-౟ౢ-಄಍಑಩಴಺-ೝ೟ೢ-ഄ഍഑ഩഺ-ൟൢ-฀ฯัิ-฿ๆ-຀຃຅-ຆຉ຋-ຌຎ-ຓຘຠ຤຦ຨ-ຩຬຯັິ-ຼ຾-຿໅-༿཈ཪ-႟჆-჏ჷ-ჿᄁᄄᄈᄊᄍᄓ-ᄻᄽᄿᅁ-ᅋᅍᅏᅑ-ᅓᅖ-ᅘᅚ-ᅞᅢᅤᅦᅨᅪ-ᅬᅯ-ᅱᅴᅶ-ᆝᆟ-ᆧᆩ-ᆪᆬ-ᆭᆰ-ᆶᆹᆻᇃ-ᇪᇬ-ᇯᇱ-ᇸᇺ-᷿ẜ-ẟỺ-ỿ἖-἗἞-἟὆-὇὎-὏὘὚὜὞὾-὿᾵᾽᾿-῁῅῍-῏῔-῕῜-῟῭-῱῵´-℥℧-℩ℬ-ℭℯ-ⅿↃ-〆〈-〠〪-぀ゕ-゠・-㄄ㄭ-䷿龦-꯿힤-￿]z#[^ a-zA-Z0-9\-'()+,./:=?;!*#@$_%]c@s~eZdZedZ      dddZdddZd d Zd d Z d dZ ddZ ddZ ddZ ddZddZddZdS) InfosetFilterz U[\dA-F]{5,5}FTcCs.||_||_||_||_||_||_i|_dSN)dropXmlnsLocalNamedropXmlnsAttrNspreventDoubleDashCommentspreventDashAtCommentEndreplaceFormFeedCharacterspreventSingleQuotePubid replaceCache)selfrErFrGrHrIrJr r r__init__s zInfosetFilter.__init__NcCsH|jr|drtdtdS|jr|dkrtdtdS||S)Nzxmlns:z"Attributes cannot begin with xmlnszhttp://www.w3.org/2000/xmlns/z)Attributes cannot be in the xml namespace)rE startswithwarningswarnrrF toXmlName)rLname namespacer r rcoerceAttributes   zInfosetFilter.coerceAttributecCs ||SrD)rQ)rLrRr r r coerceElementr2zInfosetFilter.coerceElementcCsP|jr&d|vrtdt|dd}d|vs|dr&tdt|d7}|S)Nz--z'Comments cannot contain adjacent dashesz- -r zComments cannot end in a dash )rGrOrPrr@endswith)rLdatar r r coerceComments    zInfosetFilter.coerceCommentcCs6|jrt|dD]}tdtq |dd}|S)N zText cannot contain U+000CrV)rIrangecountrOrPrr@)rLrXr r r rcoerceCharacterss  zInfosetFilter.coerceCharacterscCsl|}t|D]}tdt||}|||}q|jr4|ddkr4tdt|d|d}|S)NzCoercing non-XML pubid'rz!Pubid cannot contain single quote) nonPubidCharRegexpfindallrOrPrgetReplacementCharacterr@rJfind)rLrXZ dataOutputrB replacementr r r coercePubids   zInfosetFilter.coercePubidc Cs|d}|dd}t|}|rtd|t||}n|}|}tt|}|D]}td|t||} | || }q,||S)NrrzCoercing non-XML name: %s) nonXmlNameFirstBMPRegexprrOrPrrasetnonXmlNameBMPRegexpr`r@) rLrR nameFirstZnameRestmZnameFirstOutputZnameRestOutputZ replaceCharsrBrcr r rrQs    zInfosetFilter.toXmlNamecCs&||jvr |j|}|S||}|SrD)rK escapeCharrLrBrcr r rras   z%InfosetFilter.getReplacementCharactercCs,t|j|D] }||||}q|SrD)rfreplacementRegexpr`r@ unescapeChar)rLrRrr r r fromXmlNameszInfosetFilter.fromXmlNamecCsdt|}||j|<|S)NzU%05X)rrKrkr r rrjs  zInfosetFilter.escapeCharcCstt|dddS)Nrr')r-r0)rLZcharcoder r rrm szInfosetFilter.unescapeChar)FFFFTFrD)__name__ __module__ __qualname__recompilerlrMrTrUrYr]rdrQrarnrjrmr r r rrCs&      rC)! __future__rrrrrrO constantsrZbaseCharZ ideographicZcombiningCharacterdigitZextenderr.letterrRrhrsrrr"rr0r)r*r/rr,rgrer_objectrCr r r rs6 0       PKH]CvvSpython3.10/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-310.pycnu[o aiF@sjddlmZmZmZddlZdZiddddddd d d d d ddddddddddddddddddd d!d"d#d$id%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFidGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]dVd^dVd_d`dadbdcdddedfidgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~ddddddddddiddddddddddddddddddddddddddddddddddidddddddddddddddddddddddd“ddēddƓddȓddʓdd̓iddΓddГddғddԓdd֓ddؓddړddܓddޓdddddddddddddddddddddddddddd ZdddddddZeeddfeddfeddfeddfeddfeddfeddfedd fed d fed d fed d fed dfed dfed dfeddfeddfeddfgZ eeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfeddfedd fedd!fedd"fgZ egedd#feddfedd$fedd%fedd&fedd'fedd(fedd)fedd*fedd+fedd,fedd-feddfedd.fedd/fedd0fedd1fedd2fedd3fedd4fedd5fedd6fedd7fedd8fedd9fedd:fedd;feddfedd?fedd@feddAfeddBfeddCfeddDfeddEfeddFfeddGfeddfeddHfeddIfeddJfeddKfeddLfeddMfeddNfeddOfeddfeddPfeddQfeddRfeddSfeddTfeddUfeddfeddVfeddWfeddXfeddYfeddZfedd[fedd\fedd]fedd^feddfedd_feddfedd`feddafedd feddbfeddfeddcfedddfeddefeddffeddfZ eed dfeddfeddfeddfgZ eed d fed d fed d fed dfed dfgZ idgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~ddddddddddiddddddddddddddddddddddddddddddddddidddddddddddddddddddddddd“dÐdēdŐdƓdǐdȓdɐdʓdːd̓d͐dΐdϐdАdѐdҐdӐdԐdՐd֐dאd؜ ZdِdiZdېdedfdېdedfdېdedfdېdedfdېdedfdېdedfdېdedfdd'edfddedfddedfddedfddedfd ZddeDZegdZegdZeejZeejZeejZeejZeejZddejDZdZegdZ edd`gZ!egdZ"ideddgd^edgdJedgdeddgdeddgd[eddgd3edgdeddgd1egddGedgdPedgd9eddgdegddeddgd-eddgdKegdd]egdeddgedgd Z#d Z$egd Z%id d dd ddddddddddddddddddddd dd!d"d#d$d%d&d'd(id)d*d+d,d-d.d/d.d0d1d2d3d4d5d6d5d7d8d9d8d:d;d<d=d>d?d@dAdBdCdDdEdFdGidHdIdJdKdLdMdNdEdOdPdQdRdSdTdUdTdVdWdXdYdZd[d\d]d^d_d`dadbdadcdddedfidgdhdidjdkdldmd]dndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddidddddddddddddddd[ddddddddddddddddddidddddddddddddddddddddddddd“dÐdēdŐddƐddǐdȓidɐdʓdːd̓d͐ddΐdϓdАdѓdҐdӓdԐdՓd֐dדdؐdٓdڐdۓdܐdݓdސdߓddddddddddiddddddddddddddddȓddddddddddddddddddid dd d d d dddddddddddddddddddd d!d"d#d$d%d&d'd(id)d*d+d,d-d.d/d.d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdAdCdDdEdFdGdFidHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdiidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dyddddPddddddddiddddddddddddddddddddddddddՓddddddddiddddddddddddddddddddddddddddddÓdĐdœdƐdǓidȐdɓdʐd˓d̐d͓dΐdϓdАdѓdҐdӓdԐdՓd֐dדdؐdٓdڐdٓdېdܓdݐdޓdߐdddddddddiddddddddddddddddddddddddddddddddd d id d d dddddddddddddddʓdd̓dddd d!d"d#d$d%d&d'd(d)d*id+d,d-d.d/d0d1d2d3d4d5d6d7dϓd8dѓd9dӓd:d;d<d=d>d?d@ddAdBdCdDdEdFdGdHidIdJdKdLdMdNdOdPdQdRdSdTdUdNdVdWdXdYdZd[d\d]d^d_d`dadbdcdddcdedcdfdcidgdmdhdFdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~ddddddddiddddddddddddddddddddddddddddddddddidddddddddddddddddddddddddd“dÐdēdŐdƓdǐdȓdɐdʓidːd̓d͐dΓdϐdГdѐdғdӐdԓdՐd֓dאdؓdِdړdېdܓdݐdޓdߐdޓddddddddddddiddddddddddddddddddddddddddddddddddid d d d d d ddddddddddddddddddd d!d"dwd#d$d%d&d'd(id)d*d+d,d-d.d/d0d1d2d3dd4d5d6d7d8d9d:d;d<d;d=d>d?d@dAdBdCdDdEdFdGdFidHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^dWd_d`dadbdcdddedfdgdhididjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~ddddddddddddiddddՓddddddddddddddddddddddddddddddiddddߓddddddddddddddddddddddd“dÐdēdŐdƓdǐdȓdɐdʓidːd̓d͐dΓdϐdΓdАdѓdҐdӓdԐdՓd֐dדdؐdٓdڐdYdېdܓdݐdޓdߐdddddޓddddddiddddddddddddddddddddddddddddddddd d id d d ddddddddddddddddddddd d!d"d#d$d%d&d'd&d(d)id*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:dd;d<d=d>d?d@dAdBdCdDdEdFdGdٓdHdۓidIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdXdZd[d\d]d^d_d`dadbdcdddedfdgdhdgididjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~ddddddddddddiddddddddddddddddddddddddddddddddddiddcdddddddddddddddddddddddddÐddĐddŐdƓdǐdȓidɐdȓdʐd,dːd̓d͐dΓdϐdΓdАdѓdҐdѓdӐdԓdՐd֓dאdؓdِddڐddېdܓdݐdޓdߐdddddidddddddddddddddddddddddddddddddddd.iddddd d d dd d ddddddddddddddddddddddd did!d"d#d"d$d%d&d%d'dd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d9d;d/d<d=id>d-d?d@dAdBdCdCdDdCdEdFdGd/dHdEdIdJdKdLdMdNdOdPdQddRdSdTd3dUdVdWdXidYdZd[d\d]d^d_d`dadbdcdddededfd~dgdhdidjdkd;dldmdndodpdqdrdsdtdudvdwidxdydzd{d|d}d~dddddddddDddDddddddddddddddddiddddddddddddddddddddddddddddddddddidddd}dddddd“dÐdēdŐdƓdǐdȓdɐdʓdːd̓d͐dΓdϐdГdѐdғdӐdԓdՐd֓dאdؓdِdړidېdܓdݐdޓdߐddd1ddMdddddddddd3dd5ddddddddddddPidddddddddddddddddddddd d d d dqd dddddddiddddddddddjddjddd d!d"d!d#dld$d%d&d'd(d)d*d)d+d,d-d.d/d0id1d2d3d4d5d6d7d8d9dFd:d;d<d=d>d?d@dAdBd4dCdDdEdFdGdHdIdJdKdJdLdMdNd3idOd3dPdQdRdSdTdUdVddWdUdXddYddZd[d\dd]d^d_dd`dTdadTdbdcdddedfdgidhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddiddddddddddydd{dddddddddd}ddddddddyddddiddȓddddddddߓddddddddddddddddddddddddidddd“dÐdēdŐdƓdǐddȐdpdɐddʐddːd̓d͐d̓dΐddϐdГdѐdғdӐdԓdՐdԓd֐dԓdאdؓidِdؓdڐdۓdܐdݓdސdߓddddddddēdddddddddd?ddߓddddddpiddDdddddddddddd d d d d ddo dd dd] d d d d  d d  d d ddi d d d d d d d d d d d d d d d d d d d d  d!d3 d" d# d$ d% d& d' d( d) d* d) d+ d,i d- d. d/ d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d: d; d< d= d< d> d< d? d@ dA dB dC dD dE dF dG dH dI dJ dK dLi dM dN dO dP dQ dR dS dT dU dT dV dW dX d dY d dZd$ d[ d, d\ d6 d] d^ d_ d` dad db dc dd de df dgi dh di dj dk dldē dmd$ dn do dp dq dr dq ds dt du dt dv dw dx dy dzd1 d{d( d|d3 d} d# d~ d d di d d d d d d d d d d d d d d d d d d d d d d dd? d d d d d d d d d di d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d di d dÓ dĐ dœ dƐda dǐ dȓ dɐ dʓ dː d̓ d͐dГ dΐ dϓ dА dѓ dҐ dӓ dԐ dՓ d֐ dד dؐd] dِd_ dڐd] dېda dܐdgi dݐdg dސ dߓ d d d d d d d d d d d d ddm ddY d d d d dde d d d d d d d di d d d d d d d d d d d d d d dd d d d di d d  d d  ddF ddF d d d d d di d d d d d dϓ d d d d dd_ d dȓ d de d!di d" d# d$ d# d%d̓ d&dr d' d d(dy d) d* d+di d, d- d. d/ d0 d1 d2 d3 d4 d5 d6 d5 d7 d8 d9 d: d; d< d= d> d? d@ dA dB dC dD dE dF dG dH dI dJ dK dLi dM dN dO d1 dP dQ dR dS dTd dU dV dW dV dXd dY dZ d[ dZ d\ d] d^ d_ d` da db da dcd̓ dd de df dgi dh dg did dj dk dl dm dn do dp dq dr ds dt du dvd dwd dxd dy dz d{ d| d} d~ dd d d d di d d d dz dd d d dd d d d d d d d d d d d d d d d d d d d d d d ddi d d d d d d d d dd dd d d d d d d d d d d d d d d d d d d d d d di d d d d d dÓ dĐ dœ dƐ dǓ dȐ dɓ dʐ d˓ d̐ d͓ dΐ dϓ dА dѓ dҐ dӓ dԐd. dՐdʓ d֐ dד dؐ dٓ dڐd  dې dܓi dݐ dޓ dߐ d d d dd d d dd d d dd d d d d d d dd dd d d d d d dF d di d d d d d d d d d d d d d d d d d d  d d  d d  d d d d d d d d d d ddi d d  d d d d dd ddB d d! d" d# d$ d% d& d' d(d d) d d*d d+d d, d- d.d d/d d0d[i d1 d/ d2 d3 d4d d5 d' d6d  d7d& d8d& d9 d: d; d< d= d> d? d@ dA dB dC dD dE d dF dG dHd dI dܓi dJd" dKd( dL dM dNd dO dP dQd" dR dS dTd dUd dV dW dX dY dZ d[ d\dF d] d- d^dݓ d_ d` da dbi dc dd de df dg df dh di dj dk dl dk dm dn do dn dp di dq dr ds dt du dv dwd dxd2 dyd4 dz d{ d|d6i d} d d~ d d d d d d d d d d d dd+ d d d d ddj d d d d dd dd dd[ d di d d d d d d d d ddB dd( d d d d d d  dd d d d d ddٓ ddٓ d d d d d dGi d d3 d d d d d d d d d d dd ddq d d d dÓ dĐ dœ dƐ dœ dǐ dȓ dɐ dʓ dː dʓ d̐ d͓ dΐ dϓi dА dϓ dѐdx dҐdx dӐd dԐd dՐdF d֐ dד dؐ dٓ dڐ dۓ dܐ dݓ dސd dߐ d d d d d d d ddj ddi d d ddl ddl d d ddƓ dd d d d d d d8 ddR d d d d ddR d d dd d d d di d d d d d d dd d d  d d  d d  d d dd d d d d d d dd d d d d ddؓ d di d d  d! d" d#dؓ d$ d% d& d% d'dr d(dp d)dp d*d d+d d, d- d. d/ d0 d1 d2d֓ d3 d4 d5 d6 d7 d8i d9 d: d;d~ d< d= d> d? d@dL dAdL dB dC dDdv dE dF dGd dHd dId dJ dK dLd dMd dNd dOdi dPd dQd dRd dSd dTd dU d  dV dW dX dY dZdY d[ d\ d] d^ d_dY d` da db d  dc dd de df dg dhi did dj df dk dW dld dm dd dnd dod dpd dqd drd dsd dtd dudړ dv dw dx dy dz dy d{d|i d| d} d~ d dd| d d d d dd dd d d d d ddz ddz d d d d d d dd dd ddi dd dd d d d d d d d d d d dd dd ddƓ ddʓ ddȓ d d ddړ ddz ddғ ddԓi ddԓ ddړ ddz dd dd d d d d ddē dd“ ddē d d ddƓ ddȓ d d d d ddГ ddΓi ddГ d d dd dÐ dē dŐ dē dƐd dǐd dȐd dɐd dʐd dː d̓ d͐ dΓ dϐ dГ dѐ dғ dӐ dԓ dՐ d֓ dא dؓi dِ dړ dې dܓ dݐ dޓ dߐ d d d d d d d d d d d d d d d d d d d ddJ ddJ d d dd;i d d d d dd= dd? d d d d d d ddA d d d d ddq d d  d d  d d  d d d d d di d d d d d d dd dd dd6 d d d d d d d! d" d# d$ d% d& d' d( d) d* d+ds d, d- d. d/i d0 d1 d2du d3 d4 d5d8 d6 d7 d8 d9 d: d9 d; d< d= d< d> d? d@ d? dA dB dC dD dE dF dG dH dI d9 dJ dKi dL dK dM dN dO dP dQ dP dRdw dS dT dU dV dW dV dX dY dZdݓ d[ d\ d] d\ d^dݓ d_ d` da db dcd dd dei df dg dh di dj dk dldD dm dn do dp dq dr ds dt dudN dv dw dx dy dz d d{ d| d} d1 d~ d d d1 d di d d ddȓ d d dd d d d d dd! dd! d d d d dd! d d d d d d d d dd( d di d d dd, dd* dd( d d dd, dd* d d d d d d dd. d d dd$ d d d d d d dd2i d d d d d d dd5 dd5 dd. d d d d d d“ dÐ dē dŐ dƓ dǐ dk dȐ dɓ dʐ d˓ d̐ d͓ dΐd{ dϐ dГi dѐ dғ dӐ d` dԐd; dՐd; d֐d dאdՓ dؐ dٓ dڐd dې dܓ dݐ dޓ dߐ d dd d d ddb d d d d ddbi d d d d ddd d d ddf d d d d d d d dH d d d d d d d d dddddddd@iddhddd d d d d dddddddddddjdd dddddddd{d d{d!d"id#dWd$dd%dWd&dd'd(d)dFd*dFd+d,d-dtd.d/d0dd1dd2d3d4d5d6d7d8ddd9 did:dd;dd<dhd=d&d>d?d@ddAdBdCdDdE dgdFdhdGd&dHdIdJdKdLdKdMdNdOdPdQdRidSdldTdUdVdWdXdYdZd[d\d]d^d_d`dadbd?dcdddedfdgddhd did}djd}dkdBdldmidndodpddqdsdrdsdtdudvdwdxdydz dd{dӓd|d}d~dddddדddՓddddddiddddddddٓddddddddddd d>dd?dd?dddddddddd;idd;ddddd dÓddddddddjddݓddddddddddddddddiddddddÓdĐdœdƐdǓdȐdɓdʐd˓d̐d͓dΐddϐd;dАdѓdҐdӓdԐdjdՐd֓dאdؓdِdړdېdܓidݐdޓdߐdddddddddddddݓddddddȓdddddd“dddd“ddēiddƓddēddƓdddddd;dd;ddddddd;dd֓dd̓dddd^d dWd dtd dʓid d d d d dddѓdddddddddddddd ddѓdd ddd dd!d"d#d$id%d&d'dӓd(dd)dדd*dՓd+dd,dd-dd.dٓd/dܓd0d1d2d3d4d3d5d6d7d6d8d9d:d9id;dd<d=d>d?d@dAdBddCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSddTddUd=dVdPidWdNdXdYdZd[d\d]d^d_d` d@dad=dbd=dcdddedfdgdfdhdidjdkdlddmdndodpdqdridsd dtdudvdwdxddyddzd{d|d}d~d}ddddddddddddddddddiddddʓddddd dmd dFddddddddddddddddddd dd diddddddoddddddddddddddddddddddddddNddiddMddٓdd“dÐdēdŐdēdƐddǐdȓdɐdʓdːd̓d͐d̓dΐdϓdАd>dѐdғdӐdBdԐdՓd֐dדdؐdٓidڐdٓdېddܐddݐdޓdߐddddddddddddddddddddd@ddddidd5ddddNddddddddddddddddddddddd dmd dd d id d ddddۓddddddדddd dWd dÓd d<d dtd d|dd5dd@dd7d dd!d"id#d$d%d&d'd(d)d}d*d d+d|d,d-d.dvd/ d4d0d1d2d3d4d5d6dld7dld8d9d:d d;d“id<dΓd=d>d?d5d@d|dAdBdCd$dDd"dEd(dFd&dGdHdIdJdKdLdMdܓdNdOdPdQdRdSdTdUidVdQdWdpdXdpdYdZd[dd\dSd]d3d^d`d_d`dadѓdbd4dcdddedϓdfd2dg d{dhdidjdVidkdldmdXdndZdodӓdpd6dqdrdsd\dtdddudbdvdedwd~dxdydzdyd{d|d}d~ddddidddddddddddddddddddddddddddddddddddddddZ&iddddd dwddd dd dddBd d8dddddd2d dkddd dddddddidddddddd}dddd{dÐddĐ d:dŐ dݓdƐddǐddȐddɐdddʐ d dːd̓d͐ddΐdZ'ddϐdАdѐdҐdӐdԐdՐd֜Z(ee(de(de(dgZ)dڐdeDZ*de*d<Gdܐd݄de+Z,Gdސd߄de-Z.dS()absolute_importdivisionunicode_literalsNznull-characterz5Null character in input stream, replaced with U+FFFD.zinvalid-codepointzInvalid codepoint in stream.zincorrectly-placed-solidusz&Solidus (/) incorrectly placed in tag.zincorrect-cr-newline-entityz.Incorrect CR newline entity, replaced with LF.zillegal-windows-1252-entityz9Entity used with illegal number (windows-1252 reference).zcant-convert-numeric-entityzPNumeric entity couldn't be converted to character (codepoint U+%(charAsInt)08x).z$illegal-codepoint-for-numeric-entityzBNumeric entity represents an illegal codepoint: U+%(charAsInt)08x.z numeric-entity-without-semicolonz#Numeric entity didn't end with ';'.z#expected-numeric-entity-but-got-eofz1Numeric entity expected. Got end of file instead.zexpected-numeric-entityz'Numeric entity expected but none found.znamed-entity-without-semicolonz!Named entity didn't end with ';'.zexpected-named-entityz Named entity expected. Got none.zattributes-in-end-tagz'End tag contains unexpected attributes.zself-closing-flag-on-end-tagz.End tag contains unexpected self-closing flag.z'expected-tag-name-but-got-right-bracketz#Expected tag name. Got '>' instead.z'expected-tag-name-but-got-question-markzSExpected tag name. Got '?' instead. (HTML doesn't support processing instructions.)zexpected-tag-namez-Expected tag name. Got something else insteadz*expected-closing-tag-but-got-right-bracketz6Expected closing tag. Got '>' instead. Ignoring ''.z expected-closing-tag-but-got-eofz-Expected closing tag. Unexpected end of file.z!expected-closing-tag-but-got-charz' instead.z"equals-in-unquoted-attribute-valuez"Unexpected = in unquoted attributez0unexpected-character-in-unquoted-attribute-valuez*Unexpected character in unquoted attributez&invalid-character-after-attribute-namez*Unexpected character after attribute name.z*unexpected-character-after-attribute-valuez+Unexpected character after attribute value.z#eof-in-attribute-value-double-quotez.Unexpected end of file in attribute value (").z#eof-in-attribute-value-single-quotez.Unexpected end of file in attribute value (').z eof-in-attribute-value-no-quotesz*Unexpected end of file in attribute value.z#unexpected-EOF-after-solidus-in-tagz)Unexpected end of file in tag. Expected >z)unexpected-character-after-solidus-in-tagz/Unexpected character after / in tag. Expected >zexpected-dashes-or-doctypez&Expected '--' or 'DOCTYPE'. Not found.z,unexpected-bang-after-double-dash-in-commentz Unexpected ! after -- in commentz-unexpected-space-after-double-dash-in-commentz$Unexpected space after -- in commentzincorrect-commentzIncorrect comment.zeof-in-commentz"Unexpected end of file in comment.zeof-in-comment-end-dashz%Unexpected end of file in comment (-)z,unexpected-dash-after-double-dash-in-commentz+Unexpected '-' after '--' found in comment.zeof-in-comment-double-dashz'Unexpected end of file in comment (--).zeof-in-comment-end-space-statezeof-in-comment-end-bang-statezunexpected-char-in-commentz&Unexpected character in comment found.zneed-space-after-doctypez(No space after literal string 'DOCTYPE'.z+expected-doctype-name-but-got-right-bracketz.Unexpected > character. Expected DOCTYPE name.z!expected-doctype-name-but-got-eofz.Unexpected end of file. Expected DOCTYPE name.zeof-in-doctype-namez'Unexpected end of file in DOCTYPE name.zeof-in-doctypez"Unexpected end of file in DOCTYPE.z*expected-space-or-right-bracket-in-doctypez%Expected space or '>'. Got '%(data)s'zunexpected-end-of-doctypezUnexpected end of DOCTYPE.zunexpected-char-in-doctypez Unexpected character in DOCTYPE.zeof-in-innerhtmlzXXX innerHTML EOFzunexpected-doctypezUnexpected DOCTYPE. Ignored.z non-html-rootz%html needs to be the first start tag.zexpected-doctype-but-got-eofz)Unexpected End of file. Expected DOCTYPE.zunknown-doctypezErroneous DOCTYPE.zexpected-doctype-but-got-charsz2Unexpected non-space characters. Expected DOCTYPE.z"expected-doctype-but-got-start-tagz2Unexpected start tag (%(name)s). Expected DOCTYPE.z expected-doctype-but-got-end-tagz0Unexpected end tag (%(name)s). Expected DOCTYPE.zend-tag-after-implied-rootz?Unexpected end tag (%(name)s) after the (implied) root element.z&expected-named-closing-tag-but-got-eofz4Unexpected end of file. Expected end tag (%(name)s).z!two-heads-are-not-better-than-onez4Unexpected start tag head in existing head. Ignored.zunexpected-end-tagz'Unexpected end tag (%(name)s). Ignored.z#unexpected-start-tag-out-of-my-headz;Unexpected start tag (%(name)s) that can be in head. Moved.zunexpected-start-tagz Unexpected start tag (%(name)s).zmissing-end-tagzMissing end tag (%(name)s).zmissing-end-tagszMissing end tags (%(name)s).z$unexpected-start-tag-implies-end-tagzCUnexpected start tag (%(startName)s) implies end tag (%(endName)s).zunexpected-start-tag-treated-asz@Unexpected start tag (%(originalName)s). Treated as %(newName)s.zdeprecated-tagz,Unexpected start tag %(name)s. Don't use it!zunexpected-start-tag-ignoredz'Unexpected start tag %(name)s. Ignored.z$expected-one-end-tag-but-got-anotherzEUnexpected end tag (%(gotName)s). Missing end tag (%(expectedName)s).zend-tag-too-earlyz:End tag (%(name)s) seen too early. Expected other end tag.zend-tag-too-early-namedzFUnexpected end tag (%(gotName)s). Expected end tag (%(expectedName)s).zend-tag-too-early-ignoredz+End tag (%(name)s) seen too early. Ignored.zadoption-agency-1.1zQEnd tag (%(name)s) violates step 1, paragraph 1 of the adoption agency algorithm.zadoption-agency-1.2zQEnd tag (%(name)s) violates step 1, paragraph 2 of the adoption agency algorithm.zadoption-agency-1.3zQEnd tag (%(name)s) violates step 1, paragraph 3 of the adoption agency algorithm.zadoption-agency-4.4zQEnd tag (%(name)s) violates step 4, paragraph 4 of the adoption agency algorithm.zunexpected-end-tag-treated-asz>Unexpected end tag (%(originalName)s). Treated as %(newName)s.z no-end-tagz'This element (%(name)s) has no end tag.z#unexpected-implied-end-tag-in-tablez9Unexpected implied end tag (%(name)s) in the table phase.z(unexpected-implied-end-tag-in-table-bodyz>Unexpected implied end tag (%(name)s) in the table body phase.z$unexpected-char-implies-table-voodoozDUnexpected non-space characters in table context caused voodoo mode.z unexpected-hidden-input-in-tablez3Unexpected input with type hidden in table context.zunexpected-form-in-tablez!Unexpected form in table context.z)unexpected-start-tag-implies-table-voodoozDUnexpected start tag (%(name)s) in table context caused voodoo mode.z'unexpected-end-tag-implies-table-voodoozBUnexpected end tag (%(name)s) in table context caused voodoo mode.zunexpected-cell-in-table-bodyzCUnexpected table cell start tag (%(name)s) in the table body phase.zunexpected-cell-end-tagzFGot table cell end tag (%(name)s) while required end tags are missing.z unexpected-end-tag-in-table-bodyz?Unexpected end tag (%(name)s) in the table body phase. Ignored.z'unexpected-implied-end-tag-in-table-rowz=Unexpected implied end tag (%(name)s) in the table row phase.zunexpected-end-tag-in-table-rowz>Unexpected end tag (%(name)s) in the table row phase. Ignored.zunexpected-select-in-selectzJUnexpected select start tag in the select phase treated as select end tag.zunexpected-input-in-selectz/Unexpected input start tag in the select phase.zunexpected-start-tag-in-selectzBUnexpected start tag token (%(name)s in the select phase. Ignored.zunexpected-end-tag-in-selectz;Unexpected end tag (%(name)s) in the select phase. Ignored.z5unexpected-table-element-start-tag-in-select-in-tablezKUnexpected table element start tag (%(name)s) in the select in table phase.z3unexpected-table-element-end-tag-in-select-in-tablezIUnexpected table element end tag (%(name)s) in the select in table phase.zunexpected-char-after-bodyz8Unexpected non-space characters in the after body phase.zunexpected-start-tag-after-bodyz>Unexpected start tag token (%(name)s) in the after body phase.zunexpected-end-tag-after-bodyz s r)     )rrdrfrgrhcCsi|] }t|t|qSr)ordlower)rcrrrr#s)rDrErFrGrHrI)r,r6z event-sourcerSrVrLr1rOr=r]r)r4rPsourcetrack)rcr`rkrMrXrYrZ irrelevant itemscopescopedismapaudioautoplaycontrolsvideodeferasyncopendatagridmultipledisabled)hiddenrcheckeddefaultnoshade autosubmitreadonlyoption)rrselectedoptgroup autofocus)rrrequiredrrr)rrrrseamless)outputrM) i i ii i& i i! ii0 i`i9 iRr i}r r i i i i i" i i ii"!iai: iSr i~ix)lt;gt;amp;apos;quot;AEligÆzAElig;AMP&zAMP;AacuteÁzAacute;zAbreve;uĂAcircÂzAcirc;zAcy;uАzAfr;u𝔄AgraveÀzAgrave;zAlpha;uΑzAmacr;uĀzAnd;u⩓zAogon;uĄzAopf;u𝔸zApplyFunction;u⁡AringÅzAring;zAscr;u𝒜zAssign;u≔AtildeÃzAtilde;AumlÄzAuml;z Backslash;u∖zBarv;u⫧zBarwed;u⌆zBcy;uБzBecause;u∵z Bernoullis;uℬzBeta;uΒzBfr;u𝔅zBopf;u𝔹zBreve;u˘zBscr;zBumpeq;u≎zCHcy;uЧCOPY©zCOPY;zCacute;uĆzCap;u⋒zCapitalDifferentialD;uⅅzCayleys;uℭzCcaron;uČCcedilÇzCcedil;zCcirc;uĈzCconint;u∰zCdot;uĊzCedilla;¸z CenterDot;·zCfr;zChi;uΧz CircleDot;u⊙z CircleMinus;u⊖z CirclePlus;u⊕z CircleTimes;u⊗zClockwiseContourIntegral;u∲zCloseCurlyDoubleQuote;u”zCloseCurlyQuote;u’zColon;u∷zColone;u⩴z Congruent;u≡zConint;u∯zContourIntegral;u∮zCopf;uℂz Coproduct;u∐z CounterClockwiseContourIntegral;u∳zCross;u⨯zCscr;u𝒞zCup;u⋓zCupCap;u≍zDD;z DDotrahd;u⤑zDJcy;uЂzDScy;uЅzDZcy;uЏzDagger;u‡zDarr;u↡zDashv;u⫤zDcaron;uĎzDcy;uДzDel;u∇zDelta;uΔzDfr;u𝔇zDiacriticalAcute;´zDiacriticalDot;u˙zDiacriticalDoubleAcute;u˝zDiacriticalGrave;`zDiacriticalTilde;u˜zDiamond;u⋄zDifferentialD;uⅆzDopf;u𝔻zDot;¨zDotDot;u⃜z DotEqual;u≐zDoubleContourIntegral;z DoubleDot;zDoubleDownArrow;u⇓zDoubleLeftArrow;u⇐zDoubleLeftRightArrow;u⇔zDoubleLeftTee;zDoubleLongLeftArrow;u⟸zDoubleLongLeftRightArrow;u⟺zDoubleLongRightArrow;u⟹zDoubleRightArrow;u⇒zDoubleRightTee;u⊨zDoubleUpArrow;u⇑zDoubleUpDownArrow;u⇕zDoubleVerticalBar;u∥z DownArrow;u↓z DownArrowBar;u⤓zDownArrowUpArrow;u⇵z DownBreve;ȗzDownLeftRightVector;u⥐zDownLeftTeeVector;u⥞zDownLeftVector;u↽zDownLeftVectorBar;u⥖zDownRightTeeVector;u⥟zDownRightVector;u⇁zDownRightVectorBar;u⥗zDownTee;u⊤z DownTeeArrow;u↧z Downarrow;zDscr;u𝒟zDstrok;uĐzENG;uŊETHÐzETH;EacuteÉzEacute;zEcaron;uĚEcircÊzEcirc;zEcy;uЭzEdot;uĖzEfr;u𝔈EgraveÈzEgrave;zElement;u∈zEmacr;uĒzEmptySmallSquare;u◻zEmptyVerySmallSquare;u▫zEogon;uĘzEopf;u𝔼zEpsilon;uΕzEqual;u⩵z EqualTilde;u≂z Equilibrium;u⇌zEscr;uℰzEsim;u⩳zEta;uΗEumlËzEuml;zExists;u∃z ExponentialE;uⅇzFcy;uФzFfr;u𝔉zFilledSmallSquare;u◼zFilledVerySmallSquare;u▪zFopf;u𝔽zForAll;u∀z Fouriertrf;uℱzFscr;zGJcy;uЃGT>zGT;zGamma;uΓzGammad;uϜzGbreve;uĞzGcedil;uĢzGcirc;uĜzGcy;uГzGdot;uĠzGfr;u𝔊zGg;u⋙zGopf;u𝔾z GreaterEqual;u≥zGreaterEqualLess;u⋛zGreaterFullEqual;u≧zGreaterGreater;u⪢z GreaterLess;u≷zGreaterSlantEqual;u⩾z GreaterTilde;u≳zGscr;u𝒢zGt;u≫zHARDcy;uЪzHacek;uˇzHat;^zHcirc;uĤzHfr;uℌz HilbertSpace;uℋzHopf;uℍzHorizontalLine;u─zHscr;zHstrok;uĦz HumpDownHump;z HumpEqual;u≏zIEcy;uЕzIJlig;uIJzIOcy;uЁIacuteÍzIacute;IcircÎzIcirc;zIcy;uИzIdot;uİzIfr;uℑIgraveÌzIgrave;zIm;zImacr;uĪz ImaginaryI;uⅈzImplies;zInt;u∬z Integral;u∫z Intersection;u⋂zInvisibleComma;u⁣zInvisibleTimes;u⁢zIogon;uĮzIopf;u𝕀zIota;uΙzIscr;uℐzItilde;uĨzIukcy;uІIumlÏzIuml;zJcirc;uĴzJcy;uЙzJfr;u𝔍zJopf;u𝕁zJscr;u𝒥zJsercy;uЈzJukcy;uЄzKHcy;uХzKJcy;uЌzKappa;uΚzKcedil;uĶzKcy;uКzKfr;u𝔎zKopf;u𝕂zKscr;u𝒦zLJcy;uЉLT⃒znvinfin;u⧞znvlArr;u⤂znvle;u≤⃒znvlt;u<⃒znvltrie;u⊴⃒znvrArr;u⤃znvrtrie;u⊵⃒znvsim;u∼⃒znwArr;u⇖znwarhk;u⤣znwarr;znwarrow;znwnear;u⤧zoS;oacuteózoacute;zoast;zocir;ocircôzocirc;zocy;uоzodash;zodblac;uőzodiv;u⨸zodot;zodsold;u⦼zoelig;uœzofcir;u⦿zofr;u𝔬zogon;u˛ograveòzograve;zogt;u⧁zohbar;u⦵zohm;zoint;zolarr;zolcir;u⦾zolcross;u⦻zoline;zolt;u⧀zomacr;uōzomega;uωzomicron;uοzomid;u⦶zominus;zoopf;u𝕠zopar;u⦷zoperp;u⦹zoplus;zor;u∨zorarr;zord;u⩝zorder;uℴzorderof;ordfªzordf;ordmºzordm;zorigof;u⊶zoror;u⩖zorslope;u⩗zorv;u⩛zoscr;oslashøzoslash;zosol;u⊘otildeõzotilde;zotimes;z otimesas;u⨶oumlözouml;zovbar;u⌽zpar;para¶zpara;z parallel;zparsim;u⫳zparsl;u⫽zpart;zpcy;uпzpercnt;%zperiod;.zpermil;u‰zperp;zpertenk;u‱zpfr;u𝔭zphi;uφzphiv;uϕzphmmat;zphone;u☎zpi;uπz pitchfork;zpiv;uϖzplanck;zplanckh;uℎzplankv;zplus;+z plusacir;u⨣zplusb;zpluscir;u⨢zplusdo;zplusdu;u⨥zpluse;u⩲plusmnzplusmn;zplussim;u⨦zplustwo;u⨧zpm;z pointint;u⨕zpopf;u𝕡pound£zpound;zpr;zprE;u⪳zprap;u⪷zprcue;zpre;zprec;z precapprox;z preccurlyeq;zpreceq;z precnapprox;u⪹z precneqq;u⪵z precnsim;u⋨zprecsim;zprime;u′zprimes;zprnE;zprnap;zprnsim;zprod;z profalar;u⌮z profline;u⌒z profsurf;u⌓zprop;zpropto;zprsim;zprurel;u⊰zpscr;u𝓅zpsi;uψzpuncsp;u zqfr;u𝔮zqint;zqopf;u𝕢zqprime;u⁗zqscr;u𝓆z quaternions;zquatint;u⨖zquest;?zquesteq;quotr%zrAarr;zrArr;zrAtail;u⤜zrBarr;zrHar;u⥤zrace;u∽̱zracute;uŕzradic;z raemptyv;u⦳zrang;zrangd;u⦒zrange;u⦥zrangle;raquo»zraquo;zrarr;zrarrap;u⥵zrarrb;zrarrbfs;u⤠zrarrc;u⤳zrarrfs;u⤞zrarrhk;zrarrlp;zrarrpl;u⥅zrarrsim;u⥴zrarrtl;u↣zrarrw;u↝zratail;u⤚zratio;u∶z rationals;zrbarr;zrbbrk;u❳zrbrace;}zrbrack;]zrbrke;u⦌zrbrksld;u⦎zrbrkslu;u⦐zrcaron;uřzrcedil;uŗzrceil;zrcub;zrcy;uрzrdca;u⤷zrdldhar;u⥩zrdquo;zrdquor;zrdsh;u↳zreal;zrealine;z realpart;zreals;zrect;u▭regzreg;zrfisht;u⥽zrfloor;zrfr;u𝔯zrhard;zrharu;zrharul;u⥬zrho;uρzrhov;uϱz rightarrow;zrightarrowtail;zrightharpoondown;zrightharpoonup;zrightleftarrows;zrightleftharpoons;zrightrightarrows;u⇉zrightsquigarrow;zrightthreetimes;u⋌zring;u˚z risingdotseq;zrlarr;zrlhar;zrlm;u‏zrmoust;u⎱z rmoustache;zrnmid;u⫮zroang;u⟭zroarr;u⇾zrobrk;zropar;u⦆zropf;u𝕣zroplus;u⨮zrotimes;u⨵zrpar;)zrpargt;u⦔z rppolint;u⨒zrrarr;zrsaquo;u›zrscr;u𝓇zrsh;zrsqb;zrsquo;zrsquor;zrthree;zrtimes;u⋊zrtri;u▹zrtrie;zrtrif;z rtriltri;u⧎zruluhar;u⥨zrx;u℞zsacute;uśzsbquo;zsc;zscE;u⪴zscap;u⪸zscaron;ušzsccue;zsce;zscedil;uşzscirc;uŝzscnE;u⪶zscnap;u⪺zscnsim;u⋩z scpolint;u⨓zscsim;zscy;uсzsdot;u⋅zsdotb;zsdote;u⩦zseArr;u⇘zsearhk;zsearr;zsearrow;sect§zsect;zsemi;;zseswar;u⤩z setminus;zsetmn;zsext;u✶zsfr;u𝔰zsfrown;zsharp;u♯zshchcy;uщzshcy;uшz shortmid;zshortparallel;shy­zshy;zsigma;uσzsigmaf;uςzsigmav;zsim;zsimdot;u⩪zsime;zsimeq;zsimg;u⪞zsimgE;u⪠zsiml;u⪝zsimlE;u⪟zsimne;u≆zsimplus;u⨤zsimrarr;u⥲zslarr;zsmallsetminus;zsmashp;u⨳z smeparsl;u⧤zsmid;zsmile;u⌣zsmt;u⪪zsmte;u⪬zsmtes;u⪬︀zsoftcy;uьzsol;/zsolb;u⧄zsolbar;u⌿zsopf;u𝕤zspades;u♠z spadesuit;zspar;zsqcap;zsqcaps;u⊓︀zsqcup;zsqcups;u⊔︀zsqsub;zsqsube;z sqsubset;z sqsubseteq;zsqsup;zsqsupe;z sqsupset;z sqsupseteq;zsqu;zsquare;zsquarf;zsquf;zsrarr;zsscr;u𝓈zssetmn;zssmile;zsstarf;zstar;u☆zstarf;zstraightepsilon;z straightphi;zstrns;zsub;u⊂zsubE;u⫅zsubdot;u⪽zsube;zsubedot;u⫃zsubmult;u⫁zsubnE;u⫋zsubne;u⊊zsubplus;u⪿zsubrarr;u⥹zsubset;z subseteq;z subseteqq;z subsetneq;z subsetneqq;zsubsim;u⫇zsubsub;u⫕zsubsup;u⫓zsucc;z succapprox;z succcurlyeq;zsucceq;z succnapprox;z succneqq;z succnsim;zsuccsim;zsum;zsung;u♪sup1¹zsup1;sup2²zsup2;sup3³zsup3;zsup;zsupE;u⫆zsupdot;u⪾zsupdsub;u⫘zsupe;zsupedot;u⫄zsuphsol;u⟉zsuphsub;u⫗zsuplarr;u⥻zsupmult;u⫂zsupnE;u⫌zsupne;u⊋zsupplus;u⫀zsupset;z supseteq;z supseteqq;z supsetneq;z supsetneqq;zsupsim;u⫈zsupsub;u⫔zsupsup;u⫖zswArr;u⇙zswarhk;zswarr;zswarrow;zswnwar;u⤪szligßzszlig;ztarget;u⌖ztau;uτztbrk;ztcaron;uťztcedil;uţztcy;uтztdot;ztelrec;u⌕ztfr;u𝔱zthere4;z therefore;ztheta;uθz thetasym;uϑzthetav;z thickapprox;z thicksim;zthinsp;zthkap;zthksim;thornþzthorn;ztilde;times×ztimes;ztimesb;z timesbar;u⨱ztimesd;u⨰ztint;ztoea;ztop;ztopbot;u⌶ztopcir;u⫱ztopf;u𝕥ztopfork;u⫚ztosa;ztprime;u‴ztrade;z triangle;u▵z triangledown;z triangleleft;ztrianglelefteq;z triangleq;u≜ztriangleright;ztrianglerighteq;ztridot;u◬ztrie;z triminus;u⨺ztriplus;u⨹ztrisb;u⧍ztritime;u⨻z trpezium;u⏢ztscr;u𝓉ztscy;uцztshcy;uћztstrok;uŧztwixt;ztwoheadleftarrow;ztwoheadrightarrow;zuArr;zuHar;u⥣uacuteúzuacute;zuarr;zubrcy;uўzubreve;uŭucircûzucirc;zucy;uуzudarr;zudblac;uűzudhar;zufisht;u⥾zufr;u𝔲ugraveùzugrave;zuharl;zuharr;zuhblk;u▀zulcorn;u⌜z ulcorner;zulcrop;u⌏zultri;u◸zumacr;uūumlzuml;zuogon;uųzuopf;u𝕦zuparrow;z updownarrow;zupharpoonleft;zupharpoonright;zuplus;zupsi;uυzupsih;zupsilon;z upuparrows;u⇈zurcorn;u⌝z urcorner;zurcrop;u⌎zuring;uůzurtri;u◹zuscr;u𝓊zutdot;u⋰zutilde;uũzutri;zutrif;zuuarr;uumlüzuuml;zuwangle;u⦧zvArr;zvBar;u⫨zvBarv;u⫩zvDash;zvangrt;u⦜z varepsilon;z varkappa;z varnothing;zvarphi;zvarpi;z varpropto;zvarr;zvarrho;z varsigma;z varsubsetneq;u⊊︀zvarsubsetneqq;u⫋︀z varsupsetneq;u⊋︀zvarsupsetneqq;u⫌︀z vartheta;zvartriangleleft;zvartriangleright;zvcy;uвzvdash;zvee;zveebar;u⊻zveeeq;u≚zvellip;u⋮zverbar;zvert;zvfr;u𝔳zvltri;zvnsub;zvnsup;zvopf;u𝕧zvprop;zvrtri;zvscr;u𝓋zvsubnE;zvsubne;zvsupnE;zvsupne;zvzigzag;u⦚zwcirc;uŵzwedbar;u⩟zwedge;zwedgeq;u≙zweierp;u℘zwfr;u𝔴zwopf;u𝕨zwp;zwr;zwreath;zwscr;u𝓌zxcap;zxcirc;zxcup;zxdtri;zxfr;u𝔵zxhArr;zxharr;zxi;uξzxlArr;zxlarr;zxmap;zxnis;u⋻zxodot;zxopf;u𝕩zxoplus;zxotime;zxrArr;zxrarr;zxscr;u𝓍zxsqcup;zxuplus;zxutri;zxvee;zxwedge;yacuteýzyacute;zyacy;uяzycirc;uŷzycy;uыyen¥zyen;zyfr;u𝔶zyicy;uїzyopf;u𝕪zyscr;u𝓎zyucy;uюyumlÿzyuml;zzacute;uźzzcaron;užzzcy;uзzzdot;użzzeetrf;zzeta;uζzzfr;u𝔷zzhcy;uжzzigrarr;u⇝u𝕫u𝓏u‍u‌)zzopf;zzscr;zzwj;zzwnj;u� r)Doctype CharactersSpaceCharactersStartTagEndTagEmptyTagComment ParseErrorr?r@rAcCsi|]\}}||qSrr)rkvrrrrx smathc@seZdZdZdS)DataLossWarningzBRaised when the current tree is unable to represent the input dataN)__name__ __module__ __qualname____doc__rrrrrG| srGc@s eZdZdS)_ReparseExceptionN)rHrIrJrrrrrL srL)/ __future__rrrstringEOFE namespaces frozensetscopingElementsformattingElementsspecialElementshtmlIntegrationPointElements"mathmlTextIntegrationPointElementsadjustSVGAttributesadjustMathMLAttributesadjustForeignAttributesitemsunadjustForeignAttributesspaceCharacterstableInsertModeElementsascii_lowercaseasciiLowercaseascii_uppercaseasciiUppercase ascii_letters asciiLettersdigits hexdigits hexDigitsasciiUpper2LowerheadingElements voidElements cdataElementsrcdataElementsbooleanAttributesentitiesWindows1252 xmlEntitiesentitiesreplacementCharacters tokenTypes tagTokenTypesprefixes UserWarningrG ExceptionrLrrrrsJ  !$&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~   !#%'*-03579;>@BEHKNPRTWY\^`bdgjlorux{~  $       !"#$%&'(),-./0123456789:;<=>?@ABCDEFGHIJKLMNOPS      !"#$%&'()*+,-./01234 A               #      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDE K      !"&  PKH]Tpython3.10/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-310.pycnu[o ai,@sddlmZmZmZddlmZddlmZm Z ddl m Z ddl m Z ddl mZddl mZmZdd l mZmZmZdd l mZmZdd l mZdd lmZdd lmZeeZe dkraeZne ZGdddeZdS))absolute_importdivisionunicode_literals)unichr)deque OrderedDict) version_info)spaceCharacters)entities) asciiLettersasciiUpper2Lower)digits hexDigitsEOF) tokenTypes tagTokenTypes)replacementCharacters)HTMLInputStream)Trie)csdeZdZdZdfdd ZddZddZdd d Zd d ZddZ ddZ ddZ ddZ ddZ ddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Z!d@dAZ"dBdCZ#dDdEZ$dFdGZ%dHdIZ&dJdKZ'dLdMZ(dNdOZ)dPdQZ*dRdSZ+dTdUZ,dVdWZ-dXdYZ.dZd[Z/d\d]Z0d^d_Z1d`daZ2dbdcZ3dddeZ4dfdgZ5dhdiZ6djdkZ7dldmZ8dndoZ9dpdqZ:drdsZ;dtduZdzd{Z?d|d}Z@d~dZAddZBddZCddZDddZEddZFddZGddZHddZIddZJddZKddZLZMS) HTMLTokenizera  This class takes care of tokenizing HTML. * self.currentToken Holds the token that is currently being processed. * self.state Holds a reference to the method to be invoked... XXX * self.stream Points to HTMLInputStream object. Nc sJt|fi||_||_d|_g|_|j|_d|_d|_t t | dSNF) rstreamparser escapeFlag lastFourChars dataStatestateescape currentTokensuperr__init__)selfrrkwargs __class__/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/_tokenizer.pyr#(szHTMLTokenizer.__init__ccsftg|_|r1|jjrtd|jjddV|jjs|jr+|jV|js"|s dSdS)z This is where the magic happens. We do our usually processing through the states and when we have a token to return we yield the token which pauses processing until the next token is requested. ParseErrorrtypedataN)r tokenQueuerrerrorsrpoppopleftr$r(r(r)__iter__7s  zHTMLTokenizer.__iter__c Cst}d}|r t}d}g}|j}||vr+|tur+|||j}||vr+|tustd||}|tvrJt|}|j t ddd|idnd|krTd ksYn|d krjd }|j t ddd|idnfd |krtd ksnd|krdksnd|krdksnd|krdksn|t gdvr|j t ddd|idzt |}Wnt y|d}t d|d?Bt d|d@B}Ynw|dkr|j t ddd|j||S)zThis function returns either U+FFFD or the character based on the decimal or hexadecimal representation. It also discards ";" if present. If not present self.tokenQueue.append({"type": tokenTypes["ParseError"]}) is invoked. r*z$illegal-codepoint-for-numeric-entity charAsIntr,r-datavarsii�r ii)# iiiiiiiiiiiiiiiiiii i i i i i i i i i iiiiir:iii;z numeric-entity-without-semicolonr+)rrrcharrappendintjoinrr.r frozensetchr ValueErrorunget) r$isHexallowedradix charStackcr7rCvr(r(r)consumeNumberEntityGs\          $  z!HTMLTokenizer.consumeNumberEntityFc Csd}|jg}|dtvs!|dtddfvs!|dur+||dkr+|j|dn|ddkrd}||j|ddvrKd}||j|rS|dtvs[|si|dtvri|j|d||}n|j t d d d |j| dd |}n|dturt d |sn||j|dtuszt d |dd}t|}Wn tyd}Ynw|dur|dd kr|j t d dd |dd kr|r||tvs||tvs||dkr|j| dd |}n2t|}|j| |d ||d7}n|j t d dd |j| dd |}|rC|jddd|7<dS|tvrKd}nd}|j t ||d dS)N&r<#F)xXTr*zexpected-numeric-entityr+r6rBznamed-entity-without-semicolon=zexpected-named-entityr-r SpaceCharacters Characters)rrCr rrJrDrrrQr.rr0rF entitiesTriehas_keys_with_prefixlongest_prefixlenKeyErrorr r r!) r$ allowedChar fromAttributeoutputrNhex entityName entityLength tokenTyper(r(r) consumeEntityst                   zHTMLTokenizer.consumeEntitycCs|j|dddS)zIThis method replaces the need for "entityInAttributeValueState". T)r`raN)rg)r$r`r(r(r)processEntityInAttributesz&HTMLTokenizer.processEntityInAttributecCs|j}|dtvr^|dt|d<|dtdkr8|d}t|}t|t|kr4||ddd||d<|dtdkr^|drO|j tdd d |d r^|j tdd d |j ||j |_ dS) zThis method is a generic handler for emitting the tags. It also sets the state to "data" because that's what's needed after a token has been emitted. r,nameStartTagr-NrUEndTagr*zattributes-in-end-tagr+ selfClosingzself-closing-flag-on-end-tag) r!r translater r attributeMapr^updater.rDrr)r$tokenrawr-r(r(r)emitCurrentTokens(     zHTMLTokenizer.emitCurrentTokencCs|j}|dkr|j|_d S|dkr|j|_d S|dkr5|jtddd|jtdddd S|tur;dS|t vrS|jtd ||j t d dd S|j d }|jtd||dd S) NrRrSr*invalid-codepointr+rZFrYTrRrSrs) rrCentityDataStater tagOpenStater.rDrrr charsUntilr$r-charsr(r(r)rs6     zHTMLTokenizer.dataStatecC||j|_dSNT)rgrrr2r(r(r)rvzHTMLTokenizer.entityDataStatecCs|j}|dkr|j|_d S|dkr|j|_d S|tkrdS|dkr;|jtddd|jtdd dd S|t vrS|jtd ||j t d dd S|j d }|jtd||dd S) NrRrSFrsr*rtr+rZr;rYTru) rrCcharacterReferenceInRcdatarrcdataLessThanSignStaterr.rDrr rxryr(r(r) rcdataState"s6     zHTMLTokenizer.rcdataStatecCr{r|)rgrrr2r(r(r)r~?r}z(HTMLTokenizer.characterReferenceInRcdatacC|j}|dkr|j|_d S|dkr+|jtddd|jtdddd S|tkr1dS|jd }|jtd||dd S NrSrsr*rtr+rZr;F)rSrsT) rrCrawtextLessThanSignStaterr.rDrrrxryr(r(r) rawtextStateD&       zHTMLTokenizer.rawtextStatecCrr) rrCscriptDataLessThanSignStaterr.rDrrrxryr(r(r)scriptDataStateVrzHTMLTokenizer.scriptDataStatecCst|j}|tkr dS|dkr'|jtddd|jtddddS|jtd||jdddS) NFrsr*rtr+rZr;T)rrCrr.rDrrxr$r-r(r(r)plaintextStatehs    zHTMLTokenizer.plaintextStatecCs|j}|dkr|j|_dS|dkr|j|_dS|tvr.td|gddd|_|j|_dS|dkrN|j tddd |j td d d |j |_dS|d kri|j tdd d |j ||j |_dS|j tddd |j td dd |j ||j |_dS)N!/rjF)r,rir-rlselfClosingAcknowledged>r*z'expected-tag-name-but-got-right-bracketr+rZz<>?z'expected-tag-name-but-got-question-markzexpected-tag-namerST)rrCmarkupDeclarationOpenStatercloseTagOpenStater rr! tagNameStater.rDrrJbogusCommentStaterr(r(r)rwwsH      zHTMLTokenizer.tagOpenStatecCs|j}|tvrtd|gdd|_|j|_dS|dkr.|jtddd|j |_dS|t urN|jtddd|jtd d d|j |_dS|jtdd d |id |j ||j |_dS)NrkFr,rir-rlrr*z*expected-closing-tag-but-got-right-bracketr+z expected-closing-tag-but-got-eofrZs  z6HTMLTokenizer.scriptDataDoubleEscapedLessThanSignStatecCrr)rrCr rGr.rDrrrrrrr rJrr(r(r)rIrz,HTMLTokenizer.scriptDataDoubleEscapeEndStatecCs:|j}|tvr|jtddS|tvr&|jd|dg|j|_dS|dkr0| dS|dkr:|j |_dS|dvrY|j t ddd |jd|dg|j|_dS|d krx|j t dd d |jdd dg|j|_dS|t ur|j t dd d |j|_dS|jd|dg|j|_dS)NTr-r6rr)'"rXrSr*#invalid-character-in-attribute-namer+rsrtr;z#expected-attribute-name-but-got-eof)rrCr rxr r!rDattributeNameStaterrrrr.rrrrr(r(r)rYsJ     z&HTMLTokenizer.beforeAttributeNameStatecCs|j}d}d}|dkr|j|_n|tvr-|jddd||jtd7<d}nz|dkr4d}ns|tvr=|j|_nj|dkrF|j |_na|d kre|j t d d d |jdddd 7<d}nB|dvr|j t d dd |jddd|7<d}n#|t ur|j t d dd |j|_n|jddd|7<d}|r|jdddt|jddd<|jdddD]\}}|jddd|kr|j t d dd nq|r|dS)NTFrXr-rUrrrrsr*rtr+r;rrrSrzeof-in-attribute-namezduplicate-attribute)rrCbeforeAttributeValueStaterr r!rxr afterAttributeNameStaterr.rDrrrrmr rr)r$r-leavingThisState emitTokenri_r(r(r)rws`          z HTMLTokenizer.attributeNameStatecCsN|j}|tvr|jtddS|dkr|j|_dS|dkr&|dS|tvr:|jd |dg|j |_dS|dkrD|j |_dS|dkrc|j t dd d |jd d dg|j |_dS|d vr|j t dd d |jd |dg|j |_dS|tur|j t ddd |j|_dS|jd |dg|j |_dS)NTrXrr-r6rrsr*rtr+r;rz&invalid-character-after-attribute-namezexpected-end-of-tag-but-got-eof)rrCr rxrrrrr r!rDrrr.rrrrr(r(r)rsP     z%HTMLTokenizer.afterAttributeNameStatecCsn|j}|tvr|jtddS|dkr|j|_dS|dkr,|j|_|j|dS|dkr6|j|_dS|dkrK|j t ddd| dS|d krm|j t dd d|j d d d d7<|j|_dS|dvr|j t ddd|j d d d |7<|j|_dS|tur|j t ddd|j|_dS|j d d d |7<|j|_dS)NTrrRrrr*z.expected-attribute-value-but-got-right-bracketr+rsrtr-rUr r;)rXrS`z"equals-in-unquoted-attribute-valuez$expected-attribute-value-but-got-eof)rrCr rxattributeValueDoubleQuotedStaterattributeValueUnQuotedStaterJattributeValueSingleQuotedStater.rDrrrr!rrrr(r(r)rsV       z'HTMLTokenizer.beforeAttributeValueStatecC|j}|dkr|j|_d S|dkr|dd S|dkr8|jtddd|jddd d 7<d S|t urM|jtdd d|j |_d S|jddd ||j d 7<d S)NrrRrsr*rtr+r-rUr r;z#eof-in-attribute-value-double-quote)rrRrsT rrCafterAttributeValueStaterrhr.rDrr!rrrxrr(r(r)r.      z-HTMLTokenizer.attributeValueDoubleQuotedStatecCr)NrrRrsr*rtr+r-rUr r;z#eof-in-attribute-value-single-quote)rrRrsTrrr(r(r)rrz-HTMLTokenizer.attributeValueSingleQuotedStatecCs|j}|tvr|j|_dS|dkr|ddS|dkr$|dS|dvrB|jt ddd|j ddd |7<dS|d kr`|jt dd d|j ddd d 7<dS|t uru|jt dd d|j |_dS|j ddd ||j tdtB7<dS)NrRr)rrrXrSrr*z0unexpected-character-in-unquoted-attribute-valuer+r-rUr rsrtr;z eof-in-attribute-value-no-quotes)rRrrrrXrSrrsT)rrCr rrrhrrr.rDrr!rrrxrGrr(r(r)rs@        z)HTMLTokenizer.attributeValueUnQuotedStatecCs|j}|tvr|j|_dS|dkr|dS|dkr#|j|_dS|tur>|j t ddd|j ||j |_dS|j t ddd|j ||j|_dS)Nrrr*z$unexpected-EOF-after-attribute-valuer+z*unexpected-character-after-attribute-valueT) rrCr rrrrrrr.rDrrJrrr(r(r)r.s.       z&HTMLTokenizer.afterAttributeValueStatecCs|j}|dkrd|jd<|dS|tur/|jtddd|j||j |_ dS|jtddd|j||j |_ dS)NrTrlr*z#unexpected-EOF-after-solidus-in-tagr+z)unexpected-character-after-solidus-in-tag) rrCr!rrrr.rDrrJrrrrr(r(r)rBs$       z&HTMLTokenizer.selfClosingStartTagStatecCsD|jd}|dd}|jtd|d|j|j|_dS)Nrrsr;Commentr+T) rrxreplacer.rDrrCrrrr(r(r)rTs    zHTMLTokenizer.bogusCommentStatecCsn|jg}|ddkr)||j|ddkr(tddd|_|j|_dSnq|ddvr\d}dD]}||j|d|vrGd }nq3|r[td ddddd |_|j|_dSn>|dd kr|jdur|jj j r|jj j dj |jj j krd}d D]}||j|d|krd }nq}|r|j |_dS|jtddd|r|j||s|j|_dS)NrUrrr6r+T)dD))oOrOCtTyYpPeEFDoctype)r,ripublicIdsystemIdcorrect[)rrArrrr*zexpected-dashes-or-doctype)rrCrDrr!commentStartStater doctypeStatertree openElements namespacedefaultNamespacecdataSectionStater.rJr0r)r$rNmatchedexpectedr(r(r)rcs`         z(HTMLTokenizer.markupDeclarationOpenStatecCs|j}|dkr|j|_d S|dkr)|jtddd|jdd7<d S|dkrE|jtdd d|j|j|j|_d S|t ura|jtdd d|j|j|j|_d S|jd|7<|j |_d S) Nrrsr*rtr+r-r;rincorrect-commenteof-in-commentT) rrCcommentStartDashStaterr.rDrr!rr commentStaterr(r(r)rs6     zHTMLTokenizer.commentStartStatecCs|j}|dkr|j|_d S|dkr)|jtddd|jdd7<d S|dkrE|jtdd d|j|j|j|_d S|t ura|jtdd d|j|j|j|_d S|jdd|7<|j |_d S) Nrrsr*rtr+r--�rrrT) rrCcommentEndStaterr.rDrr!rrrrr(r(r)rs6     z#HTMLTokenizer.commentStartDashStatecCs|j}|dkr|j|_d S|dkr)|jtddd|jdd7<d S|turE|jtddd|j|j|j |_d S|jd||j d 7<d S) Nrrsr*rtr+r-r;r)rrsT) rrCcommentEndDashStaterr.rDrr!rrrxrr(r(r)rs*      zHTMLTokenizer.commentStatecCs|j}|dkr|j|_d S|dkr-|jtddd|jdd7<|j|_d S|t urI|jtddd|j|j|j |_d S|jdd|7<|j|_d S) Nrrsr*rtr+r-rzeof-in-comment-end-dashT) rrCrrr.rDrr!rrrrr(r(r)rs*    z!HTMLTokenizer.commentEndDashStatecCs6|j}|dkr|j|j|j|_dS|dkr4|jtddd|jdd7<|j|_dS|dkrI|jtdd d|j |_dS|d krc|jtdd d|jd|7<dS|t ur|jtdd d|j|j|j|_dS|jtdd d|jdd|7<|j|_dS)Nrrsr*rtr+r-u--�rz,unexpected-bang-after-double-dash-in-commentrz,unexpected-dash-after-double-dash-in-commentzeof-in-comment-double-dashzunexpected-char-in-commentz--T) rrCr.rDr!rrrrcommentEndBangStaterrr(r(r)rsJ       zHTMLTokenizer.commentEndStatecCs|j}|dkr|j|j|j|_d S|dkr)|jdd7<|j|_d S|dkrG|jtddd|jdd 7<|j |_d S|t urc|jtdd d|j|j|j|_d S|jdd|7<|j |_d S) Nrrr-z--!rsr*rtr+u--!�zeof-in-comment-end-bang-stateT) rrCr.rDr!rrrrrrrr(r(r)rs4    z!HTMLTokenizer.commentEndBangStatecCs|j}|tvr|j|_dS|tur0|jtdddd|j d<|j|j |j |_dS|jtddd|j ||j|_dS)Nr*!expected-doctype-name-but-got-eofr+Frzneed-space-after-doctypeT) rrCr beforeDoctypeNameStaterrr.rDrr!rrJrr(r(r)rs$      zHTMLTokenizer.doctypeStatecCs|j}|tvr d S|dkr-|jtdddd|jd<|j|j|j|_d S|dkrG|jtdddd |jd <|j |_d S|t urh|jtdd dd|jd<|j|j|j|_d S||jd <|j |_d S) Nrr*z+expected-doctype-name-but-got-right-bracketr+Frrsrtr;rirT) rrCr r.rDrr!rrdoctypeNameStaterrr(r(r)r*s<         z$HTMLTokenizer.beforeDoctypeNameStatecCs|j}|tvr|jdt|jd<|j|_d S|dkr6|jdt|jd<|j |j|j |_d S|dkrT|j t ddd|jdd7<|j |_d S|t ur|j t dddd |jd <|jdt|jd<|j |j|j |_d S|jd|7<d S) Nrirrsr*rtr+r;zeof-in-doctype-nameFrT)rrCr r!rmr afterDoctypeNameStaterr.rDrrrrrr(r(r)rDs8     zHTMLTokenizer.doctypeNameStatecCsH|j}|tvr dS|dkr|j|j|j|_dS|turDd|jd<|j ||jt ddd|j|j|j|_dS|dvred}d D]}|j}||vr[d}nqL|rd|j |_dSn |d vrd}d D]}|j}||vr|d}nqm|r|j |_dS|j ||jt dd d |idd|jd<|j |_dS)NrFrr*eof-in-doctyper+rT))uU)bB)lL)iIrsS)rr rr)mMz*expected-space-or-right-bracket-in-doctyper-r8)rrCr r.rDr!rrrrJrafterDoctypePublicKeywordStateafterDoctypeSystemKeywordStatebogusDoctypeState)r$r-rrr(r(r)r]s` .+   $     z#HTMLTokenizer.afterDoctypeNameStatecC|j}|tvr|j|_dS|dvr*|jtddd|j||j|_dS|t urK|jtdddd|j d<|j|j |j |_dS|j||j|_dS N)rrr*unexpected-char-in-doctyper+rFrT) rrCr "beforeDoctypePublicIdentifierStaterr.rDrrJrr!rrr(r(r)r,       z,HTMLTokenizer.afterDoctypePublicKeywordStatecCs|j}|tvr d S|dkrd|jd<|j|_d S|dkr*d|jd<|j|_d S|dkrK|jt dddd |jd <|j|j|j |_d S|t url|jt dd dd |jd <|j|j|j |_d S|jt dd dd |jd <|j |_d S)Nrr6rrrr*unexpected-end-of-doctyper+FrrrT) rrCr r!(doctypePublicIdentifierDoubleQuotedStater(doctypePublicIdentifierSingleQuotedStater.rDrrrrrr(r(r)rD          z0HTMLTokenizer.beforeDoctypePublicIdentifierStatecC|j}|dkr|j|_d S|dkr)|jtddd|jdd7<d S|dkrJ|jtdd dd |jd <|j|j|j|_d S|t urk|jtdd dd |jd <|j|j|j|_d S|jd|7<d S)Nrrsr*rtr+rr;rrFrrT rrC!afterDoctypePublicIdentifierStaterr.rDrr!rrrr(r(r)r8       z6HTMLTokenizer.doctypePublicIdentifierDoubleQuotedStatecCr)Nrrsr*rtr+rr;rrFrrTrrr(r(r)rr z6HTMLTokenizer.doctypePublicIdentifierSingleQuotedStatecCs|j}|tvr|j|_d S|dkr |j|j|j|_d S|dkr:|jt dddd|jd<|j |_d S|dkrT|jt dddd|jd<|j |_d S|t uru|jt dd dd |jd <|j|j|j|_d S|jt dddd |jd <|j |_d S) Nrrr*rr+r6rrrFrT)rrCr -betweenDoctypePublicAndSystemIdentifiersStaterr.rDr!rr(doctypeSystemIdentifierDoubleQuotedState(doctypeSystemIdentifierSingleQuotedStaterrrr(r(r)rsH          z/HTMLTokenizer.afterDoctypePublicIdentifierStatecCs|j}|tvr d S|dkr|j|j|j|_d S|dkr,d|jd<|j|_d S|dkr;d|jd<|j |_d S|t kr\|jt dddd |jd <|j|j|j|_d S|jt dd dd |jd <|j |_d S) Nrrr6rrr*rr+FrrT) rrCr r.rDr!rrr"r#rrrrr(r(r)r!s<        z;HTMLTokenizer.betweenDoctypePublicAndSystemIdentifiersStatecCrr) rrCr "beforeDoctypeSystemIdentifierStaterr.rDrrJrr!rrr(r(r)r)rz,HTMLTokenizer.afterDoctypeSystemKeywordStatecCs|j}|tvr d S|dkrd|jd<|j|_d S|dkr*d|jd<|j|_d S|dkrK|jt dddd |jd <|j|j|j |_d S|t url|jt dd dd |jd <|j|j|j |_d S|jt dddd |jd <|j |_d S) Nrr6rrrr*rr+FrrT) rrCr r!r"rr#r.rDrrrrrr(r(r)r$=rz0HTMLTokenizer.beforeDoctypeSystemIdentifierStatecCr)Nrrsr*rtr+rr;rrFrrT rrC!afterDoctypeSystemIdentifierStaterr.rDrr!rrrr(r(r)r"Zr z6HTMLTokenizer.doctypeSystemIdentifierDoubleQuotedStatecCr)Nrrsr*rtr+rr;rrFrrTr%rr(r(r)r#rr z6HTMLTokenizer.doctypeSystemIdentifierSingleQuotedStatecCs|j}|tvr dS|dkr|j|j|j|_dS|tur>|jt dddd|jd<|j|j|j|_dS|jt ddd|j |_dS) Nrr*rr+FrrT) rrCr r.rDr!rrrrrrr(r(r)r&s*     z/HTMLTokenizer.afterDoctypeSystemIdentifierStatecCs`|j}|dkr|j|j|j|_dS|tur-|j||j|j|j|_dS dS)NrT) rrCr.rDr!rrrrJrr(r(r)rs  zHTMLTokenizer.bogusDoctypeStatecCsg} ||jd||jd|j}|tkrn!|dks%J|ddddkr:|ddd|d<n||qd|}|d}|d krft|D] }|jt d d d qR| dd }|rs|jt d|d |j |_ dS)NT]rrUz]]r6rsrr*rtr+r;rZ) rDrrxrCrrFcountranger.rrrr)r$r-rC nullCountrr(r(r)rs6         zHTMLTokenizer.cdataSectionState)Nr)N__name__ __module__ __qualname____doc__r#r3rQrgrhrrrrvrr~rrrrwrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr!rr$r"r#r&rr __classcell__r(r(r&r)rs  HP#         6 "-3rN) __future__rrrZpip._vendor.sixrrH collectionsrrsysr constantsr r r r rrrrrr _inputstreamr_trierr[dictrnobjectrr(r(r(r)s"       PKH]Ppython3.10/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-310.pycnu[o aiC@sHddlmZmZmZddlmZzddlmZWney'ddl mZYnwddl m Z m Z e r.moduleFactoryr)rJrLrrIr!r ysr csifdd}|S)Ncs6t|t|f}|vr|i||<|Sr)rr)r?r@r$cachefuncrr!wrappedszmemoize..wrappedr)rOrPrrMr!memoizesrQ) __future__rrrtypesrcollections.abcr ImportError collectionsZpip._vendor.sixrrxml.etree.ElementTreeetree ElementTreer Zxml.etree.cElementTreeZ cElementTree__all__eval_xr Exceptionrrr r&r r r rQrrrr!s@        PKH][2&FF:python3.10/site-packages/pip/_vendor/html5lib/constants.pynu[from __future__ import absolute_import, division, unicode_literals import string EOF = None E = { "null-character": "Null character in input stream, replaced with U+FFFD.", "invalid-codepoint": "Invalid codepoint in stream.", "incorrectly-placed-solidus": "Solidus (/) incorrectly placed in tag.", "incorrect-cr-newline-entity": "Incorrect CR newline entity, replaced with LF.", "illegal-windows-1252-entity": "Entity used with illegal number (windows-1252 reference).", "cant-convert-numeric-entity": "Numeric entity couldn't be converted to character " "(codepoint U+%(charAsInt)08x).", "illegal-codepoint-for-numeric-entity": "Numeric entity represents an illegal codepoint: " "U+%(charAsInt)08x.", "numeric-entity-without-semicolon": "Numeric entity didn't end with ';'.", "expected-numeric-entity-but-got-eof": "Numeric entity expected. Got end of file instead.", "expected-numeric-entity": "Numeric entity expected but none found.", "named-entity-without-semicolon": "Named entity didn't end with ';'.", "expected-named-entity": "Named entity expected. Got none.", "attributes-in-end-tag": "End tag contains unexpected attributes.", 'self-closing-flag-on-end-tag': "End tag contains unexpected self-closing flag.", "expected-tag-name-but-got-right-bracket": "Expected tag name. Got '>' instead.", "expected-tag-name-but-got-question-mark": "Expected tag name. Got '?' instead. (HTML doesn't " "support processing instructions.)", "expected-tag-name": "Expected tag name. Got something else instead", "expected-closing-tag-but-got-right-bracket": "Expected closing tag. Got '>' instead. Ignoring ''.", "expected-closing-tag-but-got-eof": "Expected closing tag. Unexpected end of file.", "expected-closing-tag-but-got-char": "Expected closing tag. Unexpected character '%(data)s' found.", "eof-in-tag-name": "Unexpected end of file in the tag name.", "expected-attribute-name-but-got-eof": "Unexpected end of file. Expected attribute name instead.", "eof-in-attribute-name": "Unexpected end of file in attribute name.", "invalid-character-in-attribute-name": "Invalid character in attribute name", "duplicate-attribute": "Dropped duplicate attribute on tag.", "expected-end-of-tag-name-but-got-eof": "Unexpected end of file. Expected = or end of tag.", "expected-attribute-value-but-got-eof": "Unexpected end of file. Expected attribute value.", "expected-attribute-value-but-got-right-bracket": "Expected attribute value. Got '>' instead.", 'equals-in-unquoted-attribute-value': "Unexpected = in unquoted attribute", 'unexpected-character-in-unquoted-attribute-value': "Unexpected character in unquoted attribute", "invalid-character-after-attribute-name": "Unexpected character after attribute name.", "unexpected-character-after-attribute-value": "Unexpected character after attribute value.", "eof-in-attribute-value-double-quote": "Unexpected end of file in attribute value (\").", "eof-in-attribute-value-single-quote": "Unexpected end of file in attribute value (').", "eof-in-attribute-value-no-quotes": "Unexpected end of file in attribute value.", "unexpected-EOF-after-solidus-in-tag": "Unexpected end of file in tag. Expected >", "unexpected-character-after-solidus-in-tag": "Unexpected character after / in tag. Expected >", "expected-dashes-or-doctype": "Expected '--' or 'DOCTYPE'. Not found.", "unexpected-bang-after-double-dash-in-comment": "Unexpected ! after -- in comment", "unexpected-space-after-double-dash-in-comment": "Unexpected space after -- in comment", "incorrect-comment": "Incorrect comment.", "eof-in-comment": "Unexpected end of file in comment.", "eof-in-comment-end-dash": "Unexpected end of file in comment (-)", "unexpected-dash-after-double-dash-in-comment": "Unexpected '-' after '--' found in comment.", "eof-in-comment-double-dash": "Unexpected end of file in comment (--).", "eof-in-comment-end-space-state": "Unexpected end of file in comment.", "eof-in-comment-end-bang-state": "Unexpected end of file in comment.", "unexpected-char-in-comment": "Unexpected character in comment found.", "need-space-after-doctype": "No space after literal string 'DOCTYPE'.", "expected-doctype-name-but-got-right-bracket": "Unexpected > character. Expected DOCTYPE name.", "expected-doctype-name-but-got-eof": "Unexpected end of file. Expected DOCTYPE name.", "eof-in-doctype-name": "Unexpected end of file in DOCTYPE name.", "eof-in-doctype": "Unexpected end of file in DOCTYPE.", "expected-space-or-right-bracket-in-doctype": "Expected space or '>'. Got '%(data)s'", "unexpected-end-of-doctype": "Unexpected end of DOCTYPE.", "unexpected-char-in-doctype": "Unexpected character in DOCTYPE.", "eof-in-innerhtml": "XXX innerHTML EOF", "unexpected-doctype": "Unexpected DOCTYPE. Ignored.", "non-html-root": "html needs to be the first start tag.", "expected-doctype-but-got-eof": "Unexpected End of file. Expected DOCTYPE.", "unknown-doctype": "Erroneous DOCTYPE.", "expected-doctype-but-got-chars": "Unexpected non-space characters. Expected DOCTYPE.", "expected-doctype-but-got-start-tag": "Unexpected start tag (%(name)s). Expected DOCTYPE.", "expected-doctype-but-got-end-tag": "Unexpected end tag (%(name)s). Expected DOCTYPE.", "end-tag-after-implied-root": "Unexpected end tag (%(name)s) after the (implied) root element.", "expected-named-closing-tag-but-got-eof": "Unexpected end of file. Expected end tag (%(name)s).", "two-heads-are-not-better-than-one": "Unexpected start tag head in existing head. Ignored.", "unexpected-end-tag": "Unexpected end tag (%(name)s). Ignored.", "unexpected-start-tag-out-of-my-head": "Unexpected start tag (%(name)s) that can be in head. Moved.", "unexpected-start-tag": "Unexpected start tag (%(name)s).", "missing-end-tag": "Missing end tag (%(name)s).", "missing-end-tags": "Missing end tags (%(name)s).", "unexpected-start-tag-implies-end-tag": "Unexpected start tag (%(startName)s) " "implies end tag (%(endName)s).", "unexpected-start-tag-treated-as": "Unexpected start tag (%(originalName)s). Treated as %(newName)s.", "deprecated-tag": "Unexpected start tag %(name)s. Don't use it!", "unexpected-start-tag-ignored": "Unexpected start tag %(name)s. Ignored.", "expected-one-end-tag-but-got-another": "Unexpected end tag (%(gotName)s). " "Missing end tag (%(expectedName)s).", "end-tag-too-early": "End tag (%(name)s) seen too early. Expected other end tag.", "end-tag-too-early-named": "Unexpected end tag (%(gotName)s). Expected end tag (%(expectedName)s).", "end-tag-too-early-ignored": "End tag (%(name)s) seen too early. Ignored.", "adoption-agency-1.1": "End tag (%(name)s) violates step 1, " "paragraph 1 of the adoption agency algorithm.", "adoption-agency-1.2": "End tag (%(name)s) violates step 1, " "paragraph 2 of the adoption agency algorithm.", "adoption-agency-1.3": "End tag (%(name)s) violates step 1, " "paragraph 3 of the adoption agency algorithm.", "adoption-agency-4.4": "End tag (%(name)s) violates step 4, " "paragraph 4 of the adoption agency algorithm.", "unexpected-end-tag-treated-as": "Unexpected end tag (%(originalName)s). Treated as %(newName)s.", "no-end-tag": "This element (%(name)s) has no end tag.", "unexpected-implied-end-tag-in-table": "Unexpected implied end tag (%(name)s) in the table phase.", "unexpected-implied-end-tag-in-table-body": "Unexpected implied end tag (%(name)s) in the table body phase.", "unexpected-char-implies-table-voodoo": "Unexpected non-space characters in " "table context caused voodoo mode.", "unexpected-hidden-input-in-table": "Unexpected input with type hidden in table context.", "unexpected-form-in-table": "Unexpected form in table context.", "unexpected-start-tag-implies-table-voodoo": "Unexpected start tag (%(name)s) in " "table context caused voodoo mode.", "unexpected-end-tag-implies-table-voodoo": "Unexpected end tag (%(name)s) in " "table context caused voodoo mode.", "unexpected-cell-in-table-body": "Unexpected table cell start tag (%(name)s) " "in the table body phase.", "unexpected-cell-end-tag": "Got table cell end tag (%(name)s) " "while required end tags are missing.", "unexpected-end-tag-in-table-body": "Unexpected end tag (%(name)s) in the table body phase. Ignored.", "unexpected-implied-end-tag-in-table-row": "Unexpected implied end tag (%(name)s) in the table row phase.", "unexpected-end-tag-in-table-row": "Unexpected end tag (%(name)s) in the table row phase. Ignored.", "unexpected-select-in-select": "Unexpected select start tag in the select phase " "treated as select end tag.", "unexpected-input-in-select": "Unexpected input start tag in the select phase.", "unexpected-start-tag-in-select": "Unexpected start tag token (%(name)s in the select phase. " "Ignored.", "unexpected-end-tag-in-select": "Unexpected end tag (%(name)s) in the select phase. Ignored.", "unexpected-table-element-start-tag-in-select-in-table": "Unexpected table element start tag (%(name)s) in the select in table phase.", "unexpected-table-element-end-tag-in-select-in-table": "Unexpected table element end tag (%(name)s) in the select in table phase.", "unexpected-char-after-body": "Unexpected non-space characters in the after body phase.", "unexpected-start-tag-after-body": "Unexpected start tag token (%(name)s)" " in the after body phase.", "unexpected-end-tag-after-body": "Unexpected end tag token (%(name)s)" " in the after body phase.", "unexpected-char-in-frameset": "Unexpected characters in the frameset phase. Characters ignored.", "unexpected-start-tag-in-frameset": "Unexpected start tag token (%(name)s)" " in the frameset phase. Ignored.", "unexpected-frameset-in-frameset-innerhtml": "Unexpected end tag token (frameset) " "in the frameset phase (innerHTML).", "unexpected-end-tag-in-frameset": "Unexpected end tag token (%(name)s)" " in the frameset phase. Ignored.", "unexpected-char-after-frameset": "Unexpected non-space characters in the " "after frameset phase. Ignored.", "unexpected-start-tag-after-frameset": "Unexpected start tag (%(name)s)" " in the after frameset phase. Ignored.", "unexpected-end-tag-after-frameset": "Unexpected end tag (%(name)s)" " in the after frameset phase. Ignored.", "unexpected-end-tag-after-body-innerhtml": "Unexpected end tag after body(innerHtml)", "expected-eof-but-got-char": "Unexpected non-space characters. Expected end of file.", "expected-eof-but-got-start-tag": "Unexpected start tag (%(name)s)" ". Expected end of file.", "expected-eof-but-got-end-tag": "Unexpected end tag (%(name)s)" ". Expected end of file.", "eof-in-table": "Unexpected end of file. Expected table content.", "eof-in-select": "Unexpected end of file. Expected select content.", "eof-in-frameset": "Unexpected end of file. Expected frameset content.", "eof-in-script-in-script": "Unexpected end of file. Expected script content.", "eof-in-foreign-lands": "Unexpected end of file. Expected foreign content", "non-void-element-with-trailing-solidus": "Trailing solidus not allowed on element %(name)s", "unexpected-html-element-in-foreign-content": "Element %(name)s not allowed in a non-html context", "unexpected-end-tag-before-html": "Unexpected end tag (%(name)s) before html.", "unexpected-inhead-noscript-tag": "Element %(name)s not allowed in a inhead-noscript context", "eof-in-head-noscript": "Unexpected end of file. Expected inhead-noscript content", "char-in-head-noscript": "Unexpected non-space character. Expected inhead-noscript content", "XXX-undefined-error": "Undefined error (this sucks and should be fixed)", } namespaces = { "html": "http://www.w3.org/1999/xhtml", "mathml": "http://www.w3.org/1998/Math/MathML", "svg": "http://www.w3.org/2000/svg", "xlink": "http://www.w3.org/1999/xlink", "xml": "http://www.w3.org/XML/1998/namespace", "xmlns": "http://www.w3.org/2000/xmlns/" } scopingElements = frozenset([ (namespaces["html"], "applet"), (namespaces["html"], "caption"), (namespaces["html"], "html"), (namespaces["html"], "marquee"), (namespaces["html"], "object"), (namespaces["html"], "table"), (namespaces["html"], "td"), (namespaces["html"], "th"), (namespaces["mathml"], "mi"), (namespaces["mathml"], "mo"), (namespaces["mathml"], "mn"), (namespaces["mathml"], "ms"), (namespaces["mathml"], "mtext"), (namespaces["mathml"], "annotation-xml"), (namespaces["svg"], "foreignObject"), (namespaces["svg"], "desc"), (namespaces["svg"], "title"), ]) formattingElements = frozenset([ (namespaces["html"], "a"), (namespaces["html"], "b"), (namespaces["html"], "big"), (namespaces["html"], "code"), (namespaces["html"], "em"), (namespaces["html"], "font"), (namespaces["html"], "i"), (namespaces["html"], "nobr"), (namespaces["html"], "s"), (namespaces["html"], "small"), (namespaces["html"], "strike"), (namespaces["html"], "strong"), (namespaces["html"], "tt"), (namespaces["html"], "u") ]) specialElements = frozenset([ (namespaces["html"], "address"), (namespaces["html"], "applet"), (namespaces["html"], "area"), (namespaces["html"], "article"), (namespaces["html"], "aside"), (namespaces["html"], "base"), (namespaces["html"], "basefont"), (namespaces["html"], "bgsound"), (namespaces["html"], "blockquote"), (namespaces["html"], "body"), (namespaces["html"], "br"), (namespaces["html"], "button"), (namespaces["html"], "caption"), (namespaces["html"], "center"), (namespaces["html"], "col"), (namespaces["html"], "colgroup"), (namespaces["html"], "command"), (namespaces["html"], "dd"), (namespaces["html"], "details"), (namespaces["html"], "dir"), (namespaces["html"], "div"), (namespaces["html"], "dl"), (namespaces["html"], "dt"), (namespaces["html"], "embed"), (namespaces["html"], "fieldset"), (namespaces["html"], "figure"), (namespaces["html"], "footer"), (namespaces["html"], "form"), (namespaces["html"], "frame"), (namespaces["html"], "frameset"), (namespaces["html"], "h1"), (namespaces["html"], "h2"), (namespaces["html"], "h3"), (namespaces["html"], "h4"), (namespaces["html"], "h5"), (namespaces["html"], "h6"), (namespaces["html"], "head"), (namespaces["html"], "header"), (namespaces["html"], "hr"), (namespaces["html"], "html"), (namespaces["html"], "iframe"), # Note that image is commented out in the spec as "this isn't an # element that can end up on the stack, so it doesn't matter," (namespaces["html"], "image"), (namespaces["html"], "img"), (namespaces["html"], "input"), (namespaces["html"], "isindex"), (namespaces["html"], "li"), (namespaces["html"], "link"), (namespaces["html"], "listing"), (namespaces["html"], "marquee"), (namespaces["html"], "menu"), (namespaces["html"], "meta"), (namespaces["html"], "nav"), (namespaces["html"], "noembed"), (namespaces["html"], "noframes"), (namespaces["html"], "noscript"), (namespaces["html"], "object"), (namespaces["html"], "ol"), (namespaces["html"], "p"), (namespaces["html"], "param"), (namespaces["html"], "plaintext"), (namespaces["html"], "pre"), (namespaces["html"], "script"), (namespaces["html"], "section"), (namespaces["html"], "select"), (namespaces["html"], "style"), (namespaces["html"], "table"), (namespaces["html"], "tbody"), (namespaces["html"], "td"), (namespaces["html"], "textarea"), (namespaces["html"], "tfoot"), (namespaces["html"], "th"), (namespaces["html"], "thead"), (namespaces["html"], "title"), (namespaces["html"], "tr"), (namespaces["html"], "ul"), (namespaces["html"], "wbr"), (namespaces["html"], "xmp"), (namespaces["svg"], "foreignObject") ]) htmlIntegrationPointElements = frozenset([ (namespaces["mathml"], "annotation-xml"), (namespaces["svg"], "foreignObject"), (namespaces["svg"], "desc"), (namespaces["svg"], "title") ]) mathmlTextIntegrationPointElements = frozenset([ (namespaces["mathml"], "mi"), (namespaces["mathml"], "mo"), (namespaces["mathml"], "mn"), (namespaces["mathml"], "ms"), (namespaces["mathml"], "mtext") ]) adjustSVGAttributes = { "attributename": "attributeName", "attributetype": "attributeType", "basefrequency": "baseFrequency", "baseprofile": "baseProfile", "calcmode": "calcMode", "clippathunits": "clipPathUnits", "contentscripttype": "contentScriptType", "contentstyletype": "contentStyleType", "diffuseconstant": "diffuseConstant", "edgemode": "edgeMode", "externalresourcesrequired": "externalResourcesRequired", "filterres": "filterRes", "filterunits": "filterUnits", "glyphref": "glyphRef", "gradienttransform": "gradientTransform", "gradientunits": "gradientUnits", "kernelmatrix": "kernelMatrix", "kernelunitlength": "kernelUnitLength", "keypoints": "keyPoints", "keysplines": "keySplines", "keytimes": "keyTimes", "lengthadjust": "lengthAdjust", "limitingconeangle": "limitingConeAngle", "markerheight": "markerHeight", "markerunits": "markerUnits", "markerwidth": "markerWidth", "maskcontentunits": "maskContentUnits", "maskunits": "maskUnits", "numoctaves": "numOctaves", "pathlength": "pathLength", "patterncontentunits": "patternContentUnits", "patterntransform": "patternTransform", "patternunits": "patternUnits", "pointsatx": "pointsAtX", "pointsaty": "pointsAtY", "pointsatz": "pointsAtZ", "preservealpha": "preserveAlpha", "preserveaspectratio": "preserveAspectRatio", "primitiveunits": "primitiveUnits", "refx": "refX", "refy": "refY", "repeatcount": "repeatCount", "repeatdur": "repeatDur", "requiredextensions": "requiredExtensions", "requiredfeatures": "requiredFeatures", "specularconstant": "specularConstant", "specularexponent": "specularExponent", "spreadmethod": "spreadMethod", "startoffset": "startOffset", "stddeviation": "stdDeviation", "stitchtiles": "stitchTiles", "surfacescale": "surfaceScale", "systemlanguage": "systemLanguage", "tablevalues": "tableValues", "targetx": "targetX", "targety": "targetY", "textlength": "textLength", "viewbox": "viewBox", "viewtarget": "viewTarget", "xchannelselector": "xChannelSelector", "ychannelselector": "yChannelSelector", "zoomandpan": "zoomAndPan" } adjustMathMLAttributes = {"definitionurl": "definitionURL"} adjustForeignAttributes = { "xlink:actuate": ("xlink", "actuate", namespaces["xlink"]), "xlink:arcrole": ("xlink", "arcrole", namespaces["xlink"]), "xlink:href": ("xlink", "href", namespaces["xlink"]), "xlink:role": ("xlink", "role", namespaces["xlink"]), "xlink:show": ("xlink", "show", namespaces["xlink"]), "xlink:title": ("xlink", "title", namespaces["xlink"]), "xlink:type": ("xlink", "type", namespaces["xlink"]), "xml:base": ("xml", "base", namespaces["xml"]), "xml:lang": ("xml", "lang", namespaces["xml"]), "xml:space": ("xml", "space", namespaces["xml"]), "xmlns": (None, "xmlns", namespaces["xmlns"]), "xmlns:xlink": ("xmlns", "xlink", namespaces["xmlns"]) } unadjustForeignAttributes = {(ns, local): qname for qname, (prefix, local, ns) in adjustForeignAttributes.items()} spaceCharacters = frozenset([ "\t", "\n", "\u000C", " ", "\r" ]) tableInsertModeElements = frozenset([ "table", "tbody", "tfoot", "thead", "tr" ]) asciiLowercase = frozenset(string.ascii_lowercase) asciiUppercase = frozenset(string.ascii_uppercase) asciiLetters = frozenset(string.ascii_letters) digits = frozenset(string.digits) hexDigits = frozenset(string.hexdigits) asciiUpper2Lower = {ord(c): ord(c.lower()) for c in string.ascii_uppercase} # Heading elements need to be ordered headingElements = ( "h1", "h2", "h3", "h4", "h5", "h6" ) voidElements = frozenset([ "base", "command", "event-source", "link", "meta", "hr", "br", "img", "embed", "param", "area", "col", "input", "source", "track" ]) cdataElements = frozenset(['title', 'textarea']) rcdataElements = frozenset([ 'style', 'script', 'xmp', 'iframe', 'noembed', 'noframes', 'noscript' ]) booleanAttributes = { "": frozenset(["irrelevant", "itemscope"]), "style": frozenset(["scoped"]), "img": frozenset(["ismap"]), "audio": frozenset(["autoplay", "controls"]), "video": frozenset(["autoplay", "controls"]), "script": frozenset(["defer", "async"]), "details": frozenset(["open"]), "datagrid": frozenset(["multiple", "disabled"]), "command": frozenset(["hidden", "disabled", "checked", "default"]), "hr": frozenset(["noshade"]), "menu": frozenset(["autosubmit"]), "fieldset": frozenset(["disabled", "readonly"]), "option": frozenset(["disabled", "readonly", "selected"]), "optgroup": frozenset(["disabled", "readonly"]), "button": frozenset(["disabled", "autofocus"]), "input": frozenset(["disabled", "readonly", "required", "autofocus", "checked", "ismap"]), "select": frozenset(["disabled", "readonly", "autofocus", "multiple"]), "output": frozenset(["disabled", "readonly"]), "iframe": frozenset(["seamless"]), } # entitiesWindows1252 has to be _ordered_ and needs to have an index. It # therefore can't be a frozenset. entitiesWindows1252 = ( 8364, # 0x80 0x20AC EURO SIGN 65533, # 0x81 UNDEFINED 8218, # 0x82 0x201A SINGLE LOW-9 QUOTATION MARK 402, # 0x83 0x0192 LATIN SMALL LETTER F WITH HOOK 8222, # 0x84 0x201E DOUBLE LOW-9 QUOTATION MARK 8230, # 0x85 0x2026 HORIZONTAL ELLIPSIS 8224, # 0x86 0x2020 DAGGER 8225, # 0x87 0x2021 DOUBLE DAGGER 710, # 0x88 0x02C6 MODIFIER LETTER CIRCUMFLEX ACCENT 8240, # 0x89 0x2030 PER MILLE SIGN 352, # 0x8A 0x0160 LATIN CAPITAL LETTER S WITH CARON 8249, # 0x8B 0x2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK 338, # 0x8C 0x0152 LATIN CAPITAL LIGATURE OE 65533, # 0x8D UNDEFINED 381, # 0x8E 0x017D LATIN CAPITAL LETTER Z WITH CARON 65533, # 0x8F UNDEFINED 65533, # 0x90 UNDEFINED 8216, # 0x91 0x2018 LEFT SINGLE QUOTATION MARK 8217, # 0x92 0x2019 RIGHT SINGLE QUOTATION MARK 8220, # 0x93 0x201C LEFT DOUBLE QUOTATION MARK 8221, # 0x94 0x201D RIGHT DOUBLE QUOTATION MARK 8226, # 0x95 0x2022 BULLET 8211, # 0x96 0x2013 EN DASH 8212, # 0x97 0x2014 EM DASH 732, # 0x98 0x02DC SMALL TILDE 8482, # 0x99 0x2122 TRADE MARK SIGN 353, # 0x9A 0x0161 LATIN SMALL LETTER S WITH CARON 8250, # 0x9B 0x203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK 339, # 0x9C 0x0153 LATIN SMALL LIGATURE OE 65533, # 0x9D UNDEFINED 382, # 0x9E 0x017E LATIN SMALL LETTER Z WITH CARON 376 # 0x9F 0x0178 LATIN CAPITAL LETTER Y WITH DIAERESIS ) xmlEntities = frozenset(['lt;', 'gt;', 'amp;', 'apos;', 'quot;']) entities = { "AElig": "\xc6", "AElig;": "\xc6", "AMP": "&", "AMP;": "&", "Aacute": "\xc1", "Aacute;": "\xc1", "Abreve;": "\u0102", "Acirc": "\xc2", "Acirc;": "\xc2", "Acy;": "\u0410", "Afr;": "\U0001d504", "Agrave": "\xc0", "Agrave;": "\xc0", "Alpha;": "\u0391", "Amacr;": "\u0100", "And;": "\u2a53", "Aogon;": "\u0104", "Aopf;": "\U0001d538", "ApplyFunction;": "\u2061", "Aring": "\xc5", "Aring;": "\xc5", "Ascr;": "\U0001d49c", "Assign;": "\u2254", "Atilde": "\xc3", "Atilde;": "\xc3", "Auml": "\xc4", "Auml;": "\xc4", "Backslash;": "\u2216", "Barv;": "\u2ae7", "Barwed;": "\u2306", "Bcy;": "\u0411", "Because;": "\u2235", "Bernoullis;": "\u212c", "Beta;": "\u0392", "Bfr;": "\U0001d505", "Bopf;": "\U0001d539", "Breve;": "\u02d8", "Bscr;": "\u212c", "Bumpeq;": "\u224e", "CHcy;": "\u0427", "COPY": "\xa9", "COPY;": "\xa9", "Cacute;": "\u0106", "Cap;": "\u22d2", "CapitalDifferentialD;": "\u2145", "Cayleys;": "\u212d", "Ccaron;": "\u010c", "Ccedil": "\xc7", "Ccedil;": "\xc7", "Ccirc;": "\u0108", "Cconint;": "\u2230", "Cdot;": "\u010a", "Cedilla;": "\xb8", "CenterDot;": "\xb7", "Cfr;": "\u212d", "Chi;": "\u03a7", "CircleDot;": "\u2299", "CircleMinus;": "\u2296", "CirclePlus;": "\u2295", "CircleTimes;": "\u2297", "ClockwiseContourIntegral;": "\u2232", "CloseCurlyDoubleQuote;": "\u201d", "CloseCurlyQuote;": "\u2019", "Colon;": "\u2237", "Colone;": "\u2a74", "Congruent;": "\u2261", "Conint;": "\u222f", "ContourIntegral;": "\u222e", "Copf;": "\u2102", "Coproduct;": "\u2210", "CounterClockwiseContourIntegral;": "\u2233", "Cross;": "\u2a2f", "Cscr;": "\U0001d49e", "Cup;": "\u22d3", "CupCap;": "\u224d", "DD;": "\u2145", "DDotrahd;": "\u2911", "DJcy;": "\u0402", "DScy;": "\u0405", "DZcy;": "\u040f", "Dagger;": "\u2021", "Darr;": "\u21a1", "Dashv;": "\u2ae4", "Dcaron;": "\u010e", "Dcy;": "\u0414", "Del;": "\u2207", "Delta;": "\u0394", "Dfr;": "\U0001d507", "DiacriticalAcute;": "\xb4", "DiacriticalDot;": "\u02d9", "DiacriticalDoubleAcute;": "\u02dd", "DiacriticalGrave;": "`", "DiacriticalTilde;": "\u02dc", "Diamond;": "\u22c4", "DifferentialD;": "\u2146", "Dopf;": "\U0001d53b", "Dot;": "\xa8", "DotDot;": "\u20dc", "DotEqual;": "\u2250", "DoubleContourIntegral;": "\u222f", "DoubleDot;": "\xa8", "DoubleDownArrow;": "\u21d3", "DoubleLeftArrow;": "\u21d0", "DoubleLeftRightArrow;": "\u21d4", "DoubleLeftTee;": "\u2ae4", "DoubleLongLeftArrow;": "\u27f8", "DoubleLongLeftRightArrow;": "\u27fa", "DoubleLongRightArrow;": "\u27f9", "DoubleRightArrow;": "\u21d2", "DoubleRightTee;": "\u22a8", "DoubleUpArrow;": "\u21d1", "DoubleUpDownArrow;": "\u21d5", "DoubleVerticalBar;": "\u2225", "DownArrow;": "\u2193", "DownArrowBar;": "\u2913", "DownArrowUpArrow;": "\u21f5", "DownBreve;": "\u0311", "DownLeftRightVector;": "\u2950", "DownLeftTeeVector;": "\u295e", "DownLeftVector;": "\u21bd", "DownLeftVectorBar;": "\u2956", "DownRightTeeVector;": "\u295f", "DownRightVector;": "\u21c1", "DownRightVectorBar;": "\u2957", "DownTee;": "\u22a4", "DownTeeArrow;": "\u21a7", "Downarrow;": "\u21d3", "Dscr;": "\U0001d49f", "Dstrok;": "\u0110", "ENG;": "\u014a", "ETH": "\xd0", "ETH;": "\xd0", "Eacute": "\xc9", "Eacute;": "\xc9", "Ecaron;": "\u011a", "Ecirc": "\xca", "Ecirc;": "\xca", "Ecy;": "\u042d", "Edot;": "\u0116", "Efr;": "\U0001d508", "Egrave": "\xc8", "Egrave;": "\xc8", "Element;": "\u2208", "Emacr;": "\u0112", "EmptySmallSquare;": "\u25fb", "EmptyVerySmallSquare;": "\u25ab", "Eogon;": "\u0118", "Eopf;": "\U0001d53c", "Epsilon;": "\u0395", "Equal;": "\u2a75", "EqualTilde;": "\u2242", "Equilibrium;": "\u21cc", "Escr;": "\u2130", "Esim;": "\u2a73", "Eta;": "\u0397", "Euml": "\xcb", "Euml;": "\xcb", "Exists;": "\u2203", "ExponentialE;": "\u2147", "Fcy;": "\u0424", "Ffr;": "\U0001d509", "FilledSmallSquare;": "\u25fc", "FilledVerySmallSquare;": "\u25aa", "Fopf;": "\U0001d53d", "ForAll;": "\u2200", "Fouriertrf;": "\u2131", "Fscr;": "\u2131", "GJcy;": "\u0403", "GT": ">", "GT;": ">", "Gamma;": "\u0393", "Gammad;": "\u03dc", "Gbreve;": "\u011e", "Gcedil;": "\u0122", "Gcirc;": "\u011c", "Gcy;": "\u0413", "Gdot;": "\u0120", "Gfr;": "\U0001d50a", "Gg;": "\u22d9", "Gopf;": "\U0001d53e", "GreaterEqual;": "\u2265", "GreaterEqualLess;": "\u22db", "GreaterFullEqual;": "\u2267", "GreaterGreater;": "\u2aa2", "GreaterLess;": "\u2277", "GreaterSlantEqual;": "\u2a7e", "GreaterTilde;": "\u2273", "Gscr;": "\U0001d4a2", "Gt;": "\u226b", "HARDcy;": "\u042a", "Hacek;": "\u02c7", "Hat;": "^", "Hcirc;": "\u0124", "Hfr;": "\u210c", "HilbertSpace;": "\u210b", "Hopf;": "\u210d", "HorizontalLine;": "\u2500", "Hscr;": "\u210b", "Hstrok;": "\u0126", "HumpDownHump;": "\u224e", "HumpEqual;": "\u224f", "IEcy;": "\u0415", "IJlig;": "\u0132", "IOcy;": "\u0401", "Iacute": "\xcd", "Iacute;": "\xcd", "Icirc": "\xce", "Icirc;": "\xce", "Icy;": "\u0418", "Idot;": "\u0130", "Ifr;": "\u2111", "Igrave": "\xcc", "Igrave;": "\xcc", "Im;": "\u2111", "Imacr;": "\u012a", "ImaginaryI;": "\u2148", "Implies;": "\u21d2", "Int;": "\u222c", "Integral;": "\u222b", "Intersection;": "\u22c2", "InvisibleComma;": "\u2063", "InvisibleTimes;": "\u2062", "Iogon;": "\u012e", "Iopf;": "\U0001d540", "Iota;": "\u0399", "Iscr;": "\u2110", "Itilde;": "\u0128", "Iukcy;": "\u0406", "Iuml": "\xcf", "Iuml;": "\xcf", "Jcirc;": "\u0134", "Jcy;": "\u0419", "Jfr;": "\U0001d50d", "Jopf;": "\U0001d541", "Jscr;": "\U0001d4a5", "Jsercy;": "\u0408", "Jukcy;": "\u0404", "KHcy;": "\u0425", "KJcy;": "\u040c", "Kappa;": "\u039a", "Kcedil;": "\u0136", "Kcy;": "\u041a", "Kfr;": "\U0001d50e", "Kopf;": "\U0001d542", "Kscr;": "\U0001d4a6", "LJcy;": "\u0409", "LT": "<", "LT;": "<", "Lacute;": "\u0139", "Lambda;": "\u039b", "Lang;": "\u27ea", "Laplacetrf;": "\u2112", "Larr;": "\u219e", "Lcaron;": "\u013d", "Lcedil;": "\u013b", "Lcy;": "\u041b", "LeftAngleBracket;": "\u27e8", "LeftArrow;": "\u2190", "LeftArrowBar;": "\u21e4", "LeftArrowRightArrow;": "\u21c6", "LeftCeiling;": "\u2308", "LeftDoubleBracket;": "\u27e6", "LeftDownTeeVector;": "\u2961", "LeftDownVector;": "\u21c3", "LeftDownVectorBar;": "\u2959", "LeftFloor;": "\u230a", "LeftRightArrow;": "\u2194", "LeftRightVector;": "\u294e", "LeftTee;": "\u22a3", "LeftTeeArrow;": "\u21a4", "LeftTeeVector;": "\u295a", "LeftTriangle;": "\u22b2", "LeftTriangleBar;": "\u29cf", "LeftTriangleEqual;": "\u22b4", "LeftUpDownVector;": "\u2951", "LeftUpTeeVector;": "\u2960", "LeftUpVector;": "\u21bf", "LeftUpVectorBar;": "\u2958", "LeftVector;": "\u21bc", "LeftVectorBar;": "\u2952", "Leftarrow;": "\u21d0", "Leftrightarrow;": "\u21d4", "LessEqualGreater;": "\u22da", "LessFullEqual;": "\u2266", "LessGreater;": "\u2276", "LessLess;": "\u2aa1", "LessSlantEqual;": "\u2a7d", "LessTilde;": "\u2272", "Lfr;": "\U0001d50f", "Ll;": "\u22d8", "Lleftarrow;": "\u21da", "Lmidot;": "\u013f", "LongLeftArrow;": "\u27f5", "LongLeftRightArrow;": "\u27f7", "LongRightArrow;": "\u27f6", "Longleftarrow;": "\u27f8", "Longleftrightarrow;": "\u27fa", "Longrightarrow;": "\u27f9", "Lopf;": "\U0001d543", "LowerLeftArrow;": "\u2199", "LowerRightArrow;": "\u2198", "Lscr;": "\u2112", "Lsh;": "\u21b0", "Lstrok;": "\u0141", "Lt;": "\u226a", "Map;": "\u2905", "Mcy;": "\u041c", "MediumSpace;": "\u205f", "Mellintrf;": "\u2133", "Mfr;": "\U0001d510", "MinusPlus;": "\u2213", "Mopf;": "\U0001d544", "Mscr;": "\u2133", "Mu;": "\u039c", "NJcy;": "\u040a", "Nacute;": "\u0143", "Ncaron;": "\u0147", "Ncedil;": "\u0145", "Ncy;": "\u041d", "NegativeMediumSpace;": "\u200b", "NegativeThickSpace;": "\u200b", "NegativeThinSpace;": "\u200b", "NegativeVeryThinSpace;": "\u200b", "NestedGreaterGreater;": "\u226b", "NestedLessLess;": "\u226a", "NewLine;": "\n", "Nfr;": "\U0001d511", "NoBreak;": "\u2060", "NonBreakingSpace;": "\xa0", "Nopf;": "\u2115", "Not;": "\u2aec", "NotCongruent;": "\u2262", "NotCupCap;": "\u226d", "NotDoubleVerticalBar;": "\u2226", "NotElement;": "\u2209", "NotEqual;": "\u2260", "NotEqualTilde;": "\u2242\u0338", "NotExists;": "\u2204", "NotGreater;": "\u226f", "NotGreaterEqual;": "\u2271", "NotGreaterFullEqual;": "\u2267\u0338", "NotGreaterGreater;": "\u226b\u0338", "NotGreaterLess;": "\u2279", "NotGreaterSlantEqual;": "\u2a7e\u0338", "NotGreaterTilde;": "\u2275", "NotHumpDownHump;": "\u224e\u0338", "NotHumpEqual;": "\u224f\u0338", "NotLeftTriangle;": "\u22ea", "NotLeftTriangleBar;": "\u29cf\u0338", "NotLeftTriangleEqual;": "\u22ec", "NotLess;": "\u226e", "NotLessEqual;": "\u2270", "NotLessGreater;": "\u2278", "NotLessLess;": "\u226a\u0338", "NotLessSlantEqual;": "\u2a7d\u0338", "NotLessTilde;": "\u2274", "NotNestedGreaterGreater;": "\u2aa2\u0338", "NotNestedLessLess;": "\u2aa1\u0338", "NotPrecedes;": "\u2280", "NotPrecedesEqual;": "\u2aaf\u0338", "NotPrecedesSlantEqual;": "\u22e0", "NotReverseElement;": "\u220c", "NotRightTriangle;": "\u22eb", "NotRightTriangleBar;": "\u29d0\u0338", "NotRightTriangleEqual;": "\u22ed", "NotSquareSubset;": "\u228f\u0338", "NotSquareSubsetEqual;": "\u22e2", "NotSquareSuperset;": "\u2290\u0338", "NotSquareSupersetEqual;": "\u22e3", "NotSubset;": "\u2282\u20d2", "NotSubsetEqual;": "\u2288", "NotSucceeds;": "\u2281", "NotSucceedsEqual;": "\u2ab0\u0338", "NotSucceedsSlantEqual;": "\u22e1", "NotSucceedsTilde;": "\u227f\u0338", "NotSuperset;": "\u2283\u20d2", "NotSupersetEqual;": "\u2289", "NotTilde;": "\u2241", "NotTildeEqual;": "\u2244", "NotTildeFullEqual;": "\u2247", "NotTildeTilde;": "\u2249", "NotVerticalBar;": "\u2224", "Nscr;": "\U0001d4a9", "Ntilde": "\xd1", "Ntilde;": "\xd1", "Nu;": "\u039d", "OElig;": "\u0152", "Oacute": "\xd3", "Oacute;": "\xd3", "Ocirc": "\xd4", "Ocirc;": "\xd4", "Ocy;": "\u041e", "Odblac;": "\u0150", "Ofr;": "\U0001d512", "Ograve": "\xd2", "Ograve;": "\xd2", "Omacr;": "\u014c", "Omega;": "\u03a9", "Omicron;": "\u039f", "Oopf;": "\U0001d546", "OpenCurlyDoubleQuote;": "\u201c", "OpenCurlyQuote;": "\u2018", "Or;": "\u2a54", "Oscr;": "\U0001d4aa", "Oslash": "\xd8", "Oslash;": "\xd8", "Otilde": "\xd5", "Otilde;": "\xd5", "Otimes;": "\u2a37", "Ouml": "\xd6", "Ouml;": "\xd6", "OverBar;": "\u203e", "OverBrace;": "\u23de", "OverBracket;": "\u23b4", "OverParenthesis;": "\u23dc", "PartialD;": "\u2202", "Pcy;": "\u041f", "Pfr;": "\U0001d513", "Phi;": "\u03a6", "Pi;": "\u03a0", "PlusMinus;": "\xb1", "Poincareplane;": "\u210c", "Popf;": "\u2119", "Pr;": "\u2abb", "Precedes;": "\u227a", "PrecedesEqual;": "\u2aaf", "PrecedesSlantEqual;": "\u227c", "PrecedesTilde;": "\u227e", "Prime;": "\u2033", "Product;": "\u220f", "Proportion;": "\u2237", "Proportional;": "\u221d", "Pscr;": "\U0001d4ab", "Psi;": "\u03a8", "QUOT": "\"", "QUOT;": "\"", "Qfr;": "\U0001d514", "Qopf;": "\u211a", "Qscr;": "\U0001d4ac", "RBarr;": "\u2910", "REG": "\xae", "REG;": "\xae", "Racute;": "\u0154", "Rang;": "\u27eb", "Rarr;": "\u21a0", "Rarrtl;": "\u2916", "Rcaron;": "\u0158", "Rcedil;": "\u0156", "Rcy;": "\u0420", "Re;": "\u211c", "ReverseElement;": "\u220b", "ReverseEquilibrium;": "\u21cb", "ReverseUpEquilibrium;": "\u296f", "Rfr;": "\u211c", "Rho;": "\u03a1", "RightAngleBracket;": "\u27e9", "RightArrow;": "\u2192", "RightArrowBar;": "\u21e5", "RightArrowLeftArrow;": "\u21c4", "RightCeiling;": "\u2309", "RightDoubleBracket;": "\u27e7", "RightDownTeeVector;": "\u295d", "RightDownVector;": "\u21c2", "RightDownVectorBar;": "\u2955", "RightFloor;": "\u230b", "RightTee;": "\u22a2", "RightTeeArrow;": "\u21a6", "RightTeeVector;": "\u295b", "RightTriangle;": "\u22b3", "RightTriangleBar;": "\u29d0", "RightTriangleEqual;": "\u22b5", "RightUpDownVector;": "\u294f", "RightUpTeeVector;": "\u295c", "RightUpVector;": "\u21be", "RightUpVectorBar;": "\u2954", "RightVector;": "\u21c0", "RightVectorBar;": "\u2953", "Rightarrow;": "\u21d2", "Ropf;": "\u211d", "RoundImplies;": "\u2970", "Rrightarrow;": "\u21db", "Rscr;": "\u211b", "Rsh;": "\u21b1", "RuleDelayed;": "\u29f4", "SHCHcy;": "\u0429", "SHcy;": "\u0428", "SOFTcy;": "\u042c", "Sacute;": "\u015a", "Sc;": "\u2abc", "Scaron;": "\u0160", "Scedil;": "\u015e", "Scirc;": "\u015c", "Scy;": "\u0421", "Sfr;": "\U0001d516", "ShortDownArrow;": "\u2193", "ShortLeftArrow;": "\u2190", "ShortRightArrow;": "\u2192", "ShortUpArrow;": "\u2191", "Sigma;": "\u03a3", "SmallCircle;": "\u2218", "Sopf;": "\U0001d54a", "Sqrt;": "\u221a", "Square;": "\u25a1", "SquareIntersection;": "\u2293", "SquareSubset;": "\u228f", "SquareSubsetEqual;": "\u2291", "SquareSuperset;": "\u2290", "SquareSupersetEqual;": "\u2292", "SquareUnion;": "\u2294", "Sscr;": "\U0001d4ae", "Star;": "\u22c6", "Sub;": "\u22d0", "Subset;": "\u22d0", "SubsetEqual;": "\u2286", "Succeeds;": "\u227b", "SucceedsEqual;": "\u2ab0", "SucceedsSlantEqual;": "\u227d", "SucceedsTilde;": "\u227f", "SuchThat;": "\u220b", "Sum;": "\u2211", "Sup;": "\u22d1", "Superset;": "\u2283", "SupersetEqual;": "\u2287", "Supset;": "\u22d1", "THORN": "\xde", "THORN;": "\xde", "TRADE;": "\u2122", "TSHcy;": "\u040b", "TScy;": "\u0426", "Tab;": "\t", "Tau;": "\u03a4", "Tcaron;": "\u0164", "Tcedil;": "\u0162", "Tcy;": "\u0422", "Tfr;": "\U0001d517", "Therefore;": "\u2234", "Theta;": "\u0398", "ThickSpace;": "\u205f\u200a", "ThinSpace;": "\u2009", "Tilde;": "\u223c", "TildeEqual;": "\u2243", "TildeFullEqual;": "\u2245", "TildeTilde;": "\u2248", "Topf;": "\U0001d54b", "TripleDot;": "\u20db", "Tscr;": "\U0001d4af", "Tstrok;": "\u0166", "Uacute": "\xda", "Uacute;": "\xda", "Uarr;": "\u219f", "Uarrocir;": "\u2949", "Ubrcy;": "\u040e", "Ubreve;": "\u016c", "Ucirc": "\xdb", "Ucirc;": "\xdb", "Ucy;": "\u0423", "Udblac;": "\u0170", "Ufr;": "\U0001d518", "Ugrave": "\xd9", "Ugrave;": "\xd9", "Umacr;": "\u016a", "UnderBar;": "_", "UnderBrace;": "\u23df", "UnderBracket;": "\u23b5", "UnderParenthesis;": "\u23dd", "Union;": "\u22c3", "UnionPlus;": "\u228e", "Uogon;": "\u0172", "Uopf;": "\U0001d54c", "UpArrow;": "\u2191", "UpArrowBar;": "\u2912", "UpArrowDownArrow;": "\u21c5", "UpDownArrow;": "\u2195", "UpEquilibrium;": "\u296e", "UpTee;": "\u22a5", "UpTeeArrow;": "\u21a5", "Uparrow;": "\u21d1", "Updownarrow;": "\u21d5", "UpperLeftArrow;": "\u2196", "UpperRightArrow;": "\u2197", "Upsi;": "\u03d2", "Upsilon;": "\u03a5", "Uring;": "\u016e", "Uscr;": "\U0001d4b0", "Utilde;": "\u0168", "Uuml": "\xdc", "Uuml;": "\xdc", "VDash;": "\u22ab", "Vbar;": "\u2aeb", "Vcy;": "\u0412", "Vdash;": "\u22a9", "Vdashl;": "\u2ae6", "Vee;": "\u22c1", "Verbar;": "\u2016", "Vert;": "\u2016", "VerticalBar;": "\u2223", "VerticalLine;": "|", "VerticalSeparator;": "\u2758", "VerticalTilde;": "\u2240", "VeryThinSpace;": "\u200a", "Vfr;": "\U0001d519", "Vopf;": "\U0001d54d", "Vscr;": "\U0001d4b1", "Vvdash;": "\u22aa", "Wcirc;": "\u0174", "Wedge;": "\u22c0", "Wfr;": "\U0001d51a", "Wopf;": "\U0001d54e", "Wscr;": "\U0001d4b2", "Xfr;": "\U0001d51b", "Xi;": "\u039e", "Xopf;": "\U0001d54f", "Xscr;": "\U0001d4b3", "YAcy;": "\u042f", "YIcy;": "\u0407", "YUcy;": "\u042e", "Yacute": "\xdd", "Yacute;": "\xdd", "Ycirc;": "\u0176", "Ycy;": "\u042b", "Yfr;": "\U0001d51c", "Yopf;": "\U0001d550", "Yscr;": "\U0001d4b4", "Yuml;": "\u0178", "ZHcy;": "\u0416", "Zacute;": "\u0179", "Zcaron;": "\u017d", "Zcy;": "\u0417", "Zdot;": "\u017b", "ZeroWidthSpace;": "\u200b", "Zeta;": "\u0396", "Zfr;": "\u2128", "Zopf;": "\u2124", "Zscr;": "\U0001d4b5", "aacute": "\xe1", "aacute;": "\xe1", "abreve;": "\u0103", "ac;": "\u223e", "acE;": "\u223e\u0333", "acd;": "\u223f", "acirc": "\xe2", "acirc;": "\xe2", "acute": "\xb4", "acute;": "\xb4", "acy;": "\u0430", "aelig": "\xe6", "aelig;": "\xe6", "af;": "\u2061", "afr;": "\U0001d51e", "agrave": "\xe0", "agrave;": "\xe0", "alefsym;": "\u2135", "aleph;": "\u2135", "alpha;": "\u03b1", "amacr;": "\u0101", "amalg;": "\u2a3f", "amp": "&", "amp;": "&", "and;": "\u2227", "andand;": "\u2a55", "andd;": "\u2a5c", "andslope;": "\u2a58", "andv;": "\u2a5a", "ang;": "\u2220", "ange;": "\u29a4", "angle;": "\u2220", "angmsd;": "\u2221", "angmsdaa;": "\u29a8", "angmsdab;": "\u29a9", "angmsdac;": "\u29aa", "angmsdad;": "\u29ab", "angmsdae;": "\u29ac", "angmsdaf;": "\u29ad", "angmsdag;": "\u29ae", "angmsdah;": "\u29af", "angrt;": "\u221f", "angrtvb;": "\u22be", "angrtvbd;": "\u299d", "angsph;": "\u2222", "angst;": "\xc5", "angzarr;": "\u237c", "aogon;": "\u0105", "aopf;": "\U0001d552", "ap;": "\u2248", "apE;": "\u2a70", "apacir;": "\u2a6f", "ape;": "\u224a", "apid;": "\u224b", "apos;": "'", "approx;": "\u2248", "approxeq;": "\u224a", "aring": "\xe5", "aring;": "\xe5", "ascr;": "\U0001d4b6", "ast;": "*", "asymp;": "\u2248", "asympeq;": "\u224d", "atilde": "\xe3", "atilde;": "\xe3", "auml": "\xe4", "auml;": "\xe4", "awconint;": "\u2233", "awint;": "\u2a11", "bNot;": "\u2aed", "backcong;": "\u224c", "backepsilon;": "\u03f6", "backprime;": "\u2035", "backsim;": "\u223d", "backsimeq;": "\u22cd", "barvee;": "\u22bd", "barwed;": "\u2305", "barwedge;": "\u2305", "bbrk;": "\u23b5", "bbrktbrk;": "\u23b6", "bcong;": "\u224c", "bcy;": "\u0431", "bdquo;": "\u201e", "becaus;": "\u2235", "because;": "\u2235", "bemptyv;": "\u29b0", "bepsi;": "\u03f6", "bernou;": "\u212c", "beta;": "\u03b2", "beth;": "\u2136", "between;": "\u226c", "bfr;": "\U0001d51f", "bigcap;": "\u22c2", "bigcirc;": "\u25ef", "bigcup;": "\u22c3", "bigodot;": "\u2a00", "bigoplus;": "\u2a01", "bigotimes;": "\u2a02", "bigsqcup;": "\u2a06", "bigstar;": "\u2605", "bigtriangledown;": "\u25bd", "bigtriangleup;": "\u25b3", "biguplus;": "\u2a04", "bigvee;": "\u22c1", "bigwedge;": "\u22c0", "bkarow;": "\u290d", "blacklozenge;": "\u29eb", "blacksquare;": "\u25aa", "blacktriangle;": "\u25b4", "blacktriangledown;": "\u25be", "blacktriangleleft;": "\u25c2", "blacktriangleright;": "\u25b8", "blank;": "\u2423", "blk12;": "\u2592", "blk14;": "\u2591", "blk34;": "\u2593", "block;": "\u2588", "bne;": "=\u20e5", "bnequiv;": "\u2261\u20e5", "bnot;": "\u2310", "bopf;": "\U0001d553", "bot;": "\u22a5", "bottom;": "\u22a5", "bowtie;": "\u22c8", "boxDL;": "\u2557", "boxDR;": "\u2554", "boxDl;": "\u2556", "boxDr;": "\u2553", "boxH;": "\u2550", "boxHD;": "\u2566", "boxHU;": "\u2569", "boxHd;": "\u2564", "boxHu;": "\u2567", "boxUL;": "\u255d", "boxUR;": "\u255a", "boxUl;": "\u255c", "boxUr;": "\u2559", "boxV;": "\u2551", "boxVH;": "\u256c", "boxVL;": "\u2563", "boxVR;": "\u2560", "boxVh;": "\u256b", "boxVl;": "\u2562", "boxVr;": "\u255f", "boxbox;": "\u29c9", "boxdL;": "\u2555", "boxdR;": "\u2552", "boxdl;": "\u2510", "boxdr;": "\u250c", "boxh;": "\u2500", "boxhD;": "\u2565", "boxhU;": "\u2568", "boxhd;": "\u252c", "boxhu;": "\u2534", "boxminus;": "\u229f", "boxplus;": "\u229e", "boxtimes;": "\u22a0", "boxuL;": "\u255b", "boxuR;": "\u2558", "boxul;": "\u2518", "boxur;": "\u2514", "boxv;": "\u2502", "boxvH;": "\u256a", "boxvL;": "\u2561", "boxvR;": "\u255e", "boxvh;": "\u253c", "boxvl;": "\u2524", "boxvr;": "\u251c", "bprime;": "\u2035", "breve;": "\u02d8", "brvbar": "\xa6", "brvbar;": "\xa6", "bscr;": "\U0001d4b7", "bsemi;": "\u204f", "bsim;": "\u223d", "bsime;": "\u22cd", "bsol;": "\\", "bsolb;": "\u29c5", "bsolhsub;": "\u27c8", "bull;": "\u2022", "bullet;": "\u2022", "bump;": "\u224e", "bumpE;": "\u2aae", "bumpe;": "\u224f", "bumpeq;": "\u224f", "cacute;": "\u0107", "cap;": "\u2229", "capand;": "\u2a44", "capbrcup;": "\u2a49", "capcap;": "\u2a4b", "capcup;": "\u2a47", "capdot;": "\u2a40", "caps;": "\u2229\ufe00", "caret;": "\u2041", "caron;": "\u02c7", "ccaps;": "\u2a4d", "ccaron;": "\u010d", "ccedil": "\xe7", "ccedil;": "\xe7", "ccirc;": "\u0109", "ccups;": "\u2a4c", "ccupssm;": "\u2a50", "cdot;": "\u010b", "cedil": "\xb8", "cedil;": "\xb8", "cemptyv;": "\u29b2", "cent": "\xa2", "cent;": "\xa2", "centerdot;": "\xb7", "cfr;": "\U0001d520", "chcy;": "\u0447", "check;": "\u2713", "checkmark;": "\u2713", "chi;": "\u03c7", "cir;": "\u25cb", "cirE;": "\u29c3", "circ;": "\u02c6", "circeq;": "\u2257", "circlearrowleft;": "\u21ba", "circlearrowright;": "\u21bb", "circledR;": "\xae", "circledS;": "\u24c8", "circledast;": "\u229b", "circledcirc;": "\u229a", "circleddash;": "\u229d", "cire;": "\u2257", "cirfnint;": "\u2a10", "cirmid;": "\u2aef", "cirscir;": "\u29c2", "clubs;": "\u2663", "clubsuit;": "\u2663", "colon;": ":", "colone;": "\u2254", "coloneq;": "\u2254", "comma;": ",", "commat;": "@", "comp;": "\u2201", "compfn;": "\u2218", "complement;": "\u2201", "complexes;": "\u2102", "cong;": "\u2245", "congdot;": "\u2a6d", "conint;": "\u222e", "copf;": "\U0001d554", "coprod;": "\u2210", "copy": "\xa9", "copy;": "\xa9", "copysr;": "\u2117", "crarr;": "\u21b5", "cross;": "\u2717", "cscr;": "\U0001d4b8", "csub;": "\u2acf", "csube;": "\u2ad1", "csup;": "\u2ad0", "csupe;": "\u2ad2", "ctdot;": "\u22ef", "cudarrl;": "\u2938", "cudarrr;": "\u2935", "cuepr;": "\u22de", "cuesc;": "\u22df", "cularr;": "\u21b6", "cularrp;": "\u293d", "cup;": "\u222a", "cupbrcap;": "\u2a48", "cupcap;": "\u2a46", "cupcup;": "\u2a4a", "cupdot;": "\u228d", "cupor;": "\u2a45", "cups;": "\u222a\ufe00", "curarr;": "\u21b7", "curarrm;": "\u293c", "curlyeqprec;": "\u22de", "curlyeqsucc;": "\u22df", "curlyvee;": "\u22ce", "curlywedge;": "\u22cf", "curren": "\xa4", "curren;": "\xa4", "curvearrowleft;": "\u21b6", "curvearrowright;": "\u21b7", "cuvee;": "\u22ce", "cuwed;": "\u22cf", "cwconint;": "\u2232", "cwint;": "\u2231", "cylcty;": "\u232d", "dArr;": "\u21d3", "dHar;": "\u2965", "dagger;": "\u2020", "daleth;": "\u2138", "darr;": "\u2193", "dash;": "\u2010", "dashv;": "\u22a3", "dbkarow;": "\u290f", "dblac;": "\u02dd", "dcaron;": "\u010f", "dcy;": "\u0434", "dd;": "\u2146", "ddagger;": "\u2021", "ddarr;": "\u21ca", "ddotseq;": "\u2a77", "deg": "\xb0", "deg;": "\xb0", "delta;": "\u03b4", "demptyv;": "\u29b1", "dfisht;": "\u297f", "dfr;": "\U0001d521", "dharl;": "\u21c3", "dharr;": "\u21c2", "diam;": "\u22c4", "diamond;": "\u22c4", "diamondsuit;": "\u2666", "diams;": "\u2666", "die;": "\xa8", "digamma;": "\u03dd", "disin;": "\u22f2", "div;": "\xf7", "divide": "\xf7", "divide;": "\xf7", "divideontimes;": "\u22c7", "divonx;": "\u22c7", "djcy;": "\u0452", "dlcorn;": "\u231e", "dlcrop;": "\u230d", "dollar;": "$", "dopf;": "\U0001d555", "dot;": "\u02d9", "doteq;": "\u2250", "doteqdot;": "\u2251", "dotminus;": "\u2238", "dotplus;": "\u2214", "dotsquare;": "\u22a1", "doublebarwedge;": "\u2306", "downarrow;": "\u2193", "downdownarrows;": "\u21ca", "downharpoonleft;": "\u21c3", "downharpoonright;": "\u21c2", "drbkarow;": "\u2910", "drcorn;": "\u231f", "drcrop;": "\u230c", "dscr;": "\U0001d4b9", "dscy;": "\u0455", "dsol;": "\u29f6", "dstrok;": "\u0111", "dtdot;": "\u22f1", "dtri;": "\u25bf", "dtrif;": "\u25be", "duarr;": "\u21f5", "duhar;": "\u296f", "dwangle;": "\u29a6", "dzcy;": "\u045f", "dzigrarr;": "\u27ff", "eDDot;": "\u2a77", "eDot;": "\u2251", "eacute": "\xe9", "eacute;": "\xe9", "easter;": "\u2a6e", "ecaron;": "\u011b", "ecir;": "\u2256", "ecirc": "\xea", "ecirc;": "\xea", "ecolon;": "\u2255", "ecy;": "\u044d", "edot;": "\u0117", "ee;": "\u2147", "efDot;": "\u2252", "efr;": "\U0001d522", "eg;": "\u2a9a", "egrave": "\xe8", "egrave;": "\xe8", "egs;": "\u2a96", "egsdot;": "\u2a98", "el;": "\u2a99", "elinters;": "\u23e7", "ell;": "\u2113", "els;": "\u2a95", "elsdot;": "\u2a97", "emacr;": "\u0113", "empty;": "\u2205", "emptyset;": "\u2205", "emptyv;": "\u2205", "emsp13;": "\u2004", "emsp14;": "\u2005", "emsp;": "\u2003", "eng;": "\u014b", "ensp;": "\u2002", "eogon;": "\u0119", "eopf;": "\U0001d556", "epar;": "\u22d5", "eparsl;": "\u29e3", "eplus;": "\u2a71", "epsi;": "\u03b5", "epsilon;": "\u03b5", "epsiv;": "\u03f5", "eqcirc;": "\u2256", "eqcolon;": "\u2255", "eqsim;": "\u2242", "eqslantgtr;": "\u2a96", "eqslantless;": "\u2a95", "equals;": "=", "equest;": "\u225f", "equiv;": "\u2261", "equivDD;": "\u2a78", "eqvparsl;": "\u29e5", "erDot;": "\u2253", "erarr;": "\u2971", "escr;": "\u212f", "esdot;": "\u2250", "esim;": "\u2242", "eta;": "\u03b7", "eth": "\xf0", "eth;": "\xf0", "euml": "\xeb", "euml;": "\xeb", "euro;": "\u20ac", "excl;": "!", "exist;": "\u2203", "expectation;": "\u2130", "exponentiale;": "\u2147", "fallingdotseq;": "\u2252", "fcy;": "\u0444", "female;": "\u2640", "ffilig;": "\ufb03", "fflig;": "\ufb00", "ffllig;": "\ufb04", "ffr;": "\U0001d523", "filig;": "\ufb01", "fjlig;": "fj", "flat;": "\u266d", "fllig;": "\ufb02", "fltns;": "\u25b1", "fnof;": "\u0192", "fopf;": "\U0001d557", "forall;": "\u2200", "fork;": "\u22d4", "forkv;": "\u2ad9", "fpartint;": "\u2a0d", "frac12": "\xbd", "frac12;": "\xbd", "frac13;": "\u2153", "frac14": "\xbc", "frac14;": "\xbc", "frac15;": "\u2155", "frac16;": "\u2159", "frac18;": "\u215b", "frac23;": "\u2154", "frac25;": "\u2156", "frac34": "\xbe", "frac34;": "\xbe", "frac35;": "\u2157", "frac38;": "\u215c", "frac45;": "\u2158", "frac56;": "\u215a", "frac58;": "\u215d", "frac78;": "\u215e", "frasl;": "\u2044", "frown;": "\u2322", "fscr;": "\U0001d4bb", "gE;": "\u2267", "gEl;": "\u2a8c", "gacute;": "\u01f5", "gamma;": "\u03b3", "gammad;": "\u03dd", "gap;": "\u2a86", "gbreve;": "\u011f", "gcirc;": "\u011d", "gcy;": "\u0433", "gdot;": "\u0121", "ge;": "\u2265", "gel;": "\u22db", "geq;": "\u2265", "geqq;": "\u2267", "geqslant;": "\u2a7e", "ges;": "\u2a7e", "gescc;": "\u2aa9", "gesdot;": "\u2a80", "gesdoto;": "\u2a82", "gesdotol;": "\u2a84", "gesl;": "\u22db\ufe00", "gesles;": "\u2a94", "gfr;": "\U0001d524", "gg;": "\u226b", "ggg;": "\u22d9", "gimel;": "\u2137", "gjcy;": "\u0453", "gl;": "\u2277", "glE;": "\u2a92", "gla;": "\u2aa5", "glj;": "\u2aa4", "gnE;": "\u2269", "gnap;": "\u2a8a", "gnapprox;": "\u2a8a", "gne;": "\u2a88", "gneq;": "\u2a88", "gneqq;": "\u2269", "gnsim;": "\u22e7", "gopf;": "\U0001d558", "grave;": "`", "gscr;": "\u210a", "gsim;": "\u2273", "gsime;": "\u2a8e", "gsiml;": "\u2a90", "gt": ">", "gt;": ">", "gtcc;": "\u2aa7", "gtcir;": "\u2a7a", "gtdot;": "\u22d7", "gtlPar;": "\u2995", "gtquest;": "\u2a7c", "gtrapprox;": "\u2a86", "gtrarr;": "\u2978", "gtrdot;": "\u22d7", "gtreqless;": "\u22db", "gtreqqless;": "\u2a8c", "gtrless;": "\u2277", "gtrsim;": "\u2273", "gvertneqq;": "\u2269\ufe00", "gvnE;": "\u2269\ufe00", "hArr;": "\u21d4", "hairsp;": "\u200a", "half;": "\xbd", "hamilt;": "\u210b", "hardcy;": "\u044a", "harr;": "\u2194", "harrcir;": "\u2948", "harrw;": "\u21ad", "hbar;": "\u210f", "hcirc;": "\u0125", "hearts;": "\u2665", "heartsuit;": "\u2665", "hellip;": "\u2026", "hercon;": "\u22b9", "hfr;": "\U0001d525", "hksearow;": "\u2925", "hkswarow;": "\u2926", "hoarr;": "\u21ff", "homtht;": "\u223b", "hookleftarrow;": "\u21a9", "hookrightarrow;": "\u21aa", "hopf;": "\U0001d559", "horbar;": "\u2015", "hscr;": "\U0001d4bd", "hslash;": "\u210f", "hstrok;": "\u0127", "hybull;": "\u2043", "hyphen;": "\u2010", "iacute": "\xed", "iacute;": "\xed", "ic;": "\u2063", "icirc": "\xee", "icirc;": "\xee", "icy;": "\u0438", "iecy;": "\u0435", "iexcl": "\xa1", "iexcl;": "\xa1", "iff;": "\u21d4", "ifr;": "\U0001d526", "igrave": "\xec", "igrave;": "\xec", "ii;": "\u2148", "iiiint;": "\u2a0c", "iiint;": "\u222d", "iinfin;": "\u29dc", "iiota;": "\u2129", "ijlig;": "\u0133", "imacr;": "\u012b", "image;": "\u2111", "imagline;": "\u2110", "imagpart;": "\u2111", "imath;": "\u0131", "imof;": "\u22b7", "imped;": "\u01b5", "in;": "\u2208", "incare;": "\u2105", "infin;": "\u221e", "infintie;": "\u29dd", "inodot;": "\u0131", "int;": "\u222b", "intcal;": "\u22ba", "integers;": "\u2124", "intercal;": "\u22ba", "intlarhk;": "\u2a17", "intprod;": "\u2a3c", "iocy;": "\u0451", "iogon;": "\u012f", "iopf;": "\U0001d55a", "iota;": "\u03b9", "iprod;": "\u2a3c", "iquest": "\xbf", "iquest;": "\xbf", "iscr;": "\U0001d4be", "isin;": "\u2208", "isinE;": "\u22f9", "isindot;": "\u22f5", "isins;": "\u22f4", "isinsv;": "\u22f3", "isinv;": "\u2208", "it;": "\u2062", "itilde;": "\u0129", "iukcy;": "\u0456", "iuml": "\xef", "iuml;": "\xef", "jcirc;": "\u0135", "jcy;": "\u0439", "jfr;": "\U0001d527", "jmath;": "\u0237", "jopf;": "\U0001d55b", "jscr;": "\U0001d4bf", "jsercy;": "\u0458", "jukcy;": "\u0454", "kappa;": "\u03ba", "kappav;": "\u03f0", "kcedil;": "\u0137", "kcy;": "\u043a", "kfr;": "\U0001d528", "kgreen;": "\u0138", "khcy;": "\u0445", "kjcy;": "\u045c", "kopf;": "\U0001d55c", "kscr;": "\U0001d4c0", "lAarr;": "\u21da", "lArr;": "\u21d0", "lAtail;": "\u291b", "lBarr;": "\u290e", "lE;": "\u2266", "lEg;": "\u2a8b", "lHar;": "\u2962", "lacute;": "\u013a", "laemptyv;": "\u29b4", "lagran;": "\u2112", "lambda;": "\u03bb", "lang;": "\u27e8", "langd;": "\u2991", "langle;": "\u27e8", "lap;": "\u2a85", "laquo": "\xab", "laquo;": "\xab", "larr;": "\u2190", "larrb;": "\u21e4", "larrbfs;": "\u291f", "larrfs;": "\u291d", "larrhk;": "\u21a9", "larrlp;": "\u21ab", "larrpl;": "\u2939", "larrsim;": "\u2973", "larrtl;": "\u21a2", "lat;": "\u2aab", "latail;": "\u2919", "late;": "\u2aad", "lates;": "\u2aad\ufe00", "lbarr;": "\u290c", "lbbrk;": "\u2772", "lbrace;": "{", "lbrack;": "[", "lbrke;": "\u298b", "lbrksld;": "\u298f", "lbrkslu;": "\u298d", "lcaron;": "\u013e", "lcedil;": "\u013c", "lceil;": "\u2308", "lcub;": "{", "lcy;": "\u043b", "ldca;": "\u2936", "ldquo;": "\u201c", "ldquor;": "\u201e", "ldrdhar;": "\u2967", "ldrushar;": "\u294b", "ldsh;": "\u21b2", "le;": "\u2264", "leftarrow;": "\u2190", "leftarrowtail;": "\u21a2", "leftharpoondown;": "\u21bd", "leftharpoonup;": "\u21bc", "leftleftarrows;": "\u21c7", "leftrightarrow;": "\u2194", "leftrightarrows;": "\u21c6", "leftrightharpoons;": "\u21cb", "leftrightsquigarrow;": "\u21ad", "leftthreetimes;": "\u22cb", "leg;": "\u22da", "leq;": "\u2264", "leqq;": "\u2266", "leqslant;": "\u2a7d", "les;": "\u2a7d", "lescc;": "\u2aa8", "lesdot;": "\u2a7f", "lesdoto;": "\u2a81", "lesdotor;": "\u2a83", "lesg;": "\u22da\ufe00", "lesges;": "\u2a93", "lessapprox;": "\u2a85", "lessdot;": "\u22d6", "lesseqgtr;": "\u22da", "lesseqqgtr;": "\u2a8b", "lessgtr;": "\u2276", "lesssim;": "\u2272", "lfisht;": "\u297c", "lfloor;": "\u230a", "lfr;": "\U0001d529", "lg;": "\u2276", "lgE;": "\u2a91", "lhard;": "\u21bd", "lharu;": "\u21bc", "lharul;": "\u296a", "lhblk;": "\u2584", "ljcy;": "\u0459", "ll;": "\u226a", "llarr;": "\u21c7", "llcorner;": "\u231e", "llhard;": "\u296b", "lltri;": "\u25fa", "lmidot;": "\u0140", "lmoust;": "\u23b0", "lmoustache;": "\u23b0", "lnE;": "\u2268", "lnap;": "\u2a89", "lnapprox;": "\u2a89", "lne;": "\u2a87", "lneq;": "\u2a87", "lneqq;": "\u2268", "lnsim;": "\u22e6", "loang;": "\u27ec", "loarr;": "\u21fd", "lobrk;": "\u27e6", "longleftarrow;": "\u27f5", "longleftrightarrow;": "\u27f7", "longmapsto;": "\u27fc", "longrightarrow;": "\u27f6", "looparrowleft;": "\u21ab", "looparrowright;": "\u21ac", "lopar;": "\u2985", "lopf;": "\U0001d55d", "loplus;": "\u2a2d", "lotimes;": "\u2a34", "lowast;": "\u2217", "lowbar;": "_", "loz;": "\u25ca", "lozenge;": "\u25ca", "lozf;": "\u29eb", "lpar;": "(", "lparlt;": "\u2993", "lrarr;": "\u21c6", "lrcorner;": "\u231f", "lrhar;": "\u21cb", "lrhard;": "\u296d", "lrm;": "\u200e", "lrtri;": "\u22bf", "lsaquo;": "\u2039", "lscr;": "\U0001d4c1", "lsh;": "\u21b0", "lsim;": "\u2272", "lsime;": "\u2a8d", "lsimg;": "\u2a8f", "lsqb;": "[", "lsquo;": "\u2018", "lsquor;": "\u201a", "lstrok;": "\u0142", "lt": "<", "lt;": "<", "ltcc;": "\u2aa6", "ltcir;": "\u2a79", "ltdot;": "\u22d6", "lthree;": "\u22cb", "ltimes;": "\u22c9", "ltlarr;": "\u2976", "ltquest;": "\u2a7b", "ltrPar;": "\u2996", "ltri;": "\u25c3", "ltrie;": "\u22b4", "ltrif;": "\u25c2", "lurdshar;": "\u294a", "luruhar;": "\u2966", "lvertneqq;": "\u2268\ufe00", "lvnE;": "\u2268\ufe00", "mDDot;": "\u223a", "macr": "\xaf", "macr;": "\xaf", "male;": "\u2642", "malt;": "\u2720", "maltese;": "\u2720", "map;": "\u21a6", "mapsto;": "\u21a6", "mapstodown;": "\u21a7", "mapstoleft;": "\u21a4", "mapstoup;": "\u21a5", "marker;": "\u25ae", "mcomma;": "\u2a29", "mcy;": "\u043c", "mdash;": "\u2014", "measuredangle;": "\u2221", "mfr;": "\U0001d52a", "mho;": "\u2127", "micro": "\xb5", "micro;": "\xb5", "mid;": "\u2223", "midast;": "*", "midcir;": "\u2af0", "middot": "\xb7", "middot;": "\xb7", "minus;": "\u2212", "minusb;": "\u229f", "minusd;": "\u2238", "minusdu;": "\u2a2a", "mlcp;": "\u2adb", "mldr;": "\u2026", "mnplus;": "\u2213", "models;": "\u22a7", "mopf;": "\U0001d55e", "mp;": "\u2213", "mscr;": "\U0001d4c2", "mstpos;": "\u223e", "mu;": "\u03bc", "multimap;": "\u22b8", "mumap;": "\u22b8", "nGg;": "\u22d9\u0338", "nGt;": "\u226b\u20d2", "nGtv;": "\u226b\u0338", "nLeftarrow;": "\u21cd", "nLeftrightarrow;": "\u21ce", "nLl;": "\u22d8\u0338", "nLt;": "\u226a\u20d2", "nLtv;": "\u226a\u0338", "nRightarrow;": "\u21cf", "nVDash;": "\u22af", "nVdash;": "\u22ae", "nabla;": "\u2207", "nacute;": "\u0144", "nang;": "\u2220\u20d2", "nap;": "\u2249", "napE;": "\u2a70\u0338", "napid;": "\u224b\u0338", "napos;": "\u0149", "napprox;": "\u2249", "natur;": "\u266e", "natural;": "\u266e", "naturals;": "\u2115", "nbsp": "\xa0", "nbsp;": "\xa0", "nbump;": "\u224e\u0338", "nbumpe;": "\u224f\u0338", "ncap;": "\u2a43", "ncaron;": "\u0148", "ncedil;": "\u0146", "ncong;": "\u2247", "ncongdot;": "\u2a6d\u0338", "ncup;": "\u2a42", "ncy;": "\u043d", "ndash;": "\u2013", "ne;": "\u2260", "neArr;": "\u21d7", "nearhk;": "\u2924", "nearr;": "\u2197", "nearrow;": "\u2197", "nedot;": "\u2250\u0338", "nequiv;": "\u2262", "nesear;": "\u2928", "nesim;": "\u2242\u0338", "nexist;": "\u2204", "nexists;": "\u2204", "nfr;": "\U0001d52b", "ngE;": "\u2267\u0338", "nge;": "\u2271", "ngeq;": "\u2271", "ngeqq;": "\u2267\u0338", "ngeqslant;": "\u2a7e\u0338", "nges;": "\u2a7e\u0338", "ngsim;": "\u2275", "ngt;": "\u226f", "ngtr;": "\u226f", "nhArr;": "\u21ce", "nharr;": "\u21ae", "nhpar;": "\u2af2", "ni;": "\u220b", "nis;": "\u22fc", "nisd;": "\u22fa", "niv;": "\u220b", "njcy;": "\u045a", "nlArr;": "\u21cd", "nlE;": "\u2266\u0338", "nlarr;": "\u219a", "nldr;": "\u2025", "nle;": "\u2270", "nleftarrow;": "\u219a", "nleftrightarrow;": "\u21ae", "nleq;": "\u2270", "nleqq;": "\u2266\u0338", "nleqslant;": "\u2a7d\u0338", "nles;": "\u2a7d\u0338", "nless;": "\u226e", "nlsim;": "\u2274", "nlt;": "\u226e", "nltri;": "\u22ea", "nltrie;": "\u22ec", "nmid;": "\u2224", "nopf;": "\U0001d55f", "not": "\xac", "not;": "\xac", "notin;": "\u2209", "notinE;": "\u22f9\u0338", "notindot;": "\u22f5\u0338", "notinva;": "\u2209", "notinvb;": "\u22f7", "notinvc;": "\u22f6", "notni;": "\u220c", "notniva;": "\u220c", "notnivb;": "\u22fe", "notnivc;": "\u22fd", "npar;": "\u2226", "nparallel;": "\u2226", "nparsl;": "\u2afd\u20e5", "npart;": "\u2202\u0338", "npolint;": "\u2a14", "npr;": "\u2280", "nprcue;": "\u22e0", "npre;": "\u2aaf\u0338", "nprec;": "\u2280", "npreceq;": "\u2aaf\u0338", "nrArr;": "\u21cf", "nrarr;": "\u219b", "nrarrc;": "\u2933\u0338", "nrarrw;": "\u219d\u0338", "nrightarrow;": "\u219b", "nrtri;": "\u22eb", "nrtrie;": "\u22ed", "nsc;": "\u2281", "nsccue;": "\u22e1", "nsce;": "\u2ab0\u0338", "nscr;": "\U0001d4c3", "nshortmid;": "\u2224", "nshortparallel;": "\u2226", "nsim;": "\u2241", "nsime;": "\u2244", "nsimeq;": "\u2244", "nsmid;": "\u2224", "nspar;": "\u2226", "nsqsube;": "\u22e2", "nsqsupe;": "\u22e3", "nsub;": "\u2284", "nsubE;": "\u2ac5\u0338", "nsube;": "\u2288", "nsubset;": "\u2282\u20d2", "nsubseteq;": "\u2288", "nsubseteqq;": "\u2ac5\u0338", "nsucc;": "\u2281", "nsucceq;": "\u2ab0\u0338", "nsup;": "\u2285", "nsupE;": "\u2ac6\u0338", "nsupe;": "\u2289", "nsupset;": "\u2283\u20d2", "nsupseteq;": "\u2289", "nsupseteqq;": "\u2ac6\u0338", "ntgl;": "\u2279", "ntilde": "\xf1", "ntilde;": "\xf1", "ntlg;": "\u2278", "ntriangleleft;": "\u22ea", "ntrianglelefteq;": "\u22ec", "ntriangleright;": "\u22eb", "ntrianglerighteq;": "\u22ed", "nu;": "\u03bd", "num;": "#", "numero;": "\u2116", "numsp;": "\u2007", "nvDash;": "\u22ad", "nvHarr;": "\u2904", "nvap;": "\u224d\u20d2", "nvdash;": "\u22ac", "nvge;": "\u2265\u20d2", "nvgt;": ">\u20d2", "nvinfin;": "\u29de", "nvlArr;": "\u2902", "nvle;": "\u2264\u20d2", "nvlt;": "<\u20d2", "nvltrie;": "\u22b4\u20d2", "nvrArr;": "\u2903", "nvrtrie;": "\u22b5\u20d2", "nvsim;": "\u223c\u20d2", "nwArr;": "\u21d6", "nwarhk;": "\u2923", "nwarr;": "\u2196", "nwarrow;": "\u2196", "nwnear;": "\u2927", "oS;": "\u24c8", "oacute": "\xf3", "oacute;": "\xf3", "oast;": "\u229b", "ocir;": "\u229a", "ocirc": "\xf4", "ocirc;": "\xf4", "ocy;": "\u043e", "odash;": "\u229d", "odblac;": "\u0151", "odiv;": "\u2a38", "odot;": "\u2299", "odsold;": "\u29bc", "oelig;": "\u0153", "ofcir;": "\u29bf", "ofr;": "\U0001d52c", "ogon;": "\u02db", "ograve": "\xf2", "ograve;": "\xf2", "ogt;": "\u29c1", "ohbar;": "\u29b5", "ohm;": "\u03a9", "oint;": "\u222e", "olarr;": "\u21ba", "olcir;": "\u29be", "olcross;": "\u29bb", "oline;": "\u203e", "olt;": "\u29c0", "omacr;": "\u014d", "omega;": "\u03c9", "omicron;": "\u03bf", "omid;": "\u29b6", "ominus;": "\u2296", "oopf;": "\U0001d560", "opar;": "\u29b7", "operp;": "\u29b9", "oplus;": "\u2295", "or;": "\u2228", "orarr;": "\u21bb", "ord;": "\u2a5d", "order;": "\u2134", "orderof;": "\u2134", "ordf": "\xaa", "ordf;": "\xaa", "ordm": "\xba", "ordm;": "\xba", "origof;": "\u22b6", "oror;": "\u2a56", "orslope;": "\u2a57", "orv;": "\u2a5b", "oscr;": "\u2134", "oslash": "\xf8", "oslash;": "\xf8", "osol;": "\u2298", "otilde": "\xf5", "otilde;": "\xf5", "otimes;": "\u2297", "otimesas;": "\u2a36", "ouml": "\xf6", "ouml;": "\xf6", "ovbar;": "\u233d", "par;": "\u2225", "para": "\xb6", "para;": "\xb6", "parallel;": "\u2225", "parsim;": "\u2af3", "parsl;": "\u2afd", "part;": "\u2202", "pcy;": "\u043f", "percnt;": "%", "period;": ".", "permil;": "\u2030", "perp;": "\u22a5", "pertenk;": "\u2031", "pfr;": "\U0001d52d", "phi;": "\u03c6", "phiv;": "\u03d5", "phmmat;": "\u2133", "phone;": "\u260e", "pi;": "\u03c0", "pitchfork;": "\u22d4", "piv;": "\u03d6", "planck;": "\u210f", "planckh;": "\u210e", "plankv;": "\u210f", "plus;": "+", "plusacir;": "\u2a23", "plusb;": "\u229e", "pluscir;": "\u2a22", "plusdo;": "\u2214", "plusdu;": "\u2a25", "pluse;": "\u2a72", "plusmn": "\xb1", "plusmn;": "\xb1", "plussim;": "\u2a26", "plustwo;": "\u2a27", "pm;": "\xb1", "pointint;": "\u2a15", "popf;": "\U0001d561", "pound": "\xa3", "pound;": "\xa3", "pr;": "\u227a", "prE;": "\u2ab3", "prap;": "\u2ab7", "prcue;": "\u227c", "pre;": "\u2aaf", "prec;": "\u227a", "precapprox;": "\u2ab7", "preccurlyeq;": "\u227c", "preceq;": "\u2aaf", "precnapprox;": "\u2ab9", "precneqq;": "\u2ab5", "precnsim;": "\u22e8", "precsim;": "\u227e", "prime;": "\u2032", "primes;": "\u2119", "prnE;": "\u2ab5", "prnap;": "\u2ab9", "prnsim;": "\u22e8", "prod;": "\u220f", "profalar;": "\u232e", "profline;": "\u2312", "profsurf;": "\u2313", "prop;": "\u221d", "propto;": "\u221d", "prsim;": "\u227e", "prurel;": "\u22b0", "pscr;": "\U0001d4c5", "psi;": "\u03c8", "puncsp;": "\u2008", "qfr;": "\U0001d52e", "qint;": "\u2a0c", "qopf;": "\U0001d562", "qprime;": "\u2057", "qscr;": "\U0001d4c6", "quaternions;": "\u210d", "quatint;": "\u2a16", "quest;": "?", "questeq;": "\u225f", "quot": "\"", "quot;": "\"", "rAarr;": "\u21db", "rArr;": "\u21d2", "rAtail;": "\u291c", "rBarr;": "\u290f", "rHar;": "\u2964", "race;": "\u223d\u0331", "racute;": "\u0155", "radic;": "\u221a", "raemptyv;": "\u29b3", "rang;": "\u27e9", "rangd;": "\u2992", "range;": "\u29a5", "rangle;": "\u27e9", "raquo": "\xbb", "raquo;": "\xbb", "rarr;": "\u2192", "rarrap;": "\u2975", "rarrb;": "\u21e5", "rarrbfs;": "\u2920", "rarrc;": "\u2933", "rarrfs;": "\u291e", "rarrhk;": "\u21aa", "rarrlp;": "\u21ac", "rarrpl;": "\u2945", "rarrsim;": "\u2974", "rarrtl;": "\u21a3", "rarrw;": "\u219d", "ratail;": "\u291a", "ratio;": "\u2236", "rationals;": "\u211a", "rbarr;": "\u290d", "rbbrk;": "\u2773", "rbrace;": "}", "rbrack;": "]", "rbrke;": "\u298c", "rbrksld;": "\u298e", "rbrkslu;": "\u2990", "rcaron;": "\u0159", "rcedil;": "\u0157", "rceil;": "\u2309", "rcub;": "}", "rcy;": "\u0440", "rdca;": "\u2937", "rdldhar;": "\u2969", "rdquo;": "\u201d", "rdquor;": "\u201d", "rdsh;": "\u21b3", "real;": "\u211c", "realine;": "\u211b", "realpart;": "\u211c", "reals;": "\u211d", "rect;": "\u25ad", "reg": "\xae", "reg;": "\xae", "rfisht;": "\u297d", "rfloor;": "\u230b", "rfr;": "\U0001d52f", "rhard;": "\u21c1", "rharu;": "\u21c0", "rharul;": "\u296c", "rho;": "\u03c1", "rhov;": "\u03f1", "rightarrow;": "\u2192", "rightarrowtail;": "\u21a3", "rightharpoondown;": "\u21c1", "rightharpoonup;": "\u21c0", "rightleftarrows;": "\u21c4", "rightleftharpoons;": "\u21cc", "rightrightarrows;": "\u21c9", "rightsquigarrow;": "\u219d", "rightthreetimes;": "\u22cc", "ring;": "\u02da", "risingdotseq;": "\u2253", "rlarr;": "\u21c4", "rlhar;": "\u21cc", "rlm;": "\u200f", "rmoust;": "\u23b1", "rmoustache;": "\u23b1", "rnmid;": "\u2aee", "roang;": "\u27ed", "roarr;": "\u21fe", "robrk;": "\u27e7", "ropar;": "\u2986", "ropf;": "\U0001d563", "roplus;": "\u2a2e", "rotimes;": "\u2a35", "rpar;": ")", "rpargt;": "\u2994", "rppolint;": "\u2a12", "rrarr;": "\u21c9", "rsaquo;": "\u203a", "rscr;": "\U0001d4c7", "rsh;": "\u21b1", "rsqb;": "]", "rsquo;": "\u2019", "rsquor;": "\u2019", "rthree;": "\u22cc", "rtimes;": "\u22ca", "rtri;": "\u25b9", "rtrie;": "\u22b5", "rtrif;": "\u25b8", "rtriltri;": "\u29ce", "ruluhar;": "\u2968", "rx;": "\u211e", "sacute;": "\u015b", "sbquo;": "\u201a", "sc;": "\u227b", "scE;": "\u2ab4", "scap;": "\u2ab8", "scaron;": "\u0161", "sccue;": "\u227d", "sce;": "\u2ab0", "scedil;": "\u015f", "scirc;": "\u015d", "scnE;": "\u2ab6", "scnap;": "\u2aba", "scnsim;": "\u22e9", "scpolint;": "\u2a13", "scsim;": "\u227f", "scy;": "\u0441", "sdot;": "\u22c5", "sdotb;": "\u22a1", "sdote;": "\u2a66", "seArr;": "\u21d8", "searhk;": "\u2925", "searr;": "\u2198", "searrow;": "\u2198", "sect": "\xa7", "sect;": "\xa7", "semi;": ";", "seswar;": "\u2929", "setminus;": "\u2216", "setmn;": "\u2216", "sext;": "\u2736", "sfr;": "\U0001d530", "sfrown;": "\u2322", "sharp;": "\u266f", "shchcy;": "\u0449", "shcy;": "\u0448", "shortmid;": "\u2223", "shortparallel;": "\u2225", "shy": "\xad", "shy;": "\xad", "sigma;": "\u03c3", "sigmaf;": "\u03c2", "sigmav;": "\u03c2", "sim;": "\u223c", "simdot;": "\u2a6a", "sime;": "\u2243", "simeq;": "\u2243", "simg;": "\u2a9e", "simgE;": "\u2aa0", "siml;": "\u2a9d", "simlE;": "\u2a9f", "simne;": "\u2246", "simplus;": "\u2a24", "simrarr;": "\u2972", "slarr;": "\u2190", "smallsetminus;": "\u2216", "smashp;": "\u2a33", "smeparsl;": "\u29e4", "smid;": "\u2223", "smile;": "\u2323", "smt;": "\u2aaa", "smte;": "\u2aac", "smtes;": "\u2aac\ufe00", "softcy;": "\u044c", "sol;": "/", "solb;": "\u29c4", "solbar;": "\u233f", "sopf;": "\U0001d564", "spades;": "\u2660", "spadesuit;": "\u2660", "spar;": "\u2225", "sqcap;": "\u2293", "sqcaps;": "\u2293\ufe00", "sqcup;": "\u2294", "sqcups;": "\u2294\ufe00", "sqsub;": "\u228f", "sqsube;": "\u2291", "sqsubset;": "\u228f", "sqsubseteq;": "\u2291", "sqsup;": "\u2290", "sqsupe;": "\u2292", "sqsupset;": "\u2290", "sqsupseteq;": "\u2292", "squ;": "\u25a1", "square;": "\u25a1", "squarf;": "\u25aa", "squf;": "\u25aa", "srarr;": "\u2192", "sscr;": "\U0001d4c8", "ssetmn;": "\u2216", "ssmile;": "\u2323", "sstarf;": "\u22c6", "star;": "\u2606", "starf;": "\u2605", "straightepsilon;": "\u03f5", "straightphi;": "\u03d5", "strns;": "\xaf", "sub;": "\u2282", "subE;": "\u2ac5", "subdot;": "\u2abd", "sube;": "\u2286", "subedot;": "\u2ac3", "submult;": "\u2ac1", "subnE;": "\u2acb", "subne;": "\u228a", "subplus;": "\u2abf", "subrarr;": "\u2979", "subset;": "\u2282", "subseteq;": "\u2286", "subseteqq;": "\u2ac5", "subsetneq;": "\u228a", "subsetneqq;": "\u2acb", "subsim;": "\u2ac7", "subsub;": "\u2ad5", "subsup;": "\u2ad3", "succ;": "\u227b", "succapprox;": "\u2ab8", "succcurlyeq;": "\u227d", "succeq;": "\u2ab0", "succnapprox;": "\u2aba", "succneqq;": "\u2ab6", "succnsim;": "\u22e9", "succsim;": "\u227f", "sum;": "\u2211", "sung;": "\u266a", "sup1": "\xb9", "sup1;": "\xb9", "sup2": "\xb2", "sup2;": "\xb2", "sup3": "\xb3", "sup3;": "\xb3", "sup;": "\u2283", "supE;": "\u2ac6", "supdot;": "\u2abe", "supdsub;": "\u2ad8", "supe;": "\u2287", "supedot;": "\u2ac4", "suphsol;": "\u27c9", "suphsub;": "\u2ad7", "suplarr;": "\u297b", "supmult;": "\u2ac2", "supnE;": "\u2acc", "supne;": "\u228b", "supplus;": "\u2ac0", "supset;": "\u2283", "supseteq;": "\u2287", "supseteqq;": "\u2ac6", "supsetneq;": "\u228b", "supsetneqq;": "\u2acc", "supsim;": "\u2ac8", "supsub;": "\u2ad4", "supsup;": "\u2ad6", "swArr;": "\u21d9", "swarhk;": "\u2926", "swarr;": "\u2199", "swarrow;": "\u2199", "swnwar;": "\u292a", "szlig": "\xdf", "szlig;": "\xdf", "target;": "\u2316", "tau;": "\u03c4", "tbrk;": "\u23b4", "tcaron;": "\u0165", "tcedil;": "\u0163", "tcy;": "\u0442", "tdot;": "\u20db", "telrec;": "\u2315", "tfr;": "\U0001d531", "there4;": "\u2234", "therefore;": "\u2234", "theta;": "\u03b8", "thetasym;": "\u03d1", "thetav;": "\u03d1", "thickapprox;": "\u2248", "thicksim;": "\u223c", "thinsp;": "\u2009", "thkap;": "\u2248", "thksim;": "\u223c", "thorn": "\xfe", "thorn;": "\xfe", "tilde;": "\u02dc", "times": "\xd7", "times;": "\xd7", "timesb;": "\u22a0", "timesbar;": "\u2a31", "timesd;": "\u2a30", "tint;": "\u222d", "toea;": "\u2928", "top;": "\u22a4", "topbot;": "\u2336", "topcir;": "\u2af1", "topf;": "\U0001d565", "topfork;": "\u2ada", "tosa;": "\u2929", "tprime;": "\u2034", "trade;": "\u2122", "triangle;": "\u25b5", "triangledown;": "\u25bf", "triangleleft;": "\u25c3", "trianglelefteq;": "\u22b4", "triangleq;": "\u225c", "triangleright;": "\u25b9", "trianglerighteq;": "\u22b5", "tridot;": "\u25ec", "trie;": "\u225c", "triminus;": "\u2a3a", "triplus;": "\u2a39", "trisb;": "\u29cd", "tritime;": "\u2a3b", "trpezium;": "\u23e2", "tscr;": "\U0001d4c9", "tscy;": "\u0446", "tshcy;": "\u045b", "tstrok;": "\u0167", "twixt;": "\u226c", "twoheadleftarrow;": "\u219e", "twoheadrightarrow;": "\u21a0", "uArr;": "\u21d1", "uHar;": "\u2963", "uacute": "\xfa", "uacute;": "\xfa", "uarr;": "\u2191", "ubrcy;": "\u045e", "ubreve;": "\u016d", "ucirc": "\xfb", "ucirc;": "\xfb", "ucy;": "\u0443", "udarr;": "\u21c5", "udblac;": "\u0171", "udhar;": "\u296e", "ufisht;": "\u297e", "ufr;": "\U0001d532", "ugrave": "\xf9", "ugrave;": "\xf9", "uharl;": "\u21bf", "uharr;": "\u21be", "uhblk;": "\u2580", "ulcorn;": "\u231c", "ulcorner;": "\u231c", "ulcrop;": "\u230f", "ultri;": "\u25f8", "umacr;": "\u016b", "uml": "\xa8", "uml;": "\xa8", "uogon;": "\u0173", "uopf;": "\U0001d566", "uparrow;": "\u2191", "updownarrow;": "\u2195", "upharpoonleft;": "\u21bf", "upharpoonright;": "\u21be", "uplus;": "\u228e", "upsi;": "\u03c5", "upsih;": "\u03d2", "upsilon;": "\u03c5", "upuparrows;": "\u21c8", "urcorn;": "\u231d", "urcorner;": "\u231d", "urcrop;": "\u230e", "uring;": "\u016f", "urtri;": "\u25f9", "uscr;": "\U0001d4ca", "utdot;": "\u22f0", "utilde;": "\u0169", "utri;": "\u25b5", "utrif;": "\u25b4", "uuarr;": "\u21c8", "uuml": "\xfc", "uuml;": "\xfc", "uwangle;": "\u29a7", "vArr;": "\u21d5", "vBar;": "\u2ae8", "vBarv;": "\u2ae9", "vDash;": "\u22a8", "vangrt;": "\u299c", "varepsilon;": "\u03f5", "varkappa;": "\u03f0", "varnothing;": "\u2205", "varphi;": "\u03d5", "varpi;": "\u03d6", "varpropto;": "\u221d", "varr;": "\u2195", "varrho;": "\u03f1", "varsigma;": "\u03c2", "varsubsetneq;": "\u228a\ufe00", "varsubsetneqq;": "\u2acb\ufe00", "varsupsetneq;": "\u228b\ufe00", "varsupsetneqq;": "\u2acc\ufe00", "vartheta;": "\u03d1", "vartriangleleft;": "\u22b2", "vartriangleright;": "\u22b3", "vcy;": "\u0432", "vdash;": "\u22a2", "vee;": "\u2228", "veebar;": "\u22bb", "veeeq;": "\u225a", "vellip;": "\u22ee", "verbar;": "|", "vert;": "|", "vfr;": "\U0001d533", "vltri;": "\u22b2", "vnsub;": "\u2282\u20d2", "vnsup;": "\u2283\u20d2", "vopf;": "\U0001d567", "vprop;": "\u221d", "vrtri;": "\u22b3", "vscr;": "\U0001d4cb", "vsubnE;": "\u2acb\ufe00", "vsubne;": "\u228a\ufe00", "vsupnE;": "\u2acc\ufe00", "vsupne;": "\u228b\ufe00", "vzigzag;": "\u299a", "wcirc;": "\u0175", "wedbar;": "\u2a5f", "wedge;": "\u2227", "wedgeq;": "\u2259", "weierp;": "\u2118", "wfr;": "\U0001d534", "wopf;": "\U0001d568", "wp;": "\u2118", "wr;": "\u2240", "wreath;": "\u2240", "wscr;": "\U0001d4cc", "xcap;": "\u22c2", "xcirc;": "\u25ef", "xcup;": "\u22c3", "xdtri;": "\u25bd", "xfr;": "\U0001d535", "xhArr;": "\u27fa", "xharr;": "\u27f7", "xi;": "\u03be", "xlArr;": "\u27f8", "xlarr;": "\u27f5", "xmap;": "\u27fc", "xnis;": "\u22fb", "xodot;": "\u2a00", "xopf;": "\U0001d569", "xoplus;": "\u2a01", "xotime;": "\u2a02", "xrArr;": "\u27f9", "xrarr;": "\u27f6", "xscr;": "\U0001d4cd", "xsqcup;": "\u2a06", "xuplus;": "\u2a04", "xutri;": "\u25b3", "xvee;": "\u22c1", "xwedge;": "\u22c0", "yacute": "\xfd", "yacute;": "\xfd", "yacy;": "\u044f", "ycirc;": "\u0177", "ycy;": "\u044b", "yen": "\xa5", "yen;": "\xa5", "yfr;": "\U0001d536", "yicy;": "\u0457", "yopf;": "\U0001d56a", "yscr;": "\U0001d4ce", "yucy;": "\u044e", "yuml": "\xff", "yuml;": "\xff", "zacute;": "\u017a", "zcaron;": "\u017e", "zcy;": "\u0437", "zdot;": "\u017c", "zeetrf;": "\u2128", "zeta;": "\u03b6", "zfr;": "\U0001d537", "zhcy;": "\u0436", "zigrarr;": "\u21dd", "zopf;": "\U0001d56b", "zscr;": "\U0001d4cf", "zwj;": "\u200d", "zwnj;": "\u200c", } replacementCharacters = { 0x0: "\uFFFD", 0x0d: "\u000D", 0x80: "\u20AC", 0x81: "\u0081", 0x82: "\u201A", 0x83: "\u0192", 0x84: "\u201E", 0x85: "\u2026", 0x86: "\u2020", 0x87: "\u2021", 0x88: "\u02C6", 0x89: "\u2030", 0x8A: "\u0160", 0x8B: "\u2039", 0x8C: "\u0152", 0x8D: "\u008D", 0x8E: "\u017D", 0x8F: "\u008F", 0x90: "\u0090", 0x91: "\u2018", 0x92: "\u2019", 0x93: "\u201C", 0x94: "\u201D", 0x95: "\u2022", 0x96: "\u2013", 0x97: "\u2014", 0x98: "\u02DC", 0x99: "\u2122", 0x9A: "\u0161", 0x9B: "\u203A", 0x9C: "\u0153", 0x9D: "\u009D", 0x9E: "\u017E", 0x9F: "\u0178", } tokenTypes = { "Doctype": 0, "Characters": 1, "SpaceCharacters": 2, "StartTag": 3, "EndTag": 4, "EmptyTag": 5, "Comment": 6, "ParseError": 7 } tagTokenTypes = frozenset([tokenTypes["StartTag"], tokenTypes["EndTag"], tokenTypes["EmptyTag"]]) prefixes = {v: k for k, v in namespaces.items()} prefixes["http://www.w3.org/1998/Math/MathML"] = "math" class DataLossWarning(UserWarning): """Raised when the current tree is unable to represent the input data""" pass class _ReparseException(Exception): pass PKH]5m,,;python3.10/site-packages/pip/_vendor/html5lib/_tokenizer.pynu[from __future__ import absolute_import, division, unicode_literals from pip._vendor.six import unichr as chr from collections import deque, OrderedDict from sys import version_info from .constants import spaceCharacters from .constants import entities from .constants import asciiLetters, asciiUpper2Lower from .constants import digits, hexDigits, EOF from .constants import tokenTypes, tagTokenTypes from .constants import replacementCharacters from ._inputstream import HTMLInputStream from ._trie import Trie entitiesTrie = Trie(entities) if version_info >= (3, 7): attributeMap = dict else: attributeMap = OrderedDict class HTMLTokenizer(object): """ This class takes care of tokenizing HTML. * self.currentToken Holds the token that is currently being processed. * self.state Holds a reference to the method to be invoked... XXX * self.stream Points to HTMLInputStream object. """ def __init__(self, stream, parser=None, **kwargs): self.stream = HTMLInputStream(stream, **kwargs) self.parser = parser # Setup the initial tokenizer state self.escapeFlag = False self.lastFourChars = [] self.state = self.dataState self.escape = False # The current token being created self.currentToken = None super(HTMLTokenizer, self).__init__() def __iter__(self): """ This is where the magic happens. We do our usually processing through the states and when we have a token to return we yield the token which pauses processing until the next token is requested. """ self.tokenQueue = deque([]) # Start processing. When EOF is reached self.state will return False # instead of True and the loop will terminate. while self.state(): while self.stream.errors: yield {"type": tokenTypes["ParseError"], "data": self.stream.errors.pop(0)} while self.tokenQueue: yield self.tokenQueue.popleft() def consumeNumberEntity(self, isHex): """This function returns either U+FFFD or the character based on the decimal or hexadecimal representation. It also discards ";" if present. If not present self.tokenQueue.append({"type": tokenTypes["ParseError"]}) is invoked. """ allowed = digits radix = 10 if isHex: allowed = hexDigits radix = 16 charStack = [] # Consume all the characters that are in range while making sure we # don't hit an EOF. c = self.stream.char() while c in allowed and c is not EOF: charStack.append(c) c = self.stream.char() # Convert the set of characters consumed to an int. charAsInt = int("".join(charStack), radix) # Certain characters get replaced with others if charAsInt in replacementCharacters: char = replacementCharacters[charAsInt] self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "illegal-codepoint-for-numeric-entity", "datavars": {"charAsInt": charAsInt}}) elif ((0xD800 <= charAsInt <= 0xDFFF) or (charAsInt > 0x10FFFF)): char = "\uFFFD" self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "illegal-codepoint-for-numeric-entity", "datavars": {"charAsInt": charAsInt}}) else: # Should speed up this check somehow (e.g. move the set to a constant) if ((0x0001 <= charAsInt <= 0x0008) or (0x000E <= charAsInt <= 0x001F) or (0x007F <= charAsInt <= 0x009F) or (0xFDD0 <= charAsInt <= 0xFDEF) or charAsInt in frozenset([0x000B, 0xFFFE, 0xFFFF, 0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, 0x10FFFE, 0x10FFFF])): self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "illegal-codepoint-for-numeric-entity", "datavars": {"charAsInt": charAsInt}}) try: # Try/except needed as UCS-2 Python builds' unichar only works # within the BMP. char = chr(charAsInt) except ValueError: v = charAsInt - 0x10000 char = chr(0xD800 | (v >> 10)) + chr(0xDC00 | (v & 0x3FF)) # Discard the ; if present. Otherwise, put it back on the queue and # invoke parseError on parser. if c != ";": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "numeric-entity-without-semicolon"}) self.stream.unget(c) return char def consumeEntity(self, allowedChar=None, fromAttribute=False): # Initialise to the default output for when no entity is matched output = "&" charStack = [self.stream.char()] if (charStack[0] in spaceCharacters or charStack[0] in (EOF, "<", "&") or (allowedChar is not None and allowedChar == charStack[0])): self.stream.unget(charStack[0]) elif charStack[0] == "#": # Read the next character to see if it's hex or decimal hex = False charStack.append(self.stream.char()) if charStack[-1] in ("x", "X"): hex = True charStack.append(self.stream.char()) # charStack[-1] should be the first digit if (hex and charStack[-1] in hexDigits) \ or (not hex and charStack[-1] in digits): # At least one digit found, so consume the whole number self.stream.unget(charStack[-1]) output = self.consumeNumberEntity(hex) else: # No digits found self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-numeric-entity"}) self.stream.unget(charStack.pop()) output = "&" + "".join(charStack) else: # At this point in the process might have named entity. Entities # are stored in the global variable "entities". # # Consume characters and compare to these to a substring of the # entity names in the list until the substring no longer matches. while (charStack[-1] is not EOF): if not entitiesTrie.has_keys_with_prefix("".join(charStack)): break charStack.append(self.stream.char()) # At this point we have a string that starts with some characters # that may match an entity # Try to find the longest entity the string will match to take care # of ¬i for instance. try: entityName = entitiesTrie.longest_prefix("".join(charStack[:-1])) entityLength = len(entityName) except KeyError: entityName = None if entityName is not None: if entityName[-1] != ";": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "named-entity-without-semicolon"}) if (entityName[-1] != ";" and fromAttribute and (charStack[entityLength] in asciiLetters or charStack[entityLength] in digits or charStack[entityLength] == "=")): self.stream.unget(charStack.pop()) output = "&" + "".join(charStack) else: output = entities[entityName] self.stream.unget(charStack.pop()) output += "".join(charStack[entityLength:]) else: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-named-entity"}) self.stream.unget(charStack.pop()) output = "&" + "".join(charStack) if fromAttribute: self.currentToken["data"][-1][1] += output else: if output in spaceCharacters: tokenType = "SpaceCharacters" else: tokenType = "Characters" self.tokenQueue.append({"type": tokenTypes[tokenType], "data": output}) def processEntityInAttribute(self, allowedChar): """This method replaces the need for "entityInAttributeValueState". """ self.consumeEntity(allowedChar=allowedChar, fromAttribute=True) def emitCurrentToken(self): """This method is a generic handler for emitting the tags. It also sets the state to "data" because that's what's needed after a token has been emitted. """ token = self.currentToken # Add token to the queue to be yielded if (token["type"] in tagTokenTypes): token["name"] = token["name"].translate(asciiUpper2Lower) if token["type"] == tokenTypes["StartTag"]: raw = token["data"] data = attributeMap(raw) if len(raw) > len(data): # we had some duplicated attribute, fix so first wins data.update(raw[::-1]) token["data"] = data if token["type"] == tokenTypes["EndTag"]: if token["data"]: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "attributes-in-end-tag"}) if token["selfClosing"]: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "self-closing-flag-on-end-tag"}) self.tokenQueue.append(token) self.state = self.dataState # Below are the various tokenizer states worked out. def dataState(self): data = self.stream.char() if data == "&": self.state = self.entityDataState elif data == "<": self.state = self.tagOpenState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "\u0000"}) elif data is EOF: # Tokenization ends. return False elif data in spaceCharacters: # Directly after emitting a token you switch back to the "data # state". At that point spaceCharacters are important so they are # emitted separately. self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": data + self.stream.charsUntil(spaceCharacters, True)}) # No need to update lastFourChars here, since the first space will # have already been appended to lastFourChars and will have broken # any sequences else: chars = self.stream.charsUntil(("&", "<", "\u0000")) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data + chars}) return True def entityDataState(self): self.consumeEntity() self.state = self.dataState return True def rcdataState(self): data = self.stream.char() if data == "&": self.state = self.characterReferenceInRcdata elif data == "<": self.state = self.rcdataLessThanSignState elif data == EOF: # Tokenization ends. return False elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "\uFFFD"}) elif data in spaceCharacters: # Directly after emitting a token you switch back to the "data # state". At that point spaceCharacters are important so they are # emitted separately. self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": data + self.stream.charsUntil(spaceCharacters, True)}) # No need to update lastFourChars here, since the first space will # have already been appended to lastFourChars and will have broken # any sequences else: chars = self.stream.charsUntil(("&", "<", "\u0000")) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data + chars}) return True def characterReferenceInRcdata(self): self.consumeEntity() self.state = self.rcdataState return True def rawtextState(self): data = self.stream.char() if data == "<": self.state = self.rawtextLessThanSignState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "\uFFFD"}) elif data == EOF: # Tokenization ends. return False else: chars = self.stream.charsUntil(("<", "\u0000")) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data + chars}) return True def scriptDataState(self): data = self.stream.char() if data == "<": self.state = self.scriptDataLessThanSignState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "\uFFFD"}) elif data == EOF: # Tokenization ends. return False else: chars = self.stream.charsUntil(("<", "\u0000")) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data + chars}) return True def plaintextState(self): data = self.stream.char() if data == EOF: # Tokenization ends. return False elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "\uFFFD"}) else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data + self.stream.charsUntil("\u0000")}) return True def tagOpenState(self): data = self.stream.char() if data == "!": self.state = self.markupDeclarationOpenState elif data == "/": self.state = self.closeTagOpenState elif data in asciiLetters: self.currentToken = {"type": tokenTypes["StartTag"], "name": data, "data": [], "selfClosing": False, "selfClosingAcknowledged": False} self.state = self.tagNameState elif data == ">": # XXX In theory it could be something besides a tag name. But # do we really care? self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-tag-name-but-got-right-bracket"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<>"}) self.state = self.dataState elif data == "?": # XXX In theory it could be something besides a tag name. But # do we really care? self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-tag-name-but-got-question-mark"}) self.stream.unget(data) self.state = self.bogusCommentState else: # XXX self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-tag-name"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) self.stream.unget(data) self.state = self.dataState return True def closeTagOpenState(self): data = self.stream.char() if data in asciiLetters: self.currentToken = {"type": tokenTypes["EndTag"], "name": data, "data": [], "selfClosing": False} self.state = self.tagNameState elif data == ">": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-closing-tag-but-got-right-bracket"}) self.state = self.dataState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-closing-tag-but-got-eof"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "": self.emitCurrentToken() elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-tag-name"}) self.state = self.dataState elif data == "/": self.state = self.selfClosingStartTagState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["name"] += "\uFFFD" else: self.currentToken["name"] += data # (Don't use charsUntil here, because tag names are # very short and it's faster to not do anything fancy) return True def rcdataLessThanSignState(self): data = self.stream.char() if data == "/": self.temporaryBuffer = "" self.state = self.rcdataEndTagOpenState else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) self.stream.unget(data) self.state = self.rcdataState return True def rcdataEndTagOpenState(self): data = self.stream.char() if data in asciiLetters: self.temporaryBuffer += data self.state = self.rcdataEndTagNameState else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "" and appropriate: self.currentToken = {"type": tokenTypes["EndTag"], "name": self.temporaryBuffer, "data": [], "selfClosing": False} self.emitCurrentToken() self.state = self.dataState elif data in asciiLetters: self.temporaryBuffer += data else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "" and appropriate: self.currentToken = {"type": tokenTypes["EndTag"], "name": self.temporaryBuffer, "data": [], "selfClosing": False} self.emitCurrentToken() self.state = self.dataState elif data in asciiLetters: self.temporaryBuffer += data else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "" and appropriate: self.currentToken = {"type": tokenTypes["EndTag"], "name": self.temporaryBuffer, "data": [], "selfClosing": False} self.emitCurrentToken() self.state = self.dataState elif data in asciiLetters: self.temporaryBuffer += data else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "": self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) self.state = self.scriptDataState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "\uFFFD"}) self.state = self.scriptDataEscapedState elif data == EOF: self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) self.state = self.scriptDataEscapedState return True def scriptDataEscapedLessThanSignState(self): data = self.stream.char() if data == "/": self.temporaryBuffer = "" self.state = self.scriptDataEscapedEndTagOpenState elif data in asciiLetters: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<" + data}) self.temporaryBuffer = data self.state = self.scriptDataDoubleEscapeStartState else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) self.stream.unget(data) self.state = self.scriptDataEscapedState return True def scriptDataEscapedEndTagOpenState(self): data = self.stream.char() if data in asciiLetters: self.temporaryBuffer = data self.state = self.scriptDataEscapedEndTagNameState else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "" and appropriate: self.currentToken = {"type": tokenTypes["EndTag"], "name": self.temporaryBuffer, "data": [], "selfClosing": False} self.emitCurrentToken() self.state = self.dataState elif data in asciiLetters: self.temporaryBuffer += data else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ""))): self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) if self.temporaryBuffer.lower() == "script": self.state = self.scriptDataDoubleEscapedState else: self.state = self.scriptDataEscapedState elif data in asciiLetters: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) self.temporaryBuffer += data else: self.stream.unget(data) self.state = self.scriptDataEscapedState return True def scriptDataDoubleEscapedState(self): data = self.stream.char() if data == "-": self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) self.state = self.scriptDataDoubleEscapedDashState elif data == "<": self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) self.state = self.scriptDataDoubleEscapedLessThanSignState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "\uFFFD"}) elif data == EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-script-in-script"}) self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) return True def scriptDataDoubleEscapedDashState(self): data = self.stream.char() if data == "-": self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) self.state = self.scriptDataDoubleEscapedDashDashState elif data == "<": self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) self.state = self.scriptDataDoubleEscapedLessThanSignState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "\uFFFD"}) self.state = self.scriptDataDoubleEscapedState elif data == EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-script-in-script"}) self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) self.state = self.scriptDataDoubleEscapedState return True def scriptDataDoubleEscapedDashDashState(self): data = self.stream.char() if data == "-": self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) elif data == "<": self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) self.state = self.scriptDataDoubleEscapedLessThanSignState elif data == ">": self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) self.state = self.scriptDataState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "\uFFFD"}) self.state = self.scriptDataDoubleEscapedState elif data == EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-script-in-script"}) self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) self.state = self.scriptDataDoubleEscapedState return True def scriptDataDoubleEscapedLessThanSignState(self): data = self.stream.char() if data == "/": self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "/"}) self.temporaryBuffer = "" self.state = self.scriptDataDoubleEscapeEndState else: self.stream.unget(data) self.state = self.scriptDataDoubleEscapedState return True def scriptDataDoubleEscapeEndState(self): data = self.stream.char() if data in (spaceCharacters | frozenset(("/", ">"))): self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) if self.temporaryBuffer.lower() == "script": self.state = self.scriptDataEscapedState else: self.state = self.scriptDataDoubleEscapedState elif data in asciiLetters: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) self.temporaryBuffer += data else: self.stream.unget(data) self.state = self.scriptDataDoubleEscapedState return True def beforeAttributeNameState(self): data = self.stream.char() if data in spaceCharacters: self.stream.charsUntil(spaceCharacters, True) elif data in asciiLetters: self.currentToken["data"].append([data, ""]) self.state = self.attributeNameState elif data == ">": self.emitCurrentToken() elif data == "/": self.state = self.selfClosingStartTagState elif data in ("'", '"', "=", "<"): self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-character-in-attribute-name"}) self.currentToken["data"].append([data, ""]) self.state = self.attributeNameState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"].append(["\uFFFD", ""]) self.state = self.attributeNameState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-attribute-name-but-got-eof"}) self.state = self.dataState else: self.currentToken["data"].append([data, ""]) self.state = self.attributeNameState return True def attributeNameState(self): data = self.stream.char() leavingThisState = True emitToken = False if data == "=": self.state = self.beforeAttributeValueState elif data in asciiLetters: self.currentToken["data"][-1][0] += data +\ self.stream.charsUntil(asciiLetters, True) leavingThisState = False elif data == ">": # XXX If we emit here the attributes are converted to a dict # without being checked and when the code below runs we error # because data is a dict not a list emitToken = True elif data in spaceCharacters: self.state = self.afterAttributeNameState elif data == "/": self.state = self.selfClosingStartTagState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"][-1][0] += "\uFFFD" leavingThisState = False elif data in ("'", '"', "<"): self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-character-in-attribute-name"}) self.currentToken["data"][-1][0] += data leavingThisState = False elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-attribute-name"}) self.state = self.dataState else: self.currentToken["data"][-1][0] += data leavingThisState = False if leavingThisState: # Attributes are not dropped at this stage. That happens when the # start tag token is emitted so values can still be safely appended # to attributes, but we do want to report the parse error in time. self.currentToken["data"][-1][0] = ( self.currentToken["data"][-1][0].translate(asciiUpper2Lower)) for name, _ in self.currentToken["data"][:-1]: if self.currentToken["data"][-1][0] == name: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "duplicate-attribute"}) break # XXX Fix for above XXX if emitToken: self.emitCurrentToken() return True def afterAttributeNameState(self): data = self.stream.char() if data in spaceCharacters: self.stream.charsUntil(spaceCharacters, True) elif data == "=": self.state = self.beforeAttributeValueState elif data == ">": self.emitCurrentToken() elif data in asciiLetters: self.currentToken["data"].append([data, ""]) self.state = self.attributeNameState elif data == "/": self.state = self.selfClosingStartTagState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"].append(["\uFFFD", ""]) self.state = self.attributeNameState elif data in ("'", '"', "<"): self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-character-after-attribute-name"}) self.currentToken["data"].append([data, ""]) self.state = self.attributeNameState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-end-of-tag-but-got-eof"}) self.state = self.dataState else: self.currentToken["data"].append([data, ""]) self.state = self.attributeNameState return True def beforeAttributeValueState(self): data = self.stream.char() if data in spaceCharacters: self.stream.charsUntil(spaceCharacters, True) elif data == "\"": self.state = self.attributeValueDoubleQuotedState elif data == "&": self.state = self.attributeValueUnQuotedState self.stream.unget(data) elif data == "'": self.state = self.attributeValueSingleQuotedState elif data == ">": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-attribute-value-but-got-right-bracket"}) self.emitCurrentToken() elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"][-1][1] += "\uFFFD" self.state = self.attributeValueUnQuotedState elif data in ("=", "<", "`"): self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "equals-in-unquoted-attribute-value"}) self.currentToken["data"][-1][1] += data self.state = self.attributeValueUnQuotedState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-attribute-value-but-got-eof"}) self.state = self.dataState else: self.currentToken["data"][-1][1] += data self.state = self.attributeValueUnQuotedState return True def attributeValueDoubleQuotedState(self): data = self.stream.char() if data == "\"": self.state = self.afterAttributeValueState elif data == "&": self.processEntityInAttribute('"') elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"][-1][1] += "\uFFFD" elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-attribute-value-double-quote"}) self.state = self.dataState else: self.currentToken["data"][-1][1] += data +\ self.stream.charsUntil(("\"", "&", "\u0000")) return True def attributeValueSingleQuotedState(self): data = self.stream.char() if data == "'": self.state = self.afterAttributeValueState elif data == "&": self.processEntityInAttribute("'") elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"][-1][1] += "\uFFFD" elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-attribute-value-single-quote"}) self.state = self.dataState else: self.currentToken["data"][-1][1] += data +\ self.stream.charsUntil(("'", "&", "\u0000")) return True def attributeValueUnQuotedState(self): data = self.stream.char() if data in spaceCharacters: self.state = self.beforeAttributeNameState elif data == "&": self.processEntityInAttribute(">") elif data == ">": self.emitCurrentToken() elif data in ('"', "'", "=", "<", "`"): self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-character-in-unquoted-attribute-value"}) self.currentToken["data"][-1][1] += data elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"][-1][1] += "\uFFFD" elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-attribute-value-no-quotes"}) self.state = self.dataState else: self.currentToken["data"][-1][1] += data + self.stream.charsUntil( frozenset(("&", ">", '"', "'", "=", "<", "`", "\u0000")) | spaceCharacters) return True def afterAttributeValueState(self): data = self.stream.char() if data in spaceCharacters: self.state = self.beforeAttributeNameState elif data == ">": self.emitCurrentToken() elif data == "/": self.state = self.selfClosingStartTagState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-EOF-after-attribute-value"}) self.stream.unget(data) self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-character-after-attribute-value"}) self.stream.unget(data) self.state = self.beforeAttributeNameState return True def selfClosingStartTagState(self): data = self.stream.char() if data == ">": self.currentToken["selfClosing"] = True self.emitCurrentToken() elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-EOF-after-solidus-in-tag"}) self.stream.unget(data) self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-character-after-solidus-in-tag"}) self.stream.unget(data) self.state = self.beforeAttributeNameState return True def bogusCommentState(self): # Make a new comment token and give it as value all the characters # until the first > or EOF (charsUntil checks for EOF automatically) # and emit it. data = self.stream.charsUntil(">") data = data.replace("\u0000", "\uFFFD") self.tokenQueue.append( {"type": tokenTypes["Comment"], "data": data}) # Eat the character directly after the bogus comment which is either a # ">" or an EOF. self.stream.char() self.state = self.dataState return True def markupDeclarationOpenState(self): charStack = [self.stream.char()] if charStack[-1] == "-": charStack.append(self.stream.char()) if charStack[-1] == "-": self.currentToken = {"type": tokenTypes["Comment"], "data": ""} self.state = self.commentStartState return True elif charStack[-1] in ('d', 'D'): matched = True for expected in (('o', 'O'), ('c', 'C'), ('t', 'T'), ('y', 'Y'), ('p', 'P'), ('e', 'E')): charStack.append(self.stream.char()) if charStack[-1] not in expected: matched = False break if matched: self.currentToken = {"type": tokenTypes["Doctype"], "name": "", "publicId": None, "systemId": None, "correct": True} self.state = self.doctypeState return True elif (charStack[-1] == "[" and self.parser is not None and self.parser.tree.openElements and self.parser.tree.openElements[-1].namespace != self.parser.tree.defaultNamespace): matched = True for expected in ["C", "D", "A", "T", "A", "["]: charStack.append(self.stream.char()) if charStack[-1] != expected: matched = False break if matched: self.state = self.cdataSectionState return True self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-dashes-or-doctype"}) while charStack: self.stream.unget(charStack.pop()) self.state = self.bogusCommentState return True def commentStartState(self): data = self.stream.char() if data == "-": self.state = self.commentStartDashState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"] += "\uFFFD" elif data == ">": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "incorrect-comment"}) self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-comment"}) self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.currentToken["data"] += data self.state = self.commentState return True def commentStartDashState(self): data = self.stream.char() if data == "-": self.state = self.commentEndState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"] += "-\uFFFD" elif data == ">": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "incorrect-comment"}) self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-comment"}) self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.currentToken["data"] += "-" + data self.state = self.commentState return True def commentState(self): data = self.stream.char() if data == "-": self.state = self.commentEndDashState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"] += "\uFFFD" elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-comment"}) self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.currentToken["data"] += data + \ self.stream.charsUntil(("-", "\u0000")) return True def commentEndDashState(self): data = self.stream.char() if data == "-": self.state = self.commentEndState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"] += "-\uFFFD" self.state = self.commentState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-comment-end-dash"}) self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.currentToken["data"] += "-" + data self.state = self.commentState return True def commentEndState(self): data = self.stream.char() if data == ">": self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"] += "--\uFFFD" self.state = self.commentState elif data == "!": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-bang-after-double-dash-in-comment"}) self.state = self.commentEndBangState elif data == "-": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-dash-after-double-dash-in-comment"}) self.currentToken["data"] += data elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-comment-double-dash"}) self.tokenQueue.append(self.currentToken) self.state = self.dataState else: # XXX self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-char-in-comment"}) self.currentToken["data"] += "--" + data self.state = self.commentState return True def commentEndBangState(self): data = self.stream.char() if data == ">": self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data == "-": self.currentToken["data"] += "--!" self.state = self.commentEndDashState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["data"] += "--!\uFFFD" self.state = self.commentState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-comment-end-bang-state"}) self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.currentToken["data"] += "--!" + data self.state = self.commentState return True def doctypeState(self): data = self.stream.char() if data in spaceCharacters: self.state = self.beforeDoctypeNameState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-doctype-name-but-got-eof"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "need-space-after-doctype"}) self.stream.unget(data) self.state = self.beforeDoctypeNameState return True def beforeDoctypeNameState(self): data = self.stream.char() if data in spaceCharacters: pass elif data == ">": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-doctype-name-but-got-right-bracket"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["name"] = "\uFFFD" self.state = self.doctypeNameState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-doctype-name-but-got-eof"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.currentToken["name"] = data self.state = self.doctypeNameState return True def doctypeNameState(self): data = self.stream.char() if data in spaceCharacters: self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) self.state = self.afterDoctypeNameState elif data == ">": self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["name"] += "\uFFFD" self.state = self.doctypeNameState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype-name"}) self.currentToken["correct"] = False self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.currentToken["name"] += data return True def afterDoctypeNameState(self): data = self.stream.char() if data in spaceCharacters: pass elif data == ">": self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data is EOF: self.currentToken["correct"] = False self.stream.unget(data) self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.tokenQueue.append(self.currentToken) self.state = self.dataState else: if data in ("p", "P"): matched = True for expected in (("u", "U"), ("b", "B"), ("l", "L"), ("i", "I"), ("c", "C")): data = self.stream.char() if data not in expected: matched = False break if matched: self.state = self.afterDoctypePublicKeywordState return True elif data in ("s", "S"): matched = True for expected in (("y", "Y"), ("s", "S"), ("t", "T"), ("e", "E"), ("m", "M")): data = self.stream.char() if data not in expected: matched = False break if matched: self.state = self.afterDoctypeSystemKeywordState return True # All the characters read before the current 'data' will be # [a-zA-Z], so they're garbage in the bogus doctype and can be # discarded; only the latest character might be '>' or EOF # and needs to be ungetted self.stream.unget(data) self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "expected-space-or-right-bracket-in-doctype", "datavars": {"data": data}}) self.currentToken["correct"] = False self.state = self.bogusDoctypeState return True def afterDoctypePublicKeywordState(self): data = self.stream.char() if data in spaceCharacters: self.state = self.beforeDoctypePublicIdentifierState elif data in ("'", '"'): self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-char-in-doctype"}) self.stream.unget(data) self.state = self.beforeDoctypePublicIdentifierState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.stream.unget(data) self.state = self.beforeDoctypePublicIdentifierState return True def beforeDoctypePublicIdentifierState(self): data = self.stream.char() if data in spaceCharacters: pass elif data == "\"": self.currentToken["publicId"] = "" self.state = self.doctypePublicIdentifierDoubleQuotedState elif data == "'": self.currentToken["publicId"] = "" self.state = self.doctypePublicIdentifierSingleQuotedState elif data == ">": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-end-of-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-char-in-doctype"}) self.currentToken["correct"] = False self.state = self.bogusDoctypeState return True def doctypePublicIdentifierDoubleQuotedState(self): data = self.stream.char() if data == "\"": self.state = self.afterDoctypePublicIdentifierState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["publicId"] += "\uFFFD" elif data == ">": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-end-of-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.currentToken["publicId"] += data return True def doctypePublicIdentifierSingleQuotedState(self): data = self.stream.char() if data == "'": self.state = self.afterDoctypePublicIdentifierState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["publicId"] += "\uFFFD" elif data == ">": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-end-of-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.currentToken["publicId"] += data return True def afterDoctypePublicIdentifierState(self): data = self.stream.char() if data in spaceCharacters: self.state = self.betweenDoctypePublicAndSystemIdentifiersState elif data == ">": self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data == '"': self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-char-in-doctype"}) self.currentToken["systemId"] = "" self.state = self.doctypeSystemIdentifierDoubleQuotedState elif data == "'": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-char-in-doctype"}) self.currentToken["systemId"] = "" self.state = self.doctypeSystemIdentifierSingleQuotedState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-char-in-doctype"}) self.currentToken["correct"] = False self.state = self.bogusDoctypeState return True def betweenDoctypePublicAndSystemIdentifiersState(self): data = self.stream.char() if data in spaceCharacters: pass elif data == ">": self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data == '"': self.currentToken["systemId"] = "" self.state = self.doctypeSystemIdentifierDoubleQuotedState elif data == "'": self.currentToken["systemId"] = "" self.state = self.doctypeSystemIdentifierSingleQuotedState elif data == EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-char-in-doctype"}) self.currentToken["correct"] = False self.state = self.bogusDoctypeState return True def afterDoctypeSystemKeywordState(self): data = self.stream.char() if data in spaceCharacters: self.state = self.beforeDoctypeSystemIdentifierState elif data in ("'", '"'): self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-char-in-doctype"}) self.stream.unget(data) self.state = self.beforeDoctypeSystemIdentifierState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.stream.unget(data) self.state = self.beforeDoctypeSystemIdentifierState return True def beforeDoctypeSystemIdentifierState(self): data = self.stream.char() if data in spaceCharacters: pass elif data == "\"": self.currentToken["systemId"] = "" self.state = self.doctypeSystemIdentifierDoubleQuotedState elif data == "'": self.currentToken["systemId"] = "" self.state = self.doctypeSystemIdentifierSingleQuotedState elif data == ">": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-char-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-char-in-doctype"}) self.currentToken["correct"] = False self.state = self.bogusDoctypeState return True def doctypeSystemIdentifierDoubleQuotedState(self): data = self.stream.char() if data == "\"": self.state = self.afterDoctypeSystemIdentifierState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["systemId"] += "\uFFFD" elif data == ">": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-end-of-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.currentToken["systemId"] += data return True def doctypeSystemIdentifierSingleQuotedState(self): data = self.stream.char() if data == "'": self.state = self.afterDoctypeSystemIdentifierState elif data == "\u0000": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) self.currentToken["systemId"] += "\uFFFD" elif data == ">": self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-end-of-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.currentToken["systemId"] += data return True def afterDoctypeSystemIdentifierState(self): data = self.stream.char() if data in spaceCharacters: pass elif data == ">": self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data is EOF: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "eof-in-doctype"}) self.currentToken["correct"] = False self.tokenQueue.append(self.currentToken) self.state = self.dataState else: self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "unexpected-char-in-doctype"}) self.state = self.bogusDoctypeState return True def bogusDoctypeState(self): data = self.stream.char() if data == ">": self.tokenQueue.append(self.currentToken) self.state = self.dataState elif data is EOF: # XXX EMIT self.stream.unget(data) self.tokenQueue.append(self.currentToken) self.state = self.dataState else: pass return True def cdataSectionState(self): data = [] while True: data.append(self.stream.charsUntil("]")) data.append(self.stream.charsUntil(">")) char = self.stream.char() if char == EOF: break else: assert char == ">" if data[-1][-2:] == "]]": data[-1] = data[-1][:-2] break else: data.append(char) data = "".join(data) # pylint:disable=redefined-variable-type # Deal with null here rather than in the parser nullCount = data.count("\u0000") if nullCount > 0: for _ in range(nullCount): self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": "invalid-codepoint"}) data = data.replace("\u0000", "\uFFFD") if data: self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) self.state = self.dataState return True PKH]ʧ-XAXA:python3.10/site-packages/pip/_vendor/html5lib/_ihatexml.pynu[from __future__ import absolute_import, division, unicode_literals import re import warnings from .constants import DataLossWarning baseChar = """ [#x0041-#x005A] | [#x0061-#x007A] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x00FF] | [#x0100-#x0131] | [#x0134-#x013E] | [#x0141-#x0148] | [#x014A-#x017E] | [#x0180-#x01C3] | [#x01CD-#x01F0] | [#x01F4-#x01F5] | [#x01FA-#x0217] | [#x0250-#x02A8] | [#x02BB-#x02C1] | #x0386 | [#x0388-#x038A] | #x038C | [#x038E-#x03A1] | [#x03A3-#x03CE] | [#x03D0-#x03D6] | #x03DA | #x03DC | #x03DE | #x03E0 | [#x03E2-#x03F3] | [#x0401-#x040C] | [#x040E-#x044F] | [#x0451-#x045C] | [#x045E-#x0481] | [#x0490-#x04C4] | [#x04C7-#x04C8] | [#x04CB-#x04CC] | [#x04D0-#x04EB] | [#x04EE-#x04F5] | [#x04F8-#x04F9] | [#x0531-#x0556] | #x0559 | [#x0561-#x0586] | [#x05D0-#x05EA] | [#x05F0-#x05F2] | [#x0621-#x063A] | [#x0641-#x064A] | [#x0671-#x06B7] | [#x06BA-#x06BE] | [#x06C0-#x06CE] | [#x06D0-#x06D3] | #x06D5 | [#x06E5-#x06E6] | [#x0905-#x0939] | #x093D | [#x0958-#x0961] | [#x0985-#x098C] | [#x098F-#x0990] | [#x0993-#x09A8] | [#x09AA-#x09B0] | #x09B2 | [#x09B6-#x09B9] | [#x09DC-#x09DD] | [#x09DF-#x09E1] | [#x09F0-#x09F1] | [#x0A05-#x0A0A] | [#x0A0F-#x0A10] | [#x0A13-#x0A28] | [#x0A2A-#x0A30] | [#x0A32-#x0A33] | [#x0A35-#x0A36] | [#x0A38-#x0A39] | [#x0A59-#x0A5C] | #x0A5E | [#x0A72-#x0A74] | [#x0A85-#x0A8B] | #x0A8D | [#x0A8F-#x0A91] | [#x0A93-#x0AA8] | [#x0AAA-#x0AB0] | [#x0AB2-#x0AB3] | [#x0AB5-#x0AB9] | #x0ABD | #x0AE0 | [#x0B05-#x0B0C] | [#x0B0F-#x0B10] | [#x0B13-#x0B28] | [#x0B2A-#x0B30] | [#x0B32-#x0B33] | [#x0B36-#x0B39] | #x0B3D | [#x0B5C-#x0B5D] | [#x0B5F-#x0B61] | [#x0B85-#x0B8A] | [#x0B8E-#x0B90] | [#x0B92-#x0B95] | [#x0B99-#x0B9A] | #x0B9C | [#x0B9E-#x0B9F] | [#x0BA3-#x0BA4] | [#x0BA8-#x0BAA] | [#x0BAE-#x0BB5] | [#x0BB7-#x0BB9] | [#x0C05-#x0C0C] | [#x0C0E-#x0C10] | [#x0C12-#x0C28] | [#x0C2A-#x0C33] | [#x0C35-#x0C39] | [#x0C60-#x0C61] | [#x0C85-#x0C8C] | [#x0C8E-#x0C90] | [#x0C92-#x0CA8] | [#x0CAA-#x0CB3] | [#x0CB5-#x0CB9] | #x0CDE | [#x0CE0-#x0CE1] | [#x0D05-#x0D0C] | [#x0D0E-#x0D10] | [#x0D12-#x0D28] | [#x0D2A-#x0D39] | [#x0D60-#x0D61] | [#x0E01-#x0E2E] | #x0E30 | [#x0E32-#x0E33] | [#x0E40-#x0E45] | [#x0E81-#x0E82] | #x0E84 | [#x0E87-#x0E88] | #x0E8A | #x0E8D | [#x0E94-#x0E97] | [#x0E99-#x0E9F] | [#x0EA1-#x0EA3] | #x0EA5 | #x0EA7 | [#x0EAA-#x0EAB] | [#x0EAD-#x0EAE] | #x0EB0 | [#x0EB2-#x0EB3] | #x0EBD | [#x0EC0-#x0EC4] | [#x0F40-#x0F47] | [#x0F49-#x0F69] | [#x10A0-#x10C5] | [#x10D0-#x10F6] | #x1100 | [#x1102-#x1103] | [#x1105-#x1107] | #x1109 | [#x110B-#x110C] | [#x110E-#x1112] | #x113C | #x113E | #x1140 | #x114C | #x114E | #x1150 | [#x1154-#x1155] | #x1159 | [#x115F-#x1161] | #x1163 | #x1165 | #x1167 | #x1169 | [#x116D-#x116E] | [#x1172-#x1173] | #x1175 | #x119E | #x11A8 | #x11AB | [#x11AE-#x11AF] | [#x11B7-#x11B8] | #x11BA | [#x11BC-#x11C2] | #x11EB | #x11F0 | #x11F9 | [#x1E00-#x1E9B] | [#x1EA0-#x1EF9] | [#x1F00-#x1F15] | [#x1F18-#x1F1D] | [#x1F20-#x1F45] | [#x1F48-#x1F4D] | [#x1F50-#x1F57] | #x1F59 | #x1F5B | #x1F5D | [#x1F5F-#x1F7D] | [#x1F80-#x1FB4] | [#x1FB6-#x1FBC] | #x1FBE | [#x1FC2-#x1FC4] | [#x1FC6-#x1FCC] | [#x1FD0-#x1FD3] | [#x1FD6-#x1FDB] | [#x1FE0-#x1FEC] | [#x1FF2-#x1FF4] | [#x1FF6-#x1FFC] | #x2126 | [#x212A-#x212B] | #x212E | [#x2180-#x2182] | [#x3041-#x3094] | [#x30A1-#x30FA] | [#x3105-#x312C] | [#xAC00-#xD7A3]""" ideographic = """[#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]""" combiningCharacter = """ [#x0300-#x0345] | [#x0360-#x0361] | [#x0483-#x0486] | [#x0591-#x05A1] | [#x05A3-#x05B9] | [#x05BB-#x05BD] | #x05BF | [#x05C1-#x05C2] | #x05C4 | [#x064B-#x0652] | #x0670 | [#x06D6-#x06DC] | [#x06DD-#x06DF] | [#x06E0-#x06E4] | [#x06E7-#x06E8] | [#x06EA-#x06ED] | [#x0901-#x0903] | #x093C | [#x093E-#x094C] | #x094D | [#x0951-#x0954] | [#x0962-#x0963] | [#x0981-#x0983] | #x09BC | #x09BE | #x09BF | [#x09C0-#x09C4] | [#x09C7-#x09C8] | [#x09CB-#x09CD] | #x09D7 | [#x09E2-#x09E3] | #x0A02 | #x0A3C | #x0A3E | #x0A3F | [#x0A40-#x0A42] | [#x0A47-#x0A48] | [#x0A4B-#x0A4D] | [#x0A70-#x0A71] | [#x0A81-#x0A83] | #x0ABC | [#x0ABE-#x0AC5] | [#x0AC7-#x0AC9] | [#x0ACB-#x0ACD] | [#x0B01-#x0B03] | #x0B3C | [#x0B3E-#x0B43] | [#x0B47-#x0B48] | [#x0B4B-#x0B4D] | [#x0B56-#x0B57] | [#x0B82-#x0B83] | [#x0BBE-#x0BC2] | [#x0BC6-#x0BC8] | [#x0BCA-#x0BCD] | #x0BD7 | [#x0C01-#x0C03] | [#x0C3E-#x0C44] | [#x0C46-#x0C48] | [#x0C4A-#x0C4D] | [#x0C55-#x0C56] | [#x0C82-#x0C83] | [#x0CBE-#x0CC4] | [#x0CC6-#x0CC8] | [#x0CCA-#x0CCD] | [#x0CD5-#x0CD6] | [#x0D02-#x0D03] | [#x0D3E-#x0D43] | [#x0D46-#x0D48] | [#x0D4A-#x0D4D] | #x0D57 | #x0E31 | [#x0E34-#x0E3A] | [#x0E47-#x0E4E] | #x0EB1 | [#x0EB4-#x0EB9] | [#x0EBB-#x0EBC] | [#x0EC8-#x0ECD] | [#x0F18-#x0F19] | #x0F35 | #x0F37 | #x0F39 | #x0F3E | #x0F3F | [#x0F71-#x0F84] | [#x0F86-#x0F8B] | [#x0F90-#x0F95] | #x0F97 | [#x0F99-#x0FAD] | [#x0FB1-#x0FB7] | #x0FB9 | [#x20D0-#x20DC] | #x20E1 | [#x302A-#x302F] | #x3099 | #x309A""" digit = """ [#x0030-#x0039] | [#x0660-#x0669] | [#x06F0-#x06F9] | [#x0966-#x096F] | [#x09E6-#x09EF] | [#x0A66-#x0A6F] | [#x0AE6-#x0AEF] | [#x0B66-#x0B6F] | [#x0BE7-#x0BEF] | [#x0C66-#x0C6F] | [#x0CE6-#x0CEF] | [#x0D66-#x0D6F] | [#x0E50-#x0E59] | [#x0ED0-#x0ED9] | [#x0F20-#x0F29]""" extender = """ #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 | #x0E46 | #x0EC6 | #x3005 | #[#x3031-#x3035] | [#x309D-#x309E] | [#x30FC-#x30FE]""" letter = " | ".join([baseChar, ideographic]) # Without the name = " | ".join([letter, digit, ".", "-", "_", combiningCharacter, extender]) nameFirst = " | ".join([letter, "_"]) reChar = re.compile(r"#x([\d|A-F]{4,4})") reCharRange = re.compile(r"\[#x([\d|A-F]{4,4})-#x([\d|A-F]{4,4})\]") def charStringToList(chars): charRanges = [item.strip() for item in chars.split(" | ")] rv = [] for item in charRanges: foundMatch = False for regexp in (reChar, reCharRange): match = regexp.match(item) if match is not None: rv.append([hexToInt(item) for item in match.groups()]) if len(rv[-1]) == 1: rv[-1] = rv[-1] * 2 foundMatch = True break if not foundMatch: assert len(item) == 1 rv.append([ord(item)] * 2) rv = normaliseCharList(rv) return rv def normaliseCharList(charList): charList = sorted(charList) for item in charList: assert item[1] >= item[0] rv = [] i = 0 while i < len(charList): j = 1 rv.append(charList[i]) while i + j < len(charList) and charList[i + j][0] <= rv[-1][1] + 1: rv[-1][1] = charList[i + j][1] j += 1 i += j return rv # We don't really support characters above the BMP :( max_unicode = int("FFFF", 16) def missingRanges(charList): rv = [] if charList[0] != 0: rv.append([0, charList[0][0] - 1]) for i, item in enumerate(charList[:-1]): rv.append([item[1] + 1, charList[i + 1][0] - 1]) if charList[-1][1] != max_unicode: rv.append([charList[-1][1] + 1, max_unicode]) return rv def listToRegexpStr(charList): rv = [] for item in charList: if item[0] == item[1]: rv.append(escapeRegexp(chr(item[0]))) else: rv.append(escapeRegexp(chr(item[0])) + "-" + escapeRegexp(chr(item[1]))) return "[%s]" % "".join(rv) def hexToInt(hex_str): return int(hex_str, 16) def escapeRegexp(string): specialCharacters = (".", "^", "$", "*", "+", "?", "{", "}", "[", "]", "|", "(", ")", "-") for char in specialCharacters: string = string.replace(char, "\\" + char) return string # output from the above nonXmlNameBMPRegexp = re.compile('[\x00-,/:-@\\[-\\^`\\{-\xb6\xb8-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u02cf\u02d2-\u02ff\u0346-\u035f\u0362-\u0385\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482\u0487-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u0590\u05a2\u05ba\u05be\u05c0\u05c3\u05c5-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u063f\u0653-\u065f\u066a-\u066f\u06b8-\u06b9\u06bf\u06cf\u06d4\u06e9\u06ee-\u06ef\u06fa-\u0900\u0904\u093a-\u093b\u094e-\u0950\u0955-\u0957\u0964-\u0965\u0970-\u0980\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09bb\u09bd\u09c5-\u09c6\u09c9-\u09ca\u09ce-\u09d6\u09d8-\u09db\u09de\u09e4-\u09e5\u09f2-\u0a01\u0a03-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a3b\u0a3d\u0a43-\u0a46\u0a49-\u0a4a\u0a4e-\u0a58\u0a5d\u0a5f-\u0a65\u0a75-\u0a80\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abb\u0ac6\u0aca\u0ace-\u0adf\u0ae1-\u0ae5\u0af0-\u0b00\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3b\u0b44-\u0b46\u0b49-\u0b4a\u0b4e-\u0b55\u0b58-\u0b5b\u0b5e\u0b62-\u0b65\u0b70-\u0b81\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0bbd\u0bc3-\u0bc5\u0bc9\u0bce-\u0bd6\u0bd8-\u0be6\u0bf0-\u0c00\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c3d\u0c45\u0c49\u0c4e-\u0c54\u0c57-\u0c5f\u0c62-\u0c65\u0c70-\u0c81\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cbd\u0cc5\u0cc9\u0cce-\u0cd4\u0cd7-\u0cdd\u0cdf\u0ce2-\u0ce5\u0cf0-\u0d01\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d3d\u0d44-\u0d45\u0d49\u0d4e-\u0d56\u0d58-\u0d5f\u0d62-\u0d65\u0d70-\u0e00\u0e2f\u0e3b-\u0e3f\u0e4f\u0e5a-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eba\u0ebe-\u0ebf\u0ec5\u0ec7\u0ece-\u0ecf\u0eda-\u0f17\u0f1a-\u0f1f\u0f2a-\u0f34\u0f36\u0f38\u0f3a-\u0f3d\u0f48\u0f6a-\u0f70\u0f85\u0f8c-\u0f8f\u0f96\u0f98\u0fae-\u0fb0\u0fb8\u0fba-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u20cf\u20dd-\u20e0\u20e2-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3004\u3006\u3008-\u3020\u3030\u3036-\u3040\u3095-\u3098\u309b-\u309c\u309f-\u30a0\u30fb\u30ff-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa nonXmlNameFirstBMPRegexp = re.compile('[\x00-@\\[-\\^`\\{-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u0385\u0387\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u0640\u064b-\u0670\u06b8-\u06b9\u06bf\u06cf\u06d4\u06d6-\u06e4\u06e7-\u0904\u093a-\u093c\u093e-\u0957\u0962-\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09db\u09de\u09e2-\u09ef\u09f2-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a58\u0a5d\u0a5f-\u0a71\u0a75-\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abc\u0abe-\u0adf\u0ae1-\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3c\u0b3e-\u0b5b\u0b5e\u0b62-\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c5f\u0c62-\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cdd\u0cdf\u0ce2-\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d5f\u0d62-\u0e00\u0e2f\u0e31\u0e34-\u0e3f\u0e46-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eb1\u0eb4-\u0ebc\u0ebe-\u0ebf\u0ec5-\u0f3f\u0f48\u0f6a-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3006\u3008-\u3020\u302a-\u3040\u3095-\u30a0\u30fb-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa # Simpler things nonPubidCharRegexp = re.compile("[^\x20\x0D\x0Aa-zA-Z0-9\\-'()+,./:=?;!*#@$_%]") class InfosetFilter(object): replacementRegexp = re.compile(r"U[\dA-F]{5,5}") def __init__(self, dropXmlnsLocalName=False, dropXmlnsAttrNs=False, preventDoubleDashComments=False, preventDashAtCommentEnd=False, replaceFormFeedCharacters=True, preventSingleQuotePubid=False): self.dropXmlnsLocalName = dropXmlnsLocalName self.dropXmlnsAttrNs = dropXmlnsAttrNs self.preventDoubleDashComments = preventDoubleDashComments self.preventDashAtCommentEnd = preventDashAtCommentEnd self.replaceFormFeedCharacters = replaceFormFeedCharacters self.preventSingleQuotePubid = preventSingleQuotePubid self.replaceCache = {} def coerceAttribute(self, name, namespace=None): if self.dropXmlnsLocalName and name.startswith("xmlns:"): warnings.warn("Attributes cannot begin with xmlns", DataLossWarning) return None elif (self.dropXmlnsAttrNs and namespace == "http://www.w3.org/2000/xmlns/"): warnings.warn("Attributes cannot be in the xml namespace", DataLossWarning) return None else: return self.toXmlName(name) def coerceElement(self, name): return self.toXmlName(name) def coerceComment(self, data): if self.preventDoubleDashComments: while "--" in data: warnings.warn("Comments cannot contain adjacent dashes", DataLossWarning) data = data.replace("--", "- -") if data.endswith("-"): warnings.warn("Comments cannot end in a dash", DataLossWarning) data += " " return data def coerceCharacters(self, data): if self.replaceFormFeedCharacters: for _ in range(data.count("\x0C")): warnings.warn("Text cannot contain U+000C", DataLossWarning) data = data.replace("\x0C", " ") # Other non-xml characters return data def coercePubid(self, data): dataOutput = data for char in nonPubidCharRegexp.findall(data): warnings.warn("Coercing non-XML pubid", DataLossWarning) replacement = self.getReplacementCharacter(char) dataOutput = dataOutput.replace(char, replacement) if self.preventSingleQuotePubid and dataOutput.find("'") >= 0: warnings.warn("Pubid cannot contain single quote", DataLossWarning) dataOutput = dataOutput.replace("'", self.getReplacementCharacter("'")) return dataOutput def toXmlName(self, name): nameFirst = name[0] nameRest = name[1:] m = nonXmlNameFirstBMPRegexp.match(nameFirst) if m: warnings.warn("Coercing non-XML name: %s" % name, DataLossWarning) nameFirstOutput = self.getReplacementCharacter(nameFirst) else: nameFirstOutput = nameFirst nameRestOutput = nameRest replaceChars = set(nonXmlNameBMPRegexp.findall(nameRest)) for char in replaceChars: warnings.warn("Coercing non-XML name: %s" % name, DataLossWarning) replacement = self.getReplacementCharacter(char) nameRestOutput = nameRestOutput.replace(char, replacement) return nameFirstOutput + nameRestOutput def getReplacementCharacter(self, char): if char in self.replaceCache: replacement = self.replaceCache[char] else: replacement = self.escapeChar(char) return replacement def fromXmlName(self, name): for item in set(self.replacementRegexp.findall(name)): name = name.replace(item, self.unescapeChar(item)) return name def escapeChar(self, char): replacement = "U%05X" % ord(char) self.replaceCache[char] = replacement return replacement def unescapeChar(self, charcode): return chr(int(charcode[1:], 16)) PKH]6=a~a~=python3.10/site-packages/pip/_vendor/html5lib/_inputstream.pynu[from __future__ import absolute_import, division, unicode_literals from pip._vendor.six import text_type from pip._vendor.six.moves import http_client, urllib import codecs import re from io import BytesIO, StringIO from pip._vendor import webencodings from .constants import EOF, spaceCharacters, asciiLetters, asciiUppercase from .constants import _ReparseException from . import _utils # Non-unicode versions of constants for use in the pre-parser spaceCharactersBytes = frozenset([item.encode("ascii") for item in spaceCharacters]) asciiLettersBytes = frozenset([item.encode("ascii") for item in asciiLetters]) asciiUppercaseBytes = frozenset([item.encode("ascii") for item in asciiUppercase]) spacesAngleBrackets = spaceCharactersBytes | frozenset([b">", b"<"]) invalid_unicode_no_surrogate = "[\u0001-\u0008\u000B\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF\uFFFE\uFFFF\U0001FFFE\U0001FFFF\U0002FFFE\U0002FFFF\U0003FFFE\U0003FFFF\U0004FFFE\U0004FFFF\U0005FFFE\U0005FFFF\U0006FFFE\U0006FFFF\U0007FFFE\U0007FFFF\U0008FFFE\U0008FFFF\U0009FFFE\U0009FFFF\U000AFFFE\U000AFFFF\U000BFFFE\U000BFFFF\U000CFFFE\U000CFFFF\U000DFFFE\U000DFFFF\U000EFFFE\U000EFFFF\U000FFFFE\U000FFFFF\U0010FFFE\U0010FFFF]" # noqa if _utils.supports_lone_surrogates: # Use one extra step of indirection and create surrogates with # eval. Not using this indirection would introduce an illegal # unicode literal on platforms not supporting such lone # surrogates. assert invalid_unicode_no_surrogate[-1] == "]" and invalid_unicode_no_surrogate.count("]") == 1 invalid_unicode_re = re.compile(invalid_unicode_no_surrogate[:-1] + eval('"\\uD800-\\uDFFF"') + # pylint:disable=eval-used "]") else: invalid_unicode_re = re.compile(invalid_unicode_no_surrogate) non_bmp_invalid_codepoints = {0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, 0x10FFFE, 0x10FFFF} ascii_punctuation_re = re.compile("[\u0009-\u000D\u0020-\u002F\u003A-\u0040\u005C\u005B-\u0060\u007B-\u007E]") # Cache for charsUntil() charsUntilRegEx = {} class BufferedStream(object): """Buffering for streams that do not have buffering of their own The buffer is implemented as a list of chunks on the assumption that joining many strings will be slow since it is O(n**2) """ def __init__(self, stream): self.stream = stream self.buffer = [] self.position = [-1, 0] # chunk number, offset def tell(self): pos = 0 for chunk in self.buffer[:self.position[0]]: pos += len(chunk) pos += self.position[1] return pos def seek(self, pos): assert pos <= self._bufferedBytes() offset = pos i = 0 while len(self.buffer[i]) < offset: offset -= len(self.buffer[i]) i += 1 self.position = [i, offset] def read(self, bytes): if not self.buffer: return self._readStream(bytes) elif (self.position[0] == len(self.buffer) and self.position[1] == len(self.buffer[-1])): return self._readStream(bytes) else: return self._readFromBuffer(bytes) def _bufferedBytes(self): return sum([len(item) for item in self.buffer]) def _readStream(self, bytes): data = self.stream.read(bytes) self.buffer.append(data) self.position[0] += 1 self.position[1] = len(data) return data def _readFromBuffer(self, bytes): remainingBytes = bytes rv = [] bufferIndex = self.position[0] bufferOffset = self.position[1] while bufferIndex < len(self.buffer) and remainingBytes != 0: assert remainingBytes > 0 bufferedData = self.buffer[bufferIndex] if remainingBytes <= len(bufferedData) - bufferOffset: bytesToRead = remainingBytes self.position = [bufferIndex, bufferOffset + bytesToRead] else: bytesToRead = len(bufferedData) - bufferOffset self.position = [bufferIndex, len(bufferedData)] bufferIndex += 1 rv.append(bufferedData[bufferOffset:bufferOffset + bytesToRead]) remainingBytes -= bytesToRead bufferOffset = 0 if remainingBytes: rv.append(self._readStream(remainingBytes)) return b"".join(rv) def HTMLInputStream(source, **kwargs): # Work around Python bug #20007: read(0) closes the connection. # http://bugs.python.org/issue20007 if (isinstance(source, http_client.HTTPResponse) or # Also check for addinfourl wrapping HTTPResponse (isinstance(source, urllib.response.addbase) and isinstance(source.fp, http_client.HTTPResponse))): isUnicode = False elif hasattr(source, "read"): isUnicode = isinstance(source.read(0), text_type) else: isUnicode = isinstance(source, text_type) if isUnicode: encodings = [x for x in kwargs if x.endswith("_encoding")] if encodings: raise TypeError("Cannot set an encoding with a unicode input, set %r" % encodings) return HTMLUnicodeInputStream(source, **kwargs) else: return HTMLBinaryInputStream(source, **kwargs) class HTMLUnicodeInputStream(object): """Provides a unicode stream of characters to the HTMLTokenizer. This class takes care of character encoding and removing or replacing incorrect byte-sequences and also provides column and line tracking. """ _defaultChunkSize = 10240 def __init__(self, source): """Initialises the HTMLInputStream. HTMLInputStream(source, [encoding]) -> Normalized stream from source for use by html5lib. source can be either a file-object, local filename or a string. The optional encoding parameter must be a string that indicates the encoding. If specified, that encoding will be used, regardless of any BOM or later declaration (such as in a meta element) """ if not _utils.supports_lone_surrogates: # Such platforms will have already checked for such # surrogate errors, so no need to do this checking. self.reportCharacterErrors = None elif len("\U0010FFFF") == 1: self.reportCharacterErrors = self.characterErrorsUCS4 else: self.reportCharacterErrors = self.characterErrorsUCS2 # List of where new lines occur self.newLines = [0] self.charEncoding = (lookupEncoding("utf-8"), "certain") self.dataStream = self.openStream(source) self.reset() def reset(self): self.chunk = "" self.chunkSize = 0 self.chunkOffset = 0 self.errors = [] # number of (complete) lines in previous chunks self.prevNumLines = 0 # number of columns in the last line of the previous chunk self.prevNumCols = 0 # Deal with CR LF and surrogates split over chunk boundaries self._bufferedCharacter = None def openStream(self, source): """Produces a file object from source. source can be either a file object, local filename or a string. """ # Already a file object if hasattr(source, 'read'): stream = source else: stream = StringIO(source) return stream def _position(self, offset): chunk = self.chunk nLines = chunk.count('\n', 0, offset) positionLine = self.prevNumLines + nLines lastLinePos = chunk.rfind('\n', 0, offset) if lastLinePos == -1: positionColumn = self.prevNumCols + offset else: positionColumn = offset - (lastLinePos + 1) return (positionLine, positionColumn) def position(self): """Returns (line, col) of the current position in the stream.""" line, col = self._position(self.chunkOffset) return (line + 1, col) def char(self): """ Read one character from the stream or queue if available. Return EOF when EOF is reached. """ # Read a new chunk from the input stream if necessary if self.chunkOffset >= self.chunkSize: if not self.readChunk(): return EOF chunkOffset = self.chunkOffset char = self.chunk[chunkOffset] self.chunkOffset = chunkOffset + 1 return char def readChunk(self, chunkSize=None): if chunkSize is None: chunkSize = self._defaultChunkSize self.prevNumLines, self.prevNumCols = self._position(self.chunkSize) self.chunk = "" self.chunkSize = 0 self.chunkOffset = 0 data = self.dataStream.read(chunkSize) # Deal with CR LF and surrogates broken across chunks if self._bufferedCharacter: data = self._bufferedCharacter + data self._bufferedCharacter = None elif not data: # We have no more data, bye-bye stream return False if len(data) > 1: lastv = ord(data[-1]) if lastv == 0x0D or 0xD800 <= lastv <= 0xDBFF: self._bufferedCharacter = data[-1] data = data[:-1] if self.reportCharacterErrors: self.reportCharacterErrors(data) # Replace invalid characters data = data.replace("\r\n", "\n") data = data.replace("\r", "\n") self.chunk = data self.chunkSize = len(data) return True def characterErrorsUCS4(self, data): for _ in range(len(invalid_unicode_re.findall(data))): self.errors.append("invalid-codepoint") def characterErrorsUCS2(self, data): # Someone picked the wrong compile option # You lose skip = False for match in invalid_unicode_re.finditer(data): if skip: continue codepoint = ord(match.group()) pos = match.start() # Pretty sure there should be endianness issues here if _utils.isSurrogatePair(data[pos:pos + 2]): # We have a surrogate pair! char_val = _utils.surrogatePairToCodepoint(data[pos:pos + 2]) if char_val in non_bmp_invalid_codepoints: self.errors.append("invalid-codepoint") skip = True elif (codepoint >= 0xD800 and codepoint <= 0xDFFF and pos == len(data) - 1): self.errors.append("invalid-codepoint") else: skip = False self.errors.append("invalid-codepoint") def charsUntil(self, characters, opposite=False): """ Returns a string of characters from the stream up to but not including any character in 'characters' or EOF. 'characters' must be a container that supports the 'in' method and iteration over its characters. """ # Use a cache of regexps to find the required characters try: chars = charsUntilRegEx[(characters, opposite)] except KeyError: if __debug__: for c in characters: assert(ord(c) < 128) regex = "".join(["\\x%02x" % ord(c) for c in characters]) if not opposite: regex = "^%s" % regex chars = charsUntilRegEx[(characters, opposite)] = re.compile("[%s]+" % regex) rv = [] while True: # Find the longest matching prefix m = chars.match(self.chunk, self.chunkOffset) if m is None: # If nothing matched, and it wasn't because we ran out of chunk, # then stop if self.chunkOffset != self.chunkSize: break else: end = m.end() # If not the whole chunk matched, return everything # up to the part that didn't match if end != self.chunkSize: rv.append(self.chunk[self.chunkOffset:end]) self.chunkOffset = end break # If the whole remainder of the chunk matched, # use it all and read the next chunk rv.append(self.chunk[self.chunkOffset:]) if not self.readChunk(): # Reached EOF break r = "".join(rv) return r def unget(self, char): # Only one character is allowed to be ungotten at once - it must # be consumed again before any further call to unget if char is not EOF: if self.chunkOffset == 0: # unget is called quite rarely, so it's a good idea to do # more work here if it saves a bit of work in the frequently # called char and charsUntil. # So, just prepend the ungotten character onto the current # chunk: self.chunk = char + self.chunk self.chunkSize += 1 else: self.chunkOffset -= 1 assert self.chunk[self.chunkOffset] == char class HTMLBinaryInputStream(HTMLUnicodeInputStream): """Provides a unicode stream of characters to the HTMLTokenizer. This class takes care of character encoding and removing or replacing incorrect byte-sequences and also provides column and line tracking. """ def __init__(self, source, override_encoding=None, transport_encoding=None, same_origin_parent_encoding=None, likely_encoding=None, default_encoding="windows-1252", useChardet=True): """Initialises the HTMLInputStream. HTMLInputStream(source, [encoding]) -> Normalized stream from source for use by html5lib. source can be either a file-object, local filename or a string. The optional encoding parameter must be a string that indicates the encoding. If specified, that encoding will be used, regardless of any BOM or later declaration (such as in a meta element) """ # Raw Stream - for unicode objects this will encode to utf-8 and set # self.charEncoding as appropriate self.rawStream = self.openStream(source) HTMLUnicodeInputStream.__init__(self, self.rawStream) # Encoding Information # Number of bytes to use when looking for a meta element with # encoding information self.numBytesMeta = 1024 # Number of bytes to use when using detecting encoding using chardet self.numBytesChardet = 100 # Things from args self.override_encoding = override_encoding self.transport_encoding = transport_encoding self.same_origin_parent_encoding = same_origin_parent_encoding self.likely_encoding = likely_encoding self.default_encoding = default_encoding # Determine encoding self.charEncoding = self.determineEncoding(useChardet) assert self.charEncoding[0] is not None # Call superclass self.reset() def reset(self): self.dataStream = self.charEncoding[0].codec_info.streamreader(self.rawStream, 'replace') HTMLUnicodeInputStream.reset(self) def openStream(self, source): """Produces a file object from source. source can be either a file object, local filename or a string. """ # Already a file object if hasattr(source, 'read'): stream = source else: stream = BytesIO(source) try: stream.seek(stream.tell()) except Exception: stream = BufferedStream(stream) return stream def determineEncoding(self, chardet=True): # BOMs take precedence over everything # This will also read past the BOM if present charEncoding = self.detectBOM(), "certain" if charEncoding[0] is not None: return charEncoding # If we've been overridden, we've been overridden charEncoding = lookupEncoding(self.override_encoding), "certain" if charEncoding[0] is not None: return charEncoding # Now check the transport layer charEncoding = lookupEncoding(self.transport_encoding), "certain" if charEncoding[0] is not None: return charEncoding # Look for meta elements with encoding information charEncoding = self.detectEncodingMeta(), "tentative" if charEncoding[0] is not None: return charEncoding # Parent document encoding charEncoding = lookupEncoding(self.same_origin_parent_encoding), "tentative" if charEncoding[0] is not None and not charEncoding[0].name.startswith("utf-16"): return charEncoding # "likely" encoding charEncoding = lookupEncoding(self.likely_encoding), "tentative" if charEncoding[0] is not None: return charEncoding # Guess with chardet, if available if chardet: try: from pip._vendor.chardet.universaldetector import UniversalDetector except ImportError: pass else: buffers = [] detector = UniversalDetector() while not detector.done: buffer = self.rawStream.read(self.numBytesChardet) assert isinstance(buffer, bytes) if not buffer: break buffers.append(buffer) detector.feed(buffer) detector.close() encoding = lookupEncoding(detector.result['encoding']) self.rawStream.seek(0) if encoding is not None: return encoding, "tentative" # Try the default encoding charEncoding = lookupEncoding(self.default_encoding), "tentative" if charEncoding[0] is not None: return charEncoding # Fallback to html5lib's default if even that hasn't worked return lookupEncoding("windows-1252"), "tentative" def changeEncoding(self, newEncoding): assert self.charEncoding[1] != "certain" newEncoding = lookupEncoding(newEncoding) if newEncoding is None: return if newEncoding.name in ("utf-16be", "utf-16le"): newEncoding = lookupEncoding("utf-8") assert newEncoding is not None elif newEncoding == self.charEncoding[0]: self.charEncoding = (self.charEncoding[0], "certain") else: self.rawStream.seek(0) self.charEncoding = (newEncoding, "certain") self.reset() raise _ReparseException("Encoding changed from %s to %s" % (self.charEncoding[0], newEncoding)) def detectBOM(self): """Attempts to detect at BOM at the start of the stream. If an encoding can be determined from the BOM return the name of the encoding otherwise return None""" bomDict = { codecs.BOM_UTF8: 'utf-8', codecs.BOM_UTF16_LE: 'utf-16le', codecs.BOM_UTF16_BE: 'utf-16be', codecs.BOM_UTF32_LE: 'utf-32le', codecs.BOM_UTF32_BE: 'utf-32be' } # Go to beginning of file and read in 4 bytes string = self.rawStream.read(4) assert isinstance(string, bytes) # Try detecting the BOM using bytes from the string encoding = bomDict.get(string[:3]) # UTF-8 seek = 3 if not encoding: # Need to detect UTF-32 before UTF-16 encoding = bomDict.get(string) # UTF-32 seek = 4 if not encoding: encoding = bomDict.get(string[:2]) # UTF-16 seek = 2 # Set the read position past the BOM if one was found, otherwise # set it to the start of the stream if encoding: self.rawStream.seek(seek) return lookupEncoding(encoding) else: self.rawStream.seek(0) return None def detectEncodingMeta(self): """Report the encoding declared by the meta element """ buffer = self.rawStream.read(self.numBytesMeta) assert isinstance(buffer, bytes) parser = EncodingParser(buffer) self.rawStream.seek(0) encoding = parser.getEncoding() if encoding is not None and encoding.name in ("utf-16be", "utf-16le"): encoding = lookupEncoding("utf-8") return encoding class EncodingBytes(bytes): """String-like object with an associated position and various extra methods If the position is ever greater than the string length then an exception is raised""" def __new__(self, value): assert isinstance(value, bytes) return bytes.__new__(self, value.lower()) def __init__(self, value): # pylint:disable=unused-argument self._position = -1 def __iter__(self): return self def __next__(self): p = self._position = self._position + 1 if p >= len(self): raise StopIteration elif p < 0: raise TypeError return self[p:p + 1] def next(self): # Py2 compat return self.__next__() def previous(self): p = self._position if p >= len(self): raise StopIteration elif p < 0: raise TypeError self._position = p = p - 1 return self[p:p + 1] def setPosition(self, position): if self._position >= len(self): raise StopIteration self._position = position def getPosition(self): if self._position >= len(self): raise StopIteration if self._position >= 0: return self._position else: return None position = property(getPosition, setPosition) def getCurrentByte(self): return self[self.position:self.position + 1] currentByte = property(getCurrentByte) def skip(self, chars=spaceCharactersBytes): """Skip past a list of characters""" p = self.position # use property for the error-checking while p < len(self): c = self[p:p + 1] if c not in chars: self._position = p return c p += 1 self._position = p return None def skipUntil(self, chars): p = self.position while p < len(self): c = self[p:p + 1] if c in chars: self._position = p return c p += 1 self._position = p return None def matchBytes(self, bytes): """Look for a sequence of bytes at the start of a string. If the bytes are found return True and advance the position to the byte after the match. Otherwise return False and leave the position alone""" rv = self.startswith(bytes, self.position) if rv: self.position += len(bytes) return rv def jumpTo(self, bytes): """Look for the next sequence of bytes matching a given sequence. If a match is found advance the position to the last byte of the match""" try: self._position = self.index(bytes, self.position) + len(bytes) - 1 except ValueError: raise StopIteration return True class EncodingParser(object): """Mini parser for detecting character encoding from meta elements""" def __init__(self, data): """string - the data to work on for encoding detection""" self.data = EncodingBytes(data) self.encoding = None def getEncoding(self): if b"") def handleMeta(self): if self.data.currentByte not in spaceCharactersBytes: # if we have ") def getAttribute(self): """Return a name,value pair for the next attribute in the stream, if one is found, or None""" data = self.data # Step 1 (skip chars) c = data.skip(spaceCharactersBytes | frozenset([b"/"])) assert c is None or len(c) == 1 # Step 2 if c in (b">", None): return None # Step 3 attrName = [] attrValue = [] # Step 4 attribute name while True: if c == b"=" and attrName: break elif c in spaceCharactersBytes: # Step 6! c = data.skip() break elif c in (b"/", b">"): return b"".join(attrName), b"" elif c in asciiUppercaseBytes: attrName.append(c.lower()) elif c is None: return None else: attrName.append(c) # Step 5 c = next(data) # Step 7 if c != b"=": data.previous() return b"".join(attrName), b"" # Step 8 next(data) # Step 9 c = data.skip() # Step 10 if c in (b"'", b'"'): # 10.1 quoteChar = c while True: # 10.2 c = next(data) # 10.3 if c == quoteChar: next(data) return b"".join(attrName), b"".join(attrValue) # 10.4 elif c in asciiUppercaseBytes: attrValue.append(c.lower()) # 10.5 else: attrValue.append(c) elif c == b">": return b"".join(attrName), b"" elif c in asciiUppercaseBytes: attrValue.append(c.lower()) elif c is None: return None else: attrValue.append(c) # Step 11 while True: c = next(data) if c in spacesAngleBrackets: return b"".join(attrName), b"".join(attrValue) elif c in asciiUppercaseBytes: attrValue.append(c.lower()) elif c is None: return None else: attrValue.append(c) class ContentAttrParser(object): def __init__(self, data): assert isinstance(data, bytes) self.data = data def parse(self): try: # Check if the attr name is charset # otherwise return self.data.jumpTo(b"charset") self.data.position += 1 self.data.skip() if not self.data.currentByte == b"=": # If there is no = sign keep looking for attrs return None self.data.position += 1 self.data.skip() # Look for an encoding between matching quote marks if self.data.currentByte in (b'"', b"'"): quoteMark = self.data.currentByte self.data.position += 1 oldPosition = self.data.position if self.data.jumpTo(quoteMark): return self.data[oldPosition:self.data.position] else: return None else: # Unquoted value oldPosition = self.data.position try: self.data.skipUntil(spaceCharactersBytes) return self.data[oldPosition:self.data.position] except StopIteration: # Return the whole remaining value return self.data[oldPosition:] except StopIteration: return None def lookupEncoding(encoding): """Return the python codec name corresponding to an encoding or None if the string doesn't correspond to a valid encoding.""" if isinstance(encoding, bytes): try: encoding = encoding.decode("ascii") except UnicodeDecodeError: return None if encoding is not None: try: return webencodings.lookup(encoding) except AttributeError: return None else: return None PKH]̦Xpython3.10/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-310.pycnu[o aim@s*ddlmZmZmZddlmZdgZdS))absolute_importdivisionunicode_literals)TrierN) __future__rrrpyr__all__r r /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/__init__.pys  PKH]W ppUpython3.10/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-310.pycnu[o ai@sXddlmZmZmZzddlmZWney!ddlmZYnwGdddeZdS))absolute_importdivisionunicode_literals)Mappingcs:eZdZdZd fdd ZddZddZd d ZZS) TriezAbstract base class for triesNcs0tt|}durt|Sfdd|DS)Ncsh|] }|r|qS) startswith).0xprefixr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/_base.py szTrie.keys..)superrkeysset)selfr r __class__r r r sz Trie.keyscCs"|D] }||rdSqdS)NTF)rr)rr keyrrr has_keys_with_prefixs  zTrie.has_keys_with_prefixcCsP||vr|Stdt|dD]}|d| |vr#|d| Sqt|)N)rangelenKeyError)rr irrr longest_prefixszTrie.longest_prefixcCs||}|||fSN)r)rr lprefixrrr longest_prefix_item&s  zTrie.longest_prefix_itemr) __name__ __module__ __qualname____doc__rrrr __classcell__rrrr r s   rN) __future__rrrcollections.abcr ImportError collectionsrrrrr s PKH]O*  Rpython3.10/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-310.pycnu[o ai@sLddlmZmZmZddlmZddlmZddlm Z Gddde Z dS) )absolute_importdivisionunicode_literals) text_type) bisect_left)Triec@sFeZdZddZddZddZddZd d Zdd d ZddZ d S)rcCsJtdd|Dstd||_t||_d|_dt|f|_dS)Ncss|]}t|tVqdSN) isinstancer).0xr /builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/py.py sz Trie.__init__..zAll keys must be stringsr) allkeys TypeError_datasorted_keys _cachestrlen _cachepoints)selfdatar r r__init__ s z Trie.__init__cCs ||jvSr rrkeyr r r __contains__ zTrie.__contains__cC t|jSr )rrrr r r__len__r!z Trie.__len__cCr"r )iterrr#r r r__iter__r!z Trie.__iter__cCs |j|Sr rrr r r __getitem__r!zTrie.__getitem__NcCs|dus |dks |jst|jS||jr&|j\}}t|j|||}}nt|j|}}t}|t|jkr:|S|j||rV||j||d7}|j||sB||_||f|_|S)Nrr)rset startswithrrrradd)rprefixlohistartirr r rrs     z Trie.keyscCsd||jvrdS||jr|j\}}t|j|||}nt|j|}|t|jkr*dS|j||S)NTF)rr)rrrrr)rr+r,r-r/r r rhas_keys_with_prefix6s    zTrie.has_keys_with_prefixr ) __name__ __module__ __qualname__rr r$r&r'rr0r r r rr s   rN) __future__rrrZpip._vendor.sixrbisectr_baserABCTrier r r rs    PKH]KOn9python3.10/site-packages/pip/_vendor/html5lib/_trie/py.pynu[from __future__ import absolute_import, division, unicode_literals from pip._vendor.six import text_type from bisect import bisect_left from ._base import Trie as ABCTrie class Trie(ABCTrie): def __init__(self, data): if not all(isinstance(x, text_type) for x in data.keys()): raise TypeError("All keys must be strings") self._data = data self._keys = sorted(data.keys()) self._cachestr = "" self._cachepoints = (0, len(data)) def __contains__(self, key): return key in self._data def __len__(self): return len(self._data) def __iter__(self): return iter(self._data) def __getitem__(self, key): return self._data[key] def keys(self, prefix=None): if prefix is None or prefix == "" or not self._keys: return set(self._keys) if prefix.startswith(self._cachestr): lo, hi = self._cachepoints start = i = bisect_left(self._keys, prefix, lo, hi) else: start = i = bisect_left(self._keys, prefix) keys = set() if start == len(self._keys): return keys while self._keys[i].startswith(prefix): keys.add(self._keys[i]) i += 1 self._cachestr = prefix self._cachepoints = (start, i) return keys def has_keys_with_prefix(self, prefix): if prefix in self._data: return True if prefix.startswith(self._cachestr): lo, hi = self._cachepoints i = bisect_left(self._keys, prefix, lo, hi) else: i = bisect_left(self._keys, prefix) if i == len(self._keys): return False return self._keys[i].startswith(prefix) PKH]<python3.10/site-packages/pip/_vendor/html5lib/_trie/_base.pynu[from __future__ import absolute_import, division, unicode_literals try: from collections.abc import Mapping except ImportError: # Python 2.7 from collections import Mapping class Trie(Mapping): """Abstract base class for tries""" def keys(self, prefix=None): # pylint:disable=arguments-differ keys = super(Trie, self).keys() if prefix is None: return set(keys) return {x for x in keys if x.startswith(prefix)} def has_keys_with_prefix(self, prefix): for key in self.keys(): if key.startswith(prefix): return True return False def longest_prefix(self, prefix): if prefix in self: return prefix for i in range(1, len(prefix) + 1): if prefix[:-i] in self: return prefix[:-i] raise KeyError(prefix) def longest_prefix_item(self, prefix): lprefix = self.longest_prefix(prefix) return (lprefix, self[lprefix]) PKH]]Tmm?python3.10/site-packages/pip/_vendor/html5lib/_trie/__init__.pynu[from __future__ import absolute_import, division, unicode_literals from .py import Trie __all__ = ["Trie"] PKH]s==;python3.10/site-packages/pip/_vendor/html5lib/serializer.pynu[from __future__ import absolute_import, division, unicode_literals from pip._vendor.six import text_type import re from codecs import register_error, xmlcharrefreplace_errors from .constants import voidElements, booleanAttributes, spaceCharacters from .constants import rcdataElements, entities, xmlEntities from . import treewalkers, _utils from xml.sax.saxutils import escape _quoteAttributeSpecChars = "".join(spaceCharacters) + "\"'=<>`" _quoteAttributeSpec = re.compile("[" + _quoteAttributeSpecChars + "]") _quoteAttributeLegacy = re.compile("[" + _quoteAttributeSpecChars + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n" "\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15" "\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x20\x2f\x60\xa0\u1680\u180e\u180f\u2000" "\u2001\u2002\u2003\u2004\u2005\u2006\u2007" "\u2008\u2009\u200a\u2028\u2029\u202f\u205f" "\u3000]") _encode_entity_map = {} _is_ucs4 = len("\U0010FFFF") == 1 for k, v in list(entities.items()): # skip multi-character entities if ((_is_ucs4 and len(v) > 1) or (not _is_ucs4 and len(v) > 2)): continue if v != "&": if len(v) == 2: v = _utils.surrogatePairToCodepoint(v) else: v = ord(v) if v not in _encode_entity_map or k.islower(): # prefer < over < and similarly for &, >, etc. _encode_entity_map[v] = k def htmlentityreplace_errors(exc): if isinstance(exc, (UnicodeEncodeError, UnicodeTranslateError)): res = [] codepoints = [] skip = False for i, c in enumerate(exc.object[exc.start:exc.end]): if skip: skip = False continue index = i + exc.start if _utils.isSurrogatePair(exc.object[index:min([exc.end, index + 2])]): codepoint = _utils.surrogatePairToCodepoint(exc.object[index:index + 2]) skip = True else: codepoint = ord(c) codepoints.append(codepoint) for cp in codepoints: e = _encode_entity_map.get(cp) if e: res.append("&") res.append(e) if not e.endswith(";"): res.append(";") else: res.append("&#x%s;" % (hex(cp)[2:])) return ("".join(res), exc.end) else: return xmlcharrefreplace_errors(exc) register_error("htmlentityreplace", htmlentityreplace_errors) def serialize(input, tree="etree", encoding=None, **serializer_opts): """Serializes the input token stream using the specified treewalker :arg input: the token stream to serialize :arg tree: the treewalker to use :arg encoding: the encoding to use :arg serializer_opts: any options to pass to the :py:class:`html5lib.serializer.HTMLSerializer` that gets created :returns: the tree serialized as a string Example: >>> from html5lib.html5parser import parse >>> from html5lib.serializer import serialize >>> token_stream = parse('

Hi!

') >>> serialize(token_stream, omit_optional_tags=False) '

Hi!

' """ # XXX: Should we cache this? walker = treewalkers.getTreeWalker(tree) s = HTMLSerializer(**serializer_opts) return s.render(walker(input), encoding) class HTMLSerializer(object): # attribute quoting options quote_attr_values = "legacy" # be secure by default quote_char = '"' use_best_quote_char = True # tag syntax options omit_optional_tags = True minimize_boolean_attributes = True use_trailing_solidus = False space_before_trailing_solidus = True # escaping options escape_lt_in_attrs = False escape_rcdata = False resolve_entities = True # miscellaneous options alphabetical_attributes = False inject_meta_charset = True strip_whitespace = False sanitize = False options = ("quote_attr_values", "quote_char", "use_best_quote_char", "omit_optional_tags", "minimize_boolean_attributes", "use_trailing_solidus", "space_before_trailing_solidus", "escape_lt_in_attrs", "escape_rcdata", "resolve_entities", "alphabetical_attributes", "inject_meta_charset", "strip_whitespace", "sanitize") def __init__(self, **kwargs): """Initialize HTMLSerializer :arg inject_meta_charset: Whether or not to inject the meta charset. Defaults to ``True``. :arg quote_attr_values: Whether to quote attribute values that don't require quoting per legacy browser behavior (``"legacy"``), when required by the standard (``"spec"``), or always (``"always"``). Defaults to ``"legacy"``. :arg quote_char: Use given quote character for attribute quoting. Defaults to ``"`` which will use double quotes unless attribute value contains a double quote, in which case single quotes are used. :arg escape_lt_in_attrs: Whether or not to escape ``<`` in attribute values. Defaults to ``False``. :arg escape_rcdata: Whether to escape characters that need to be escaped within normal elements within rcdata elements such as style. Defaults to ``False``. :arg resolve_entities: Whether to resolve named character entities that appear in the source tree. The XML predefined entities < > & " ' are unaffected by this setting. Defaults to ``True``. :arg strip_whitespace: Whether to remove semantically meaningless whitespace. (This compresses all whitespace to a single space except within ``pre``.) Defaults to ``False``. :arg minimize_boolean_attributes: Shortens boolean attributes to give just the attribute value, for example:: becomes:: Defaults to ``True``. :arg use_trailing_solidus: Includes a close-tag slash at the end of the start tag of void elements (empty elements whose end tag is forbidden). E.g. ``
``. Defaults to ``False``. :arg space_before_trailing_solidus: Places a space immediately before the closing slash in a tag using a trailing solidus. E.g. ``
``. Requires ``use_trailing_solidus=True``. Defaults to ``True``. :arg sanitize: Strip all unsafe or unknown constructs from output. See :py:class:`html5lib.filters.sanitizer.Filter`. Defaults to ``False``. :arg omit_optional_tags: Omit start/end tags that are optional. Defaults to ``True``. :arg alphabetical_attributes: Reorder attributes to be in alphabetical order. Defaults to ``False``. """ unexpected_args = frozenset(kwargs) - frozenset(self.options) if len(unexpected_args) > 0: raise TypeError("__init__() got an unexpected keyword argument '%s'" % next(iter(unexpected_args))) if 'quote_char' in kwargs: self.use_best_quote_char = False for attr in self.options: setattr(self, attr, kwargs.get(attr, getattr(self, attr))) self.errors = [] self.strict = False def encode(self, string): assert(isinstance(string, text_type)) if self.encoding: return string.encode(self.encoding, "htmlentityreplace") else: return string def encodeStrict(self, string): assert(isinstance(string, text_type)) if self.encoding: return string.encode(self.encoding, "strict") else: return string def serialize(self, treewalker, encoding=None): # pylint:disable=too-many-nested-blocks self.encoding = encoding in_cdata = False self.errors = [] if encoding and self.inject_meta_charset: from .filters.inject_meta_charset import Filter treewalker = Filter(treewalker, encoding) # Alphabetical attributes is here under the assumption that none of # the later filters add or change order of attributes; it needs to be # before the sanitizer so escaped elements come out correctly if self.alphabetical_attributes: from .filters.alphabeticalattributes import Filter treewalker = Filter(treewalker) # WhitespaceFilter should be used before OptionalTagFilter # for maximum efficiently of this latter filter if self.strip_whitespace: from .filters.whitespace import Filter treewalker = Filter(treewalker) if self.sanitize: from .filters.sanitizer import Filter treewalker = Filter(treewalker) if self.omit_optional_tags: from .filters.optionaltags import Filter treewalker = Filter(treewalker) for token in treewalker: type = token["type"] if type == "Doctype": doctype = "= 0: if token["systemId"].find("'") >= 0: self.serializeError("System identifier contains both single and double quote characters") quote_char = "'" else: quote_char = '"' doctype += " %s%s%s" % (quote_char, token["systemId"], quote_char) doctype += ">" yield self.encodeStrict(doctype) elif type in ("Characters", "SpaceCharacters"): if type == "SpaceCharacters" or in_cdata: if in_cdata and token["data"].find("= 0: self.serializeError("Unexpected ") elif type == "EndTag": name = token["name"] if name in rcdataElements: in_cdata = False elif in_cdata: self.serializeError("Unexpected child element of a CDATA element") yield self.encodeStrict("" % name) elif type == "Comment": data = token["data"] if data.find("--") >= 0: self.serializeError("Comment contains --") yield self.encodeStrict("" % token["data"]) elif type == "Entity": name = token["name"] key = name + ";" if key not in entities: self.serializeError("Entity %s not recognized" % name) if self.resolve_entities and key not in xmlEntities: data = entities[key] else: data = "&%s;" % name yield self.encodeStrict(data) else: self.serializeError(token["data"]) def render(self, treewalker, encoding=None): """Serializes the stream from the treewalker into a string :arg treewalker: the treewalker to serialize :arg encoding: the string encoding to use :returns: the serialized tree Example: >>> from html5lib import parse, getTreeWalker >>> from html5lib.serializer import HTMLSerializer >>> token_stream = parse('Hi!') >>> walker = getTreeWalker('etree') >>> serializer = HTMLSerializer(omit_optional_tags=False) >>> serializer.render(walker(token_stream)) 'Hi!' """ if encoding: return b"".join(list(self.serialize(treewalker, encoding))) else: return "".join(list(self.serialize(treewalker))) def serializeError(self, data="XXX ERROR MESSAGE NEEDED"): # XXX The idea is to make data mandatory. self.errors.append(data) if self.strict: raise SerializeError class SerializeError(Exception): """Error in serialized tree""" pass PKH]Z|Zpython3.10/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-310.pycnu[o ai@sdddlmZmZmZddlmZddlmZmZiZ e D] \Z Z Z e dur+e e e <qddZdS))absolute_importdivisionunicode_literals)AttributesNSImpl)adjustForeignAttributesunadjustForeignAttributesNcCs|tD] \}}|||q|D]_}|d}|dkr q|dvrMt|dt}||d|df|d||dkrL||d|df|dq|dkr`||d|df|dq|d vrl||dq|d krqqJd tD] \}}| |qy| d S)zCall SAX-like content handler based on treewalker walker :arg walker: the treewalker to use to walk the tree to convert it :arg handler: SAX handler to use typeDoctype)StartTagEmptyTagdata namespacenamer EndTag) CharactersSpaceCharactersCommentFzUnknown token typeN) startDocumentprefix_mappingitemsstartPrefixMappingrrstartElementNS endElementNS charactersendPrefixMapping endDocument)walkerhandlerprefixrtokenr attrsr"/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/sax.pyto_sax s@  r$) __future__rrrZxml.sax.xmlreaderr constantsrrrvaluesrZ localNamerr$r"r"r"r#s  PKH]u_python3.10/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-310.pycnu[o ai@s^dZddlmZmZmZddlmZdgZzddlmZWn e y'YdSwe ddS) aTree adapters let you convert from one tree structure to another Example: .. code-block:: python from pip._vendor import html5lib from pip._vendor.html5lib.treeadapters import genshi doc = 'Hi!' treebuilder = html5lib.getTreeBuilder('etree') parser = html5lib.HTMLParser(tree=treebuilder) tree = parser.parse(doc) TreeWalker = html5lib.getTreeWalker('etree') genshi_tree = genshi.to_genshi(TreeWalker(tree)) )absolute_importdivisionunicode_literals)saxr)genshirN) __doc__ __future__rrrr__all__r ImportErrorappendrr/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/__init__.pys  PKH]6==]python3.10/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-310.pycnu[o ai@sLddlmZmZmZddlmZmZddlmZmZm Z m Z m Z ddZ dS))absolute_importdivisionunicode_literals)QNameAttrs)STARTENDTEXTCOMMENTDOCTYPEccsTg}|D]}|d}|dvr||dn |r$td|dfVg}|dvrX|dr7d|d|d f}n|d }td d |dD}tt||fdfV|d krXd }|d krx|drkd|d|d f}n|d }tt|dfVq|dkrt|ddfVq|dkrt |d |d|dfdfVq q|rtd|dfVdSdS)zConvert a tree to a genshi tree :arg walker: the treewalker to use to walk the tree to convert it :returns: generator of genshi nodes type) CharactersSpaceCharactersdata)Nr)StartTagEmptyTag namespace{%s}%snamecSs4g|]\}}t|ddurd|n|d|fqS)rNr)r).0attrvaluer/builddir/build/BUILDROOT/alt-python310-pip-21.3.1-5.el8.x86_64/opt/alt/python310/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py s(zto_genshi..rEndTagCommentDoctypepublicIdsystemIdN) appendr joinritemsrrrr r )walkertexttokenr rattrsrrr to_genshisH r*N) __future__rrrZ genshi.corerrrrr r r r*rrrrs PKH]R)Dpython3.10/site-packages/pip/_vendor/html5lib/treeadapters/genshi.pynu[from __future__ import absolute_import, division, unicode_literals from genshi.core import QName, Attrs from genshi.core import START, END, TEXT, COMMENT, DOCTYPE def to_genshi(walker): """Convert a tree to a genshi tree :arg walker: the treewalker to use to walk the tree to convert it :returns: generator of genshi nodes """ text = [] for token in walker: type = token["type"] if type in ("Characters", "SpaceCharacters"): text.append(token["data"]) elif text: yield TEXT, "".join(text), (None, -1, -1) text = [] if type in ("StartTag", "EmptyTag"): if token["namespace"]: name = "{%s}%s" % (token["namespace"], token["name"]) else: name = token["name"] attrs = Attrs([(QName("{%s}%s" % attr if attr[0] is not None else attr[1]), value) for attr, value in token["data"].items()]) yield (START, (QName(name), attrs), (None, -1, -1)) if type == "EmptyTag": type = "EndTag" if type == "EndTag": if token["namespace"]: name = "{%s}%s" % (token["namespace"], token["name"]) else: name = token["name"] yield END, QName(name), (None, -1, -1) elif type == "Comment": yield COMMENT, token["data"], (None, -1, -1) elif type == "Doctype": yield DOCTYPE, (token["name"], token["publicId"], token["systemId"]), (None, -1, -1) else: pass # FIXME: What to do? if text: yield TEXT, "".join(text), (None, -1, -1) PKH]iApython3.10/site-packages/pip/_vendor/html5lib/treeadapters/sax.pynu[from __future__ import absolute_import, division, unicode_literals from xml.sax.xmlreader import AttributesNSImpl from ..constants import adjustForeignAttributes, unadjustForeignAttributes prefix_mapping = {} for prefix, localName, namespace in adjustForeignAttributes.values(): if prefix is not None: prefix_mapping[prefix] = namespace def to_sax(walker, handler): """Call SAX-like content handler based on treewalker walker :arg walker: the treewalker to use to walk the tree to convert it :arg handler: SAX handler to use """ handler.startDocument() for prefix, namespace in prefix_mapping.items(): handler.startPrefixMapping(prefix, namespace) for token in walker: type = token["type"] if type == "Doctype": continue elif type in ("StartTag", "EmptyTag"): attrs = AttributesNSImpl(token["data"], unadjustForeignAttributes) handler.startElementNS((token["namespace"], token["name"]), token["name"], attrs) if type == "EmptyTag": handler.endElementNS((token["namespace"], token["name"]), token["name"]) elif type == "EndTag": handler.endElementNS((token["namespace"], token["name"]), token["name"]) elif type in ("Characters", "SpaceCharacters"): handler.characters(token["data"]) elif type == "Comment": pass else: assert False, "Unknown token type" for prefix, namespace in prefix_mapping.items(): handler.endPrefixMapping(prefix) handler.endDocument() PKH]9qZFpython3.10/site-packages/pip/_vendor/html5lib/treeadapters/__init__.pynu["""Tree adapters let you convert from one tree structure to another Example: .. code-block:: python from pip._vendor import html5lib from pip._vendor.html5lib.treeadapters import genshi doc = 'Hi!' treebuilder = html5lib.getTreeBuilder('etree') parser = html5lib.HTMLParser(tree=treebuilder) tree = parser.parse(doc) TreeWalker = html5lib.getTreeWalker('etree') genshi_tree = genshi.to_genshi(TreeWalker(tree)) """ from __future__ import absolute_import, division, unicode_literals from . import sax __all__ = ["sax"] try: from . import genshi # noqa except ImportError: pass else: __all__.append("genshi") PKH]<python3.10/site-packages/pip/_vendor/html5lib/html5parser.pynu[from __future__ import absolute_import, division, unicode_literals from pip._vendor.six import with_metaclass, viewkeys import types from . import _inputstream from . import _tokenizer from . import treebuilders from .treebuilders.base import Marker from . import _utils from .constants import ( spaceCharacters, asciiUpper2Lower, specialElements, headingElements, cdataElements, rcdataElements, tokenTypes, tagTokenTypes, namespaces, htmlIntegrationPointElements, mathmlTextIntegrationPointElements, adjustForeignAttributes as adjustForeignAttributesMap, adjustMathMLAttributes, adjustSVGAttributes, E, _ReparseException ) def parse(doc, treebuilder="etree", namespaceHTMLElements=True, **kwargs): """Parse an HTML document as a string or file-like object into a tree :arg doc: the document to parse as a string or file-like object :arg treebuilder: the treebuilder to use when parsing :arg namespaceHTMLElements: whether or not to namespace HTML elements :returns: parsed tree Example: >>> from html5lib.html5parser import parse >>> parse('

This is a doc

') """ tb = treebuilders.getTreeBuilder(treebuilder) p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) return p.parse(doc, **kwargs) def parseFragment(doc, container="div", treebuilder="etree", namespaceHTMLElements=True, **kwargs): """Parse an HTML fragment as a string or file-like object into a tree :arg doc: the fragment to parse as a string or file-like object :arg container: the container context to parse the fragment in :arg treebuilder: the treebuilder to use when parsing :arg namespaceHTMLElements: whether or not to namespace HTML elements :returns: parsed tree Example: >>> from html5lib.html5libparser import parseFragment >>> parseFragment('this is a fragment') """ tb = treebuilders.getTreeBuilder(treebuilder) p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) return p.parseFragment(doc, container=container, **kwargs) def method_decorator_metaclass(function): class Decorated(type): def __new__(meta, classname, bases, classDict): for attributeName, attribute in classDict.items(): if isinstance(attribute, types.FunctionType): attribute = function(attribute) classDict[attributeName] = attribute return type.__new__(meta, classname, bases, classDict) return Decorated class HTMLParser(object): """HTML parser Generates a tree structure from a stream of (possibly malformed) HTML. """ def __init__(self, tree=None, strict=False, namespaceHTMLElements=True, debug=False): """ :arg tree: a treebuilder class controlling the type of tree that will be returned. Built in treebuilders can be accessed through html5lib.treebuilders.getTreeBuilder(treeType) :arg strict: raise an exception when a parse error is encountered :arg namespaceHTMLElements: whether or not to namespace HTML elements :arg debug: whether or not to enable debug mode which logs things Example: >>> from html5lib.html5parser import HTMLParser >>> parser = HTMLParser() # generates parser with etree builder >>> parser = HTMLParser('lxml', strict=True) # generates parser with lxml builder which is strict """ # Raise an exception on the first error encountered self.strict = strict if tree is None: tree = treebuilders.getTreeBuilder("etree") self.tree = tree(namespaceHTMLElements) self.errors = [] self.phases = {name: cls(self, self.tree) for name, cls in getPhases(debug).items()} def _parse(self, stream, innerHTML=False, container="div", scripting=False, **kwargs): self.innerHTMLMode = innerHTML self.container = container self.scripting = scripting self.tokenizer = _tokenizer.HTMLTokenizer(stream, parser=self, **kwargs) self.reset() try: self.mainLoop() except _ReparseException: self.reset() self.mainLoop() def reset(self): self.tree.reset() self.firstStartTag = False self.errors = [] self.log = [] # only used with debug mode # "quirks" / "limited quirks" / "no quirks" self.compatMode = "no quirks" if self.innerHTMLMode: self.innerHTML = self.container.lower() if self.innerHTML in cdataElements: self.tokenizer.state = self.tokenizer.rcdataState elif self.innerHTML in rcdataElements: self.tokenizer.state = self.tokenizer.rawtextState elif self.innerHTML == 'plaintext': self.tokenizer.state = self.tokenizer.plaintextState else: # state already is data state # self.tokenizer.state = self.tokenizer.dataState pass self.phase = self.phases["beforeHtml"] self.phase.insertHtmlElement() self.resetInsertionMode() else: self.innerHTML = False # pylint:disable=redefined-variable-type self.phase = self.phases["initial"] self.lastPhase = None self.beforeRCDataPhase = None self.framesetOK = True @property def documentEncoding(self): """Name of the character encoding that was used to decode the input stream, or :obj:`None` if that is not determined yet """ if not hasattr(self, 'tokenizer'): return None return self.tokenizer.stream.charEncoding[0].name def isHTMLIntegrationPoint(self, element): if (element.name == "annotation-xml" and element.namespace == namespaces["mathml"]): return ("encoding" in element.attributes and element.attributes["encoding"].translate( asciiUpper2Lower) in ("text/html", "application/xhtml+xml")) else: return (element.namespace, element.name) in htmlIntegrationPointElements def isMathMLTextIntegrationPoint(self, element): return (element.namespace, element.name) in mathmlTextIntegrationPointElements def mainLoop(self): CharactersToken = tokenTypes["Characters"] SpaceCharactersToken = tokenTypes["SpaceCharacters"] StartTagToken = tokenTypes["StartTag"] EndTagToken = tokenTypes["EndTag"] CommentToken = tokenTypes["Comment"] DoctypeToken = tokenTypes["Doctype"] ParseErrorToken = tokenTypes["ParseError"] for token in self.tokenizer: prev_token = None new_token = token while new_token is not None: prev_token = new_token currentNode = self.tree.openElements[-1] if self.tree.openElements else None currentNodeNamespace = currentNode.namespace if currentNode else None currentNodeName = currentNode.name if currentNode else None type = new_token["type"] if type == ParseErrorToken: self.parseError(new_token["data"], new_token.get("datavars", {})) new_token = None else: if (len(self.tree.openElements) == 0 or currentNodeNamespace == self.tree.defaultNamespace or (self.isMathMLTextIntegrationPoint(currentNode) and ((type == StartTagToken and token["name"] not in frozenset(["mglyph", "malignmark"])) or type in (CharactersToken, SpaceCharactersToken))) or (currentNodeNamespace == namespaces["mathml"] and currentNodeName == "annotation-xml" and type == StartTagToken and token["name"] == "svg") or (self.isHTMLIntegrationPoint(currentNode) and type in (StartTagToken, CharactersToken, SpaceCharactersToken))): phase = self.phase else: phase = self.phases["inForeignContent"] if type == CharactersToken: new_token = phase.processCharacters(new_token) elif type == SpaceCharactersToken: new_token = phase.processSpaceCharacters(new_token) elif type == StartTagToken: new_token = phase.processStartTag(new_token) elif type == EndTagToken: new_token = phase.processEndTag(new_token) elif type == CommentToken: new_token = phase.processComment(new_token) elif type == DoctypeToken: new_token = phase.processDoctype(new_token) if (type == StartTagToken and prev_token["selfClosing"] and not prev_token["selfClosingAcknowledged"]): self.parseError("non-void-element-with-trailing-solidus", {"name": prev_token["name"]}) # When the loop finishes it's EOF reprocess = True phases = [] while reprocess: phases.append(self.phase) reprocess = self.phase.processEOF() if reprocess: assert self.phase not in phases def parse(self, stream, *args, **kwargs): """Parse a HTML document into a well-formed tree :arg stream: a file-like object or string containing the HTML to be parsed The optional encoding parameter must be a string that indicates the encoding. If specified, that encoding will be used, regardless of any BOM or later declaration (such as in a meta element). :arg scripting: treat noscript elements as if JavaScript was turned on :returns: parsed tree Example: >>> from html5lib.html5parser import HTMLParser >>> parser = HTMLParser() >>> parser.parse('

This is a doc

') """ self._parse(stream, False, None, *args, **kwargs) return self.tree.getDocument() def parseFragment(self, stream, *args, **kwargs): """Parse a HTML fragment into a well-formed tree fragment :arg container: name of the element we're setting the innerHTML property if set to None, default to 'div' :arg stream: a file-like object or string containing the HTML to be parsed The optional encoding parameter must be a string that indicates the encoding. If specified, that encoding will be used, regardless of any BOM or later declaration (such as in a meta element) :arg scripting: treat noscript elements as if JavaScript was turned on :returns: parsed tree Example: >>> from html5lib.html5libparser import HTMLParser >>> parser = HTMLParser() >>> parser.parseFragment('this is a fragment') """ self._parse(stream, True, *args, **kwargs) return self.tree.getFragment() def parseError(self, errorcode="XXX-undefined-error", datavars=None): # XXX The idea is to make errorcode mandatory. if datavars is None: datavars = {} self.errors.append((self.tokenizer.stream.position(), errorcode, datavars)) if self.strict: raise ParseError(E[errorcode] % datavars) def adjustMathMLAttributes(self, token): adjust_attributes(token, adjustMathMLAttributes) def adjustSVGAttributes(self, token): adjust_attributes(token, adjustSVGAttributes) def adjustForeignAttributes(self, token): adjust_attributes(token, adjustForeignAttributesMap) def reparseTokenNormal(self, token): # pylint:disable=unused-argument self.parser.phase() def resetInsertionMode(self): # The name of this method is mostly historical. (It's also used in the # specification.) last = False newModes = { "select": "inSelect", "td": "inCell", "th": "inCell", "tr": "inRow", "tbody": "inTableBody", "thead": "inTableBody", "tfoot": "inTableBody", "caption": "inCaption", "colgroup": "inColumnGroup", "table": "inTable", "head": "inBody", "body": "inBody", "frameset": "inFrameset", "html": "beforeHead" } for node in self.tree.openElements[::-1]: nodeName = node.name new_phase = None if node == self.tree.openElements[0]: assert self.innerHTML last = True nodeName = self.innerHTML # Check for conditions that should only happen in the innerHTML # case if nodeName in ("select", "colgroup", "head", "html"): assert self.innerHTML if not last and node.namespace != self.tree.defaultNamespace: continue if nodeName in newModes: new_phase = self.phases[newModes[nodeName]] break elif last: new_phase = self.phases["inBody"] break self.phase = new_phase def parseRCDataRawtext(self, token, contentType): # Generic RCDATA/RAWTEXT Parsing algorithm assert contentType in ("RAWTEXT", "RCDATA") self.tree.insertElement(token) if contentType == "RAWTEXT": self.tokenizer.state = self.tokenizer.rawtextState else: self.tokenizer.state = self.tokenizer.rcdataState self.originalPhase = self.phase self.phase = self.phases["text"] @_utils.memoize def getPhases(debug): def log(function): """Logger that records which phase processes each token""" type_names = {value: key for key, value in tokenTypes.items()} def wrapped(self, *args, **kwargs): if function.__name__.startswith("process") and len(args) > 0: token = args[0] info = {"type": type_names[token['type']]} if token['type'] in tagTokenTypes: info["name"] = token['name'] self.parser.log.append((self.parser.tokenizer.state.__name__, self.parser.phase.__class__.__name__, self.__class__.__name__, function.__name__, info)) return function(self, *args, **kwargs) else: return function(self, *args, **kwargs) return wrapped def getMetaclass(use_metaclass, metaclass_func): if use_metaclass: return method_decorator_metaclass(metaclass_func) else: return type # pylint:disable=unused-argument class Phase(with_metaclass(getMetaclass(debug, log))): """Base class for helper object that implements each phase of processing """ __slots__ = ("parser", "tree", "__startTagCache", "__endTagCache") def __init__(self, parser, tree): self.parser = parser self.tree = tree self.__startTagCache = {} self.__endTagCache = {} def processEOF(self): raise NotImplementedError def processComment(self, token): # For most phases the following is correct. Where it's not it will be # overridden. self.tree.insertComment(token, self.tree.openElements[-1]) def processDoctype(self, token): self.parser.parseError("unexpected-doctype") def processCharacters(self, token): self.tree.insertText(token["data"]) def processSpaceCharacters(self, token): self.tree.insertText(token["data"]) def processStartTag(self, token): # Note the caching is done here rather than BoundMethodDispatcher as doing it there # requires a circular reference to the Phase, and this ends up with a significant # (CPython 2.7, 3.8) GC cost when parsing many short inputs name = token["name"] # In Py2, using `in` is quicker in general than try/except KeyError # In Py3, `in` is quicker when there are few cache hits (typically short inputs) if name in self.__startTagCache: func = self.__startTagCache[name] else: func = self.__startTagCache[name] = self.startTagHandler[name] # bound the cache size in case we get loads of unknown tags while len(self.__startTagCache) > len(self.startTagHandler) * 1.1: # this makes the eviction policy random on Py < 3.7 and FIFO >= 3.7 self.__startTagCache.pop(next(iter(self.__startTagCache))) return func(token) def startTagHtml(self, token): if not self.parser.firstStartTag and token["name"] == "html": self.parser.parseError("non-html-root") # XXX Need a check here to see if the first start tag token emitted is # this token... If it's not, invoke self.parser.parseError(). for attr, value in token["data"].items(): if attr not in self.tree.openElements[0].attributes: self.tree.openElements[0].attributes[attr] = value self.parser.firstStartTag = False def processEndTag(self, token): # Note the caching is done here rather than BoundMethodDispatcher as doing it there # requires a circular reference to the Phase, and this ends up with a significant # (CPython 2.7, 3.8) GC cost when parsing many short inputs name = token["name"] # In Py2, using `in` is quicker in general than try/except KeyError # In Py3, `in` is quicker when there are few cache hits (typically short inputs) if name in self.__endTagCache: func = self.__endTagCache[name] else: func = self.__endTagCache[name] = self.endTagHandler[name] # bound the cache size in case we get loads of unknown tags while len(self.__endTagCache) > len(self.endTagHandler) * 1.1: # this makes the eviction policy random on Py < 3.7 and FIFO >= 3.7 self.__endTagCache.pop(next(iter(self.__endTagCache))) return func(token) class InitialPhase(Phase): __slots__ = tuple() def processSpaceCharacters(self, token): pass def processComment(self, token): self.tree.insertComment(token, self.tree.document) def processDoctype(self, token): name = token["name"] publicId = token["publicId"] systemId = token["systemId"] correct = token["correct"] if (name != "html" or publicId is not None or systemId is not None and systemId != "about:legacy-compat"): self.parser.parseError("unknown-doctype") if publicId is None: publicId = "" self.tree.insertDoctype(token) if publicId != "": publicId = publicId.translate(asciiUpper2Lower) if (not correct or token["name"] != "html" or publicId.startswith( ("+//silmaril//dtd html pro v0r11 19970101//", "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", "-//as//dtd html 3.0 aswedit + extensions//", "-//ietf//dtd html 2.0 level 1//", "-//ietf//dtd html 2.0 level 2//", "-//ietf//dtd html 2.0 strict level 1//", "-//ietf//dtd html 2.0 strict level 2//", "-//ietf//dtd html 2.0 strict//", "-//ietf//dtd html 2.0//", "-//ietf//dtd html 2.1e//", "-//ietf//dtd html 3.0//", "-//ietf//dtd html 3.2 final//", "-//ietf//dtd html 3.2//", "-//ietf//dtd html 3//", "-//ietf//dtd html level 0//", "-//ietf//dtd html level 1//", "-//ietf//dtd html level 2//", "-//ietf//dtd html level 3//", "-//ietf//dtd html strict level 0//", "-//ietf//dtd html strict level 1//", "-//ietf//dtd html strict level 2//", "-//ietf//dtd html strict level 3//", "-//ietf//dtd html strict//", "-//ietf//dtd html//", "-//metrius//dtd metrius presentational//", "-//microsoft//dtd internet explorer 2.0 html strict//", "-//microsoft//dtd internet explorer 2.0 html//", "-//microsoft//dtd internet explorer 2.0 tables//", "-//microsoft//dtd internet explorer 3.0 html strict//", "-//microsoft//dtd internet explorer 3.0 html//", "-//microsoft//dtd internet explorer 3.0 tables//", "-//netscape comm. corp.//dtd html//", "-//netscape comm. corp.//dtd strict html//", "-//o'reilly and associates//dtd html 2.0//", "-//o'reilly and associates//dtd html extended 1.0//", "-//o'reilly and associates//dtd html extended relaxed 1.0//", "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", "-//spyglass//dtd html 2.0 extended//", "-//sq//dtd html 2.0 hotmetal + extensions//", "-//sun microsystems corp.//dtd hotjava html//", "-//sun microsystems corp.//dtd hotjava strict html//", "-//w3c//dtd html 3 1995-03-24//", "-//w3c//dtd html 3.2 draft//", "-//w3c//dtd html 3.2 final//", "-//w3c//dtd html 3.2//", "-//w3c//dtd html 3.2s draft//", "-//w3c//dtd html 4.0 frameset//", "-//w3c//dtd html 4.0 transitional//", "-//w3c//dtd html experimental 19960712//", "-//w3c//dtd html experimental 970421//", "-//w3c//dtd w3 html//", "-//w3o//dtd w3 html 3.0//", "-//webtechs//dtd mozilla html 2.0//", "-//webtechs//dtd mozilla html//")) or publicId in ("-//w3o//dtd w3 html strict 3.0//en//", "-/w3c/dtd html 4.0 transitional/en", "html") or publicId.startswith( ("-//w3c//dtd html 4.01 frameset//", "-//w3c//dtd html 4.01 transitional//")) and systemId is None or systemId and systemId.lower() == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"): self.parser.compatMode = "quirks" elif (publicId.startswith( ("-//w3c//dtd xhtml 1.0 frameset//", "-//w3c//dtd xhtml 1.0 transitional//")) or publicId.startswith( ("-//w3c//dtd html 4.01 frameset//", "-//w3c//dtd html 4.01 transitional//")) and systemId is not None): self.parser.compatMode = "limited quirks" self.parser.phase = self.parser.phases["beforeHtml"] def anythingElse(self): self.parser.compatMode = "quirks" self.parser.phase = self.parser.phases["beforeHtml"] def processCharacters(self, token): self.parser.parseError("expected-doctype-but-got-chars") self.anythingElse() return token def processStartTag(self, token): self.parser.parseError("expected-doctype-but-got-start-tag", {"name": token["name"]}) self.anythingElse() return token def processEndTag(self, token): self.parser.parseError("expected-doctype-but-got-end-tag", {"name": token["name"]}) self.anythingElse() return token def processEOF(self): self.parser.parseError("expected-doctype-but-got-eof") self.anythingElse() return True class BeforeHtmlPhase(Phase): __slots__ = tuple() # helper methods def insertHtmlElement(self): self.tree.insertRoot(impliedTagToken("html", "StartTag")) self.parser.phase = self.parser.phases["beforeHead"] # other def processEOF(self): self.insertHtmlElement() return True def processComment(self, token): self.tree.insertComment(token, self.tree.document) def processSpaceCharacters(self, token): pass def processCharacters(self, token): self.insertHtmlElement() return token def processStartTag(self, token): if token["name"] == "html": self.parser.firstStartTag = True self.insertHtmlElement() return token def processEndTag(self, token): if token["name"] not in ("head", "body", "html", "br"): self.parser.parseError("unexpected-end-tag-before-html", {"name": token["name"]}) else: self.insertHtmlElement() return token class BeforeHeadPhase(Phase): __slots__ = tuple() def processEOF(self): self.startTagHead(impliedTagToken("head", "StartTag")) return True def processSpaceCharacters(self, token): pass def processCharacters(self, token): self.startTagHead(impliedTagToken("head", "StartTag")) return token def startTagHtml(self, token): return self.parser.phases["inBody"].processStartTag(token) def startTagHead(self, token): self.tree.insertElement(token) self.tree.headPointer = self.tree.openElements[-1] self.parser.phase = self.parser.phases["inHead"] def startTagOther(self, token): self.startTagHead(impliedTagToken("head", "StartTag")) return token def endTagImplyHead(self, token): self.startTagHead(impliedTagToken("head", "StartTag")) return token def endTagOther(self, token): self.parser.parseError("end-tag-after-implied-root", {"name": token["name"]}) startTagHandler = _utils.MethodDispatcher([ ("html", startTagHtml), ("head", startTagHead) ]) startTagHandler.default = startTagOther endTagHandler = _utils.MethodDispatcher([ (("head", "body", "html", "br"), endTagImplyHead) ]) endTagHandler.default = endTagOther class InHeadPhase(Phase): __slots__ = tuple() # the real thing def processEOF(self): self.anythingElse() return True def processCharacters(self, token): self.anythingElse() return token def startTagHtml(self, token): return self.parser.phases["inBody"].processStartTag(token) def startTagHead(self, token): self.parser.parseError("two-heads-are-not-better-than-one") def startTagBaseLinkCommand(self, token): self.tree.insertElement(token) self.tree.openElements.pop() token["selfClosingAcknowledged"] = True def startTagMeta(self, token): self.tree.insertElement(token) self.tree.openElements.pop() token["selfClosingAcknowledged"] = True attributes = token["data"] if self.parser.tokenizer.stream.charEncoding[1] == "tentative": if "charset" in attributes: self.parser.tokenizer.stream.changeEncoding(attributes["charset"]) elif ("content" in attributes and "http-equiv" in attributes and attributes["http-equiv"].lower() == "content-type"): # Encoding it as UTF-8 here is a hack, as really we should pass # the abstract Unicode string, and just use the # ContentAttrParser on that, but using UTF-8 allows all chars # to be encoded and as a ASCII-superset works. data = _inputstream.EncodingBytes(attributes["content"].encode("utf-8")) parser = _inputstream.ContentAttrParser(data) codec = parser.parse() self.parser.tokenizer.stream.changeEncoding(codec) def startTagTitle(self, token): self.parser.parseRCDataRawtext(token, "RCDATA") def startTagNoFramesStyle(self, token): # Need to decide whether to implement the scripting-disabled case self.parser.parseRCDataRawtext(token, "RAWTEXT") def startTagNoscript(self, token): if self.parser.scripting: self.parser.parseRCDataRawtext(token, "RAWTEXT") else: self.tree.insertElement(token) self.parser.phase = self.parser.phases["inHeadNoscript"] def startTagScript(self, token): self.tree.insertElement(token) self.parser.tokenizer.state = self.parser.tokenizer.scriptDataState self.parser.originalPhase = self.parser.phase self.parser.phase = self.parser.phases["text"] def startTagOther(self, token): self.anythingElse() return token def endTagHead(self, token): node = self.parser.tree.openElements.pop() assert node.name == "head", "Expected head got %s" % node.name self.parser.phase = self.parser.phases["afterHead"] def endTagHtmlBodyBr(self, token): self.anythingElse() return token def endTagOther(self, token): self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) def anythingElse(self): self.endTagHead(impliedTagToken("head")) startTagHandler = _utils.MethodDispatcher([ ("html", startTagHtml), ("title", startTagTitle), (("noframes", "style"), startTagNoFramesStyle), ("noscript", startTagNoscript), ("script", startTagScript), (("base", "basefont", "bgsound", "command", "link"), startTagBaseLinkCommand), ("meta", startTagMeta), ("head", startTagHead) ]) startTagHandler.default = startTagOther endTagHandler = _utils.MethodDispatcher([ ("head", endTagHead), (("br", "html", "body"), endTagHtmlBodyBr) ]) endTagHandler.default = endTagOther class InHeadNoscriptPhase(Phase): __slots__ = tuple() def processEOF(self): self.parser.parseError("eof-in-head-noscript") self.anythingElse() return True def processComment(self, token): return self.parser.phases["inHead"].processComment(token) def processCharacters(self, token): self.parser.parseError("char-in-head-noscript") self.anythingElse() return token def processSpaceCharacters(self, token): return self.parser.phases["inHead"].processSpaceCharacters(token) def startTagHtml(self, token): return self.parser.phases["inBody"].processStartTag(token) def startTagBaseLinkCommand(self, token): return self.parser.phases["inHead"].processStartTag(token) def startTagHeadNoscript(self, token): self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) def startTagOther(self, token): self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) self.anythingElse() return token def endTagNoscript(self, token): node = self.parser.tree.openElements.pop() assert node.name == "noscript", "Expected noscript got %s" % node.name self.parser.phase = self.parser.phases["inHead"] def endTagBr(self, token): self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) self.anythingElse() return token def endTagOther(self, token): self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) def anythingElse(self): # Caller must raise parse error first! self.endTagNoscript(impliedTagToken("noscript")) startTagHandler = _utils.MethodDispatcher([ ("html", startTagHtml), (("basefont", "bgsound", "link", "meta", "noframes", "style"), startTagBaseLinkCommand), (("head", "noscript"), startTagHeadNoscript), ]) startTagHandler.default = startTagOther endTagHandler = _utils.MethodDispatcher([ ("noscript", endTagNoscript), ("br", endTagBr), ]) endTagHandler.default = endTagOther class AfterHeadPhase(Phase): __slots__ = tuple() def processEOF(self): self.anythingElse() return True def processCharacters(self, token): self.anythingElse() return token def startTagHtml(self, token): return self.parser.phases["inBody"].processStartTag(token) def startTagBody(self, token): self.parser.framesetOK = False self.tree.insertElement(token) self.parser.phase = self.parser.phases["inBody"] def startTagFrameset(self, token): self.tree.insertElement(token) self.parser.phase = self.parser.phases["inFrameset"] def startTagFromHead(self, token): self.parser.parseError("unexpected-start-tag-out-of-my-head", {"name": token["name"]}) self.tree.openElements.append(self.tree.headPointer) self.parser.phases["inHead"].processStartTag(token) for node in self.tree.openElements[::-1]: if node.name == "head": self.tree.openElements.remove(node) break def startTagHead(self, token): self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) def startTagOther(self, token): self.anythingElse() return token def endTagHtmlBodyBr(self, token): self.anythingElse() return token def endTagOther(self, token): self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) def anythingElse(self): self.tree.insertElement(impliedTagToken("body", "StartTag")) self.parser.phase = self.parser.phases["inBody"] self.parser.framesetOK = True startTagHandler = _utils.MethodDispatcher([ ("html", startTagHtml), ("body", startTagBody), ("frameset", startTagFrameset), (("base", "basefont", "bgsound", "link", "meta", "noframes", "script", "style", "title"), startTagFromHead), ("head", startTagHead) ]) startTagHandler.default = startTagOther endTagHandler = _utils.MethodDispatcher([(("body", "html", "br"), endTagHtmlBodyBr)]) endTagHandler.default = endTagOther class InBodyPhase(Phase): # http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-inbody # the really-really-really-very crazy mode __slots__ = ("processSpaceCharacters",) def __init__(self, *args, **kwargs): super(InBodyPhase, self).__init__(*args, **kwargs) # Set this to the default handler self.processSpaceCharacters = self.processSpaceCharactersNonPre def isMatchingFormattingElement(self, node1, node2): return (node1.name == node2.name and node1.namespace == node2.namespace and node1.attributes == node2.attributes) # helper def addFormattingElement(self, token): self.tree.insertElement(token) element = self.tree.openElements[-1] matchingElements = [] for node in self.tree.activeFormattingElements[::-1]: if node is Marker: break elif self.isMatchingFormattingElement(node, element): matchingElements.append(node) assert len(matchingElements) <= 3 if len(matchingElements) == 3: self.tree.activeFormattingElements.remove(matchingElements[-1]) self.tree.activeFormattingElements.append(element) # the real deal def processEOF(self): allowed_elements = frozenset(("dd", "dt", "li", "p", "tbody", "td", "tfoot", "th", "thead", "tr", "body", "html")) for node in self.tree.openElements[::-1]: if node.name not in allowed_elements: self.parser.parseError("expected-closing-tag-but-got-eof") break # Stop parsing def processSpaceCharactersDropNewline(self, token): # Sometimes (start of
, , and